Compare commits

..
Author SHA1 Message Date
Benjamin Doherty d0eb56ff20 Merge branch 'rc/1.51.2' into release 2024-04-01 16:44:39 -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 3ed008c0b6 Bump material version to 51 in MaterialEnums.h 2024-03-26 21:38:02 +00:00
Powei Feng 66ec81187d vk: delete instead of ref-count EmptyTexture (#7711) 2024-03-26 20:36:45 +00:00
Powei Feng 0efd94a769 Add missing include to Platform.h (#7709) 2024-03-26 20:09:47 +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
Ben Doherty dbf0cde330 Metal: track buffer allocations (#7556) 2024-03-22 12:48:24 -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
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 de6df6dc0e Bump MATERIAL_VERSION to 51 2024-03-14 10:40:26 -07:00
Ben Doherty 6dd85c6530 Remove erroneous assertion (#7661) 2024-03-12 14:33:14 -07: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
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
Ben Doherty ca27bb58bf Metal: change shader compilation pool size to 1 (#7639) 2024-03-08 10:33:37 -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 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 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 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
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
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
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
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
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 fadd5eb953 fix a uninitialized memory access when no renderable are visible 2024-02-21 10:52:50 -08:00
Powei Feng b48b6136ba geometry: properly reference memcpy usage (#7576) 2024-02-16 15:35:01 -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
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
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 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
Ben Doherty 3c5316f1e9 Metal: schedule PresentDrawable for destruction on the main thread (#7535) 2024-02-01 10:47:37 -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
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 6b7450dc0b Update material version to 50 2024-01-22 23:25:59 +00: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
Powei Feng 20dc6d479b Merge branch 'rc/1.49.3' into release 2024-01-22 11:43:54 -08:00
Powei Feng 0736f3c3b3 Add missing includes (#7501)
BUG=320668410
2024-01-17 11:08:58 -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
634 changed files with 29207 additions and 45008 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: macos-14
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: macos-14
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/ios && printf "y" | ./build.sh continuous
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/linux && printf "y" | ./build.sh continuous
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: macos-14
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh continuous
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
name: npm-deploy
runs-on: macos-14
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
with:
ref: ${{ github.event.inputs.release_tag }}
# Setup .npmrc file to publish to npm
+5 -5
View File
@@ -18,7 +18,7 @@ jobs:
os: [macos-14, ubuntu-22.04]
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
WORKFLOW_OS=`echo \`uname\` | sed "s/Darwin/mac/" | tr [:upper:] [:lower:]`
@@ -32,7 +32,7 @@ jobs:
runs-on: windows-2019
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
build\windows\build-github.bat presubmit
@@ -43,7 +43,7 @@ jobs:
runs-on: macos-14
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
@@ -57,7 +57,7 @@ jobs:
runs-on: macos-14
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/ios && printf "y" | ./build.sh presubmit
@@ -70,7 +70,7 @@ jobs:
runs-on: macos-14
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh presubmit
+5 -5
View File
@@ -41,7 +41,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -76,7 +76,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -109,7 +109,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- uses: actions/setup-java@v3
@@ -163,7 +163,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -197,7 +197,7 @@ jobs:
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
shell: bash
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: macos-14
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh continuous
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: windows-2019
steps:
- uses: actions/checkout@v4.1.6
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
build\windows\build-github.bat continuous
+16 -45
View File
@@ -73,6 +73,7 @@ The following CMake options are boolean options specific to Filament:
- `FILAMENT_SUPPORTS_VULKAN`: Include the Vulkan backend
- `FILAMENT_INSTALL_BACKEND_TEST`: Install the backend test library so it can be consumed on iOS
- `FILAMENT_USE_EXTERNAL_GLES3`: Experimental: Compile Filament against OpenGL ES 3
- `FILAMENT_USE_SWIFTSHADER`: Compile Filament against SwiftShader
- `FILAMENT_SKIP_SAMPLES`: Don't build sample apps
To turn an option on or off:
@@ -425,7 +426,7 @@ value is the desired roughness between 0 and 1.
## Generating C++ documentation
To generate the documentation you must first install `doxygen` and `graphviz`, then run the
To generate the documentation you must first install `doxygen` and `graphviz`, then run the
following commands:
```shell
@@ -435,62 +436,32 @@ doxygen docs/doxygen/filament.doxygen
Finally simply open `docs/html/index.html` in your web browser.
## Software Rasterization
## SwiftShader
We have tested swiftshader and Mesa for software rasterization on the Vulkan/GL backends.
To use this for Vulkan, please first make sure that the [Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) is
installed on your machine. If you are doing a manual installation of the SDK on Linux, you will have
to source `setup-env.sh` in the SDK's root folder to make sure the Vulkan loader is the first lib loaded.
### Swiftshader (Vulkan) [tested on macOS and Linux]
First, build SwiftShader
To try out Filament's Vulkan support with SwiftShader, first build SwiftShader and set the
`SWIFTSHADER_LD_LIBRARY_PATH` variable to the folder that contains `libvk_swiftshader.dylib`:
```shell
git clone https://github.com/google/swiftshader.git
cd swiftshader/build
cmake .. && make -j
export SWIFTSHADER_LD_LIBRARY_PATH=`pwd`
```
and then set `VK_ICD_FILENAMES` to the ICD json produced in the build. For example,
```shell
export VK_ICD_FILENAMES=/Users/user/swiftshader/build/Darwin/vk_swiftshader_icd.json
```
Next, go to your Filament repo and use the [easy build](#easy-build) script with `-t`.
Build and run Filament as usual and specify the Vulkan backend when creating the Engine.
## SwiftShader for CI
### Mesa's LLVMPipe (GL) and Lavapipe (Vulkan) [tested on Linux]
We will only cover steps that build Mesa from source. The official documentation of Mesa mentioned
that in general precompiled libraries [are **not** made available](https://docs.mesa3d.org/precompiled.html).
Download the repo and make sure you have the build depedencies. For example (assuming an Ubuntu/Debian distro),
```shell
git clone https://gitlab.freedesktop.org/mesa/mesa.git
sudo apt-get build-dep mesa
```
To build both the GL and Vulkan rasterizers,
Continuous testing turnaround can be quite slow if you need to build SwiftShader from scratch, so we
provide an Ubuntu-based Docker image that has it already built. The Docker image also includes
everything necessary for building Filament. You can fetch and run the image as follows:
```shell
cd mesa
mkdir -p out
meson setup builddir/ -Dprefix=$(pwd)/out -Dglx=xlib -Dgallium-drivers=swrast -Dvulkan-drivers=swrast
meson install -C builddir/
docker pull ghcr.io/filament-assets/swiftshader
docker run -it ghcr.io/filament-assets/swiftshader
```
For GL, we need to ensure that we load the GL lib from the mesa output directory. For example, to run
the debug `gltf_viewer`, we would execute
```shell
LD_LIBRARY_PATH=/Users/user/mesa/out/lib/x86_64-linux-gnu \
./out/cmake-debug/samples/gltf_viewer -a opengl
```
To do more with the container, see the helper script at `build/swiftshader/test.sh`.
For Vulkan, we need to set the path to the ICD json, which tells the loader where to find the driver
library. To run `gltf_viewer`, we would execute
```shell
VK_ICD_FILENAMES=/Users/user/mesa/out/share/vulkan/icd.d/lvp_icd.x86_64.json \
./out/cmake-debug/samples/gltf_viewer -a vulkan
```
If you are a team member, you can update the public image to the latest SwiftShader by
following the instructions at the top of `build/swiftshader/Dockerfile`.
+42 -27
View File
@@ -21,6 +21,8 @@ project(TNT)
# ==================================================================================================
option(FILAMENT_USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" OFF)
option(FILAMENT_USE_SWIFTSHADER "Compile Filament against SwiftShader" OFF)
option(FILAMENT_ENABLE_LTO "Enable link-time optimizations if supported by the compiler" OFF)
option(FILAMENT_SKIP_SAMPLES "Don't build samples" OFF)
@@ -69,10 +71,6 @@ set(FILAMENT_METAL_HANDLE_ARENA_SIZE_IN_MB "8" CACHE STRING
"Size of the Metal handle arena, default 8."
)
set(FILAMENT_BACKEND_DEBUG_FLAG "" CACHE STRING
"A debug flag meant for enabling/disabling backend debugging paths"
)
# Enable exceptions by default in spirv-cross.
set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS OFF)
@@ -143,6 +141,11 @@ if (LINUX)
add_definitions(-DFILAMENT_SUPPORTS_XCB)
endif()
# Default Swiftshader build does not enable the xlib extension
if (FILAMENT_SUPPORTS_XLIB AND FILAMENT_USE_SWIFTSHADER)
set(FILAMENT_SUPPORTS_XLIB OFF)
endif()
if (FILAMENT_SUPPORTS_XLIB)
add_definitions(-DFILAMENT_SUPPORTS_XLIB)
endif()
@@ -166,6 +169,15 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS AND NOT FILAMENT_LINUX_IS_MOBILE)
set(IS_HOST_PLATFORM TRUE)
endif()
if (IOS)
# Remove the headerpad_max_install_names linker flag on iOS. It causes warnings when linking
# executables with bitcode.
string(REPLACE "-Wl,-headerpad_max_install_names" "" CMAKE_C_LINK_FLAGS ${CMAKE_C_LINK_FLAGS})
string(REPLACE "-Wl,-headerpad_max_install_names" "" CMAKE_CXX_LINK_FLAGS ${CMAKE_CXX_LINK_FLAGS})
string(REPLACE "-Wl,-headerpad_max_install_names" "" CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS})
string(REPLACE "-Wl,-headerpad_max_install_names" "" CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS})
endif()
if (WIN32)
# Link statically against c/c++ lib to avoid missing redistriburable such as
# "VCRUNTIME140.dll not found. Try reinstalling the app.", but give users
@@ -320,6 +332,10 @@ if (FILAMENT_SUPPORTS_EGL_ON_LINUX)
set(EGL TRUE)
endif()
if (FILAMENT_USE_SWIFTSHADER)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFILAMENT_USE_SWIFTSHADER")
endif()
if (WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_USE_MATH_DEFINES=1")
endif()
@@ -373,9 +389,8 @@ endif()
if (NOT MSVC AND NOT IOS)
# Omitting stack frame pointers prevents the generation of readable stack traces in crash reports on iOS
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer")
endif()
if (NOT MSVC)
# These aren't compatible with -fembed-bitcode (and seem to have no effect on Apple platforms anyway)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections")
endif()
@@ -440,13 +455,8 @@ endif()
if (NOT WEBGL)
set(GC_SECTIONS "-Wl,--gc-sections")
endif()
set(B_SYMBOLIC_FUNCTIONS "-Wl,-Bsymbolic-functions")
if (ANDROID)
set(BINARY_ALIGNMENT "-Wl,-z,max-page-size=16384")
endif()
if (APPLE)
set(GC_SECTIONS "-Wl,-dead_strip")
set(B_SYMBOLIC_FUNCTIONS "")
@@ -460,7 +470,7 @@ if (APPLE)
endif()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GC_SECTIONS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GC_SECTIONS} ${B_SYMBOLIC_FUNCTIONS} ${BINARY_ALIGNMENT}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GC_SECTIONS} ${B_SYMBOLIC_FUNCTIONS}")
if (WEBGL_PTHREADS)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pthread")
@@ -524,15 +534,13 @@ else()
endif()
# This only affects the prebuilt shader files in gltfio and samples, not filament library.
# The value can be either "instanced", "multiview", or "none"
set(FILAMENT_SAMPLES_STEREO_TYPE "none" CACHE STRING
# 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"
AND NOT FILAMENT_SAMPLES_STEREO_TYPE STREQUAL "none")
message(FATAL_ERROR "Invalid stereo type: \"${FILAMENT_SAMPLES_STEREO_TYPE}\" choose either \"instanced\", \"multiview\", or \"none\" ")
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.
@@ -540,12 +548,6 @@ if (FILAMENT_SAMPLES_STEREO_TYPE STREQUAL "multiview")
set(FILAMENT_ENABLE_MULTIVIEW ON)
endif ()
# Define backend flag for debug only
if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT FILAMENT_BACKEND_DEBUG_FLAG STREQUAL "")
add_definitions(-DFILAMENT_BACKEND_DEBUG_FLAG=${FILAMENT_BACKEND_DEBUG_FLAG})
unset(FILAMENT_BACKEND_DEBUG_FLAG)
endif()
# ==================================================================================================
# Material compilation flags
# ==================================================================================================
@@ -674,6 +676,21 @@ else()
set(IMPORT_EXECUTABLES ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-${CMAKE_BUILD_TYPE}.cmake)
endif()
# ==================================================================================================
# Try to find Vulkan if the SDK is installed, otherwise fall back to the bundled version.
# This needs to stay in our top-level CMakeLists because it sets up variables that are used by the
# "bluevk" and "samples" targets.
# ==================================================================================================
if (FILAMENT_USE_SWIFTSHADER)
if (NOT FILAMENT_SUPPORTS_VULKAN)
message(ERROR "SwiftShader is only useful when Vulkan is enabled.")
endif()
find_library(SWIFTSHADER_VK NAMES vk_swiftshader HINTS "$ENV{SWIFTSHADER_LD_LIBRARY_PATH}")
message(STATUS "Found SwiftShader VK library in: ${SWIFTSHADER_VK}.")
add_definitions(-DFILAMENT_VKLIBRARY_PATH=\"${SWIFTSHADER_VK}\")
endif()
# ==================================================================================================
# Common Functions
# ==================================================================================================
@@ -735,6 +752,7 @@ add_subdirectory(${FILAMENT}/filament)
add_subdirectory(${FILAMENT}/shaders)
add_subdirectory(${EXTERNAL}/basisu/tnt)
add_subdirectory(${EXTERNAL}/civetweb/tnt)
add_subdirectory(${EXTERNAL}/hat-trie/tnt)
add_subdirectory(${EXTERNAL}/imgui/tnt)
add_subdirectory(${EXTERNAL}/robin-map/tnt)
add_subdirectory(${EXTERNAL}/smol-v/tnt)
@@ -801,9 +819,6 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${TOOLS}/glslminifier)
add_subdirectory(${TOOLS}/matc)
add_subdirectory(${TOOLS}/matinfo)
if (NOT WIN32) # matedit not yet supported on Windows
add_subdirectory(${TOOLS}/matedit)
endif()
add_subdirectory(${TOOLS}/mipgen)
add_subdirectory(${TOOLS}/normal-blending)
add_subdirectory(${TOOLS}/resgen)
-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
- Add a `name` API to Filament objects for debugging handle use-after-free assertions
+2 -3
View File
@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.54.0'
implementation 'com.google.android.filament:filament-android:1.51.2'
}
```
@@ -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.54.0'
pod 'Filament', '~> 1.51.2'
```
### Snapshots
@@ -176,7 +176,6 @@ steps:
- [x] KHR_materials_unlit
- [x] KHR_materials_variants
- [x] KHR_materials_volume
- [x] KHR_materials_specular
- [x] KHR_mesh_quantization
- [x] KHR_texture_basisu
- [x] KHR_texture_transform
-71
View File
@@ -7,77 +7,6 @@ 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.54.1
## v1.54.0
- materials: add a new `stereoscopicType` material parameter. [⚠️ **New Material Version**]
- Fix a crash when compiling shaders on IMG devices
## v1.53.5
- engine: Fix bug causing certain sampler parameters to not be applied correctly in GLES 2.0 and on
certain GLES 3.0 drivers.
## v1.53.4
## v1.53.3
- Add drag and drop support for IBL files for desktop gltf_viewer.
## v1.53.2
## v1.53.1
## v1.53.0
- engine: fix skinning normals with large transforms (b/342459864) [⚠️ **New Material Version**]
## v1.52.3
## v1.52.2
## v1.52.1
- Add instructions for using Mesa for software rasterization
## v1.51.9
## v1.51.8
- filagui: Fix regression which broke WebGL
- Add a new Engine::Config setting to control preferred shader language
- Add `getEyeIndex` vertex API
- ios: Remove bitcode from iOS builds
## v1.51.7
- Add new matedit tool
- filagui: Support rendering `GL_TEXTURE_EXTERNAL_OES` textures.
- `setFrameScheduledCallback` now takes a `utils::Invocable`.
- engine: Add `isPaused()`
## v1.51.6
- Add new matedit tool
- filagui: Support rendering `GL_TEXTURE_EXTERNAL_OES` textures.
## v1.51.5
## v1.51.4
## v1.51.3
## v1.51.2
- engine: Add experimental APIs `Engine::builder::paused()` and `Engine::setPaused()`
+6 -6
View File
@@ -83,12 +83,12 @@ buildscript {
'minSdk': 21,
'targetSdk': 34,
'compileSdk': 34,
'kotlin': '2.0.0',
'kotlin_coroutines': '1.9.0-RC',
'kotlin': '1.9.21',
'kotlin_coroutines': '1.7.3',
'buildTools': '34.0.0',
'ndk': '27.0.11718014',
'androidx_core': '1.13.1',
'androidx_annotations': '1.8.0'
'ndk': '26.1.10909125',
'androidx_core': '1.12.0',
'androidx_annotations': '1.7.0'
]
ext.deps = [
@@ -104,7 +104,7 @@ buildscript {
]
dependencies {
classpath 'com.android.tools.build:gradle:8.4.1'
classpath 'com.android.tools.build:gradle:8.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
}
-1
View File
@@ -38,7 +38,6 @@ set(FILAMAT_INCLUDE_DIRS
include_directories(${FILAMENT_DIR}/include)
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_SOURCE_DIR}/libfilamat-jni.map")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
add_library(filamat-jni SHARED src/main/cpp/MaterialBuilder.cpp)
target_include_directories(filamat-jni PRIVATE ${FILAMAT_INCLUDE_DIRS})
-1
View File
@@ -59,7 +59,6 @@ endif()
set(VERSION_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/libfilament-jni.map")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${VERSION_SCRIPT}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
add_library(filament-jni SHARED
src/main/cpp/BufferObject.cpp
@@ -342,21 +342,6 @@ Java_com_google_android_filament_Engine_nIsValidMaterial(JNIEnv*, jclass,
return (jboolean)engine->isValid((Material*)nativeMaterial);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidMaterialInstance(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeMaterial, jlong nativeMaterialInstance) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((Material*)nativeMaterial,
(MaterialInstance*)nativeMaterialInstance);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidExpensiveMaterialInstance(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeMaterialInstance) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValidExpensive((MaterialInstance*)nativeMaterialInstance);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidSkybox(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeSkybox) {
@@ -406,13 +391,6 @@ Java_com_google_android_filament_Engine_nFlush(JNIEnv*, jclass,
engine->flush();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsPaused(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jboolean)engine->isPaused();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Engine_nSetPaused(JNIEnv*, jclass,
jlong nativeEngine, jboolean paused) {
@@ -420,13 +398,6 @@ Java_com_google_android_filament_Engine_nSetPaused(JNIEnv*, jclass,
engine->setPaused(paused);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Engine_nUnprotected(JNIEnv*, jclass,
jlong nativeEngine, jboolean paused) {
Engine* engine = (Engine*) nativeEngine;
engine->unprotected();
}
// Managers...
extern "C" JNIEXPORT jlong JNICALL
@@ -524,9 +495,7 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBu
jlong textureUseAfterFreePoolSize, jboolean disableParallelShaderCompile,
jint stereoscopicType, jlong stereoscopicEyeCount,
jlong resourceAllocatorCacheSizeMB, jlong resourceAllocatorCacheMaxAge,
jboolean disableHandleUseAfterFreeCheck,
jint preferredShaderLanguage,
jboolean forceGLES2Context) {
jboolean disableHandleUseAfterFreeCheck) {
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
Engine::Config config = {
.commandBufferSizeMB = (uint32_t) commandBufferSizeMB,
@@ -542,8 +511,6 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBu
.resourceAllocatorCacheSizeMB = (uint32_t) resourceAllocatorCacheSizeMB,
.resourceAllocatorCacheMaxAge = (uint8_t) resourceAllocatorCacheMaxAge,
.disableHandleUseAfterFreeCheck = (bool) disableHandleUseAfterFreeCheck,
.preferredShaderLanguage = (Engine::Config::ShaderLanguage) preferredShaderLanguage,
.forceGLES2Context = (bool) forceGLES2Context,
};
builder->config(&config);
}
@@ -571,9 +538,3 @@ Java_com_google_android_filament_Engine_nBuilderBuild(JNIEnv*, jclass, jlong nat
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
return (jlong) builder->build();
}
extern "C"
JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_getSteadyClockTimeNano(JNIEnv *env, jclass clazz) {
return (jlong)Engine::getSteadyClockTimeNano();
}
@@ -25,17 +25,12 @@ using namespace filament;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
jlong nativeEngine, jobject buffer_, jint size, jint shBandCount) {
jlong nativeEngine, jobject buffer_, jint size) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, buffer_, size);
auto builder = Material::Builder();
if (shBandCount) {
builder.sphericalHarmonicsBandCount(shBandCount);
}
Material* material = builder
Material* material = Material::Builder()
.package(buffer.getData(), buffer.getSize())
.build(*engine);
return (jlong) material;
}
@@ -245,18 +245,12 @@ Java_com_google_android_filament_RenderableManager_nBuilderMorphing(JNIEnv*, jcl
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderMorphingStandard(JNIEnv*, jclass,
jlong nativeBuilder, jlong nativeMorphTargetBuffer) {
Java_com_google_android_filament_RenderableManager_nBuilderSetMorphTargetBufferAt(JNIEnv*, jclass,
jlong nativeBuilder, int level, int primitiveIndex, jlong nativeMorphTargetBuffer,
int offset, int count) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeMorphTargetBuffer;
builder->morphing(morphTargetBuffer);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderSetMorphTargetBufferOffsetAt(JNIEnv*, jclass,
jlong nativeBuilder, int level, int primitiveIndex, int offset) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
builder->morphing(level, primitiveIndex, offset);
builder->morphing(level, primitiveIndex, morphTargetBuffer, offset, count);
}
extern "C" JNIEXPORT void JNICALL
@@ -328,12 +322,13 @@ Java_com_google_android_filament_RenderableManager_nSetMorphWeights(JNIEnv* env,
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetMorphTargetBufferOffsetAt(JNIEnv*,
Java_com_google_android_filament_RenderableManager_nSetMorphTargetBufferAt(JNIEnv*,
jclass, jlong nativeRenderableManager, jint i, int level, jint primitiveIndex,
jlong, jint offset) {
jlong nativeMorphTargetBuffer, jint offset, jint count) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
rm->setMorphTargetBufferOffsetAt((RenderableManager::Instance) i, (uint8_t) level,
(size_t) primitiveIndex, (size_t) offset);
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeMorphTargetBuffer;
rm->setMorphTargetBufferAt((RenderableManager::Instance) i, (uint8_t) level,
(size_t) primitiveIndex, morphTargetBuffer, (size_t) offset, (size_t) count);
}
extern "C" JNIEXPORT jint JNICALL
@@ -28,14 +28,6 @@
using namespace filament;
using namespace backend;
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Renderer_nSkipFrame(JNIEnv *, jclass, jlong nativeRenderer,
jlong vsyncSteadyClockTimeNano) {
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->skipFrame(uint64_t(vsyncSteadyClockTimeNano));
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Renderer_nBeginFrame(JNIEnv *, jclass, jlong nativeRenderer,
jlong nativeSwapChain, jlong frameTimeNanos) {
@@ -195,10 +187,3 @@ Java_com_google_android_filament_Renderer_nSetPresentationTime(JNIEnv *, jclass
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->setPresentationTime(monotonicClockNanos);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Renderer_nSetVsyncTime(JNIEnv *, jclass,
jlong nativeRenderer, jlong steadyClockTimeNano) {
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->setVsyncTime(steadyClockTimeNano);
}
@@ -49,12 +49,6 @@ Java_com_google_android_filament_View_nSetCamera(JNIEnv*, jclass,
view->setCamera(camera);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_View_nHasCamera(JNIEnv*, jclass, jlong nativeView) {
View* view = (View*) nativeView;
return (jboolean)view->hasCamera();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetColorGrading(JNIEnv*, jclass,
jlong nativeView, jlong nativeColorGrading) {
@@ -531,12 +525,3 @@ Java_com_google_android_filament_View_nGetFogEntity(JNIEnv *env, jclass clazz,
View *view = (View *) nativeView;
return (jint)view->getFogEntity().getId();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nClearFrameHistory(JNIEnv *env, jclass clazz,
jlong nativeView, jlong nativeEngine) {
View *view = (View *) nativeView;
Engine *engine = (Engine *) nativeEngine;
view->clearFrameHistory(*engine);
}
@@ -159,12 +159,9 @@ public class Engine {
};
/**
* The type of technique for stereoscopic rendering. (Note that the materials used will need to be
* compatible with the chosen technique.)
* The type of technique for stereoscopic rendering
*/
public enum StereoscopicType {
/** No stereoscopic rendering. */
NONE,
/** Stereoscopic rendering is performed using instanced rendering technique. */
INSTANCED,
/** Stereoscopic rendering is performed using the multiview feature from the graphics backend. */
@@ -228,9 +225,7 @@ public class Engine {
config.textureUseAfterFreePoolSize, config.disableParallelShaderCompile,
config.stereoscopicType.ordinal(), config.stereoscopicEyeCount,
config.resourceAllocatorCacheSizeMB, config.resourceAllocatorCacheMaxAge,
config.disableHandleUseAfterFreeCheck,
config.preferredShaderLanguage.ordinal(),
config.forceGLES2Context);
config.disableHandleUseAfterFreeCheck);
return this;
}
@@ -408,7 +403,7 @@ public class Engine {
*
* @see View#setStereoscopicOptions
*/
public StereoscopicType stereoscopicType = StereoscopicType.NONE;
public StereoscopicType stereoscopicType = StereoscopicType.INSTANCED;
/**
* The number of eyes to render when stereoscopic rendering is enabled. Supported values are
@@ -425,46 +420,14 @@ public class Engine {
public long resourceAllocatorCacheSizeMB = 64;
/*
* This value determines how many frames texture entries are kept for in the cache. This
* is a soft limit, meaning some texture older than this are allowed to stay in the cache.
* Typically only one texture is evicted per frame.
* The default is 1.
* This value determines for how many frames are texture entries kept in the cache.
*/
public long resourceAllocatorCacheMaxAge = 1;
public long resourceAllocatorCacheMaxAge = 2;
/*
* Disable backend handles use-after-free checks.
*/
public boolean disableHandleUseAfterFreeCheck = false;
/*
* Sets a preferred shader language for Filament to use.
*
* The Metal backend supports two shader languages: MSL (Metal Shading Language) and
* METAL_LIBRARY (precompiled .metallib). This option controls which shader language is
* used when materials contain both.
*
* By default, when preferredShaderLanguage is unset, Filament will prefer METAL_LIBRARY
* shaders if present within a material, falling back to MSL. Setting
* preferredShaderLanguage to ShaderLanguage::MSL will instead instruct Filament to check
* for the presence of MSL in a material first, falling back to METAL_LIBRARY if MSL is not
* present.
*
* When using a non-Metal backend, setting this has no effect.
*/
public enum ShaderLanguage {
DEFAULT,
MSL,
METAL_LIBRARY,
};
public ShaderLanguage preferredShaderLanguage = ShaderLanguage.DEFAULT;
/*
* When the OpenGL ES backend is used, setting this value to true will force a GLES2.0
* context if supported by the Platform, or if not, will have the backend pretend
* it's a GLES2 context. Ignored on other backends.
*/
public boolean forceGLES2Context = false;
}
private Engine(long nativeEngine, Config config) {
@@ -886,24 +849,6 @@ public class Engine {
return nIsValidMaterial(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidMaterialInstance(@NonNull Material ma, MaterialInstance mi) {
return nIsValidMaterialInstance(getNativeObject(), ma.getNativeObject(), mi.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidExpensiveMaterialInstance(@NonNull MaterialInstance object) {
return nIsValidExpensiveMaterialInstance(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
@@ -1264,17 +1209,6 @@ public class Engine {
nFlush(getNativeObject());
}
/**
* Get paused state of rendering thread.
*
* <p>Warning: This is an experimental API.
*
* @see #setPaused
*/
public boolean isPaused() {
return nIsPaused(getNativeObject());
}
/**
* Pause or resume the rendering thread.
*
@@ -1292,24 +1226,6 @@ public class Engine {
nSetPaused(getNativeObject(), paused);
}
/**
* Switch the command queue to unprotected mode. Protected mode can be activated via
* Renderer::beginFrame() using a protected SwapChain.
* @see Renderer
* @see SwapChain
*/
public void unprotected() {
nUnprotected(getNativeObject());
}
/**
* Get the current time. This is a convenience function that simply returns the
* time in nanosecond since epoch of std::chrono::steady_clock.
* @return current time in nanosecond since epoch of std::chrono::steady_clock.
* @see Renderer#beginFrame
*/
public static native long getSteadyClockTimeNano();
@UsedByReflection("TextureHelper.java")
public long getNativeObject() {
if (mNativeObject == 0) {
@@ -1375,8 +1291,6 @@ public class Engine {
private static native boolean nIsValidSkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
private static native boolean nIsValidIndirectLight(long nativeEngine, long nativeIndirectLight);
private static native boolean nIsValidMaterial(long nativeEngine, long nativeMaterial);
private static native boolean nIsValidMaterialInstance(long nativeEngine, long nativeMaterial, long nativeMaterialInstance);
private static native boolean nIsValidExpensiveMaterialInstance(long nativeEngine, long nativeMaterialInstance);
private static native boolean nIsValidSkybox(long nativeEngine, long nativeSkybox);
private static native boolean nIsValidColorGrading(long nativeEngine, long nativeColorGrading);
private static native boolean nIsValidTexture(long nativeEngine, long nativeTexture);
@@ -1385,9 +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 boolean nIsPaused(long nativeEngine);
private static native void nSetPaused(long nativeEngine, boolean paused);
private static native void nUnprotected(long nativeEngine);
private static native long nGetTransformManager(long nativeEngine);
private static native long nGetLightManager(long nativeEngine);
private static native long nGetRenderableManager(long nativeEngine);
@@ -1409,9 +1321,7 @@ public class Engine {
long textureUseAfterFreePoolSize, boolean disableParallelShaderCompile,
int stereoscopicType, long stereoscopicEyeCount,
long resourceAllocatorCacheSizeMB, long resourceAllocatorCacheMaxAge,
boolean disableHandleUseAfterFreeCheck,
int preferredShaderLanguage,
boolean forceGLES2Context);
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);
@@ -346,7 +346,6 @@ public class Material {
public static class Builder {
private Buffer mBuffer;
private int mSize;
private int mShBandCount = 0;
/**
* Specifies the material data. The material data is a binary blob produced by
@@ -362,22 +361,6 @@ public class Material {
return this;
}
/**
* Sets the quality of the indirect lights computations. This is only taken into account
* if this material is lit and in the surface domain. This setting will affect the
* IndirectLight computation if one is specified on the Scene and Spherical Harmonics
* are used for the irradiance.
*
* @param shBandCount Number of spherical harmonic bands. Must be 1, 2 or 3 (default).
* @return Reference to this Builder for chaining calls.
* @see IndirectLight
*/
@NonNull
public Builder sphericalHarmonicsBandCount(@IntRange(from = 0) int shBandCount) {
mShBandCount = shBandCount;
return this;
}
/**
* Creates and returns the Material object.
*
@@ -389,8 +372,7 @@ public class Material {
*/
@NonNull
public Material build(@NonNull Engine engine) {
long nativeMaterial = nBuilderBuild(engine.getNativeObject(),
mBuffer, mSize, mShBandCount);
long nativeMaterial = nBuilderBuild(engine.getNativeObject(), mBuffer, mSize);
if (nativeMaterial == 0) throw new IllegalStateException("Couldn't create Material");
return new Material(nativeMaterial);
}
@@ -1041,7 +1023,7 @@ public class Material {
mNativeObject = 0;
}
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size, int shBandCount);
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size);
private static native long nCreateInstance(long nativeMaterial);
private static native long nCreateInstanceWithName(long nativeMaterial, @NonNull String name);
private static native long nGetDefaultInstance(long nativeMaterial);
@@ -74,7 +74,7 @@ public class MorphTargetBuffer {
*
* @exception IllegalStateException if the MorphTargetBuffer could not be created
*
* @see #setMorphTargetBufferOffsetAt
* @see #setMorphTargetBufferAt
*/
@NonNull
public MorphTargetBuffer build(@NonNull Engine engine) {
@@ -524,7 +524,14 @@ public class RenderableManager {
}
/**
* Controls if the renderable has legacy vertex morphing targets, zero by default.
* Controls if the renderable has vertex morphing targets, zero by default. This is
* required to enable GPU morphing.
*
* <p>Filament supports two morphing modes: standard (default) and legacy.</p>
*
* <p>For standard morphing, A {@link MorphTargetBuffer} must be created and provided via
* {@link RenderableManager#setMorphTargetBufferAt}. Standard morphing supports up to
* <code>CONFIG_MAX_MORPH_TARGET_COUNT</code> morph targets.</p>
*
* For legacy morphing, the attached {@link VertexBuffer} must provide data in the
* appropriate {@link VertexBuffer.VertexAttribute} slots (<code>MORPH_POSITION_0</code> etc).
@@ -542,22 +549,6 @@ public class RenderableManager {
return this;
}
/**
* Controls if the renderable has vertex morphing targets, zero by default.
*
* <p>For standard morphing, A {@link MorphTargetBuffer} must be provided.
* Standard morphing supports up to
* <code>CONFIG_MAX_MORPH_TARGET_COUNT</code> morph targets.</p>
*
* <p>See also {@link RenderableManager#setMorphWeights}, which can be called on a per-frame basis
* to advance the animation.</p>
*/
@NonNull
public Builder morphing(@NonNull MorphTargetBuffer morphTargetBuffer) {
nBuilderMorphingStandard(mNativeBuilder, morphTargetBuffer.getNativeObject());
return this;
}
/**
* Specifies the morph target buffer for a primitive.
*
@@ -569,13 +560,31 @@ public class RenderableManager {
*
* @param level the level of detail (lod), only 0 can be specified
* @param primitiveIndex zero-based index of the primitive, must be less than the count passed to Builder constructor
* @param morphTargetBuffer specifies the morph target buffer
* @param offset specifies where in the morph target buffer to start reading (expressed as a number of vertices)
* @param count number of vertices in the morph target buffer to read, must equal the geometry's count (for triangles, this should be a multiple of 3)
*/
@NonNull
public Builder morphing(@IntRange(from = 0) int level,
@IntRange(from = 0) int primitiveIndex,
@IntRange(from = 0) int offset) {
nBuilderSetMorphTargetBufferOffsetAt(mNativeBuilder, level, primitiveIndex, offset);
@NonNull MorphTargetBuffer morphTargetBuffer,
@IntRange(from = 0) int offset,
@IntRange(from = 0) int count) {
nBuilderSetMorphTargetBufferAt(mNativeBuilder, level, primitiveIndex,
morphTargetBuffer.getNativeObject(), offset, count);
return this;
}
/**
* Utility method to specify morph target buffer for a primitive.
* For details, see the {@link RenderableManager.Builder#morphing}.
*/
@NonNull
public Builder morphing(@IntRange(from = 0) int level,
@IntRange(from = 0) int primitiveIndex,
@NonNull MorphTargetBuffer morphTargetBuffer) {
nBuilderSetMorphTargetBufferAt(mNativeBuilder, level, primitiveIndex,
morphTargetBuffer.getNativeObject(), 0, morphTargetBuffer.getVertexCount());
return this;
}
@@ -678,11 +687,26 @@ public class RenderableManager {
*
* @see Builder#morphing
*/
public void setMorphTargetBufferOffsetAt(@EntityInstance int i,
public void setMorphTargetBufferAt(@EntityInstance int i,
@IntRange(from = 0) int level,
@IntRange(from = 0) int primitiveIndex,
@IntRange(from = 0) int offset) {
nSetMorphTargetBufferOffsetAt(mNativeObject, i, level, primitiveIndex, 0, offset);
@NonNull MorphTargetBuffer morphTargetBuffer,
@IntRange(from = 0) int offset,
@IntRange(from = 0) int count) {
nSetMorphTargetBufferAt(mNativeObject, i, level, primitiveIndex,
morphTargetBuffer.getNativeObject(), offset, count);
}
/**
* Utility method to change morph target buffer for the given primitive.
* For details, see the {@link RenderableManager#setMorphTargetBufferAt}.
*/
public void setMorphTargetBufferAt(@EntityInstance int i,
@IntRange(from = 0) int level,
@IntRange(from = 0) int primitiveIndex,
@NonNull MorphTargetBuffer morphTargetBuffer) {
nSetMorphTargetBufferAt(mNativeObject, i, level, primitiveIndex,
morphTargetBuffer.getNativeObject(), 0, morphTargetBuffer.getVertexCount());
}
/**
@@ -982,8 +1006,7 @@ public class RenderableManager {
private static native int nBuilderSkinningBones(long nativeBuilder, int boneCount, Buffer bones, int remaining);
private static native void nBuilderSkinningBuffer(long nativeBuilder, long nativeSkinningBuffer, int boneCount, int offset);
private static native void nBuilderMorphing(long nativeBuilder, int targetCount);
private static native void nBuilderMorphingStandard(long nativeBuilder, long nativeMorphTargetBuffer);
private static native void nBuilderSetMorphTargetBufferOffsetAt(long nativeBuilder, int level, int primitiveIndex, int offset);
private static native void nBuilderSetMorphTargetBufferAt(long nativeBuilder, int level, int primitiveIndex, long nativeMorphTargetBuffer, int offset, int count);
private static native void nBuilderEnableSkinningBuffers(long nativeBuilder, boolean enabled);
private static native void nBuilderFog(long nativeBuilder, boolean enabled);
private static native void nBuilderLightChannel(long nativeRenderableManager, int channel, boolean enable);
@@ -993,7 +1016,7 @@ public class RenderableManager {
private static native int nSetBonesAsMatrices(long nativeObject, int i, Buffer matrices, int remaining, int boneCount, int offset);
private static native int nSetBonesAsQuaternions(long nativeObject, int i, Buffer quaternions, int remaining, int boneCount, int offset);
private static native void nSetMorphWeights(long nativeObject, int instance, float[] weights, int offset);
private static native void nSetMorphTargetBufferOffsetAt(long nativeObject, int i, int level, int primitiveIndex, long nativeMorphTargetBuffer, int offset);
private static native void nSetMorphTargetBufferAt(long nativeObject, int i, int level, int primitiveIndex, long nativeMorphTargetBuffer, int offset, int count);
private static native int nGetMorphTargetCount(long nativeObject, int i);
private static native void nSetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float cx, float cy, float cz, float ex, float ey, float ez);
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
@@ -284,33 +284,6 @@ public class Renderer {
nSetPresentationTime(getNativeObject(), monotonicClockNanos);
}
/**
* The use of this method is optional. It sets the VSYNC time expressed as the duration in
* nanosecond since epoch of std::chrono::steady_clock.
* If called, passing 0 to frameTimeNanos in Renderer.BeginFrame will use this
* time instead.
* @param steadyClockTimeNano duration in nanosecond since epoch of std::chrono::steady_clock
* @see Engine#getSteadyClockTimeNano
* @see Renderer#beginFrame
*/
public void setVsyncTime(long steadyClockTimeNano) {
nSetVsyncTime(getNativeObject(), steadyClockTimeNano);
}
/**
* Call skipFrame when momentarily skipping frames, for instance if the content of the
* scene doesn't change.
*
* @param vsyncSteadyClockTimeNano The time in nanoseconds when the frame started being rendered,
* in the {@link System#nanoTime()} timebase. Divide this value by 1000000 to
* convert it to the {@link android.os.SystemClock#uptimeMillis()}
* time base. This typically comes from
* {@link android.view.Choreographer.FrameCallback}.
*/
public void skipFrame(long vsyncSteadyClockTimeNano) {
nSkipFrame(getNativeObject(), vsyncSteadyClockTimeNano);
}
/**
* Sets up a frame for this <code>Renderer</code>.
* <p><code>beginFrame</code> manages frame pacing, and returns whether or not a frame should be
@@ -729,8 +702,6 @@ public class Renderer {
}
private static native void nSetPresentationTime(long nativeObject, long monotonicClockNanos);
private static native void nSetVsyncTime(long nativeObject, long steadyClockTimeNano);
private static native void nSkipFrame(long nativeObject, long vsyncSteadyClockTimeNano);
private static native boolean nBeginFrame(long nativeRenderer, long nativeSwapChain, long frameTimeNanos);
private static native void nEndFrame(long nativeRenderer);
private static native void nRender(long nativeRenderer, long nativeView);
@@ -241,15 +241,6 @@ public class View {
nSetCamera(getNativeObject(), camera == null ? 0 : camera.getNativeObject());
}
/**
* Query whether a camera is set.
* @return true if a camera is set, false otherwise
* @see #setCamera
*/
public boolean hasCamera() {
return nHasCamera(getNativeObject());
}
/**
* Gets this View's associated Camera, or null if none has been assigned.
*
@@ -1233,18 +1224,6 @@ public class View {
return nGetFogEntity(getNativeObject());
}
/**
* When certain temporal features are used (e.g.: TAA or Screen-space reflections), the view
* keeps a history of previous frame renders associated with the Renderer the view was last
* used with. When switching Renderer, it may be necessary to clear that history by calling
* this method. Similarly, if the whole content of the screen change, like when a cut-scene
* starts, clearing the history might be needed to avoid artifacts due to the previous frame
* being very different.
*/
public void clearFrameHistory(Engine engine) {
nClearFrameHistory(getNativeObject(), engine.getNativeObject());
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed View");
@@ -1259,7 +1238,6 @@ public class View {
private static native void nSetName(long nativeView, String name);
private static native void nSetScene(long nativeView, long nativeScene);
private static native void nSetCamera(long nativeView, long nativeCamera);
private static native boolean nHasCamera(long nativeView);
private static native void nSetViewport(long nativeView, int left, int bottom, int width, int height);
private static native void nSetVisibleLayers(long nativeView, int select, int value);
private static native void nSetShadowingEnabled(long nativeView, boolean enabled);
@@ -1306,7 +1284,7 @@ public class View {
private static native void nSetMaterialGlobal(long nativeView, int index, float x, float y, float z, float w);
private static native void nGetMaterialGlobal(long nativeView, int index, float[] out);
private static native int nGetFogEntity(long nativeView);
private static native void nClearFrameHistory(long nativeView, long nativeEngine);
/**
* List of available ambient occlusion techniques.
@@ -31,7 +31,6 @@ set_target_properties(iblprefilter PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilament-iblprefilter.a)
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libfilament-utils-jni.map")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
add_library(filament-utils-jni SHARED
src/main/cpp/AutomationEngine.cpp
@@ -125,11 +125,6 @@ extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBu
builder->groundPlane(a, b, c, d);
}
extern "C" JNIEXPORT void Java_com_google_android_filament_utils_Manipulator_nBuilderPanning(JNIEnv*, jclass, jlong nativeBuilder, jboolean enabled) {
Builder* builder = (Builder*) nativeBuilder;
builder->panning(enabled);
}
extern "C" JNIEXPORT long Java_com_google_android_filament_utils_Manipulator_nBuilderBuild(JNIEnv*, jclass, jlong nativeBuilder, jint mode) {
Builder* builder = (Builder*) nativeBuilder;
return (jlong) builder->build((Mode) mode);
@@ -274,17 +274,6 @@ public class Manipulator {
return this;
}
/**
* Sets whether panning is enabled in the manipulator.
*
* @return this <code>Builder</code> object for chaining calls
*/
@NonNull
public Builder panning(Boolean enabled) {
nBuilderPanning(mNativeBuilder, enabled);
return this;
}
/**
* Creates and returns the <code>Manipulator</code> object.
*
@@ -494,7 +483,6 @@ public class Manipulator {
private static native void nBuilderFlightPanSpeed(long nativeBuilder, float x, float y);
private static native void nBuilderFlightMoveDamping(long nativeBuilder, float damping);
private static native void nBuilderGroundPlane(long nativeBuilder, float a, float b, float c, float d);
private static native void nBuilderPanning(long nativeBuilder, Boolean enabled);
private static native long nBuilderBuild(long nativeBuilder, int mode);
private static native void nDestroyManipulator(long nativeManip);
+1 -4
View File
@@ -44,7 +44,6 @@ set_target_properties(uberarchive PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libuberarchive.a)
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
set(GLTFIO_SRCS
${GLTFIO_DIR}/include/gltfio/Animator.h
@@ -87,10 +86,7 @@ set(GLTFIO_SRCS
${GLTFIO_DIR}/src/Wireframe.cpp
${GLTFIO_DIR}/src/Wireframe.h
${GLTFIO_DIR}/src/downcast.h
${GLTFIO_DIR}/src/extended/AssetLoaderExtended.cpp
${GLTFIO_DIR}/src/extended/AssetLoaderExtended.h
${GLTFIO_DIR}/src/extended/ResourceLoaderExtended.cpp
${GLTFIO_DIR}/src/extended/ResourceLoaderExtended.h
${GLTFIO_DIR}/src/extended/TangentsJobExtended.cpp
${GLTFIO_DIR}/src/extended/TangentsJobExtended.h
${GLTFIO_DIR}/src/extended/TangentSpaceMeshWrapper.cpp
@@ -120,6 +116,7 @@ set(GLTFIO_INCLUDE_DIRS
../../third_party/cgltf
../../third_party/meshoptimizer/src
../../third_party/robin-map
../../third_party/hat-trie
../../third_party/stb
../../libs/utils/include
../../libs/ktxreader/include
+1 -1
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.54.0
VERSION_NAME=1.51.2
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
+1 -1
View File
@@ -1,6 +1,6 @@
#Wed Nov 17 10:40:18 PST 2021
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -321,7 +321,7 @@ class MainActivity : Activity() {
var flags = uiHelper.swapChainFlags
if (engine.activeFeatureLevel == Engine.FeatureLevel.FEATURE_LEVEL_0) {
if (SwapChain.isSRGBSwapChainSupported(engine)) {
flags = flags or SwapChainFlags.CONFIG_SRGB_COLORSPACE
flags = flags or SwapChain.CONFIG_SRGB_COLORSPACE
}
}
+11 -43
View File
@@ -44,6 +44,8 @@ function print_help {
echo " Exclude Vulkan support from the Android build."
echo " -s"
echo " Add iOS simulator support to the iOS build."
echo " -t"
echo " Enable SwiftShader support for Vulkan in desktop builds."
echo " -e"
echo " Enable EGL on Linux support for desktop builds."
echo " -l"
@@ -59,14 +61,6 @@ function print_help {
echo " -b"
echo " Enable Address and Undefined Behavior Sanitizers (asan/ubsan) for debugging."
echo " This is only for the desktop build."
echo " -x value"
echo " Define a preprocessor flag FILAMENT_BACKEND_DEBUG_FLAG with [value]. This is useful for"
echo " enabling debug paths in the backend from the build script. For example, make a"
echo " systrace-enabled build without directly changing #defines. Remember to add -f when"
echo " changing this option."
echo " -S type"
echo " Enable stereoscopic rendering where type is one of [instanced|multiview]. This is only"
echo " meant for building the samples."
echo ""
echo "Build types:"
echo " release"
@@ -166,6 +160,8 @@ INSTALL_COMMAND=
VULKAN_ANDROID_OPTION="-DFILAMENT_SUPPORTS_VULKAN=ON"
VULKAN_ANDROID_GRADLE_OPTION=""
SWIFTSHADER_OPTION="-DFILAMENT_USE_SWIFTSHADER=OFF"
EGL_ON_LINUX_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_LINUX=OFF"
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
@@ -176,10 +172,6 @@ MATOPT_GRADLE_OPTION=""
ASAN_UBSAN_OPTION=""
BACKEND_DEBUG_FLAG_OPTION=""
STEREOSCOPIC_OPTION=""
IOS_BUILD_SIMULATOR=false
BUILD_UNIVERSAL_LIBRARIES=false
@@ -234,12 +226,11 @@ function build_desktop_target {
-DIMPORT_EXECUTABLES_DIR=out \
-DCMAKE_BUILD_TYPE="$1" \
-DCMAKE_INSTALL_PREFIX="../${lc_target}/filament" \
${SWIFTSHADER_OPTION} \
${EGL_ON_LINUX_OPTION} \
${MATDBG_OPTION} \
${MATOPT_OPTION} \
${ASAN_UBSAN_OPTION} \
${BACKEND_DEBUG_FLAG_OPTION} \
${STEREOSCOPIC_OPTION} \
${architectures} \
../..
ln -sf "out/cmake-${lc_target}/compile_commands.json" \
@@ -298,7 +289,6 @@ function build_webgl_with_target {
-DCMAKE_BUILD_TYPE="$1" \
-DCMAKE_INSTALL_PREFIX="../webgl-${lc_target}/filament" \
-DWEBGL=1 \
${BACKEND_DEBUG_FLAG_OPTION} \
../..
ln -sf "out/cmake-webgl-${lc_target}/compile_commands.json" \
../../compile_commands.json
@@ -373,8 +363,6 @@ function build_android_target {
${MATDBG_OPTION} \
${MATOPT_OPTION} \
${VULKAN_ANDROID_OPTION} \
${BACKEND_DEBUG_FLAG_OPTION} \
${STEREOSCOPIC_OPTION} \
../..
ln -sf "out/cmake-android-${lc_target}-${arch}/compile_commands.json" \
../../compile_commands.json
@@ -609,7 +597,6 @@ function build_ios_target {
-DCMAKE_TOOLCHAIN_FILE=../../third_party/clang/iOS.cmake \
${MATDBG_OPTION} \
${MATOPT_OPTION} \
${STEREOSCOPIC_OPTION} \
../..
ln -sf "out/cmake-ios-${lc_target}-${arch}/compile_commands.json" \
../../compile_commands.json
@@ -743,13 +730,6 @@ function validate_build_command {
exit 1
fi
fi
# Make sure FILAMENT_BACKEND_DEBUG_FLAG is only meant for debug builds
if [[ "${ISSUE_DEBUG_BUILD}" != "true" ]] && [[ ! -z "${BACKEND_DEBUG_FLAG_OPTION}" ]]; then
echo "Error: cannot specify FILAMENT_BACKEND_DEBUG_FLAG in non-debug build"
exit 1
fi
set -e
}
@@ -796,7 +776,7 @@ function check_debug_release_build {
pushd "$(dirname "$0")" > /dev/null
while getopts ":hacCfgijmp:q:uvslwedk:bx:S:" opt; do
while getopts ":hacCfgijmp:q:uvslwtedk:b" opt; do
case ${opt} in
h)
print_help
@@ -860,7 +840,7 @@ while getopts ":hacCfgijmp:q:uvslwedk:bx:S:" opt; do
echo "Platform must be one of [desktop|android|ios|webgl|all]"
echo ""
exit 1
;;
;;
esac
done
;;
@@ -915,6 +895,10 @@ while getopts ":hacCfgijmp:q:uvslwedk:bx:S:" opt; do
IOS_BUILD_SIMULATOR=true
echo "iOS simulator support enabled."
;;
t)
SWIFTSHADER_OPTION="-DFILAMENT_USE_SWIFTSHADER=ON"
echo "SwiftShader support enabled."
;;
e)
EGL_ON_LINUX_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_LINUX=ON -DFILAMENT_SKIP_SDL2=ON -DFILAMENT_SKIP_SAMPLES=ON"
echo "EGL on Linux support enabled; skipping SDL2."
@@ -934,22 +918,6 @@ while getopts ":hacCfgijmp:q:uvslwedk:bx:S:" opt; do
b) ASAN_UBSAN_OPTION="-DFILAMENT_ENABLE_ASAN_UBSAN=ON"
echo "Enabled ASAN/UBSAN"
;;
x) BACKEND_DEBUG_FLAG_OPTION="-DFILAMENT_BACKEND_DEBUG_FLAG=${OPTARG}"
;;
S) case $(echo "${OPTARG}" | tr '[:upper:]' '[:lower:]') in
instanced)
STEREOSCOPIC_OPTION="-DFILAMENT_SAMPLES_STEREO_TYPE=instanced"
;;
multiview)
STEREOSCOPIC_OPTION="-DFILAMENT_SAMPLES_STEREO_TYPE=multiview"
;;
*)
echo "Unknown stereoscopic type ${OPTARG}"
echo "Type must be one of [instanced|multiview]"
echo ""
exit 1
esac
;;
\?)
echo "Invalid option: -${OPTARG}" >&2
echo ""
+1 -2
View File
@@ -57,8 +57,7 @@ FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/ndk.version)}
# Install the required NDK version specifically (if not present)
if [[ ! -d "${ANDROID_HOME}/ndk/$FILAMENT_NDK_VERSION" ]]; then
yes | ${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager --licenses
${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION"
${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION" > /dev/null
fi
# Only build 1 64 bit target during presubmit to cut down build times during presubmit
+1 -1
View File
@@ -1 +1 @@
27.0.11718014
26.1.10909125
+53
View File
@@ -0,0 +1,53 @@
# Build the image:
# docker build --no-cache --tag ssfilament -f build/swiftshader/Dockerfile .
# docker tag ssfilament ghcr.io/filament-assets/swiftshader
#
# Publish the image:
# docker login ghcr.io --username <user> --password <token>
# docker push ghcr.io/filament-assets/swiftshader
#
# Run the image and mount the current directory:
# docker run -it -v `pwd`:/trees/filament -t ssfilament
FROM ubuntu:focal
WORKDIR /trees
ARG DEBIAN_FRONTEND=noninteractive
ENV SWIFTSHADER_LD_LIBRARY_PATH=/trees/swiftshader/build
ENV CXXFLAGS='-fno-builtin -Wno-pass-failed'
RUN apt-get update && \
apt-get --no-install-recommends install -y \
apt-transport-https \
apt-utils \
build-essential \
cmake \
ca-certificates \
git \
ninja-build \
python \
python3 \
xorg-dev \
clang-7 \
libc++-7-dev \
libc++abi-7-dev \
lldb
# Ensure that clang is used instead of gcc.
RUN set -eux ;\
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-7 100 ;\
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-7 100 ;\
update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100 ;\
update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
# Get patch files from the local Filament tree.
COPY build/swiftshader/*.diff .
# Clone SwiftShader, apply patches, and build it.
RUN set -eux ;\
git clone https://swiftshader.googlesource.com/SwiftShader swiftshader ;\
cd swiftshader ;\
git checkout 139f5c3 ;\
git apply /trees/*.diff ;\
cd build ;\
cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release ;\
ninja
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env python3
from pathlib import Path
import os
spath = os.path.dirname(os.path.realpath(__file__))
path = Path(spath)
folder = "../../results/"
images = list(path.glob(folder + '*.png'))
images.sort()
gallery = open(path.absolute().joinpath(folder + 'index.html'), 'w')
gallery.write("""<html>
<head>
<script type="module" src="https://unpkg.com/img-comparison-slider@latest/dist/component/component.esm.js"></script>
<script nomodule="" src="https://unpkg.com/img-comparison-slider@latest/dist/component/component.js"></script>
<link rel="stylesheet" href="https://unpkg.com/img-comparison-slider@latest/dist/collection/styles/initial.css"/>
<style>
h2 {
font-weight: normal;
margin-top: 150px;
margin-bottom: 20px;
}
a {
text-decoration: none;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: blue;
}
a:hover {
font-weight: bold;
}
</style>
</head>
<body>
""")
tag = ''
for image in images:
group = image.stem.rstrip('0123456789')
before = f'https://filament-assets.github.io/golden/{group}/{image.name}'
after = image.name
gallery.write('\n')
gallery.write(f'<h2><a href="{image.stem}.json">{image.stem}.json</a></h2>\n')
gallery.write('<img-comparison-slider>\n')
gallery.write(f'<img slot="before" src="{before}" /> <img slot="after" src="{after}" />\n')
gallery.write('</img-comparison-slider>\n')
gallery.write("""</body>
</html>
""")
+62
View File
@@ -0,0 +1,62 @@
diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp
index 86913ec72..3b35345af 100644
--- a/src/Vulkan/VkPipeline.cpp
+++ b/src/Vulkan/VkPipeline.cpp
@@ -71,7 +71,56 @@ std::vector<uint32_t> preprocessSpirv(
if(optimize)
{
// Full optimization list taken from spirv-opt.
- opt.RegisterPerformancePasses();
+
+ // We have removed CreateRedundancyEliminationPass because it segfaults when encountering:
+ // %389 = OpCompositeConstruct %7 %386 %387 %388 %86
+ // When inserting an entry into instruction_to_value_ (which is an unordered_map)
+ // This could perhaps be investigated further with help from asan.
+
+ using namespace spvtools;
+ opt.RegisterPass(CreateWrapOpKillPass())
+ .RegisterPass(CreateDeadBranchElimPass())
+ .RegisterPass(CreateMergeReturnPass())
+ .RegisterPass(CreateInlineExhaustivePass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreatePrivateToLocalPass())
+ .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
+ .RegisterPass(CreateLocalSingleStoreElimPass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateScalarReplacementPass())
+ .RegisterPass(CreateLocalAccessChainConvertPass())
+ .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
+ .RegisterPass(CreateLocalSingleStoreElimPass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateLocalMultiStoreElimPass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateCCPPass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateLoopUnrollPass(true))
+ .RegisterPass(CreateDeadBranchElimPass())
+ .RegisterPass(CreateRedundancyEliminationPass()) // workaround for SEGFAULT
+ .RegisterPass(CreateCombineAccessChainsPass())
+ .RegisterPass(CreateSimplificationPass())
+ .RegisterPass(CreateScalarReplacementPass())
+ .RegisterPass(CreateLocalAccessChainConvertPass())
+ .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
+ .RegisterPass(CreateLocalSingleStoreElimPass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateSSARewritePass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateVectorDCEPass())
+ .RegisterPass(CreateDeadInsertElimPass())
+ .RegisterPass(CreateDeadBranchElimPass())
+ .RegisterPass(CreateSimplificationPass())
+ .RegisterPass(CreateIfConversionPass())
+ .RegisterPass(CreateCopyPropagateArraysPass())
+ .RegisterPass(CreateReduceLoadSizePass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateBlockMergePass())
+ .RegisterPass(CreateRedundancyEliminationPass()) // workaround for SEGFAULT
+ .RegisterPass(CreateDeadBranchElimPass())
+ .RegisterPass(CreateBlockMergePass())
+ .RegisterPass(CreateSimplificationPass());
}
std::vector<uint32_t> optimized;
+127
View File
@@ -0,0 +1,127 @@
#!/bin/bash
set -e
function print_help {
local self_name=$(basename "$0")
echo "This script issues docker commands for testing Filament with SwiftShader."
echo "The usual sequence of commands is: fetch, start, build filament release, and run."
echo ""
echo "Usage:"
echo " $self_name [command]"
echo ""
echo "Commands:"
echo " build filament [debug | release]"
echo " Use the container to build Filament."
echo " build swiftshader [debug | release]"
echo " Use the container to do a clean rebuild of SwiftShader."
echo " (Note that the container already has SwiftShader built.)"
echo " fetch"
echo " Download the docker image from the central repository."
echo " help"
echo " Print this help message."
echo " logs"
echo " Print messages from the container's kernel ring buffer."
echo " This is useful for diagnosing OOM issues."
echo " run [lldb]"
echo " Launch a test inside the container, optionally via lldb."
echo " shell"
echo " Interact with a bash prompt in the container."
echo " start"
echo " Start a container from the image."
echo " stop"
echo " Stop the container."
echo ""
}
# Change the current working directory to the Filament root.
pushd "$(dirname "$0")/../.." > /dev/null
if [[ "$1" == "build" ]] && [[ "$2" == "filament" ]]; then
docker exec runner filament/build.sh -t $3 gltf_viewer
exit $?
fi
if [[ "$1" == "build" ]] && [[ "$2" == "swiftshader" ]]; then
BUILD_TYPE="$3"
BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
docker exec --workdir /trees/swiftshader runner rm -rf build
docker exec --workdir /trees/swiftshader runner mkdir build
docker exec --workdir /trees/swiftshader/build runner cmake -GNinja -DCMAKE_BUILD_TYPE="$BUILD_TYPE" ..
docker exec --workdir /trees/swiftshader/build runner ninja
exit $?
fi
if [[ "$1" == "fetch" ]]; then
docker pull ghcr.io/filament-assets/swiftshader:latest
docker tag ghcr.io/filament-assets/swiftshader:latest ssfilament
exit $?
fi
if [[ "$1" == "help" ]]; then
print_help
exit 0
fi
if [[ "$1" == "logs" ]]; then
docker exec runner dmesg --human --read-clear
exit $?
fi
if [[ "$1" == "run" ]] && [[ "$2" == "lldb" ]]; then
docker exec -i --workdir /trees/filament/results runner \
lldb --batch -o run -o bt -- \
../out/cmake-release/samples/gltf_viewer \
--headless \
--batch ../libs/viewer/tests/basic.json \
--api vulkan
docker exec runner /trees/filament/build/swiftshader/gallery.py
exit $?
fi
if [[ "$1" == "run" ]]; then
docker exec --tty --workdir /trees/filament/results runner \
/usr/bin/catchsegv \
../out/cmake-release/samples/gltf_viewer \
--headless \
--batch ../libs/viewer/tests/basic.json \
--api vulkan
docker exec runner /trees/filament/build/swiftshader/gallery.py
exit $?
fi
if [[ "$1" == "shell" ]]; then
docker exec --interactive --tty runner /bin/bash
exit $?
fi
# Notes on options being passed to docker's run command:
#
# - The memory constraint seems to prevent an OOM signal in GitHub Actions.
# - The cap / security args allow use of lldb and creation of core dumps.
# - The privileged arg allows use of dmesg for examining OOM logs.
#
# Currently, a GitHub Actions VM has 2 CPUs, 7 GB RAM, and 14 GB of SSD disk space.
#
# Please be aware that Docker Desktop might impose additional resource constraints, and that those
# settings can only be controlled with its GUI. We recommend at least 7 GB of memory and 2 GB swap.
if [[ "$1" == "start" ]]; then
mkdir -p results
docker run --tty --rm --detach --privileged \
--memory 6.5g \
--name runner \
--cap-add=SYS_PTRACE \
--security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
--volume `pwd`:/trees/filament \
--workdir /trees \
ssfilament
exit $?
fi
if [[ "$1" == "stop" ]]; then
docker container rm runner --force
exit $?
fi
print_help
exit 1
+2 -2
View File
@@ -476,7 +476,7 @@ Energy conservation is one of the key components of a good BRDF for physically b
<p>
For the specular term, \(f_r\) is a mirror BRDF that can be modeled with the Fresnel law, noted \(F\) in the Cook-Torrance approximation of the microfacet model integration:
For the specular term, \(f_m\) is a mirror BRDF that can be modeled with the Fresnel law, noted \(F\) in the Cook-Torrance approximation of the microfacet model integration:
</p><p>
@@ -857,7 +857,7 @@ The full GLSL implementation of the standard model is shown in <a href="#listing
<span class="line"> <span class="hljs-comment">// perceptually linear roughness to roughness (see parameterization)</span></span>
<span class="line"> <span class="hljs-type">float</span> roughness = perceptualRoughness * perceptualRoughness;</span>
<span class="line"></span>
<span class="line"> <span class="hljs-type">float</span> D = D_GGX(NoH, roughness);</span>
<span class="line"> <span class="hljs-type">float</span> D = D_GGX(NoH, a);</span>
<span class="line"> <span class="hljs-type">vec3</span> F = F_Schlick(LoH, f0);</span>
<span class="line"> <span class="hljs-type">float</span> V = V_SmithGGXCorrelated(NoV, NoL, roughness);</span>
<span class="line"></span>
+53 -141
View File
File diff suppressed because one or more lines are too long
+3 -44
View File
@@ -1308,12 +1308,7 @@ Description
declare a variable called `eyeDirection` you can access it in the fragment shader using
`variable_eyeDirection`. In the vertex shader, the interpolant name is simply a member of
the `MaterialVertexInputs` structure (`material.eyeDirection` in your example). Each
interpolant is of type `float4` (`vec4`) in the shaders. By default the precision of the
interpolant is `highp` in *both* the vertex and fragment shaders.
An alternate syntax can be used to specify both the name and precision of the interpolant.
In this case the specified precision is used as-is in both fragment and vertex stages, in
particular if `default` is specified the default precision is used is the fragment shader
(`mediump`) and in the vertex shader (`highp`).
interpolant is of type `float4` (`vec4`) in the shaders.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
@@ -1325,11 +1320,7 @@ material {
}
],
variables : [
eyeDirection,
{
name : eyeColor,
precision : medium
}
eyeDirection
],
vertexDomain : device,
depthWrite : false,
@@ -1406,7 +1397,7 @@ Type
: `string`
Value
: Any of `opaque`, `transparent`, `fade`, `add`, `masked`, `multiply`, `screen`, `custom`. Defaults to `opaque`.
: Any of `opaque`, `transparent`, `fade`, `add`, `masked`, `multiply`, `screen`. Defaults to `opaque`.
Description
: Defines how/if the rendered object is blended with the content of the render target.
@@ -1429,7 +1420,6 @@ 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.
@@ -1442,36 +1432,6 @@ 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
@@ -2434,7 +2394,6 @@ The following APIs are only available from the vertex block:
**getWorldFromModelMatrix()** | float4x4 | Matrix that converts from model (object) space to world space
**getWorldFromModelNormalMatrix()** | float3x3 | Matrix that converts normals from model (object) space to world space
**getVertexIndex()** | int | Index of the current vertex
**getEyeIndex()** | int | Index of the eye being rendered, starting at 0
### Fragment only
File diff suppressed because one or more lines are too long
Binary file not shown.
+1 -1
View File
@@ -43,7 +43,7 @@ filament-viewer::part(canvas) {
</p>
</main>
<script src="https://unpkg.com/filament@1.51.6/filament.js"></script>
<script src="https://unpkg.com/filament@1.44.0/filament.js"></script>
<script src="https://unpkg.com/gltumble"></script>
<script src="filament-viewer.js" type="module"></script>
</body>
-3
View File
@@ -61,7 +61,6 @@ set(SRCS
src/Engine.cpp
src/Exposure.cpp
src/Fence.cpp
src/FilamentBuilder.cpp
src/FrameInfo.cpp
src/FrameSkipper.cpp
src/Froxelizer.cpp
@@ -164,7 +163,6 @@ set(PRIVATE_HDRS
src/ResourceList.h
src/ShadowMap.h
src/ShadowMapManager.h
src/SharedHandle.h
src/TypedUniformBuffer.h
src/UniformBuffer.h
src/components/CameraManager.h
@@ -216,7 +214,6 @@ set(PRIVATE_HDRS
set(MATERIAL_SRCS
src/materials/antiAliasing/fxaa.mat
src/materials/antiAliasing/taa.mat
src/materials/blitDepth.mat
src/materials/blitLow.mat
src/materials/blitArray.mat
src/materials/bloom/bloomDownsample.mat
+3 -13
View File
@@ -66,13 +66,11 @@ set(PRIVATE_HDRS
# OpenGL / OpenGL ES Sources
# ==================================================================================================
if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3)
if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMENT_USE_SWIFTSHADER)
list(APPEND SRCS
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
@@ -168,10 +166,8 @@ 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/caching/VulkanDescriptorSet.cpp
src/vulkan/caching/VulkanDescriptorSet.h
src/vulkan/platform/VulkanPlatform.cpp
src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp
src/vulkan/platform/VulkanPlatformSwapChainImpl.h
@@ -417,9 +413,7 @@ if (APPLE OR LINUX)
test/test_MissingRequiredAttributes.cpp
test/test_ReadPixels.cpp
test/test_BufferUpdates.cpp
test/test_Callbacks.cpp
test/test_MRT.cpp
test/test_PushConstants.cpp
test/test_LoadImage.cpp
test/test_StencilBuffer.cpp
test/test_Scissor.cpp
@@ -480,10 +474,6 @@ if (APPLE)
# linker from removing "unused" symbols.
target_link_libraries(backend_test_mac PRIVATE -force_load backend_test)
set_target_properties(backend_test_mac PROPERTIES FOLDER Tests)
# This is needed after XCode 15.3
set_target_properties(backend_test_mac PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
set_target_properties(backend_test_mac PROPERTIES INSTALL_RPATH /usr/local/lib)
endif()
endif()
+18 -21
View File
@@ -22,17 +22,14 @@
#include <utils/BitmaskEnum.h>
#include <utils/unwindows.h> // Because we define ERROR in the FenceStatus enum.
#include <backend/Platform.h>
#include <backend/PresentCallable.h>
#include <utils/Invocable.h>
#include <utils/ostream.h>
#include <math/vec4.h>
#include <array> // FIXME: STL headers are not allowed in public headers
#include <type_traits> // 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>
@@ -93,15 +90,12 @@ static constexpr uint64_t SWAP_CHAIN_HAS_STENCIL_BUFFER = SWAP_CHAIN_CON
*/
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.
static constexpr size_t MAX_SAMPLER_COUNT = 62; // Maximum needed at feature level 3.
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
static constexpr size_t MAX_SSBO_COUNT = 4; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_PUSH_CONSTANT_COUNT = 32; // Vulkan 1.1 spec allows for 128-byte
// of push constant (we assume 4-byte
// types).
// Per feature level caps
// Use (int)FeatureLevel to index this array
static constexpr struct {
@@ -118,7 +112,7 @@ static_assert(MAX_VERTEX_BUFFER_COUNT <= MAX_VERTEX_ATTRIBUTE_COUNT,
"The number of buffer objects that can be attached to a VertexBuffer must be "
"less than or equal to the maximum number of vertex attributes.");
static constexpr size_t CONFIG_UNIFORM_BINDING_COUNT = 9; // This is guaranteed by OpenGL ES.
static constexpr size_t CONFIG_UNIFORM_BINDING_COUNT = 10; // This is guaranteed by OpenGL ES.
static constexpr size_t CONFIG_SAMPLER_BINDING_COUNT = 4; // This is guaranteed by OpenGL ES.
/**
@@ -164,16 +158,14 @@ static constexpr const char* backendToString(Backend backend) {
}
/**
* Defines the shader language. Similar to the above backend enum, with some differences:
* - The OpenGL backend can select between two shader languages: ESSL 1.0 and ESSL 3.0.
* - The Metal backend can prefer precompiled Metal libraries, while falling back to MSL.
* Defines the shader language. Similar to the above backend enum, but the OpenGL backend can select
* between two shader languages: ESSL 1.0 and ESSL 3.0.
*/
enum class ShaderLanguage {
ESSL1 = 0,
ESSL3 = 1,
SPIRV = 2,
MSL = 3,
METAL_LIBRARY = 4,
};
static constexpr const char* shaderLanguageToString(ShaderLanguage shaderLanguage) {
@@ -186,8 +178,6 @@ static constexpr const char* shaderLanguageToString(ShaderLanguage shaderLanguag
return "SPIR-V";
case ShaderLanguage::MSL:
return "MSL";
case ShaderLanguage::METAL_LIBRARY:
return "Metal precompiled library";
}
}
@@ -337,7 +327,7 @@ enum class UniformType : uint8_t {
/**
* Supported constant parameter types
*/
enum class ConstantType : uint8_t {
enum class ConstantType : uint8_t {
INT,
FLOAT,
BOOL
@@ -692,7 +682,7 @@ enum class TextureUsage : uint16_t {
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 for protected content
PROTECTED = 0x0100, //!< Texture can be used the destination of a blit()
DEFAULT = UPLOADABLE | SAMPLEABLE //!< Default texture usage
};
@@ -1224,15 +1214,13 @@ struct StencilState {
uint8_t padding = 0;
};
using PushConstantVariant = std::variant<int32_t, float, bool>;
static_assert(sizeof(StencilState::StencilOperations) == 5u,
"StencilOperations size not what was intended");
static_assert(sizeof(StencilState) == 12u,
"StencilState size not what was intended");
using FrameScheduledCallback = utils::Invocable<void(backend::PresentCallable)>;
using FrameScheduledCallback = void(*)(PresentCallable callable, void* user);
enum class Workaround : uint16_t {
// The EASU pass must split because shader compiler flattens early-exit branch
@@ -1244,14 +1232,23 @@ enum class Workaround : uint16_t {
ADRENO_UNIFORM_ARRAY_CRASH,
// Workaround a Metal pipeline compilation error with the message:
// "Could not statically determine the target of a texture". See light_indirect.fs
METAL_STATIC_TEXTURE_TARGET_ERROR,
A8X_STATIC_TEXTURE_TARGET_ERROR,
// Adreno drivers sometimes aren't able to blit into a layer of a texture array.
DISABLE_BLIT_INTO_TEXTURE_ARRAY,
// Multiple workarounds needed for PowerVR GPUs
POWER_VR_SHADER_WORKAROUNDS,
// The driver has some threads pinned, and we can't easily know on which core, it can hurt
// performance more if we end-up pinned on the same one.
DISABLE_THREAD_AFFINITY
};
using StereoscopicType = backend::Platform::StereoscopicType;
//! 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
-15
View File
@@ -75,19 +75,6 @@ protected:
HandleBase(HandleBase const& rhs) noexcept = default;
HandleBase& operator=(HandleBase const& rhs) noexcept = default;
HandleBase(HandleBase&& rhs) noexcept
: object(rhs.object) {
rhs.object = nullid;
}
HandleBase& operator=(HandleBase&& rhs) noexcept {
if (this != &rhs) {
object = rhs.object;
rhs.object = nullid;
}
return *this;
}
private:
HandleId object;
};
@@ -102,10 +89,8 @@ struct Handle : public HandleBase {
Handle() noexcept = default;
Handle(Handle const& rhs) noexcept = default;
Handle(Handle&& rhs) noexcept = default;
Handle& operator=(Handle const& rhs) noexcept = default;
Handle& operator=(Handle&& rhs) noexcept = default;
explicit Handle(HandleId id) noexcept : HandleBase(id) { }
@@ -41,26 +41,6 @@ public:
struct Fence {};
struct Stream {};
/**
* The type of technique for stereoscopic rendering. (Note that the materials used will need to
* be compatible with the chosen technique.)
*/
enum class StereoscopicType : uint8_t {
/**
* No stereoscopic rendering
*/
NONE,
/**
* Stereoscopic rendering is performed using instanced rendering technique.
*/
INSTANCED,
/**
* Stereoscopic rendering is performed using the multiview feature from the graphics
* backend.
*/
MULTIVIEW,
};
struct DriverConfig {
/**
* Size of handle arena in bytes. Setting to 0 indicates default value is to be used.
@@ -75,8 +55,6 @@ public:
*/
size_t textureUseAfterFreePoolSize = 0;
size_t metalUploadBufferSizeBytes = 512 * 1024;
/**
* Set to `true` to forcibly disable parallel shader compilation in the backend.
* Currently only honored by the GL and Metal backends.
@@ -87,17 +65,6 @@ public:
* Disable backend handles use-after-free checks.
*/
bool disableHandleUseAfterFreeCheck = false;
/**
* Force GLES2 context if supported, or pretend the context is ES2. Only meaningful on
* GLES 3.x backends.
*/
bool forceGLES2Context = false;
/**
* Sets the technique for stereoscopic rendering.
*/
StereoscopicType stereoscopicType = StereoscopicType::NONE;
};
Platform() noexcept;
@@ -48,7 +48,7 @@ namespace filament::backend {
* and optional user data:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* swapChain->setFrameScheduledCallback(nullptr, myFrameScheduledCallback);
* swapChain->setFrameScheduledCallback(myFrameScheduledCallback, nullptr);
* if (renderer->beginFrame(swapChain)) {
* renderer->render(view);
* renderer->endFrame();
@@ -58,6 +58,8 @@ namespace filament::backend {
* @remark Only Filament's Metal backend supports PresentCallables and frame callbacks. Other
* backends ignore the callback (which will never be called) and proceed normally.
*
* @remark The SwapChain::FrameScheduledCallback is called on an arbitrary thread.
*
* Applications *must* call each PresentCallable they receive. Each PresentCallable represents a
* frame that is waiting to be presented. If an application fails to call a PresentCallable, a
* memory leak could occur. To "cancel" the presentation of a frame, pass false to the
@@ -84,9 +84,6 @@ public:
// null terminating character.
Program& shader(ShaderStage shader, void const* data, size_t size);
// sets the language of the shader sources provided with shader() (defaults to ESSL3)
Program& shaderLanguage(ShaderLanguage shaderLanguage);
// Note: This is only needed for GLES3.0 backends, because the layout(binding=) syntax is
// not permitted in glsl. The backend needs a way to associate a uniform block
// to a binding point.
@@ -117,14 +114,6 @@ public:
Program& specializationConstants(
utils::FixedCapacityVector<SpecializationConstant> specConstants) noexcept;
struct PushConstant {
utils::CString name;
ConstantType type;
};
Program& pushConstants(ShaderStage stage,
utils::FixedCapacityVector<PushConstant> constants) noexcept;
Program& cacheId(uint64_t cacheId) noexcept;
Program& multiview(bool multiview) noexcept;
@@ -147,8 +136,6 @@ public:
utils::CString const& getName() const noexcept { return mName; }
utils::CString& getName() noexcept { return mName; }
auto const& getShaderLanguage() const { return mShaderLanguage; }
utils::FixedCapacityVector<SpecializationConstant> const& getSpecializationConstants() const noexcept {
return mSpecializationConstants;
}
@@ -156,15 +143,6 @@ public:
return mSpecializationConstants;
}
utils::FixedCapacityVector<PushConstant> const& getPushConstants(
ShaderStage stage) const noexcept {
return mPushConstants[static_cast<uint8_t>(stage)];
}
utils::FixedCapacityVector<PushConstant>& getPushConstants(ShaderStage stage) noexcept {
return mPushConstants[static_cast<uint8_t>(stage)];
}
uint64_t getCacheId() const noexcept { return mCacheId; }
bool isMultiview() const noexcept { return mMultiview; }
@@ -177,12 +155,10 @@ private:
UniformBlockInfo mUniformBlocks = {};
SamplerGroupInfo mSamplerGroups = {};
ShaderSource mShadersSource;
ShaderLanguage mShaderLanguage = ShaderLanguage::ESSL3;
utils::CString mName;
uint64_t mCacheId{};
utils::Invocable<utils::io::ostream&(utils::io::ostream& out)> mLogger;
utils::FixedCapacityVector<SpecializationConstant> mSpecializationConstants;
std::array<utils::FixedCapacityVector<PushConstant>, SHADER_TYPE_COUNT> mPushConstants;
utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>> mAttributes;
std::array<UniformInfo, Program::UNIFORM_BINDING_COUNT> mBindingUniformInfo;
CompilerPriorityQueue mPriorityQueue = CompilerPriorityQueue::HIGH;
@@ -29,36 +29,17 @@ namespace filament::backend {
//! \privatesection
struct TargetBufferInfo {
// note: the parameters of this constructor are not in the order of this structure's fields
TargetBufferInfo(Handle<HwTexture> handle, uint8_t level, uint16_t layer, uint8_t baseViewIndex) noexcept
: handle(handle), baseViewIndex(baseViewIndex), level(level), layer(layer) {
}
TargetBufferInfo(Handle<HwTexture> handle, uint8_t level, uint16_t layer) noexcept
: handle(handle), level(level), layer(layer) {
}
TargetBufferInfo(Handle<HwTexture> handle, uint8_t level) noexcept
: handle(handle), level(level) {
}
TargetBufferInfo(Handle<HwTexture> handle) noexcept // NOLINT(*-explicit-constructor)
: handle(handle) {
}
TargetBufferInfo() noexcept = default;
// 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
// 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;
// For cubemaps and 3D textures. See TextureCubemapFace for the face->layer mapping
// for cubemaps and 3D textures. See TextureCubemapFace for the face->layer mapping
uint16_t layer = 0;
};
@@ -83,7 +64,7 @@ public:
MRT() noexcept = default;
MRT(TargetBufferInfo const& color) noexcept // NOLINT(hicpp-explicit-conversions, *-explicit-constructor)
MRT(TargetBufferInfo const& color) noexcept // NOLINT(hicpp-explicit-conversions)
: mInfos{ color } {
}
@@ -103,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, 0 }} {
: mInfos{{ handle, 0, level, layer }} {
}
};
@@ -140,23 +140,6 @@ public:
*/
virtual uint32_t getDefaultFramebufferObject() noexcept;
/**
* Called by the backend when a frame starts.
* @param steady_clock_ns vsync time point on the monotonic clock
* @param refreshIntervalNs refresh interval in nanosecond
* @param frameId a frame id
*/
virtual void beginFrame(
int64_t monotonic_clock_ns,
int64_t refreshIntervalNs,
uint32_t frameId) noexcept;
/**
* Called by the backend when a frame ends.
* @param frameId the frame id used in beginFrame
*/
virtual void endFrame(
uint32_t frameId) noexcept;
/**
* Type of contexts available
@@ -208,12 +191,6 @@ public:
utils::Invocable<void()> preContextChange,
utils::Invocable<void(size_t index)> postContextChange) noexcept;
/**
* Called by the backend just before calling commit()
* @see commit()
*/
virtual void preCommit() 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.
@@ -22,10 +22,6 @@
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/platforms/PlatformEGL.h>
#include <utils/android/PerformanceHintManager.h>
#include <chrono>
#include <stddef.h>
#include <stdint.h>
@@ -62,13 +58,6 @@ protected:
void terminate() noexcept override;
void beginFrame(
int64_t monotonic_clock_ns,
int64_t refreshIntervalNs,
uint32_t frameId) noexcept override;
void preCommit() noexcept override;
/**
* Set the presentation time using `eglPresentationTimeANDROID`
* @param presentationTimeInNanosecond
@@ -90,18 +79,8 @@ protected:
AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept override;
private:
struct InitializeJvmForPerformanceManagerIfNeeded {
InitializeJvmForPerformanceManagerIfNeeded();
};
int mOSVersion;
ExternalStreamManagerAndroid& mExternalStreamManager;
InitializeJvmForPerformanceManagerIfNeeded const mInitializeJvmForPerformanceManagerIfNeeded;
utils::PerformanceHintManager mPerformanceHintManager;
utils::PerformanceHintManager::Session mPerformanceHintSession;
using clock = std::chrono::high_resolution_clock;
clock::time_point mStartTimeOfActualWork;
};
} // namespace filament::backend
@@ -23,9 +23,9 @@
#include <utils/CString.h>
#include <utils/FixedCapacityVector.h>
#include <utils/Hash.h>
#include <utils/PrivateImplementation.h>
#include <string_view>
#include <tuple>
#include <unordered_set>
@@ -47,14 +47,6 @@ struct VulkanPlatformPrivate;
class VulkanPlatform : public Platform, utils::PrivateImplementation<VulkanPlatformPrivate> {
public:
struct ExtensionHashFn {
std::size_t operator()(utils::CString const& s) const noexcept {
return std::hash<std::string>{}(s.data());
}
};
// Utility for managing device or instance extensions during initialization.
using ExtensionSet = std::unordered_set<utils::CString, ExtensionHashFn>;
/**
* A collection of handles to objects and metadata that comprises a Vulkan context. The client
* can instantiate this struct and pass to Engine::Builder::sharedContext if they wishes to
@@ -90,20 +82,6 @@ public:
VkExtent2D extent = {0, 0};
};
struct ImageSyncData {
static constexpr uint32_t INVALID_IMAGE_INDEX = UINT32_MAX;
// The index of the next image as returned by vkAcquireNextImage or equivalent.
uint32_t imageIndex = INVALID_IMAGE_INDEX;
// Semaphore to be signaled once the image is available.
VkSemaphore imageReadySemaphore = VK_NULL_HANDLE;
// A function called right before vkQueueSubmit. After this call, the image must be
// available. This pointer can be null if imageReadySemaphore is not VK_NULL_HANDLE.
std::function<void(SwapChainPtr handle)> explicitImageReadyWait = nullptr;
};
VulkanPlatform();
~VulkanPlatform() override;
@@ -141,12 +119,6 @@ public:
* before recreating the swapchain. Default is true.
*/
bool flushAndWaitOnWindowResize = true;
/**
* Whether the swapchain image should be transitioned to a layout suitable for
* presentation. Default is true.
*/
bool transitionSwapChainImageLayoutForPresent = true;
};
/**
@@ -175,10 +147,13 @@ public:
* corresponding VkImage will be used as the output color attachment. The client should signal
* the `clientSignal` semaphore when the image is ready to be used by the backend.
* @param handle The handle returned by createSwapChain()
* @param outImageSyncData The synchronization data used for image readiness
* @param clientSignal The semaphore that the client will signal to indicate that the backend
* may render into the image.
* @param index Pointer to memory that will be filled with the index that corresponding
* to an image in the `SwapChainBundle.colors` array.
* @return Result of acquire
*/
virtual VkResult acquire(SwapChainPtr handle, ImageSyncData* outImageSyncData);
virtual VkResult acquire(SwapChainPtr handle, VkSemaphore clientSignal, uint32_t* index);
/**
* Present the image corresponding to `index` to the display. The client should wait on
@@ -217,13 +192,6 @@ public:
virtual SwapChainPtr createSwapChain(void* nativeWindow, uint64_t flags = 0,
VkExtent2D extent = {0, 0});
/**
* Allows implementers to provide instance extensions that they'd like to include in the
* instance creation.
* @return A set of extensions to enable for the instance.
*/
virtual ExtensionSet getRequiredInstanceExtensions() { return {}; }
/**
* Destroy the swapchain.
* @param handle The handle returned by createSwapChain()
@@ -268,9 +236,10 @@ public:
VkQueue getGraphicsQueue() const noexcept;
private:
static ExtensionSet getSwapchainInstanceExtensions();
// Platform dependent helper methods
using ExtensionSet = std::unordered_set<std::string_view>;
static ExtensionSet getRequiredInstanceExtensions();
using SurfaceBundle = std::tuple<VkSurfaceKHR, VkExtent2D>;
static SurfaceBundle createVkSurfaceKHR(void* nativeWindow, VkInstance instance,
uint64_t flags) noexcept;
@@ -82,7 +82,6 @@ public:
void requestExit();
// suspend or unsuspend the queue.
bool isPaused() const noexcept;
void setPaused(bool paused);
bool isExitRequested() const;
@@ -134,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) {
static inline void execute(M&& method, D&& driver, CommandBase* base, intptr_t* next) noexcept {
Command* self = static_cast<Command*>(base);
*next = align(sizeof(Command));
#if DEBUG_COMMAND_STREAM
@@ -168,7 +168,7 @@ struct CommandType<void (Driver::*)(ARGS...)> {
class CustomCommand : public CommandBase {
std::function<void()> mCommand;
static void execute(Driver&, CommandBase* base, intptr_t* next);
static void execute(Driver&, CommandBase* base, intptr_t* next) noexcept;
public:
inline CustomCommand(CustomCommand&& rhs) = default;
inline explicit CustomCommand(std::function<void()> cmd)
@@ -76,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);
virtual void execute(std::function<void(void)> const& fn) noexcept;
// This is called on debug build, or when enabled manually on the backend thread side.
virtual void debugCommandBegin(CommandStream* cmds,
@@ -133,18 +133,18 @@ DECL_DRIVER_API_0(tick)
DECL_DRIVER_API_N(beginFrame,
int64_t, monotonic_clock_ns,
int64_t, refreshIntervalNs,
uint32_t, frameId)
DECL_DRIVER_API_N(setFrameScheduledCallback,
backend::SwapChainHandle, sch,
backend::CallbackHandler*, handler,
backend::FrameScheduledCallback&&, callback)
backend::FrameScheduledCallback, callback,
void*, user)
DECL_DRIVER_API_N(setFrameCompletedCallback,
backend::SwapChainHandle, sch,
backend::CallbackHandler*, handler,
utils::Invocable<void(void)>&&, callback)
backend::CallbackHandler::Callback, callback,
void*, user)
DECL_DRIVER_API_N(setPresentationTime,
int64_t, monotonic_clock_ns)
@@ -162,10 +162,6 @@ DECL_DRIVER_API_0(finish)
// reset state tracking, if the driver does any state tracking (e.g. GL)
DECL_DRIVER_API_0(resetState)
DECL_DRIVER_API_N(setDebugTag,
backend::HandleBase::HandleId, handleId,
utils::CString, tag)
/*
* Creating driver objects
* -----------------------
@@ -304,10 +300,9 @@ 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, isProtectedContentSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isStereoSupported)
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_N(bool, isDepthStencilBlitSupported, backend::TextureFormat, format)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isProtectedTexturesSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(uint8_t, getMaxDrawBuffers)
DECL_DRIVER_API_SYNCHRONOUS_0(size_t, getMaxUniformBufferSize)
@@ -437,11 +432,6 @@ DECL_DRIVER_API_N(bindSamplers,
uint32_t, index,
backend::SamplerGroupHandle, sbh)
DECL_DRIVER_API_N(setPushConstant,
backend::ShaderStage, stage,
uint8_t, index,
backend::PushConstantVariant, value)
DECL_DRIVER_API_N(insertEventMarker,
const char*, string,
uint32_t, len = 0)
@@ -505,7 +495,7 @@ DECL_DRIVER_API_N(blit,
math::uint2, size)
DECL_DRIVER_API_N(bindPipeline,
backend::PipelineState const&, state)
backend::PipelineState, state)
DECL_DRIVER_API_N(bindRenderPrimitive,
backend::RenderPrimitiveHandle, rph)
@@ -20,12 +20,11 @@
#include <backend/Handle.h>
#include <utils/Allocator.h>
#include <utils/CString.h>
#include <utils/Log.h>
#include <utils/Panic.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ostream.h>
#include <utils/Panic.h>
#include <tsl/robin_map.h>
@@ -40,7 +39,7 @@
#define HandleAllocatorGL HandleAllocator<32, 64, 136> // ~4520 / pool / MiB
#define HandleAllocatorVK HandleAllocator<64, 160, 312> // ~1820 / pool / MiB
#define HandleAllocatorMTL HandleAllocator<32, 64, 552> // ~1660 / pool / MiB
#define HandleAllocatorMTL HandleAllocator<32, 48, 552> // ~1660 / pool / MiB
namespace filament::backend {
@@ -66,7 +65,7 @@ public:
*
*/
template<typename D, typename ... ARGS>
Handle<D> allocateAndConstruct(ARGS&& ... args) {
Handle<D> allocateAndConstruct(ARGS&& ... args) noexcept {
Handle<D> h{ allocateHandle<D>() };
D* addr = handle_cast<D*>(h);
new(addr) D(std::forward<ARGS>(args)...);
@@ -98,7 +97,7 @@ 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) {
destroyAndConstruct(Handle<B> const& handle, ARGS&& ... args) noexcept {
assert_invariant(handle);
D* addr = handle_cast<D*>(const_cast<Handle<B>&>(handle));
assert_invariant(addr);
@@ -164,7 +163,7 @@ 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) {
handle_cast(Handle<B>& handle) noexcept {
assert_invariant(handle);
auto [p, tag] = handleToPointer(handle.getId());
@@ -174,64 +173,22 @@ public:
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;
// getHandleTag() is only called if the check fails.
FILAMENT_CHECK_POSTCONDITION(expectedAge == age)
<< "use-after-free of Handle with id=" << handle.getId()
<< ", tag=" << getHandleTag(handle.getId()).c_str_safe();
ASSERT_POSTCONDITION(expectedAge == age,
"use-after-free of Handle with id=%d", handle.getId());
}
}
return static_cast<Dp>(p);
}
template<typename B>
bool is_valid(Handle<B>& handle) {
if (handle && isPoolHandle(handle.getId())) {
auto [p, tag] = handleToPointer(handle.getId());
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;
return expectedAge == age;
}
return true;
}
template<typename Dp, typename B>
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) {
handle_cast(Handle<B> const& handle) noexcept {
return handle_cast<Dp>(const_cast<Handle<B>&>(handle));
}
void associateTagToHandle(HandleBase::HandleId id, utils::CString&& tag) noexcept {
// TODO: for now, only pool handles check for use-after-free, so we only keep tags for
// those
if (isPoolHandle(id)) {
// Truncate the tag's age to N bits.
constexpr uint8_t N = 2; // support a history of 4 tags
constexpr uint8_t mask = (1 << N) - 1;
uint8_t const age = (id & HANDLE_AGE_MASK) >> HANDLE_AGE_SHIFT;
uint8_t const newAge = age & mask;
uint32_t const key = (id & ~HANDLE_AGE_MASK) | (newAge << HANDLE_AGE_SHIFT);
// This line is the costly part. In the future, we could potentially use a custom
// allocator.
mDebugTags[key] = std::move(tag);
}
}
utils::CString getHandleTag(HandleBase::HandleId id) const noexcept {
if (!isPoolHandle(id)) {
return "(no tag)";
}
if (auto pos = mDebugTags.find(id); pos != mDebugTags.end()) {
return pos->second;
}
return "(no tag)";
}
private:
template<typename D>
@@ -283,8 +240,8 @@ private:
Node* const pNode = static_cast<Node*>(p);
uint8_t& expectedAge = pNode[-1].age;
if (UTILS_UNLIKELY(!mUseAfterFreeCheckDisabled)) {
FILAMENT_CHECK_POSTCONDITION(expectedAge == age) <<
"double-free of Handle of size " << size << " at " << p;
ASSERT_POSTCONDITION(expectedAge == age,
"double-free of Handle of size %d at %p", size, p);
}
expectedAge = (expectedAge + 1) & 0xF; // fixme
@@ -360,7 +317,7 @@ private:
return (id & HANDLE_HEAP_FLAG) == 0u;
}
HandleBase::HandleId allocateHandleSlow(size_t size);
HandleBase::HandleId allocateHandleSlow(size_t size) noexcept;
void deallocateHandleSlow(HandleBase::HandleId id, size_t size) noexcept;
// We inline this because it's just 4 instructions in the fast case
@@ -394,7 +351,6 @@ private:
// Below is only used when running out of space in the HandleArena
mutable utils::Mutex mLock;
tsl::robin_map<HandleBase::HandleId, void*> mOverflowMap;
tsl::robin_map<HandleBase::HandleId, utils::CString> mDebugTags;
HandleBase::HandleId mId = 0;
bool mUseAfterFreeCheckDisabled = false;
};
+2 -2
View File
@@ -27,8 +27,8 @@ PresentCallable::PresentCallable(PresentFn fn, void* user) noexcept
}
void PresentCallable::operator()(bool presentFrame) noexcept {
FILAMENT_CHECK_PRECONDITION(mPresentFn) << "This PresentCallable was already called. "
"PresentCallables should be called exactly once.";
ASSERT_PRECONDITION(mPresentFn, "This PresentCallable was already called. " \
"PresentCallables should be called exactly once.");
mPresentFn(presentFrame, mUser);
// Set mPresentFn to nullptr to denote that the callable has been called.
mPresentFn = nullptr;
+8 -11
View File
@@ -32,11 +32,10 @@
# define HAS_MMAP 0
#endif
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
using namespace utils;
@@ -82,9 +81,6 @@ void* CircularBuffer::alloc(size_t size) noexcept {
// map the circular buffer once...
vaddr = mmap(reserve_vaddr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (vaddr != MAP_FAILED) {
// populate the address space with pages (because this is a circular buffer,
// all the pages will be allocated eventually, might as well do it now)
memset(vaddr, 0, size);
// and map the circular buffer again, behind the previous copy...
vaddr_shadow = mmap((char*)vaddr + size, size,
PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
@@ -105,7 +101,7 @@ void* CircularBuffer::alloc(size_t size) noexcept {
if (UTILS_UNLIKELY(mAshmemFd < 0)) {
// ashmem failed
if (vaddr_guard != MAP_FAILED) {
munmap(vaddr_guard, BLOCK_SIZE);
munmap(vaddr_guard, size);
}
if (vaddr_shadow != MAP_FAILED) {
@@ -123,11 +119,12 @@ void* CircularBuffer::alloc(size_t size) noexcept {
data = mmap(nullptr, size * 2 + BLOCK_SIZE,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
FILAMENT_CHECK_POSTCONDITION(data != MAP_FAILED) <<
"couldn't allocate " << (size * 2 / 1024) <<
" KiB of virtual address space for the command buffer";
ASSERT_POSTCONDITION(data,
"couldn't allocate %u KiB of virtual address space for the command buffer",
(size * 2 / 1024));
slog.w << "Using 'soft' CircularBuffer (" << (size * 2 / 1024) << " KiB)" << io::endl;
slog.d << "WARNING: Using soft CircularBuffer (" << (size * 2 / 1024) << " KiB)"
<< io::endl;
// guard page at the end
void* guard = (void*)(uintptr_t(data) + size * 2);
+18 -22
View File
@@ -57,11 +57,6 @@ void CommandBufferQueue::requestExit() {
mCondition.notify_one();
}
bool CommandBufferQueue::isPaused() const noexcept {
std::lock_guard<utils::Mutex> const lock(mLock);
return mPaused;
}
void CommandBufferQueue::setPaused(bool paused) {
std::lock_guard<utils::Mutex> const lock(mLock);
if (paused) {
@@ -74,6 +69,8 @@ void CommandBufferQueue::setPaused(bool paused) {
bool CommandBufferQueue::isExitRequested() const {
std::lock_guard<utils::Mutex> const lock(mLock);
ASSERT_PRECONDITION( mExitRequested == 0 || mExitRequested == EXIT_REQUESTED,
"mExitRequested is corrupted (value = 0x%08x)!", mExitRequested);
return (bool)mExitRequested;
}
@@ -101,23 +98,22 @@ void CommandBufferQueue::flush() noexcept {
size_t const used = std::distance(
static_cast<char const*>(begin), static_cast<char const*>(end));
std::unique_lock<utils::Mutex> lock(mLock);
// circular buffer is too small, we corrupted the stream
FILAMENT_CHECK_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: " << used <<
" bytes, overflow: " << used - mFreeSpace << " bytes";
mFreeSpace -= used;
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, overflow: %u bytes",
(unsigned)used, unsigned(used - mFreeSpace));
// wait until there is enough space in the buffer
mFreeSpace -= used;
if (UTILS_UNLIKELY(mFreeSpace < requiredSize)) {
#ifndef NDEBUG
size_t const totalUsed = circularBuffer.size() - mFreeSpace;
slog.d << "CommandStream used too much space (will block): "
@@ -130,11 +126,9 @@ void CommandBufferQueue::flush() noexcept {
#endif
SYSTRACE_NAME("waiting: CircularBuffer::flush()");
FILAMENT_CHECK_POSTCONDITION(!mPaused) <<
ASSERT_POSTCONDITION(!mPaused,
"CommandStream is full, but since the rendering thread is paused, "
"the buffer cannot flush and we will deadlock. Instead, abort.";
"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;
@@ -150,14 +144,16 @@ std::vector<CommandBufferQueue::Range> CommandBufferQueue::waitForCommands() con
while ((mCommandBuffersToExecute.empty() || mPaused) && !mExitRequested) {
mCondition.wait(lock);
}
ASSERT_PRECONDITION( mExitRequested == 0 || mExitRequested == EXIT_REQUESTED,
"mExitRequested is corrupted (value = 0x%08x)!", mExitRequested);
return std::move(mCommandBuffersToExecute);
}
void CommandBufferQueue::releaseBuffer(CommandBufferQueue::Range const& buffer) {
size_t const used = std::distance(
static_cast<char const*>(buffer.begin), static_cast<char const*>(buffer.end));
std::lock_guard<utils::Mutex> const lock(mLock);
mFreeSpace += used;
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) {
void CustomCommand::execute(Driver&, CommandBase* base, intptr_t* next) noexcept {
*next = CustomCommand::align(sizeof(CustomCommand));
static_cast<CustomCommand*>(base)->mCommand();
static_cast<CustomCommand*>(base)->~CustomCommand();
+1 -1
View File
@@ -214,7 +214,7 @@ size_t Driver::getElementTypeSize(ElementType type) noexcept {
Driver::~Driver() noexcept = default;
void Driver::execute(std::function<void(void)> const& fn) {
void Driver::execute(std::function<void(void)> const& fn) noexcept {
fn();
}
+3 -6
View File
@@ -80,9 +80,6 @@ HandleAllocator<P0, P1, P2>::HandleAllocator(const char* name, size_t size,
bool disableUseAfterFreeCheck) noexcept
: mHandleArena(name, size, disableUseAfterFreeCheck),
mUseAfterFreeCheckDisabled(disableUseAfterFreeCheck) {
// Reserve initial space for debug tags. This prevents excessive calls to malloc when the first
// few tags are set.
mDebugTags.reserve(512);
}
template <size_t P0, size_t P1, size_t P2>
@@ -110,15 +107,15 @@ 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) {
HandleBase::HandleId HandleAllocator<P0, P1, P2>::allocateHandleSlow(size_t size) noexcept {
void* p = ::malloc(size);
std::unique_lock lock(mLock);
HandleBase::HandleId id = (++mId) | HANDLE_HEAP_FLAG;
FILAMENT_CHECK_POSTCONDITION(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";
" for a while. Please increase FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB");
mOverflowMap.emplace(id, p);
lock.unlock();
+6 -5
View File
@@ -29,21 +29,21 @@
#include "backend/platforms/PlatformCocoaTouchGL.h"
#endif
#elif defined(__APPLE__)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include <backend/platforms/PlatformCocoaGL.h>
#endif
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_X11)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "backend/platforms/PlatformGLX.h"
#endif
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "backend/platforms/PlatformEGLHeadless.h"
#endif
#endif
#elif defined(WIN32)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "backend/platforms/PlatformWGL.h"
#endif
#elif defined(__EMSCRIPTEN__)
@@ -111,7 +111,8 @@ Platform* PlatformFactory::create(Backend* backend) noexcept {
}
assert_invariant(*backend == Backend::OPENGL);
#if defined(FILAMENT_SUPPORTS_OPENGL)
#if defined(FILAMENT_USE_EXTERNAL_GLES3)
#if defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(FILAMENT_USE_SWIFTSHADER)
// Swiftshader OpenGLES support is deprecated and incomplete
return nullptr;
#elif defined(__ANDROID__)
return new PlatformEGLAndroid();
+1 -12
View File
@@ -21,7 +21,7 @@ namespace filament::backend {
using namespace utils;
// We want these in the .cpp file, so they're not inlined (not worth it)
Program::Program() noexcept { // NOLINT(modernize-use-equals-default)
Program::Program() noexcept { // NOLINT(modernize-use-equals-default)
}
Program::Program(Program&& rhs) noexcept = default;
@@ -47,11 +47,6 @@ Program& Program::shader(ShaderStage shader, void const* data, size_t size) {
return *this;
}
Program& Program::shaderLanguage(ShaderLanguage shaderLanguage) {
mShaderLanguage = shaderLanguage;
return *this;
}
Program& Program::uniformBlockBindings(
FixedCapacityVector<std::pair<utils::CString, uint8_t>> const& uniformBlockBindings) noexcept {
for (auto const& item : uniformBlockBindings) {
@@ -91,12 +86,6 @@ Program& Program::specializationConstants(
return *this;
}
Program& Program::pushConstants(ShaderStage stage,
utils::FixedCapacityVector<PushConstant> constants) noexcept {
mPushConstants[static_cast<uint8_t>(stage)] = std::move(constants);
return *this;
}
Program& Program::cacheId(uint64_t cacheId) noexcept {
mCacheId = cacheId;
return *this;
+1 -11
View File
@@ -16,23 +16,13 @@
#include "private/backend/VirtualMachineEnv.h"
#include <utils/compiler.h>
#include <utils/debug.h>
#include <jni.h>
namespace filament {
JavaVM* VirtualMachineEnv::sVirtualMachine = nullptr;
/*
* This is typically called by filament_jni.so when it is loaded. If filament_jni.so is not used,
* then this must be called manually -- however, this is a problem because VirtualMachineEnv.h
* is currently private and part of backend.
* For now, we authorize this usage, but we will need to fix it; by making a proper public
* API for this.
*/
UTILS_PUBLIC
// This is called when the library is loaded. We need this to get a reference to the global VM
UTILS_NOINLINE
jint VirtualMachineEnv::JNI_OnLoad(JavaVM* vm) noexcept {
JNIEnv* env = nullptr;
+5 -6
View File
@@ -109,8 +109,9 @@ inline bool MTLSizeEqual(T a, T b) noexcept {
MetalBlitter::MetalBlitter(MetalContext& context) noexcept : mContext(context) { }
void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args, const char* label) {
FILAMENT_CHECK_PRECONDITION(args.source.region.size.depth == args.destination.region.size.depth)
<< "Blitting requires the source and destination regions to have the same depth.";
ASSERT_PRECONDITION(args.source.region.size.depth == args.destination.region.size.depth,
"Blitting requires the source and destination regions to have the same depth.");
// Determine if the blit for color or depth are eligible to use a MTLBlitCommandEncoder.
// blitFastPath returns true upon success.
@@ -326,8 +327,7 @@ id<MTLFunction> MetalBlitter::compileFragmentFunction(BlitFunctionKey key) const
utils::slog.e << description << utils::io::endl;
}
}
FILAMENT_CHECK_POSTCONDITION(library && function)
<< "Unable to compile fragment shader for MetalBlitter.";
ASSERT_POSTCONDITION(library && function, "Unable to compile fragment shader for MetalBlitter.");
return function;
}
@@ -352,8 +352,7 @@ id<MTLFunction> MetalBlitter::getBlitVertexFunction() {
utils::slog.e << description << utils::io::endl;
}
}
FILAMENT_CHECK_POSTCONDITION(library && function)
<< "Unable to compile vertex shader for MetalBlitter.";
ASSERT_POSTCONDITION(library && function, "Unable to compile vertex shader for MetalBlitter.");
mVertexFunction = function;
+11 -108
View File
@@ -18,7 +18,6 @@
#define TNT_FILAMENT_DRIVER_METALBUFFER_H
#include "MetalContext.h"
#include "MetalPlatform.h"
#include <backend/DriverEnums.h>
@@ -29,88 +28,20 @@
#include <utility>
#include <memory>
#include <atomic>
#include <chrono>
namespace filament::backend {
class ScopedAllocationTimer {
public:
ScopedAllocationTimer(const char* name) : mBeginning(clock_t::now()), mName(name) {}
~ScopedAllocationTimer() {
using namespace std::literals::chrono_literals;
static constexpr std::chrono::seconds LONG_TIME_THRESHOLD = 10s;
auto end = clock_t::now();
std::chrono::duration<double, std::micro> allocationTimeMicroseconds = end - mBeginning;
if (UTILS_UNLIKELY(allocationTimeMicroseconds > LONG_TIME_THRESHOLD)) {
if (platform && platform->hasDebugUpdateStatFunc()) {
char buffer[64];
snprintf(buffer, sizeof(buffer), "filament.metal.long_buffer_allocation_time.%s",
mName);
platform->debugUpdateStat(
buffer, static_cast<uint64_t>(allocationTimeMicroseconds.count()));
}
}
}
static void setPlatform(MetalPlatform* p) { platform = p; }
private:
typedef std::chrono::steady_clock clock_t;
static MetalPlatform* platform;
std::chrono::time_point<clock_t> mBeginning;
const char* mName;
};
class TrackedMetalBuffer {
public:
static constexpr size_t EXCESS_BUFFER_COUNT = 30000;
enum class Type {
NONE = 0,
GENERIC = 1,
RING = 2,
STAGING = 3,
};
static constexpr size_t TypeCount = 3;
static constexpr auto toIndex(Type t) {
assert_invariant(t != Type::NONE);
switch (t) {
case Type::NONE:
case Type::GENERIC:
return 0;
case Type::RING:
return 1;
case Type::STAGING:
return 2;
}
}
TrackedMetalBuffer() noexcept : mBuffer(nil) {}
TrackedMetalBuffer(nullptr_t) noexcept : mBuffer(nil) {}
TrackedMetalBuffer(id<MTLBuffer> buffer, Type type) : mBuffer(buffer), mType(type) {
assert_invariant(type != Type::NONE);
TrackedMetalBuffer(id<MTLBuffer> buffer) noexcept : mBuffer(buffer) {
if (buffer) {
aliveBuffers[toIndex(type)]++;
mType = type;
if (getAliveBuffers() >= EXCESS_BUFFER_COUNT) {
if (platform && platform->hasDebugUpdateStatFunc()) {
platform->debugUpdateStat("filament.metal.excess_buffers_allocated",
TrackedMetalBuffer::getAliveBuffers());
}
}
aliveBuffers++;
}
}
~TrackedMetalBuffer() {
if (mBuffer) {
assert_invariant(mType != Type::NONE);
aliveBuffers[toIndex(mType)]--;
aliveBuffers--;
}
}
@@ -126,31 +57,18 @@ public:
id<MTLBuffer> get() const noexcept { return mBuffer; }
operator bool() const noexcept { return bool(mBuffer); }
static uint64_t getAliveBuffers() {
uint64_t sum = 0;
for (const auto& v : aliveBuffers) {
sum += v;
}
return sum;
}
static uint64_t getAliveBuffers(Type type) {
assert_invariant(type != Type::NONE);
return aliveBuffers[toIndex(type)];
}
static void setPlatform(MetalPlatform* p) { platform = p; }
static uint64_t getAliveBuffers() { return aliveBuffers; }
private:
void swap(TrackedMetalBuffer& other) noexcept {
std::swap(mBuffer, other.mBuffer);
std::swap(mType, other.mType);
id<MTLBuffer> temp = mBuffer;
mBuffer = other.mBuffer;
other.mBuffer = temp;
}
id<MTLBuffer> mBuffer;
Type mType = Type::NONE;
static MetalPlatform* platform;
static std::array<uint64_t, TypeCount> aliveBuffers;
static std::atomic<uint64_t> aliveBuffers;
};
class MetalBuffer {
@@ -204,15 +122,6 @@ public:
private:
enum class UploadStrategy {
POOL,
BUMP_ALLOCATOR,
};
void uploadWithPoolBuffer(void* src, size_t size, size_t byteOffset) const;
void uploadWithBumpAllocator(void* src, size_t size, size_t byteOffset) const;
UploadStrategy mUploadStrategy;
TrackedMetalBuffer mBuffer;
size_t mBufferSize = 0;
void* mCpuBuffer = nullptr;
@@ -262,9 +171,7 @@ public:
mBufferOptions(options),
mSlotSizeBytes(computeSlotSize(layout)),
mSlotCount(slotCount) {
ScopedAllocationTimer timer("ring");
mBuffer = { [device newBufferWithLength:mSlotSizeBytes * mSlotCount options:mBufferOptions],
TrackedMetalBuffer::Type::RING };
mBuffer = [device newBufferWithLength:mSlotSizeBytes * mSlotCount options:mBufferOptions];
assert_invariant(mBuffer);
}
@@ -282,13 +189,9 @@ public:
// If we already have an aux buffer, it will get freed here, unless it has been retained
// by a MTLCommandBuffer. In that case, it will be freed when the command buffer
// finishes executing.
{
ScopedAllocationTimer timer("ring");
mAuxBuffer = { [mDevice newBufferWithLength:mSlotSizeBytes options:mBufferOptions],
TrackedMetalBuffer::Type::RING };
}
mAuxBuffer = [mDevice newBufferWithLength:mSlotSizeBytes options:mBufferOptions];
assert_invariant(mAuxBuffer);
return { mAuxBuffer.get(), 0 };
return {mAuxBuffer.get(), 0};
}
mCurrentSlot = (mCurrentSlot + 1) % mSlotCount;
mOccupiedSlots->fetch_add(1, std::memory_order_relaxed);
+29 -71
View File
@@ -22,21 +22,10 @@
namespace filament {
namespace backend {
std::array<uint64_t, TrackedMetalBuffer::TypeCount> TrackedMetalBuffer::aliveBuffers = { 0 };
MetalPlatform* TrackedMetalBuffer::platform = nullptr;
MetalPlatform* ScopedAllocationTimer::platform = nullptr;
std::atomic<uint64_t> TrackedMetalBuffer::aliveBuffers = 0;
MetalBuffer::MetalBuffer(MetalContext& context, BufferObjectBinding bindingType, BufferUsage usage,
size_t size, bool forceGpuBuffer)
: mBufferSize(size), mContext(context) {
const MetalBumpAllocator& allocator = *mContext.bumpAllocator;
// VERTEX is also used for index buffers
if (allocator.getCapacity() > 0 && bindingType == BufferObjectBinding::VERTEX) {
mUploadStrategy = UploadStrategy::BUMP_ALLOCATOR;
} else {
mUploadStrategy = UploadStrategy::POOL;
}
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
// buffer. Instead, we use immediate command encoder methods like setVertexBytes:length:atIndex:.
// This won't work for SSBOs, since they are read/write.
@@ -48,13 +37,8 @@ MetalBuffer::MetalBuffer(MetalContext& context, BufferObjectBinding bindingType,
}
// Otherwise, we allocate a private GPU buffer.
{
ScopedAllocationTimer timer("generic");
mBuffer = { [context.device newBufferWithLength:size options:MTLResourceStorageModePrivate],
TrackedMetalBuffer::Type::GENERIC };
}
FILAMENT_CHECK_POSTCONDITION(mBuffer)
<< "Could not allocate Metal buffer of size " << size << ".";
mBuffer = [context.device newBufferWithLength:size options:MTLResourceStorageModePrivate];
ASSERT_POSTCONDITION(mBuffer, "Could not allocate Metal buffer of size %zu.", size);
}
MetalBuffer::~MetalBuffer() {
@@ -67,26 +51,37 @@ void MetalBuffer::copyIntoBuffer(void* src, size_t size, size_t byteOffset) {
if (size <= 0) {
return;
}
FILAMENT_CHECK_PRECONDITION(size + byteOffset <= mBufferSize)
<< "Attempting to copy " << size << " bytes into a buffer of size " << mBufferSize
<< " at offset " << byteOffset;
// The copy blit requires that byteOffset be a multiple of 4.
FILAMENT_CHECK_PRECONDITION(!(byteOffset & 0x3)) << "byteOffset must be a multiple of 4";
ASSERT_PRECONDITION(size + byteOffset <= mBufferSize,
"Attempting to copy %zu bytes into a buffer of size %zu at offset %zu",
size, mBufferSize, byteOffset);
// If we have a cpu buffer, we can directly copy into it.
// Either copy into the Metal buffer or into our cpu buffer.
if (mCpuBuffer) {
memcpy(static_cast<uint8_t*>(mCpuBuffer) + byteOffset, src, size);
return;
}
switch (mUploadStrategy) {
case UploadStrategy::BUMP_ALLOCATOR:
uploadWithBumpAllocator(src, size, byteOffset);
break;
case UploadStrategy::POOL:
uploadWithPoolBuffer(src, size, byteOffset);
break;
}
// 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.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");
// Encode a blit from the staging buffer into the private GPU buffer.
id<MTLCommandBuffer> cmdBuffer = getPendingCommandBuffer(&mContext);
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
blitEncoder.label = @"Buffer upload blit";
[blitEncoder copyFromBuffer:staging->buffer.get()
sourceOffset:0
toBuffer:mBuffer.get()
destinationOffset:byteOffset
size:size];
[blitEncoder endEncoding];
[cmdBuffer addCompletedHandler:^(id<MTLCommandBuffer> cb) {
bufferPool->releaseBuffer(staging);
}];
}
void MetalBuffer::copyIntoBufferUnsynchronized(void* src, size_t size, size_t byteOffset) {
@@ -197,42 +192,5 @@ void MetalBuffer::bindBuffers(id<MTLCommandBuffer> cmdBuffer, id<MTLCommandEncod
}
}
void MetalBuffer::uploadWithPoolBuffer(void* src, size_t size, size_t byteOffset) const {
MetalBufferPool* bufferPool = mContext.bufferPool;
const MetalBufferPoolEntry* const staging = bufferPool->acquireBuffer(size);
memcpy(staging->buffer.get().contents, src, size);
// Encode a blit from the staging buffer into the private GPU buffer.
id<MTLCommandBuffer> cmdBuffer = getPendingCommandBuffer(&mContext);
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
blitEncoder.label = @"Buffer upload blit - pool buffer";
[blitEncoder copyFromBuffer:staging->buffer.get()
sourceOffset:0
toBuffer:mBuffer.get()
destinationOffset:byteOffset
size:size];
[blitEncoder endEncoding];
[cmdBuffer addCompletedHandler:^(id<MTLCommandBuffer> cb) {
bufferPool->releaseBuffer(staging);
}];
}
void MetalBuffer::uploadWithBumpAllocator(void* src, size_t size, size_t byteOffset) const {
MetalBumpAllocator& allocator = *mContext.bumpAllocator;
auto [buffer, offset] = allocator.allocateStagingArea(size);
memcpy(static_cast<char*>(buffer.contents) + offset, src, size);
// Encode a blit from the staging buffer into the private GPU buffer.
id<MTLCommandBuffer> cmdBuffer = getPendingCommandBuffer(&mContext);
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
blitEncoder.label = @"Buffer upload blit - bump allocator";
[blitEncoder copyFromBuffer:buffer
sourceOffset:offset
toBuffer:mBuffer.get()
destinationOffset:byteOffset
size:size];
[blitEncoder endEncoding];
}
} // namespace backend
} // namespace filament
@@ -38,28 +38,6 @@ struct MetalBufferPoolEntry {
mutable uint32_t referenceCount;
};
class MetalBumpAllocator {
public:
MetalBumpAllocator(id<MTLDevice> device, size_t capacity);
/**
* Allocates a staging area of the given size. Returns a pair of the buffer and the offset
* within the buffer. The buffer is guaranteed to be at least the given size, but may be larger.
* Clients must not write to the buffer beyond the returned offset + size.
* Clients are responsible for holding a reference to the returned buffer.
* Allocations are guaranteed to be aligned to 4 bytes.
*/
std::pair<id<MTLBuffer>, size_t> allocateStagingArea(size_t size);
size_t getCapacity() const noexcept { return mCapacity; }
private:
id<MTLDevice> mDevice;
TrackedMetalBuffer mCurrentUploadBuffer = nil;
size_t mHead = 0;
size_t mCapacity;
};
// Manages a pool of Metal buffers, periodically releasing ones that have been unused for awhile.
class MetalBufferPool {
public:
+4 -43
View File
@@ -42,16 +42,11 @@ MetalBufferPoolEntry const* MetalBufferPool::acquireBuffer(size_t numBytes) {
}
// We were not able to find a sufficiently large stage, so create a new one.
id<MTLBuffer> buffer = nil;
{
ScopedAllocationTimer timer("staging");
buffer = [mContext.device newBufferWithLength:numBytes
options:MTLResourceStorageModeShared];
}
FILAMENT_CHECK_POSTCONDITION(buffer)
<< "Could not allocate Metal staging buffer of size " << 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 {
.buffer = { buffer, TrackedMetalBuffer::Type::STAGING },
.buffer = buffer,
.capacity = numBytes,
.lastAccessed = mCurrentFrame,
.referenceCount = 1
@@ -116,39 +111,5 @@ void MetalBufferPool::reset() noexcept {
mFreeStages.clear();
}
MetalBumpAllocator::MetalBumpAllocator(id<MTLDevice> device, size_t capacity)
: mDevice(device), mCapacity(capacity) {
if (mCapacity > 0) {
mCurrentUploadBuffer = { [device newBufferWithLength:capacity options:MTLStorageModeShared],
TrackedMetalBuffer::Type::STAGING };
}
}
std::pair<id<MTLBuffer>, size_t> MetalBumpAllocator::allocateStagingArea(size_t size) {
if (size == 0) {
return { nil, 0 };
}
if (size > mCapacity) {
return { [mDevice newBufferWithLength:size options:MTLStorageModeShared], 0 };
}
assert_invariant(mCurrentUploadBuffer);
// Align the head to a 4-byte boundary.
mHead = (mHead + 3) & ~3;
if (UTILS_LIKELY(mHead + size <= mCapacity)) {
const size_t oldHead = mHead;
mHead += size;
return { mCurrentUploadBuffer.get(), oldHead };
}
// We're finished with the current allocation.
mCurrentUploadBuffer = { [mDevice newBufferWithLength:mCapacity options:MTLStorageModeShared],
TrackedMetalBuffer::Type::STAGING };
mHead = size;
return { mCurrentUploadBuffer.get(), 0 };
}
} // namespace backend
} // namespace filament
+1 -17
View File
@@ -44,7 +44,6 @@ namespace backend {
class MetalDriver;
class MetalBlitter;
class MetalBufferPool;
class MetalBumpAllocator;
class MetalRenderTarget;
class MetalSamplerGroup;
class MetalSwapChain;
@@ -56,18 +55,6 @@ struct MetalVertexBuffer;
constexpr static uint8_t MAX_SAMPLE_COUNT = 8; // Metal devices support at most 8 MSAA samples
class MetalPushConstantBuffer {
public:
void setPushConstant(PushConstantVariant value, uint8_t index);
bool isDirty() const { return mDirty; }
void setBytes(id<MTLCommandEncoder> encoder, ShaderStage stage);
void clear();
private:
std::vector<PushConstantVariant> mPushConstants;
bool mDirty = false;
};
struct MetalContext {
explicit MetalContext(size_t metalFreedTextureListSize)
: texturesToDestroy(metalFreedTextureListSize) {}
@@ -93,7 +80,7 @@ struct MetalContext {
} highestSupportedGpuFamily;
struct {
bool staticTextureTargetError;
bool a8xStaticTextureTargetError;
} bugs;
// sampleCountLookup[requestedSamples] gives a <= sample count supported by the device.
@@ -122,8 +109,6 @@ struct MetalContext {
PolygonOffset currentPolygonOffset = {0.0f, 0.0f};
std::array<MetalPushConstantBuffer, Program::SHADER_TYPE_COUNT> currentPushConstants;
MetalSamplerGroup* samplerBindings[Program::SAMPLER_BINDING_COUNT] = {};
// Keeps track of sampler groups we've finalized for the current render pass.
@@ -142,7 +127,6 @@ struct MetalContext {
utils::FixedCircularBuffer<Handle<HwTexture>> texturesToDestroy;
MetalBufferPool* bufferPool;
MetalBumpAllocator* bumpAllocator;
MetalSwapChain* currentDrawSwapChain = nil;
MetalSwapChain* currentReadSwapChain = nil;
+1 -65
View File
@@ -113,8 +113,7 @@ id<MTLCommandBuffer> getPendingCommandBuffer(MetalContext* context) {
}
}
}];
FILAMENT_CHECK_POSTCONDITION(context->pendingCommandBuffer)
<< "Could not obtain command buffer.";
ASSERT_POSTCONDITION(context->pendingCommandBuffer, "Could not obtain command buffer.");
return context->pendingCommandBuffer;
}
@@ -154,68 +153,5 @@ bool isInRenderPass(MetalContext* context) {
return context->currentRenderPassEncoder != nil;
}
void MetalPushConstantBuffer::setPushConstant(PushConstantVariant value, uint8_t index) {
if (mPushConstants.size() <= index) {
mPushConstants.resize(index + 1);
mDirty = true;
}
if (UTILS_LIKELY(mPushConstants[index] != value)) {
mDirty = true;
mPushConstants[index] = value;
}
}
void MetalPushConstantBuffer::setBytes(id<MTLCommandEncoder> encoder, ShaderStage stage) {
constexpr size_t PUSH_CONSTANT_SIZE_BYTES = 4;
constexpr size_t PUSH_CONSTANT_BUFFER_INDEX = 26;
static char buffer[MAX_PUSH_CONSTANT_COUNT * PUSH_CONSTANT_SIZE_BYTES];
assert_invariant(mPushConstants.size() <= MAX_PUSH_CONSTANT_COUNT);
size_t bufferSize = PUSH_CONSTANT_SIZE_BYTES * mPushConstants.size();
for (size_t i = 0; i < mPushConstants.size(); i++) {
const auto& constant = mPushConstants[i];
std::visit(
[i](auto arg) {
if constexpr (std::is_same_v<decltype(arg), bool>) {
// bool push constants are converted to uints in MSL.
// We must ensure we write all the bytes for boolean values to work
// correctly.
uint32_t boolAsUint = arg ? 0x00000001 : 0x00000000;
*(reinterpret_cast<uint32_t*>(buffer + PUSH_CONSTANT_SIZE_BYTES * i)) =
boolAsUint;
} else {
*(decltype(arg)*)(buffer + PUSH_CONSTANT_SIZE_BYTES * i) = arg;
}
},
constant);
}
switch (stage) {
case ShaderStage::VERTEX:
[(id<MTLRenderCommandEncoder>)encoder setVertexBytes:buffer
length:bufferSize
atIndex:PUSH_CONSTANT_BUFFER_INDEX];
break;
case ShaderStage::FRAGMENT:
[(id<MTLRenderCommandEncoder>)encoder setFragmentBytes:buffer
length:bufferSize
atIndex:PUSH_CONSTANT_BUFFER_INDEX];
break;
case ShaderStage::COMPUTE:
[(id<MTLComputeCommandEncoder>)encoder setBytes:buffer
length:bufferSize
atIndex:PUSH_CONSTANT_BUFFER_INDEX];
break;
}
mDirty = false;
}
void MetalPushConstantBuffer::clear() {
mPushConstants.clear();
mDirty = false;
}
} // namespace backend
} // namespace filament
-2
View File
@@ -17,7 +17,6 @@
#ifndef TNT_FILAMENT_DRIVER_METALDRIVER_H
#define TNT_FILAMENT_DRIVER_METALDRIVER_H
#include <backend/DriverEnums.h>
#include "private/backend/Driver.h"
#include "DriverBase.h"
@@ -141,7 +140,6 @@ private:
void enumerateBoundBuffers(BufferObjectBinding bindingType,
const std::function<void(const BufferState&, MetalBuffer*, uint32_t)>& f);
backend::StereoscopicType const mStereoscopicType;
};
} // namespace backend
+127 -182
View File
@@ -53,14 +53,14 @@ Driver* MetalDriverFactory::create(MetalPlatform* const platform, const Platform
// MetalRenderPrimitive : 24 many
// MetalVertexBuffer : 32 moderate
// -- less than or equal 32 bytes
// MetalIndexBuffer : 40 moderate
// MetalFence : 48 few
// MetalIndexBuffer : 56 moderate
// MetalBufferObject : 64 many
// -- less than or equal 64 bytes
// MetalBufferObject : 48 many
// -- less than or equal 48 bytes
// MetalSamplerGroup : 112 few
// MetalProgram : 152 moderate
// MetalTexture : 152 moderate
// MetalSwapChain : 208 few
// MetalSwapChain : 184 few
// MetalRenderTarget : 272 few
// MetalVertexBufferInfo : 552 moderate
// -- less than or equal to 552 bytes
@@ -102,13 +102,9 @@ MetalDriver::MetalDriver(MetalPlatform* platform, const Platform::DriverConfig&
mContext(new MetalContext(driverConfig.textureUseAfterFreePoolSize)),
mHandleAllocator("Handles",
driverConfig.handleArenaSize,
driverConfig.disableHandleUseAfterFreeCheck),
mStereoscopicType(driverConfig.stereoscopicType) {
driverConfig.disableHandleUseAfterFreeCheck) {
mContext->driver = this;
TrackedMetalBuffer::setPlatform(platform);
ScopedAllocationTimer::setPlatform(platform);
mContext->device = mPlatform.createDevice();
assert_invariant(mContext->device);
@@ -162,10 +158,8 @@ MetalDriver::MetalDriver(MetalPlatform* platform, const Platform::DriverConfig&
sc[s] = [mContext->device supportsTextureSampleCount:s] ? s : sc[s - 1];
}
mContext->bugs.staticTextureTargetError =
[mContext->device.name containsString:@"Apple A8X GPU"] ||
[mContext->device.name containsString:@"Apple A8 GPU"] ||
[mContext->device.name containsString:@"Apple A7 GPU"];
mContext->bugs.a8xStaticTextureTargetError =
[mContext->device.name containsString:@"Apple A8X GPU"];
mContext->commandQueue = mPlatform.createCommandQueue(mContext->device);
mContext->pipelineStateCache.setDevice(mContext->device);
@@ -173,8 +167,6 @@ MetalDriver::MetalDriver(MetalPlatform* platform, const Platform::DriverConfig&
mContext->samplerStateCache.setDevice(mContext->device);
mContext->argumentEncoderCache.setDevice(mContext->device);
mContext->bufferPool = new MetalBufferPool(*mContext);
mContext->bumpAllocator =
new MetalBumpAllocator(mContext->device, driverConfig.metalUploadBufferSizeBytes);
mContext->blitter = new MetalBlitter(*mContext);
if (@available(iOS 12, *)) {
@@ -185,8 +177,7 @@ MetalDriver::MetalDriver(MetalPlatform* platform, const Platform::DriverConfig&
CVReturn success = CVMetalTextureCacheCreate(kCFAllocatorDefault, nullptr, mContext->device,
nullptr, &mContext->textureCache);
FILAMENT_CHECK_POSTCONDITION(success == kCVReturnSuccess)
<< "Could not create Metal texture cache.";
ASSERT_POSTCONDITION(success == kCVReturnSuccess, "Could not create Metal texture cache.");
if (@available(iOS 12, *)) {
dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);
@@ -207,13 +198,10 @@ MetalDriver::MetalDriver(MetalPlatform* platform, const Platform::DriverConfig&
}
MetalDriver::~MetalDriver() noexcept {
TrackedMetalBuffer::setPlatform(nullptr);
ScopedAllocationTimer::setPlatform(nullptr);
mContext->device = nil;
mContext->emptyTexture = nil;
CFRelease(mContext->textureCache);
delete mContext->bufferPool;
delete mContext->bumpAllocator;
delete mContext->blitter;
delete mContext->timerQueryImpl;
delete mContext->shaderCompiler;
@@ -224,32 +212,25 @@ void MetalDriver::tick(int) {
executeTickOps();
}
void MetalDriver::beginFrame(int64_t monotonic_clock_ns,
int64_t refreshIntervalNs, uint32_t frameId) {
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());
mPlatform.debugUpdateStat("filament.metal.alive_buffers.generic",
TrackedMetalBuffer::getAliveBuffers(TrackedMetalBuffer::Type::GENERIC));
mPlatform.debugUpdateStat("filament.metal.alive_buffers.ring",
TrackedMetalBuffer::getAliveBuffers(TrackedMetalBuffer::Type::RING));
mPlatform.debugUpdateStat("filament.metal.alive_buffers.staging",
TrackedMetalBuffer::getAliveBuffers(TrackedMetalBuffer::Type::STAGING));
}
}
void MetalDriver::setFrameScheduledCallback(
Handle<HwSwapChain> sch, CallbackHandler* handler, FrameScheduledCallback&& callback) {
void MetalDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch,
FrameScheduledCallback callback, void* user) {
auto* swapChain = handle_cast<MetalSwapChain>(sch);
swapChain->setFrameScheduledCallback(handler, std::move(callback));
swapChain->setFrameScheduledCallback(callback, user);
}
void MetalDriver::setFrameCompletedCallback(
Handle<HwSwapChain> sch, CallbackHandler* handler, utils::Invocable<void(void)>&& callback) {
void MetalDriver::setFrameCompletedCallback(Handle<HwSwapChain> sch,
CallbackHandler* handler, CallbackHandler::Callback callback, void* user) {
auto* swapChain = handle_cast<MetalSwapChain>(sch);
swapChain->setFrameCompletedCallback(handler, std::move(callback));
swapChain->setFrameCompletedCallback(handler, callback, user);
}
void MetalDriver::execute(std::function<void(void)> const& fn) noexcept {
@@ -295,14 +276,14 @@ void MetalDriver::endFrame(uint32_t frameId) {
}
void MetalDriver::flush(int) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "flush must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"flush must be called outside of a render pass.");
submitPendingCommands(mContext);
}
void MetalDriver::finish(int) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "finish must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"finish must be called outside of a render pass.");
// Wait for all frames to finish by submitting and waiting on a dummy command buffer.
submitPendingCommands(mContext);
id<MTLCommandBuffer> oneOffBuffer = [mContext->commandQueue commandBuffer];
@@ -363,19 +344,19 @@ void MetalDriver::importTextureR(Handle<HwTexture> th, intptr_t i,
TextureFormat format, uint8_t samples, uint32_t width, uint32_t height,
uint32_t depth, TextureUsage usage) {
id<MTLTexture> metalTexture = (id<MTLTexture>) CFBridgingRelease((void*) i);
FILAMENT_CHECK_PRECONDITION(metalTexture.width == width)
<< "Imported id<MTLTexture> width (" << metalTexture.width
<< ") != Filament texture width (" << width << ")";
FILAMENT_CHECK_PRECONDITION(metalTexture.height == height)
<< "Imported id<MTLTexture> height (" << metalTexture.height
<< ") != Filament texture height (" << height << ")";
FILAMENT_CHECK_PRECONDITION(metalTexture.mipmapLevelCount == levels)
<< "Imported id<MTLTexture> levels (" << metalTexture.mipmapLevelCount
<< ") != Filament texture levels (" << levels << ")";
ASSERT_PRECONDITION(metalTexture.width == width,
"Imported id<MTLTexture> width (%d) != Filament texture width (%d)",
metalTexture.width, width);
ASSERT_PRECONDITION(metalTexture.height == height,
"Imported id<MTLTexture> height (%d) != Filament texture height (%d)",
metalTexture.height, height);
ASSERT_PRECONDITION(metalTexture.mipmapLevelCount == levels,
"Imported id<MTLTexture> levels (%d) != Filament texture levels (%d)",
metalTexture.mipmapLevelCount, levels);
MTLTextureType filamentMetalType = getMetalType(target);
FILAMENT_CHECK_PRECONDITION(metalTexture.textureType == filamentMetalType)
<< "Imported id<MTLTexture> type (" << metalTexture.textureType
<< ") != Filament texture type (" << filamentMetalType << ")";
ASSERT_PRECONDITION(metalTexture.textureType == filamentMetalType,
"Imported id<MTLTexture> type (%d) != Filament texture type (%d)",
metalTexture.textureType, filamentMetalType);
mContext->textures.insert(construct_handle<MetalTexture>(th, *mContext,
target, levels, format, samples, width, height, depth, usage, metalTexture));
}
@@ -404,8 +385,8 @@ void MetalDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
TargetBufferFlags targetBufferFlags, uint32_t width, uint32_t height,
uint8_t samples, uint8_t layerCount, MRT color,
TargetBufferInfo depth, TargetBufferInfo stencil) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "createRenderTarget must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"createRenderTarget must be called outside of a render pass.");
// Clamp sample count to what the device supports.
auto& sc = mContext->sampleCountLookup;
samples = sc[std::min(MAX_SAMPLE_COUNT, samples)];
@@ -416,33 +397,33 @@ void MetalDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
continue;
}
const auto& buffer = color[i];
FILAMENT_CHECK_PRECONDITION(buffer.handle)
<< "The COLOR" << i << " flag was specified, but invalid color handle provided.";
ASSERT_PRECONDITION(buffer.handle,
"The COLOR%u flag was specified, but invalid color handle provided.", i);
auto colorTexture = handle_cast<MetalTexture>(buffer.handle);
FILAMENT_CHECK_PRECONDITION(colorTexture->getMtlTextureForWrite())
<< "Color texture passed to render target has no texture allocation";
ASSERT_PRECONDITION(colorTexture->getMtlTextureForWrite(),
"Color texture passed to render target has no texture allocation");
colorTexture->extendLodRangeTo(buffer.level);
colorAttachments[i] = { colorTexture, color[i].level, color[i].layer };
}
MetalRenderTarget::Attachment depthAttachment = {};
if (any(targetBufferFlags & TargetBufferFlags::DEPTH)) {
FILAMENT_CHECK_PRECONDITION(depth.handle)
<< "The DEPTH flag was specified, but invalid depth handle provided.";
ASSERT_PRECONDITION(depth.handle,
"The DEPTH flag was specified, but invalid depth handle provided.");
auto depthTexture = handle_cast<MetalTexture>(depth.handle);
FILAMENT_CHECK_PRECONDITION(depthTexture->getMtlTextureForWrite())
<< "Depth texture passed to render target has no texture allocation.";
ASSERT_PRECONDITION(depthTexture->getMtlTextureForWrite(),
"Depth texture passed to render target has no texture allocation.");
depthTexture->extendLodRangeTo(depth.level);
depthAttachment = { depthTexture, depth.level, depth.layer };
}
MetalRenderTarget::Attachment stencilAttachment = {};
if (any(targetBufferFlags & TargetBufferFlags::STENCIL)) {
FILAMENT_CHECK_PRECONDITION(stencil.handle)
<< "The STENCIL flag was specified, but invalid stencil handle provided.";
ASSERT_PRECONDITION(stencil.handle,
"The STENCIL flag was specified, but invalid stencil handle provided.");
auto stencilTexture = handle_cast<MetalTexture>(stencil.handle);
FILAMENT_CHECK_PRECONDITION(stencilTexture->getMtlTextureForWrite())
<< "Stencil texture passed to render target has no texture allocation.";
ASSERT_PRECONDITION(stencilTexture->getMtlTextureForWrite(),
"Stencil texture passed to render target has no texture allocation.");
stencilTexture->extendLodRangeTo(stencil.level);
stencilAttachment = { stencilTexture, stencil.level, stencil.layer };
}
@@ -806,15 +787,13 @@ bool MetalDriver::isProtectedContentSupported() {
return false;
}
bool MetalDriver::isStereoSupported() {
switch (mStereoscopicType) {
case backend::StereoscopicType::INSTANCED:
return true;
case backend::StereoscopicType::MULTIVIEW:
// TODO: implement multiview feature in Metal.
return false;
case backend::StereoscopicType::NONE:
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;
}
}
@@ -826,10 +805,6 @@ bool MetalDriver::isDepthStencilResolveSupported() {
return false;
}
bool MetalDriver::isDepthStencilBlitSupported(TextureFormat format) {
return true;
}
bool MetalDriver::isProtectedTexturesSupported() {
return false;
}
@@ -842,8 +817,8 @@ bool MetalDriver::isWorkaroundNeeded(Workaround workaround) {
return true;
case Workaround::ADRENO_UNIFORM_ARRAY_CRASH:
return false;
case Workaround::METAL_STATIC_TEXTURE_TARGET_ERROR:
return mContext->bugs.staticTextureTargetError;
case Workaround::A8X_STATIC_TEXTURE_TARGET_ERROR:
return mContext->bugs.a8xStaticTextureTargetError;
case Workaround::DISABLE_BLIT_INTO_TEXTURE_ARRAY:
return false;
default:
@@ -887,8 +862,8 @@ void MetalDriver::updateIndexBuffer(Handle<HwIndexBuffer> ibh, BufferDescriptor&
void MetalDriver::updateBufferObject(Handle<HwBufferObject> boh, BufferDescriptor&& data,
uint32_t byteOffset) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "updateBufferObject must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"updateBufferObject must be called outside of a render pass.");
auto* bo = handle_cast<MetalBufferObject>(boh);
bo->updateBuffer(data.buffer, data.size, byteOffset);
scheduleDestroy(std::move(data));
@@ -927,8 +902,8 @@ void MetalDriver::update3DImage(Handle<HwTexture> th, uint32_t level,
uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
uint32_t width, uint32_t height, uint32_t depth,
PixelBufferDescriptor&& data) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "update3DImage must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"update3DImage must be called outside of a render pass.");
auto tex = handle_cast<MetalTexture>(th);
tex->loadImage(level, MTLRegionMake3D(xoffset, yoffset, zoffset, width, height, depth), data);
scheduleDestroy(std::move(data));
@@ -944,15 +919,15 @@ void MetalDriver::setupExternalImage(void* image) {
}
void MetalDriver::setExternalImage(Handle<HwTexture> th, void* image) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "setExternalImage must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"setExternalImage must be called outside of a render pass.");
auto texture = handle_cast<MetalTexture>(th);
texture->externalImage.set((CVPixelBufferRef) image);
}
void MetalDriver::setExternalImagePlane(Handle<HwTexture> th, void* image, uint32_t plane) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "setExternalImagePlane must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"setExternalImagePlane must be called outside of a render pass.");
auto texture = handle_cast<MetalTexture>(th);
texture->externalImage.set((CVPixelBufferRef) image, plane);
}
@@ -967,15 +942,15 @@ TimerQueryResult MetalDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint6
}
void MetalDriver::generateMipmaps(Handle<HwTexture> th) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "generateMipmaps must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"generateMipmaps must be called outside of a render pass.");
auto tex = handle_cast<MetalTexture>(th);
tex->generateMipmaps();
}
void MetalDriver::updateSamplerGroup(Handle<HwSamplerGroup> sbh, BufferDescriptor&& data) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "updateSamplerGroup must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"updateSamplerGroup must be called outside of a render pass.");
auto sb = handle_cast<MetalSamplerGroup>(sbh);
assert_invariant(sb->size == data.size / sizeof(SamplerDescriptor));
@@ -1114,10 +1089,6 @@ void MetalDriver::beginRenderPass(Handle<HwRenderTarget> rth,
mContext->currentPolygonOffset = {0.0f, 0.0f};
mContext->finalizedSamplerGroups.clear();
for (auto& pc : mContext->currentPushConstants) {
pc.clear();
}
}
void MetalDriver::nextSubpass(int dummy) {}
@@ -1265,16 +1236,6 @@ void MetalDriver::bindSamplers(uint32_t index, Handle<HwSamplerGroup> sbh) {
mContext->samplerBindings[index] = sb;
}
void MetalDriver::setPushConstant(backend::ShaderStage stage, uint8_t index,
backend::PushConstantVariant value) {
FILAMENT_CHECK_PRECONDITION(isInRenderPass(mContext))
<< "setPushConstant must be called inside a render pass.";
assert_invariant(static_cast<size_t>(stage) < mContext->currentPushConstants.size());
MetalPushConstantBuffer& pushConstants =
mContext->currentPushConstants[static_cast<size_t>(stage)];
pushConstants.setPushConstant(value, index);
}
void MetalDriver::insertEventMarker(const char* string, uint32_t len) {
}
@@ -1325,8 +1286,8 @@ void MetalDriver::stopCapture(int) {
void MetalDriver::readPixels(Handle<HwRenderTarget> src, uint32_t x, uint32_t y, uint32_t width,
uint32_t height, PixelBufferDescriptor&& data) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "readPixels must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"readPixels must be called outside of a render pass.");
auto srcTarget = handle_cast<MetalRenderTarget>(src);
// We always readPixels from the COLOR0 attachment.
@@ -1340,19 +1301,17 @@ void MetalDriver::readPixels(Handle<HwRenderTarget> src, uint32_t x, uint32_t y,
width = std::min(static_cast<uint32_t>(srcTextureSize.width), width);
const MTLPixelFormat format = getMetalFormat(data.format, data.type);
FILAMENT_CHECK_PRECONDITION(format != MTLPixelFormatInvalid)
<< "The chosen combination of PixelDataFormat (" << (int)data.format
<< ") and PixelDataType (" << (int)data.type
<< ") is not supported for "
"readPixels.";
ASSERT_PRECONDITION(format != MTLPixelFormatInvalid,
"The chosen combination of PixelDataFormat (%d) and PixelDataType (%d) is not supported for "
"readPixels.", (int) data.format, (int) data.type);
const bool formatConversionNecessary = srcTexture.pixelFormat != format;
// TODO: MetalBlitter does not currently support format conversions to integer types.
// The format and type must match the source pixel format exactly.
FILAMENT_CHECK_PRECONDITION(!formatConversionNecessary || !isMetalFormatInteger(format))
<< "readPixels does not support integer format conversions from MTLPixelFormat ("
<< (int)srcTexture.pixelFormat << ") to (" << (int)format << ").";
ASSERT_PRECONDITION(!formatConversionNecessary || !isMetalFormatInteger(format),
"readPixels does not support integer format conversions from MTLPixelFormat (%d) to (%d).",
(int) srcTexture.pixelFormat, (int) format);
MTLTextureDescriptor* textureDescriptor =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format
@@ -1418,31 +1377,31 @@ void MetalDriver::resolve(
assert_invariant(srcTexture);
assert_invariant(dstTexture);
FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder == nil)
<< "resolve() cannot be invoked inside a render pass.";
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder == nil,
"resolve() cannot be invoked inside a render pass.");
FILAMENT_CHECK_PRECONDITION(
dstTexture->width == srcTexture->width && dstTexture->height == srcTexture->height)
<< "invalid resolve: src and dst sizes don't match";
ASSERT_PRECONDITION(
dstTexture->width == srcTexture->width && dstTexture->height == srcTexture->height,
"invalid resolve: src and dst sizes don't match");
FILAMENT_CHECK_PRECONDITION(srcTexture->samples > 1 && dstTexture->samples == 1)
<< "invalid resolve: src.samples=" << +srcTexture->samples
<< ", dst.samples=" << +dstTexture->samples;
ASSERT_PRECONDITION(srcTexture->samples > 1 && dstTexture->samples == 1,
"invalid resolve: src.samples=%u, dst.samples=%u",
+srcTexture->samples, +dstTexture->samples);
FILAMENT_CHECK_PRECONDITION(srcTexture->format == dstTexture->format)
<< "src and dst texture format don't match";
ASSERT_PRECONDITION(srcTexture->format == dstTexture->format,
"src and dst texture format don't match");
FILAMENT_CHECK_PRECONDITION(!isDepthFormat(srcTexture->format))
<< "can't resolve depth formats";
ASSERT_PRECONDITION(!isDepthFormat(srcTexture->format),
"can't resolve depth formats");
FILAMENT_CHECK_PRECONDITION(!isStencilFormat(srcTexture->format))
<< "can't resolve stencil formats";
ASSERT_PRECONDITION(!isStencilFormat(srcTexture->format),
"can't resolve stencil formats");
FILAMENT_CHECK_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST))
<< "texture doesn't have BLIT_DST";
ASSERT_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST),
"texture doesn't have BLIT_DST");
FILAMENT_CHECK_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC))
<< "texture doesn't have BLIT_SRC";
ASSERT_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC),
"texture doesn't have BLIT_SRC");
// FIXME: on metal the blit() call below always take the slow path (using a shader)
@@ -1467,22 +1426,21 @@ void MetalDriver::blit(
assert_invariant(srcTexture);
assert_invariant(dstTexture);
FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder == nil)
<< "blit() cannot be invoked inside a render pass.";
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder == nil,
"blit() cannot be invoked inside a render pass.");
FILAMENT_CHECK_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST))
<< "texture doesn't have BLIT_DST";
ASSERT_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST),
"texture doesn't have BLIT_DST");
FILAMENT_CHECK_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC))
<< "texture doesn't have BLIT_SRC";
ASSERT_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC),
"texture doesn't have BLIT_SRC");
FILAMENT_CHECK_PRECONDITION(srcTexture->format == dstTexture->format)
<< "src and dst texture format don't match";
ASSERT_PRECONDITION(srcTexture->format == dstTexture->format,
"src and dst texture format don't match");
FILAMENT_CHECK_PRECONDITION(
isBlitableTextureType(srcTexture->getMtlTextureForRead().textureType) &&
isBlitableTextureType(dstTexture->getMtlTextureForWrite().textureType))
<< "Metal does not support blitting to/from non-2D textures.";
ASSERT_PRECONDITION(isBlitableTextureType(srcTexture->getMtlTextureForRead().textureType) &&
isBlitableTextureType(dstTexture->getMtlTextureForWrite().textureType),
"Metal does not support blitting to/from non-2D textures.");
MetalBlitter::BlitArgs args{};
args.filter = SamplerMagFilter::NEAREST;
@@ -1520,18 +1478,18 @@ void MetalDriver::blitDEPRECATED(TargetBufferFlags buffers,
// It is called between beginFrame and endFrame, but should never be called in the middle of
// a render pass.
FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder == nil)
<< "blitDEPRECATED() cannot be invoked inside a render pass.";
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder == nil,
"blitDEPRECATED() cannot be invoked inside a render pass.");
auto srcTarget = handle_cast<MetalRenderTarget>(src);
auto dstTarget = handle_cast<MetalRenderTarget>(dst);
FILAMENT_CHECK_PRECONDITION(buffers == TargetBufferFlags::COLOR0)
<< "blitDEPRECATED only supports COLOR0";
ASSERT_PRECONDITION(buffers == TargetBufferFlags::COLOR0,
"blitDEPRECATED only supports COLOR0");
FILAMENT_CHECK_PRECONDITION(
srcRect.left >= 0 && srcRect.bottom >= 0 && dstRect.left >= 0 && dstRect.bottom >= 0)
<< "Source and destination rects must be positive.";
ASSERT_PRECONDITION(srcRect.left >= 0 && srcRect.bottom >= 0 &&
dstRect.left >= 0 && dstRect.bottom >= 0,
"Source and destination rects must be positive.");
auto isBlitableTextureType = [](MTLTextureType t) {
return t == MTLTextureType2D || t == MTLTextureType2DMultisample ||
@@ -1543,10 +1501,9 @@ void MetalDriver::blitDEPRECATED(TargetBufferFlags buffers,
MetalRenderTarget::Attachment const dstColorAttachment = dstTarget->getDrawColorAttachment(0);
if (srcColorAttachment && dstColorAttachment) {
FILAMENT_CHECK_PRECONDITION(
isBlitableTextureType(srcColorAttachment.getTexture().textureType) &&
isBlitableTextureType(dstColorAttachment.getTexture().textureType))
<< "Metal does not support blitting to/from non-2D textures.";
ASSERT_PRECONDITION(isBlitableTextureType(srcColorAttachment.getTexture().textureType) &&
isBlitableTextureType(dstColorAttachment.getTexture().textureType),
"Metal does not support blitting to/from non-2D textures.");
MetalBlitter::BlitArgs args{};
args.filter = filter;
@@ -1657,9 +1614,9 @@ void MetalDriver::finalizeSamplerGroup(MetalSamplerGroup* samplerGroup) {
}
}
void MetalDriver::bindPipeline(PipelineState const& ps) {
FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder != nullptr)
<< "bindPipeline() without a valid command encoder.";
void MetalDriver::bindPipeline(PipelineState ps) {
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr,
"bindPipeline() without a valid command encoder.");
MetalVertexBufferInfo const* const vbi =
handle_cast<MetalVertexBufferInfo>(ps.vertexBufferInfo);
@@ -1677,7 +1634,7 @@ void MetalDriver::bindPipeline(PipelineState const& ps) {
return;
}
functions.validate();
ASSERT_PRECONDITION(bool(functions), "Attempting to bind an invalid Metal program.");
auto [fragment, vertex] = functions.getRasterFunctions();
@@ -1831,8 +1788,8 @@ void MetalDriver::bindPipeline(PipelineState const& ps) {
}
void MetalDriver::bindRenderPrimitive(Handle<HwRenderPrimitive> rph) {
FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder != nullptr)
<< "bindRenderPrimitive() without a valid command encoder.";
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr,
"bindRenderPrimitive() without a valid command encoder.");
// Bind the user vertex buffers.
MetalBuffer* vertexBuffers[MAX_VERTEX_BUFFER_COUNT] = {};
@@ -1868,8 +1825,8 @@ void MetalDriver::bindRenderPrimitive(Handle<HwRenderPrimitive> rph) {
}
void MetalDriver::draw2(uint32_t indexOffset, uint32_t indexCount, uint32_t instanceCount) {
FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder != nullptr)
<< "draw() without a valid command encoder.";
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr,
"draw() without a valid command encoder.");
// Bind uniform buffers.
MetalBuffer* uniformsToBind[Program::UNIFORM_BINDING_COUNT] = { nil };
@@ -1885,14 +1842,6 @@ void MetalDriver::draw2(uint32_t indexOffset, uint32_t indexCount, uint32_t inst
UNIFORM_BUFFER_BINDING_START, MetalBuffer::Stage::VERTEX | MetalBuffer::Stage::FRAGMENT,
uniformsToBind, offsets, Program::UNIFORM_BINDING_COUNT);
// Update push constants.
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
auto& pushConstants = mContext->currentPushConstants[i];
if (UTILS_UNLIKELY(pushConstants.isDirty())) {
pushConstants.setBytes(mContext->currentRenderPassEncoder, static_cast<ShaderStage>(i));
}
}
auto primitive = handle_cast<MetalRenderPrimitive>(mContext->currentRenderPrimitive);
MetalIndexBuffer* indexBuffer = primitive->indexBuffer;
@@ -1918,8 +1867,8 @@ void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph,
}
void MetalDriver::dispatchCompute(Handle<HwProgram> program, math::uint3 workGroupCount) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "dispatchCompute must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"dispatchCompute must be called outside of a render pass.");
auto mtlProgram = handle_cast<MetalProgram>(program);
@@ -2019,15 +1968,15 @@ void MetalDriver::scissor(Viewport scissorBox) {
}
void MetalDriver::beginTimerQuery(Handle<HwTimerQuery> tqh) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "beginTimerQuery must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"beginTimerQuery must be called outside of a render pass.");
auto* tq = handle_cast<MetalTimerQuery>(tqh);
mContext->timerQueryImpl->beginTimeElapsedQuery(tq);
}
void MetalDriver::endTimerQuery(Handle<HwTimerQuery> tqh) {
FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext))
<< "endTimerQuery must be called outside of a render pass.";
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"endTimerQuery must be called outside of a render pass.");
auto* tq = handle_cast<MetalTimerQuery>(tqh);
mContext->timerQueryImpl->endTimeElapsedQuery(tq);
}
@@ -2061,10 +2010,6 @@ void MetalDriver::enumerateBoundBuffers(BufferObjectBinding bindingType,
void MetalDriver::resetState(int) {
}
void MetalDriver::setDebugTag(HandleBase::HandleId handleId, utils::CString tag) {
mHandleAllocator.associateTagToHandle(handleId, std::move(tag));
}
void MetalDriver::runAtNextTick(const std::function<void()>& fn) noexcept {
std::lock_guard<std::mutex> const lock(mTickOpsLock);
mTickOps.push_back(fn);
+3 -4
View File
@@ -71,7 +71,7 @@ constexpr inline MTLIndexType getIndexType(size_t elementSize) noexcept {
} else if (elementSize == 4) {
return MTLIndexTypeUInt32;
}
FILAMENT_CHECK_POSTCONDITION(false) << "Index element size not supported.";
ASSERT_POSTCONDITION(false, "Index element size not supported.");
}
constexpr inline MTLVertexFormat getMetalFormat(ElementType type, bool normalized) noexcept {
@@ -100,7 +100,7 @@ constexpr inline MTLVertexFormat getMetalFormat(ElementType type, bool normalize
case ElementType::SHORT4: return MTLVertexFormatShort4Normalized;
case ElementType::USHORT4: return MTLVertexFormatUShort4Normalized;
default:
FILAMENT_CHECK_POSTCONDITION(false) << "Normalized format does not exist.";
ASSERT_POSTCONDITION(false, "Normalized format does not exist.");
return MTLVertexFormatInvalid;
}
}
@@ -326,8 +326,7 @@ constexpr inline MTLCullMode getMetalCullMode(CullingMode cullMode) noexcept {
case CullingMode::FRONT: return MTLCullModeFront;
case CullingMode::BACK: return MTLCullModeBack;
case CullingMode::FRONT_AND_BACK:
FILAMENT_CHECK_POSTCONDITION(false)
<< "FRONT_AND_BACK culling is not supported in Metal.";
ASSERT_POSTCONDITION(false, "FRONT_AND_BACK culling is not supported in Metal.");
}
}
@@ -29,7 +29,7 @@
auto description = [error.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding]; \
utils::slog.e << description << utils::io::endl; \
} \
FILAMENT_CHECK_POSTCONDITION(error == nil) << message;
ASSERT_POSTCONDITION(error == nil, message);
namespace filament {
namespace backend {
@@ -86,14 +86,14 @@ void MetalExternalImage::set(CVPixelBufferRef image) noexcept {
}
OSType formatType = CVPixelBufferGetPixelFormatType(image);
FILAMENT_CHECK_POSTCONDITION(formatType == kCVPixelFormatType_32BGRA ||
formatType == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)
<< "Metal external images must be in either 32BGRA or 420f format.";
ASSERT_POSTCONDITION(formatType == kCVPixelFormatType_32BGRA ||
formatType == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
"Metal external images must be in either 32BGRA or 420f format.");
size_t planeCount = CVPixelBufferGetPlaneCount(image);
FILAMENT_CHECK_POSTCONDITION(planeCount == 0 || planeCount == 2)
<< "The Metal backend does not support images with plane counts of " << planeCount
<< ".";
ASSERT_POSTCONDITION(planeCount == 0 || planeCount == 2,
"The Metal backend does not support images with plane counts of %d.", planeCount);
if (planeCount == 0) {
mImage = image;
@@ -138,8 +138,8 @@ void MetalExternalImage::set(CVPixelBufferRef image, size_t plane) noexcept {
}
const OSType formatType = CVPixelBufferGetPixelFormatType(image);
FILAMENT_CHECK_POSTCONDITION(formatType == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)
<< "Metal planar external images must be in the 420f format.";
ASSERT_POSTCONDITION(formatType == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange,
"Metal planar external images must be in the 420f format.");
mImage = image;
@@ -191,8 +191,8 @@ CVMetalTextureRef MetalExternalImage::createTextureFromImage(CVPixelBufferRef im
CVMetalTextureRef texture;
CVReturn result = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
mContext.textureCache, image, nullptr, format, width, height, plane, &texture);
FILAMENT_CHECK_POSTCONDITION(result == kCVReturnSuccess)
<< "Could not create a CVMetalTexture from CVPixelBuffer.";
ASSERT_POSTCONDITION(result == kCVReturnSuccess,
"Could not create a CVMetalTexture from CVPixelBuffer.");
return texture;
}
@@ -203,8 +203,8 @@ void MetalExternalImage::shutdown(MetalContext& context) noexcept {
void MetalExternalImage::assertWritableImage(CVPixelBufferRef image) {
OSType formatType = CVPixelBufferGetPixelFormatType(image);
FILAMENT_CHECK_PRECONDITION(formatType == kCVPixelFormatType_32BGRA)
<< "Metal SwapChain images must be in the 32BGRA format.";
ASSERT_PRECONDITION(formatType == kCVPixelFormatType_32BGRA,
"Metal SwapChain images must be in the 32BGRA format.");
}
void MetalExternalImage::unset() {
+13 -16
View File
@@ -31,8 +31,6 @@
#include "private/backend/SamplerGroup.h"
#include <backend/DriverEnums.h>
#include <utils/bitset.h>
#include <utils/CString.h>
#include <utils/FixedCapacityVector.h>
@@ -73,9 +71,9 @@ public:
void releaseDrawable();
void setFrameScheduledCallback(CallbackHandler* handler, FrameScheduledCallback&& callback);
void setFrameCompletedCallback(
CallbackHandler* handler, utils::Invocable<void(void)>&& callback);
void setFrameScheduledCallback(FrameScheduledCallback callback, void* user);
void setFrameCompletedCallback(CallbackHandler* handler,
CallbackHandler::Callback callback, void* user);
// For CAMetalLayer-backed SwapChains, presents the drawable or schedules a
// FrameScheduledCallback.
@@ -109,23 +107,22 @@ private:
NSUInteger headlessWidth = 0;
NSUInteger headlessHeight = 0;
CAMetalLayer* layer = nullptr;
std::shared_ptr<std::mutex> layerDrawableMutex;
MetalExternalImage externalImage;
SwapChainType type;
// These fields store a callback to notify the client that a frame is ready for presentation. If
// !frameScheduled.callback, then the Metal backend automatically calls presentDrawable when the
// frame is committed. Otherwise, the Metal backend will not automatically present the frame.
// Instead, clients bear the responsibility of presenting the frame by calling the
// PresentCallable object.
struct {
CallbackHandler* handler = nullptr;
std::shared_ptr<FrameScheduledCallback> callback = nullptr;
} frameScheduled;
// These two fields store a callback and user data to notify the client that a frame is ready
// for presentation.
// If frameScheduledCallback is nullptr, then the Metal backend automatically calls
// presentDrawable when the frame is committed.
// Otherwise, the Metal backend will not automatically present the frame. Instead, clients bear
// the responsibility of presenting the frame by calling the PresentCallable object.
FrameScheduledCallback frameScheduledCallback = nullptr;
void* frameScheduledUserData = nullptr;
struct {
CallbackHandler* handler = nullptr;
std::shared_ptr<utils::Invocable<void(void)>> callback = nullptr;
CallbackHandler::Callback callback = {};
void* user = nullptr;
} frameCompleted;
};
+47 -102
View File
@@ -73,7 +73,6 @@ MetalSwapChain::MetalSwapChain(MetalContext& context, CAMetalLayer* nativeWindow
: context(context),
depthStencilFormat(decideDepthStencilFormat(flags)),
layer(nativeWindow),
layerDrawableMutex(std::make_shared<std::mutex>()),
externalImage(context),
type(SwapChainType::CAMETALLAYER) {
@@ -175,24 +174,14 @@ id<MTLTexture> MetalSwapChain::acquireDrawable() {
}
assert_invariant(isCaMetalLayer());
drawable = [layer nextDrawable];
// CAMetalLayer's drawable pool is not thread safe. Use a mutex when
// calling -nextDrawable, or when releasing the last known reference
// to any CAMetalDrawable returned from a previous -nextDrawable.
{
std::lock_guard<std::mutex> lock(*layerDrawableMutex);
drawable = [layer nextDrawable];
}
FILAMENT_CHECK_POSTCONDITION(drawable != nil) << "Could not obtain drawable.";
ASSERT_POSTCONDITION(drawable != nil, "Could not obtain drawable.");
return drawable.texture;
}
void MetalSwapChain::releaseDrawable() {
if (drawable) {
std::lock_guard<std::mutex> lock(*layerDrawableMutex);
drawable = nil;
}
drawable = nil;
}
id<MTLTexture> MetalSwapChain::acquireDepthTexture() {
@@ -232,16 +221,16 @@ void MetalSwapChain::ensureDepthStencilTexture() {
depthStencilTexture = [context.device newTextureWithDescriptor:descriptor];
}
void MetalSwapChain::setFrameScheduledCallback(
CallbackHandler* handler, FrameScheduledCallback&& callback) {
frameScheduled.handler = handler;
frameScheduled.callback = std::make_shared<FrameScheduledCallback>(std::move(callback));
void MetalSwapChain::setFrameScheduledCallback(FrameScheduledCallback callback, void* user) {
frameScheduledCallback = callback;
frameScheduledUserData = user;
}
void MetalSwapChain::setFrameCompletedCallback(
CallbackHandler* handler, utils::Invocable<void(void)>&& callback) {
void MetalSwapChain::setFrameCompletedCallback(CallbackHandler* handler,
CallbackHandler::Callback callback, void* user) {
frameCompleted.handler = handler;
frameCompleted.callback = std::make_shared<utils::Invocable<void(void)>>(std::move(callback));
frameCompleted.callback = callback;
frameCompleted.user = user;
}
void MetalSwapChain::present() {
@@ -249,7 +238,7 @@ void MetalSwapChain::present() {
scheduleFrameCompletedCallback();
}
if (drawable) {
if (frameScheduled.callback) {
if (frameScheduledCallback) {
scheduleFrameScheduledCallback();
} else {
[getPendingCommandBuffer(&context) presentDrawable:drawable];
@@ -267,11 +256,9 @@ public:
PresentDrawableData(const PresentDrawableData&) = delete;
PresentDrawableData& operator=(const PresentDrawableData&) = delete;
static PresentDrawableData* create(id<CAMetalDrawable> drawable,
std::shared_ptr<std::mutex> drawableMutex, MetalDriver* driver) {
assert_invariant(drawableMutex);
static PresentDrawableData* create(id<CAMetalDrawable> drawable, MetalDriver* driver) {
assert_invariant(driver);
return new PresentDrawableData(drawable, drawableMutex, driver);
return new PresentDrawableData(drawable, driver);
}
static void maybePresentAndDestroyAsync(PresentDrawableData* that, bool shouldPresent) {
@@ -290,22 +277,16 @@ public:
}
private:
PresentDrawableData(id<CAMetalDrawable> drawable, std::shared_ptr<std::mutex> drawableMutex,
MetalDriver* driver)
: mDrawable(drawable), mDrawableMutex(drawableMutex), mDriver(driver) {}
PresentDrawableData(id<CAMetalDrawable> drawable, MetalDriver* driver)
: mDrawable(drawable), mDriver(driver) {}
static void cleanupAndDestroy(PresentDrawableData *that) {
if (that->mDrawable) {
std::lock_guard<std::mutex> lock(*(that->mDrawableMutex));
that->mDrawable = nil;
}
that->mDrawableMutex.reset();
that->mDrawable = nil;
that->mDriver = nullptr;
delete that;
}
id<CAMetalDrawable> mDrawable;
std::shared_ptr<std::mutex> mDrawableMutex;
MetalDriver* mDriver = nullptr;
};
@@ -315,38 +296,21 @@ void presentDrawable(bool presentFrame, void* user) {
}
void MetalSwapChain::scheduleFrameScheduledCallback() {
if (!frameScheduled.callback) {
if (!frameScheduledCallback) {
return;
}
assert_invariant(drawable);
struct Callback {
Callback(std::shared_ptr<FrameScheduledCallback> callback, id<CAMetalDrawable> drawable,
std::shared_ptr<std::mutex> drawableMutex, MetalDriver* driver)
: f(callback), data(PresentDrawableData::create(drawable, drawableMutex, driver)) {}
std::shared_ptr<FrameScheduledCallback> f;
// PresentDrawableData* is destroyed by maybePresentAndDestroyAsync() later.
std::unique_ptr<PresentDrawableData> data;
static void func(void* user) {
auto* const c = reinterpret_cast<Callback*>(user);
PresentDrawableData* presentDrawableData = c->data.release();
PresentCallable presentCallable(presentDrawable, presentDrawableData);
c->f->operator()(presentCallable);
delete c;
}
};
// Destroy this by calling maybePresentAndDestroyAsync() later.
auto* presentData = PresentDrawableData::create(drawable, context.driver);
// This callback pointer will be captured by the block. Even if the scheduled handler is never
// called, the unique_ptr will still ensure we don't leak memory.
__block auto callback = std::make_unique<Callback>(
frameScheduled.callback, drawable, layerDrawableMutex, context.driver);
FrameScheduledCallback userCallback = frameScheduledCallback;
void* userData = frameScheduledUserData;
backend::CallbackHandler* handler = frameScheduled.handler;
MetalDriver* driver = context.driver;
[getPendingCommandBuffer(&context) addScheduledHandler:^(id<MTLCommandBuffer> cb) {
Callback* user = callback.release();
driver->scheduleCallback(handler, user, &Callback::func);
PresentCallable callable(presentDrawable, static_cast<void*>(presentData));
userCallback(callable, userData);
}];
}
@@ -355,25 +319,13 @@ void MetalSwapChain::scheduleFrameCompletedCallback() {
return;
}
struct Callback {
Callback(std::shared_ptr<utils::Invocable<void(void)>> callback) : f(callback) {}
std::shared_ptr<utils::Invocable<void(void)>> f;
static void func(void* user) {
auto* const c = reinterpret_cast<Callback*>(user);
c->f->operator()();
delete c;
}
};
// This callback pointer will be captured by the block. Even if the completed handler is never
// called, the unique_ptr will still ensure we don't leak memory.
__block auto callback = std::make_unique<Callback>(frameCompleted.callback);
CallbackHandler* handler = frameCompleted.handler;
void* user = frameCompleted.user;
CallbackHandler::Callback callback = frameCompleted.callback;
MetalDriver* driver = context.driver;
[getPendingCommandBuffer(&context) addCompletedHandler:^(id<MTLCommandBuffer> cb) {
Callback* user = callback.release();
driver->scheduleCallback(handler, user, &Callback::func);
driver->scheduleCallback(handler, user, callback);
}];
}
@@ -512,16 +464,15 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le
externalImage(context, r, g, b, a) {
devicePixelFormat = decidePixelFormat(&context, format);
FILAMENT_CHECK_POSTCONDITION(devicePixelFormat != MTLPixelFormatInvalid)
<< "Texture format not supported.";
ASSERT_POSTCONDITION(devicePixelFormat != MTLPixelFormatInvalid, "Texture format not supported.");
const BOOL mipmapped = levels > 1;
const BOOL multisampled = samples > 1;
#if defined(IOS)
const BOOL textureArray = target == SamplerType::SAMPLER_2D_ARRAY;
FILAMENT_CHECK_PRECONDITION(!textureArray || !multisampled)
<< "iOS does not support multisampled texture arrays.";
ASSERT_PRECONDITION(!textureArray || !multisampled,
"iOS does not support multisampled texture arrays.");
#endif
const auto get2DTextureType = [](SamplerType target, bool isMultisampled) {
@@ -556,12 +507,12 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le
descriptor.usage = getMetalTextureUsage(usage);
descriptor.storageMode = MTLStorageModePrivate;
texture = [context.device newTextureWithDescriptor:descriptor];
ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?");
break;
case SamplerType::SAMPLER_CUBEMAP:
case SamplerType::SAMPLER_CUBEMAP_ARRAY:
FILAMENT_CHECK_POSTCONDITION(!multisampled)
<< "Multisampled cubemap faces not supported.";
FILAMENT_CHECK_POSTCONDITION(width == height) << "Cubemap faces must be square.";
ASSERT_POSTCONDITION(!multisampled, "Multisampled cubemap faces not supported.");
ASSERT_POSTCONDITION(width == height, "Cubemap faces must be square.");
descriptor = [MTLTextureDescriptor textureCubeDescriptorWithPixelFormat:devicePixelFormat
size:width
mipmapped:mipmapped];
@@ -570,6 +521,7 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le
descriptor.usage = getMetalTextureUsage(usage);
descriptor.storageMode = MTLStorageModePrivate;
texture = [context.device newTextureWithDescriptor:descriptor];
ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?");
break;
case SamplerType::SAMPLER_3D:
descriptor = [MTLTextureDescriptor new];
@@ -582,6 +534,7 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le
descriptor.usage = getMetalTextureUsage(usage);
descriptor.storageMode = MTLStorageModePrivate;
texture = [context.device newTextureWithDescriptor:descriptor];
ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?");
break;
case SamplerType::SAMPLER_EXTERNAL:
// If we're using external textures (CVPixelBufferRefs), we don't need to make any
@@ -590,12 +543,6 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le
break;
}
FILAMENT_CHECK_POSTCONDITION(target == SamplerType::SAMPLER_EXTERNAL || texture != nil)
<< "Could not create Metal texture (SamplerType = " << int(target)
<< ", levels = " << int(levels) << ", MTLPixelFormat = " << int(devicePixelFormat)
<< ", width = " << width << ", height = " << height << ", depth = " << depth
<< "). Out of memory?";
// If swizzling is set, set up a swizzled texture view that we'll use when sampling this texture.
const bool isDefaultSwizzle =
r == TextureSwizzle::CHANNEL_0 &&
@@ -789,9 +736,9 @@ void MetalTexture::loadSlice(uint32_t level, MTLRegion region, uint32_t byteOffs
PixelBufferDescriptor const& data) noexcept {
const PixelBufferShape shape = PixelBufferShape::compute(data, format, region.size, byteOffset);
FILAMENT_CHECK_PRECONDITION(data.size >= shape.totalBytes)
<< "Expected buffer size of at least " << shape.totalBytes
<< " but received PixelBufferDescriptor with size " << data.size << ".";
ASSERT_PRECONDITION(data.size >= shape.totalBytes,
"Expected buffer size of at least %d but "
"received PixelBufferDescriptor with size %d.", shape.totalBytes, data.size);
// Earlier versions of iOS don't have the maxBufferLength query, but 256 MB is a safe bet.
NSUInteger deviceMaxBufferLength = 256 * 1024 * 1024; // 256 MB
@@ -1012,9 +959,9 @@ MetalRenderTarget::MetalRenderTarget(MetalContext* context, uint32_t width, uint
}
color[i] = colorAttachments[i];
FILAMENT_CHECK_PRECONDITION(color[i].getSampleCount() <= samples)
<< "MetalRenderTarget was initialized with a MSAA COLOR" << i
<< " texture, but sample count is " << samples << ".";
ASSERT_PRECONDITION(color[i].getSampleCount() <= samples,
"MetalRenderTarget was initialized with a MSAA COLOR%d texture, but sample count is %d.",
i, samples);
auto t = color[i].metalTexture;
const auto twidth = std::max(1u, t->width >> color[i].level);
@@ -1037,10 +984,9 @@ MetalRenderTarget::MetalRenderTarget(MetalContext* context, uint32_t width, uint
if (depthAttachment) {
depth = depthAttachment;
FILAMENT_CHECK_PRECONDITION(depth.getSampleCount() <= samples)
<< "MetalRenderTarget was initialized with a MSAA DEPTH texture, but sample count "
"is "
<< samples << ".";
ASSERT_PRECONDITION(depth.getSampleCount() <= samples,
"MetalRenderTarget was initialized with a MSAA DEPTH texture, but sample count is %d.",
samples);
auto t = depth.metalTexture;
const auto twidth = std::max(1u, t->width >> depth.level);
@@ -1063,10 +1009,9 @@ MetalRenderTarget::MetalRenderTarget(MetalContext* context, uint32_t width, uint
if (stencilAttachment) {
stencil = stencilAttachment;
FILAMENT_CHECK_PRECONDITION(stencil.getSampleCount() <= samples)
<< "MetalRenderTarget was initialized with a MSAA STENCIL texture, but sample "
"count is "
<< samples << ".";
ASSERT_PRECONDITION(stencil.getSampleCount() <= samples,
"MetalRenderTarget was initialized with a MSAA STENCIL texture, but sample count is %d.",
samples);
auto t = stencil.metalTexture;
const auto twidth = std::max(1u, t->width >> stencil.level);
@@ -106,41 +106,26 @@ bool MetalShaderCompiler::isParallelShaderCompileSupported() const noexcept {
continue;
}
assert_invariant(source[source.size() - 1] == '\0');
// the shader string is null terminated and the length includes the null character
NSString* objcSource = [[NSString alloc] initWithBytes:source.data()
length:source.size() - 1
encoding:NSUTF8StringEncoding];
// By default, Metal uses the most recent language version.
MTLCompileOptions* options = [MTLCompileOptions new];
// Disable Fast Math optimizations.
// This ensures that operations adhere to IEEE standards for floating-point arithmetic,
// which is crucial for half precision floats in scenarios where fast math optimizations
// lead to inaccuracies, such as in handling special values like NaN or Infinity.
options.fastMathEnabled = NO;
NSError* error = nil;
id<MTLLibrary> library = nil;
switch (program.getShaderLanguage()) {
case ShaderLanguage::MSL: {
// By default, Metal uses the most recent language version.
MTLCompileOptions* options = [MTLCompileOptions new];
// Disable Fast Math optimizations.
// This ensures that operations adhere to IEEE standards for floating-point
// arithmetic, which is crucial for half precision floats in scenarios where fast
// math optimizations lead to inaccuracies, such as in handling special values like
// NaN or Infinity.
options.fastMathEnabled = NO;
assert_invariant(source[source.size() - 1] == '\0');
// the shader string is null terminated and the length includes the null character
NSString* objcSource = [[NSString alloc] initWithBytes:source.data()
length:source.size() - 1
encoding:NSUTF8StringEncoding];
library = [device newLibraryWithSource:objcSource options:options error:&error];
break;
}
case ShaderLanguage::METAL_LIBRARY: {
dispatch_data_t data = dispatch_data_create(source.data(), source.size(),
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
DISPATCH_DATA_DESTRUCTOR_DEFAULT);
library = [device newLibraryWithData:data error:&error];
break;
}
case ShaderLanguage::ESSL1:
case ShaderLanguage::ESSL3:
case ShaderLanguage::SPIRV:
break;
}
id<MTLLibrary> library = [device newLibraryWithSource:objcSource
options:options
error:&error];
if (library == nil) {
NSString* errorMessage = @"unknown error";
if (error) {
@@ -169,23 +154,6 @@ bool MetalShaderCompiler::isParallelShaderCompileSupported() const noexcept {
id<MTLFunction> function = [library newFunctionWithName:@"main0"
constantValues:constants
error:&error];
if (function == nil) {
// If the library loads but functions within it fail to load, it usually means the
// GPU backend crashed. (This can happen if it's a Metallib shader that was compiled
// with a minimum iOS version that's newer than this device.)
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 load main0 in Metal program.");
NSString* programName =
[NSString stringWithFormat:@"%s::main0", program.getName().c_str_safe()];
return MetalFunctionBundle::error(errorMessage, programName);
}
if (!program.getName().empty()) {
function.label = @(program.getName().c_str());
}
+2 -4
View File
@@ -43,8 +43,7 @@ inline bool operator==(const SamplerParams& lhs, const SamplerParams& rhs) {
// ------------------------------------------------------
// 0 Zero buffer (placeholder vertex buffer) 1
// 1-16 Filament vertex buffers 16 limited by MAX_VERTEX_BUFFER_COUNT
// 17-25 Uniform buffers 9 Program::UNIFORM_BINDING_COUNT
// 26 Push constants 1
// 17-26 Uniform buffers 10 Program::UNIFORM_BINDING_COUNT
// 27-30 Sampler groups (argument buffers) 4 Program::SAMPLER_BINDING_COUNT
//
// Total 31
@@ -54,8 +53,7 @@ inline bool operator==(const SamplerParams& lhs, const SamplerParams& rhs) {
// Bindings Buffer name Count
// ------------------------------------------------------
// 0-3 SSBO buffers 4 MAX_SSBO_COUNT
// 17-25 Uniform buffers 9 Program::UNIFORM_BINDING_COUNT
// 26 Push constants 1
// 17-26 Uniform buffers 10 Program::UNIFORM_BINDING_COUNT
// 27-30 Sampler groups (argument buffers) 4 Program::SAMPLER_BINDING_COUNT
//
// Total 18
+3 -9
View File
@@ -90,17 +90,11 @@ id<MTLRenderPipelineState> PipelineStateCreator::operator()(id<MTLDevice> device
NSError* error = nullptr;
id<MTLRenderPipelineState> pipeline = [device newRenderPipelineStateWithDescriptor:descriptor
error:&error];
if (UTILS_UNLIKELY(pipeline == nil)) {
NSString *errorMessage =
[NSString stringWithFormat:@"Could not create Metal pipeline state: %@",
error ? error.localizedDescription : @"unknown error"];
auto description = [errorMessage cStringUsingEncoding:NSUTF8StringEncoding];
if (error) {
auto description = [error.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding];
utils::slog.e << description << utils::io::endl;
[[NSException exceptionWithName:@"MetalRenderPipelineFailure"
reason:errorMessage
userInfo:nil] raise];
}
FILAMENT_CHECK_POSTCONDITION(error == nil) << "Could not create Metal pipeline state.";
ASSERT_POSTCONDITION(error == nil, "Could not create Metal pipeline state.");
return pipeline;
}
+5 -17
View File
@@ -49,17 +49,16 @@ void NoopDriver::terminate() {
void NoopDriver::tick(int) {
}
void NoopDriver::beginFrame(int64_t monotonic_clock_ns,
int64_t refreshIntervalNs, uint32_t frameId) {
void NoopDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) {
}
void NoopDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch,
CallbackHandler* handler, FrameScheduledCallback&& callback) {
FrameScheduledCallback callback, void* user) {
}
void NoopDriver::setFrameCompletedCallback(Handle<HwSwapChain> sch,
CallbackHandler* handler, utils::Invocable<void(void)>&& callback) {
CallbackHandler* handler, CallbackHandler::Callback callback, void* user) {
}
@@ -182,7 +181,7 @@ bool NoopDriver::isProtectedContentSupported() {
return false;
}
bool NoopDriver::isStereoSupported() {
bool NoopDriver::isStereoSupported(backend::StereoscopicType) {
return false;
}
@@ -194,10 +193,6 @@ bool NoopDriver::isDepthStencilResolveSupported() {
return true;
}
bool NoopDriver::isDepthStencilBlitSupported(TextureFormat format) {
return true;
}
bool NoopDriver::isProtectedTexturesSupported() {
return true;
}
@@ -312,10 +307,6 @@ void NoopDriver::unbindBuffer(BufferObjectBinding bindingType, uint32_t index) {
void NoopDriver::bindSamplers(uint32_t index, Handle<HwSamplerGroup> sbh) {
}
void NoopDriver::setPushConstant(backend::ShaderStage stage, uint8_t index,
backend::PushConstantVariant value) {
}
void NoopDriver::insertEventMarker(char const* string, uint32_t len) {
}
@@ -359,7 +350,7 @@ void NoopDriver::blit(
math::uint2 size) {
}
void NoopDriver::bindPipeline(PipelineState const& pipelineState) {
void NoopDriver::bindPipeline(PipelineState pipelineState) {
}
void NoopDriver::bindRenderPrimitive(Handle<HwRenderPrimitive> rph) {
@@ -388,7 +379,4 @@ void NoopDriver::endTimerQuery(Handle<HwTimerQuery> tqh) {
void NoopDriver::resetState(int) {
}
void NoopDriver::setDebugTag(HandleBase::HandleId handleId, utils::CString tag) {
}
} // namespace filament
@@ -1,51 +0,0 @@
/*
* 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
@@ -1,55 +0,0 @@
/*
* 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), reserved1(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 reserved0 = 0;
bool imported : 1;
uint8_t sidecarSamples : 4;
uint8_t reserved1 : 3;
} gl;
OpenGLPlatform::ExternalTexture* externalTexture = nullptr;
};
} // namespace filament::backend
#endif //TNT_FILAMENT_BACKEND_OPENGL_GLTEXTURE_H
+11 -83
View File
@@ -63,11 +63,8 @@ bool OpenGLContext::queryOpenGLVersion(GLint* major, GLint* minor) noexcept {
#endif
}
OpenGLContext::OpenGLContext(OpenGLPlatform& platform,
Platform::DriverConfig const& driverConfig) noexcept
: mPlatform(platform),
mSamplerMap(32),
mDriverConfig(driverConfig) {
OpenGLContext::OpenGLContext(OpenGLPlatform& platform) noexcept
: mPlatform(platform) {
state.vao.p = &mDefaultVAO;
@@ -87,13 +84,6 @@ OpenGLContext::OpenGLContext(OpenGLPlatform& platform,
queryOpenGLVersion(&state.major, &state.minor);
#if defined(BACKEND_OPENGL_VERSION_GLES)
if (UTILS_UNLIKELY(driverConfig.forceGLES2Context)) {
state.major = 2;
state.minor = 0;
}
#endif
OpenGLContext::initExtensions(&ext, state.major, state.minor);
OpenGLContext::initProcs(&procs, ext, state.major, state.minor);
@@ -262,23 +252,9 @@ OpenGLContext::OpenGLContext(OpenGLPlatform& platform,
}
OpenGLContext::~OpenGLContext() noexcept {
// note: this is called from the main thread. Can't do any GL calls.
delete mTimerQueryFactory;
}
void OpenGLContext::terminate() noexcept {
// note: this is called from the backend thread
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
if (!isES2()) {
for (auto& item: mSamplerMap) {
unbindSampler(item.second);
glDeleteSamplers(1, &item.second);
}
mSamplerMap.clear();
}
#endif
}
void OpenGLContext::destroyWithContext(
size_t index, std::function<void(OpenGLContext&)> const& closure) noexcept {
if (index == 0) {
@@ -367,8 +343,7 @@ void OpenGLContext::setDefaultState() noexcept {
}
#endif
if (ext.EXT_clip_cull_distance
&& mDriverConfig.stereoscopicType == StereoscopicType::INSTANCED) {
if (ext.EXT_clip_cull_distance) {
glEnable(GL_CLIP_DISTANCE0);
glEnable(GL_CLIP_DISTANCE1);
}
@@ -541,6 +516,8 @@ void OpenGLContext::initBugs(Bugs* bugs, Extensions const& exts,
bugs->delay_fbo_destruction = true;
// PowerVR seems to have no problem with this (which is good for us)
bugs->allow_read_only_ancillary_feedback_loop = true;
// PowerVR has a shader compiler thread pinned on the last core
bugs->disable_thread_affinity = true;
} else if (strstr(renderer, "Apple")) {
// Apple GPU
} else if (strstr(renderer, "Tegra") ||
@@ -891,32 +868,19 @@ default_case:
}
}
void OpenGLContext::unbindTexture(
UTILS_UNUSED_IN_RELEASE GLenum target, GLuint texture_id) noexcept {
void OpenGLContext::unbindTexture(GLenum target, GLuint texture_id) noexcept {
// unbind this texture from all the units it might be bound to
// no need unbind the texture from FBOs because we're not tracking that state (and there is
// no need to).
// Never attempt to unbind texture 0. This could happen with external textures w/ streaming if
// never populated.
if (texture_id) {
UTILS_NOUNROLL
for (GLuint unit = 0; unit < MAX_TEXTURE_UNIT_COUNT; unit++) {
if (state.textures.units[unit].id == texture_id) {
// if this texture is bound, it should be at the same target
assert_invariant(state.textures.units[unit].target == target);
unbindTextureUnit(unit);
}
const size_t index = getIndexForTextureTarget(target);
UTILS_NOUNROLL
for (GLuint unit = 0; unit < MAX_TEXTURE_UNIT_COUNT; unit++) {
if (state.textures.units[unit].targets[index].texture_id == texture_id) {
bindTexture(unit, target, (GLuint)0, index);
}
}
}
void OpenGLContext::unbindTextureUnit(GLuint unit) noexcept {
update_state(state.textures.units[unit].id, 0u, [&]() {
activeTexture(unit);
glBindTexture(state.textures.units[unit].target, 0u);
});
}
void OpenGLContext::unbindSampler(GLuint sampler) noexcept {
// unbind this sampler from all the units it might be bound to
UTILS_NOUNROLL // clang generates >800B of code!!!
@@ -970,37 +934,6 @@ void OpenGLContext::deleteVertexArray(GLuint vao) noexcept {
}
}
#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
@@ -1044,11 +977,6 @@ void OpenGLContext::resetState() noexcept {
);
glDepthMask(state.raster.depthMask);
glDepthFunc(state.raster.depthFunc);
utils::slog.e << "stencil front=" <<
state.stencil.front.func.func << " " <<
state.stencil.front.func.ref << " " <<
state.stencil.front.func.mask << " " << utils::io::endl;
// state.stencil
glStencilFuncSeparate(
+44 -54
View File
@@ -34,8 +34,6 @@
#include <math/vec2.h>
#include <math/vec4.h>
#include <tsl/robin_map.h>
#include <array>
#include <functional>
#include <optional>
@@ -91,13 +89,9 @@ public:
static bool queryOpenGLVersion(GLint* major, GLint* minor) noexcept;
explicit OpenGLContext(OpenGLPlatform& platform,
Platform::DriverConfig const& driverConfig) noexcept;
explicit OpenGLContext(OpenGLPlatform& platform) noexcept;
~OpenGLContext() noexcept final;
void terminate() noexcept;
// TimerQueryInterface ------------------------------------------------------------------------
// note: OpenGLContext being final ensures (clang) these are not called through the vtable
@@ -138,6 +132,7 @@ public:
#endif
}
constexpr static inline size_t getIndexForTextureTarget(GLuint target) noexcept;
constexpr inline size_t getIndexForCap(GLenum cap) noexcept;
constexpr static inline size_t getIndexForBufferTarget(GLenum target) noexcept;
@@ -149,10 +144,10 @@ public:
void pixelStore(GLenum, GLint) noexcept;
inline void activeTexture(GLuint unit) noexcept;
inline void bindTexture(GLuint unit, GLuint target, GLuint texId, size_t targetIndex) noexcept;
inline void bindTexture(GLuint unit, GLuint target, GLuint texId) noexcept;
void unbindTexture(GLenum target, GLuint id) noexcept;
void unbindTextureUnit(GLuint unit) noexcept;
inline void bindVertexArray(RenderPrimitive const* p) noexcept;
inline void bindSampler(GLuint unit, GLuint sampler) noexcept;
void unbindSampler(GLuint sampler) noexcept;
@@ -311,6 +306,10 @@ public:
// a glFinish. So we must delay the destruction until we know the GPU is finished.
bool delay_fbo_destruction;
// The driver has some threads pinned, and we can't easily know on which core, it can hurt
// performance more if we end-up pinned on the same one.
bool disable_thread_affinity;
// Force feature level 0. Typically used for low end ES3 devices with significant driver
// bugs or performance issues.
bool force_feature_level0;
@@ -322,14 +321,8 @@ public:
// function to handle state changes we don't control
void updateTexImage(GLenum target, GLuint id) noexcept {
assert_invariant(target == GL_TEXTURE_EXTERNAL_OES);
// if another target is bound to this texture unit, unbind that texture
if (UTILS_UNLIKELY(state.textures.units[state.textures.active].target != target)) {
glBindTexture(state.textures.units[state.textures.active].target, 0);
state.textures.units[state.textures.active].target = GL_TEXTURE_EXTERNAL_OES;
}
// the texture is already bound to `target`, we just update our internal state
state.textures.units[state.textures.active].id = id;
const size_t index = getIndexForTextureTarget(target);
state.textures.units[state.textures.active].targets[index].texture_id = id;
}
void resetProgram() noexcept { state.program.use = 0; }
@@ -432,8 +425,9 @@ public:
GLuint active = 0; // zero-based
struct {
GLuint sampler = 0;
GLuint target = 0;
GLuint id = 0;
struct {
GLuint texture_id = 0;
} targets[7]; // this must match getIndexForTextureTarget()
} units[MAX_TEXTURE_UNIT_COUNT];
} textures;
@@ -473,29 +467,6 @@ public:
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;
@@ -505,13 +476,6 @@ private:
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;
Platform::DriverConfig const mDriverConfig;
void bindFramebufferResolved(GLenum target, GLuint buffer) noexcept;
@@ -558,6 +522,9 @@ private:
{ bugs.delay_fbo_destruction,
"delay_fbo_destruction",
""},
{ bugs.disable_thread_affinity,
"disable_thread_affinity",
""},
{ bugs.force_feature_level0,
"force_feature_level0",
""},
@@ -605,10 +572,31 @@ private:
}
void setDefaultState() noexcept;
static constexpr const size_t TEXTURE_TARGET_COUNT =
sizeof(state.textures.units[0].targets) / sizeof(state.textures.units[0].targets[0]);
};
// ------------------------------------------------------------------------------------------------
constexpr size_t OpenGLContext::getIndexForTextureTarget(GLuint target) noexcept {
// this must match state.textures[].targets[]
switch (target) {
case GL_TEXTURE_2D: return 0;
case GL_TEXTURE_2D_ARRAY: return 1;
case GL_TEXTURE_CUBE_MAP: return 2;
#if defined(BACKEND_OPENGL_LEVEL_GLES31)
case GL_TEXTURE_2D_MULTISAMPLE: return 3;
#endif
case GL_TEXTURE_EXTERNAL_OES: return 4;
case GL_TEXTURE_3D: return 5;
case GL_TEXTURE_CUBE_MAP_ARRAY: return 6;
default:
return 0;
}
}
constexpr size_t OpenGLContext::getIndexForCap(GLenum cap) noexcept { //NOLINT
size_t index = 0;
switch (cap) {
@@ -756,17 +744,19 @@ void OpenGLContext::bindBufferRange(GLenum target, GLuint index, GLuint buffer,
#endif
}
void OpenGLContext::bindTexture(GLuint unit, GLuint target, GLuint texId) noexcept {
update_state(state.textures.units[unit].target, target, [&]() {
activeTexture(unit);
glBindTexture(state.textures.units[unit].target, 0);
});
update_state(state.textures.units[unit].id, texId, [&]() {
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);
}
void OpenGLContext::bindTexture(GLuint unit, GLuint target, GLuint texId) noexcept {
bindTexture(unit, target, texId, getIndexForTextureTarget(target));
}
void OpenGLContext::useProgram(GLuint program) noexcept {
update_state(state.program.use, program, [&]() {
glUseProgram(program);
+166 -240
View File
@@ -83,20 +83,12 @@
#define HAS_MAPBUFFERS 1
#endif
#define DEBUG_GROUP_MARKER_NONE 0x00 // no debug marker
#define DEBUG_GROUP_MARKER_OPENGL 0x01 // markers in the gl command queue (req. driver support)
#define DEBUG_GROUP_MARKER_BACKEND 0x02 // markers on the backend side (systrace)
#define DEBUG_GROUP_MARKER_ALL 0x03 // all markers
#define DEBUG_MARKER_NONE 0x00 // no debug marker
#define DEBUG_MARKER_OPENGL 0x01 // markers in the gl command queue (req. driver support)
#define DEBUG_MARKER_BACKEND 0x02 // markers on the backend side (systrace)
#define DEBUG_MARKER_ALL 0x03 // all markers
#define DEBUG_MARKER_NONE 0x00 // no debug marker
#define DEBUG_MARKER_OPENGL 0x01 // markers in the gl command queue (req. driver support)
#define DEBUG_MARKER_BACKEND 0x02 // markers on the backend side (systrace)
#define DEBUG_MARKER_ALL 0x03 // all markers
// set to the desired debug marker level (for user markers [default: All])
#define DEBUG_GROUP_MARKER_LEVEL DEBUG_GROUP_MARKER_ALL
// set to the desired debug level (for internal debugging [Default: None])
// set to the desired debug marker level
#define DEBUG_MARKER_LEVEL DEBUG_MARKER_NONE
#if DEBUG_MARKER_LEVEL > DEBUG_MARKER_NONE
@@ -181,10 +173,6 @@ Driver* OpenGLDriver::create(OpenGLPlatform* const platform,
PANIC_LOG("OpenGL ES 2.0 minimum needed (current %d.%d)", major, minor);
goto cleanup;
}
if (UTILS_UNLIKELY(driverConfig.forceGLES2Context)) {
major = 2;
minor = 0;
}
#else
// we require GL 4.1 headers and minimum version
if (UTILS_UNLIKELY(!((major == 4 && minor >= 1) || major > 4))) {
@@ -204,50 +192,24 @@ Driver* OpenGLDriver::create(OpenGLPlatform* const platform,
OpenGLDriver::DebugMarker::DebugMarker(OpenGLDriver& driver, const char* string) noexcept
: driver(driver) {
#ifndef __EMSCRIPTEN__
#ifdef GL_EXT_debug_marker
#if DEBUG_MARKER_LEVEL & DEBUG_MARKER_OPENGL
if (UTILS_LIKELY(driver.getContext().ext.EXT_debug_marker)) {
glPushGroupMarkerEXT(GLsizei(strlen(string)), string);
}
#endif
#endif
#if DEBUG_MARKER_LEVEL & DEBUG_MARKER_BACKEND
SYSTRACE_CONTEXT();
SYSTRACE_NAME_BEGIN(string);
#endif
#endif
driver.pushGroupMarker(string, strlen(string));
}
OpenGLDriver::DebugMarker::~DebugMarker() noexcept {
#ifndef __EMSCRIPTEN__
#ifdef GL_EXT_debug_marker
#if DEBUG_MARKER_LEVEL & DEBUG_MARKER_OPENGL
if (UTILS_LIKELY(driver.getContext().ext.EXT_debug_marker)) {
glPopGroupMarkerEXT();
}
#endif
#endif
#if DEBUG_MARKER_LEVEL & DEBUG_MARKER_BACKEND
SYSTRACE_CONTEXT();
SYSTRACE_NAME_END();
#endif
#endif
driver.popGroupMarker();
}
// ------------------------------------------------------------------------------------------------
OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfig& driverConfig) noexcept
: mPlatform(*platform),
mContext(mPlatform, driverConfig),
mContext(mPlatform),
mShaderCompilerService(*this),
mHandleAllocator("Handles",
driverConfig.handleArenaSize,
driverConfig.disableHandleUseAfterFreeCheck),
mDriverConfig(driverConfig),
mCurrentPushConstants(new(std::nothrow) PushConstantBundle{}) {
mSamplerMap(32),
mDriverConfig(driverConfig) {
std::fill(mSamplerBindings.begin(), mSamplerBindings.end(), nullptr);
@@ -271,19 +233,10 @@ OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfi
}
OpenGLDriver::~OpenGLDriver() noexcept { // NOLINT(modernize-use-equals-default)
// this is called from the main thread. Can't call GL.
}
Dispatcher OpenGLDriver::getDispatcher() const noexcept {
auto dispatcher = ConcreteDispatcher<OpenGLDriver>::make();
if (mContext.isES2()) {
dispatcher.draw2_ = +[](Driver& driver, CommandBase* base, intptr_t* next){
using Cmd = COMMAND_TYPE(draw2);
OpenGLDriver& concreteDriver = static_cast<OpenGLDriver&>(driver);
Cmd::execute(&OpenGLDriver::draw2GLES2, concreteDriver, base, next);
};
}
return dispatcher;
return ConcreteDispatcher<OpenGLDriver>::make();
}
// ------------------------------------------------------------------------------------------------
@@ -310,13 +263,16 @@ void OpenGLDriver::terminate() {
// because we called glFinish(), all callbacks should have been executed
assert_invariant(mGpuCommandCompleteOps.empty());
if (!getContext().isES2()) {
for (auto& item: mSamplerMap) {
mContext.unbindSampler(item.second);
glDeleteSamplers(1, &item.second);
}
mSamplerMap.clear();
}
#endif
delete mCurrentPushConstants;
mCurrentPushConstants = nullptr;
mContext.terminate();
mPlatform.terminate();
}
@@ -335,59 +291,23 @@ void OpenGLDriver::bindSampler(GLuint unit, GLuint sampler) noexcept {
mContext.bindSampler(unit, sampler);
}
void OpenGLDriver::setPushConstant(backend::ShaderStage stage, uint8_t index,
backend::PushConstantVariant value) {
assert_invariant(stage == ShaderStage::VERTEX || stage == ShaderStage::FRAGMENT);
#if FILAMENT_ENABLE_MATDBG
if (UTILS_UNLIKELY(!mValidProgram)) {
return;
}
#endif
utils::Slice<std::pair<GLint, ConstantType>> constants;
if (stage == ShaderStage::VERTEX) {
constants = mCurrentPushConstants->vertexConstants;
} else if (stage == ShaderStage::FRAGMENT) {
constants = mCurrentPushConstants->fragmentConstants;
}
assert_invariant(index < constants.size());
auto const& [location, type] = constants[index];
// This push constant wasn't found in the shader. It's ok to return without error-ing here.
if (location < 0) {
return;
}
if (std::holds_alternative<bool>(value)) {
assert_invariant(type == ConstantType::BOOL);
bool const bval = std::get<bool>(value);
glUniform1i(location, bval ? 1 : 0);
} else if (std::holds_alternative<float>(value)) {
assert_invariant(type == ConstantType::FLOAT);
float const fval = std::get<float>(value);
glUniform1f(location, fval);
} else {
assert_invariant(type == ConstantType::INT);
int const ival = std::get<int>(value);
glUniform1i(location, ival);
}
}
void OpenGLDriver::bindTexture(GLuint unit, GLTexture const* t) noexcept {
assert_invariant(t != nullptr);
mContext.bindTexture(unit, t->gl.target, t->gl.id);
mContext.bindTexture(unit, t->gl.target, t->gl.id, t->gl.targetIndex);
}
bool OpenGLDriver::useProgram(OpenGLProgram* p) noexcept {
// set-up textures and samplers in the proper TMUs (as specified in setSamplers)
bool const success = p->use(this, mContext);
assert_invariant(success == p->isValid());
if (UTILS_UNLIKELY(!p->isValid())) {
// If the program is not valid, we can't call use().
return false;
}
if (UTILS_UNLIKELY(mContext.isES2() && success)) {
// set-up textures and samplers in the proper TMUs (as specified in setSamplers)
p->use(this, mContext);
if (UTILS_UNLIKELY(mContext.isES2())) {
for (uint32_t i = 0; i < Program::UNIFORM_BINDING_COUNT; i++) {
auto [id, buffer, age] = mContext.getEs2UniformBinding(i);
auto [id, buffer, age] = mUniformBindings[i];
if (buffer) {
p->updateUniforms(i, id, buffer, age);
}
@@ -396,8 +316,7 @@ bool OpenGLDriver::useProgram(OpenGLProgram* p) noexcept {
// when mPlatform.isSRGBSwapChainSupported() is false (no need to check though).
p->setRec709ColorSpace(mRec709OutputColorspace);
}
return success;
return true;
}
@@ -460,20 +379,20 @@ void OpenGLDriver::setStencilState(StencilState ss) noexcept {
// stencil test / operation
// GL_STENCIL_TEST must be enabled if we're testing OR writing to the stencil buffer.
// if (UTILS_LIKELY(
// ss.front.stencilFunc == StencilState::StencilFunction::A &&
// ss.back.stencilFunc == StencilState::StencilFunction::A &&
// ss.front.stencilOpDepthFail == StencilOperation::KEEP &&
// ss.back.stencilOpDepthFail == StencilOperation::KEEP &&
// ss.front.stencilOpStencilFail == StencilOperation::KEEP &&
// ss.back.stencilOpStencilFail == StencilOperation::KEEP &&
// ss.front.stencilOpDepthStencilPass == StencilOperation::KEEP &&
// ss.back.stencilOpDepthStencilPass == StencilOperation::KEEP) && false) {
// // that's equivalent to having the stencil test disabled
// gl.disable(GL_STENCIL_TEST);
// } else {
if (UTILS_LIKELY(
ss.front.stencilFunc == StencilState::StencilFunction::A &&
ss.back.stencilFunc == StencilState::StencilFunction::A &&
ss.front.stencilOpDepthFail == StencilOperation::KEEP &&
ss.back.stencilOpDepthFail == StencilOperation::KEEP &&
ss.front.stencilOpStencilFail == StencilOperation::KEEP &&
ss.back.stencilOpStencilFail == StencilOperation::KEEP &&
ss.front.stencilOpDepthStencilPass == StencilOperation::KEEP &&
ss.back.stencilOpDepthStencilPass == StencilOperation::KEEP)) {
// that's equivalent to having the stencil test disabled
gl.disable(GL_STENCIL_TEST);
} else {
gl.enable(GL_STENCIL_TEST);
// }
}
// glStencilFuncSeparate() also sets the reference value, which may be used depending
// on the stencilOp, so we always need to call glStencilFuncSeparate().
@@ -481,9 +400,9 @@ void OpenGLDriver::setStencilState(StencilState ss) noexcept {
getStencilFunc(ss.front.stencilFunc), ss.front.ref, ss.front.readMask,
getStencilFunc(ss.back.stencilFunc), ss.back.ref, ss.back.readMask);
// if (UTILS_LIKELY(!ss.stencilWrite)) {
// gl.stencilMaskSeparate(0x00, 0x00);
// } else {
if (UTILS_LIKELY(!ss.stencilWrite)) {
gl.stencilMaskSeparate(0x00, 0x00);
} else {
// Stencil ops are only relevant when stencil write is enabled
gl.stencilOpSeparate(
getStencilOp(ss.front.stencilOpStencilFail),
@@ -493,7 +412,7 @@ void OpenGLDriver::setStencilState(StencilState ss) noexcept {
getStencilOp(ss.back.stencilOpDepthFail),
getStencilOp(ss.back.stencilOpDepthStencilPass));
gl.stencilMaskSeparate(ss.front.writeMask, ss.back.writeMask);
// }
}
}
// ------------------------------------------------------------------------------------------------
@@ -805,19 +724,10 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
GLenum internalFormat = getInternalFormat(format);
assert_invariant(internalFormat);
if (any(usage & TextureUsage::PROTECTED)) {
if (UTILS_UNLIKELY(usage & TextureUsage::PROTECTED)) {
// renderbuffers don't have a protected mode, so we need to use a texture
// because protected textures are only supported on GLES 3.2, MSAA will be available.
usage |= TextureUsage::SAMPLEABLE;
} else if (any(usage & TextureUsage::UPLOADABLE)) {
// if we have the uploadable flag, we also need to use a texture
usage |= TextureUsage::SAMPLEABLE;
} else if (target != SamplerType::SAMPLER_2D) {
// renderbuffers can only be 2D
usage |= TextureUsage::SAMPLEABLE;
} else if (levels > 1) {
// renderbuffers can't have mip levels
usage |= TextureUsage::SAMPLEABLE;
}
auto& gl = mContext;
@@ -836,6 +746,7 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
if (t->externalTexture) {
t->gl.target = t->externalTexture->target;
t->gl.id = t->externalTexture->id;
t->gl.targetIndex = (uint8_t)OpenGLContext::getIndexForTextureTarget(t->gl.target);
// internalFormat actually depends on the external image, but it doesn't matter
// because it's not used anywhere for anything important.
t->gl.internalFormat = internalFormat;
@@ -847,23 +758,30 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
t->gl.internalFormat = internalFormat;
// We DO NOT update targetIndex at function exit to take advantage of the fact that
// getIndexForTextureTarget() is constexpr -- so all of this disappears at compile time.
switch (target) {
case SamplerType::SAMPLER_EXTERNAL:
// we can't be here -- doesn't matter what we do
case SamplerType::SAMPLER_2D:
t->gl.target = GL_TEXTURE_2D;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_2D);
break;
case SamplerType::SAMPLER_3D:
t->gl.target = GL_TEXTURE_3D;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_3D);
break;
case SamplerType::SAMPLER_2D_ARRAY:
t->gl.target = GL_TEXTURE_2D_ARRAY;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_2D_ARRAY);
break;
case SamplerType::SAMPLER_CUBEMAP:
t->gl.target = GL_TEXTURE_CUBE_MAP;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_CUBE_MAP);
break;
case SamplerType::SAMPLER_CUBEMAP_ARRAY:
t->gl.target = GL_TEXTURE_CUBE_MAP_ARRAY;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_CUBE_MAP_ARRAY);
break;
}
@@ -874,6 +792,8 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
if (gl.features.multisample_texture) {
// multi-sample texture on GL 3.2 / GLES 3.1 and above
t->gl.target = GL_TEXTURE_2D_MULTISAMPLE;
t->gl.targetIndex = (uint8_t)
OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_2D_MULTISAMPLE);
} else {
// Turn off multi-sampling for that texture. It's just not supported.
}
@@ -883,6 +803,13 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
textureStorage(t, w, h, depth, bool(usage & TextureUsage::PROTECTED));
}
} else {
assert_invariant(any(usage & (
TextureUsage::COLOR_ATTACHMENT |
TextureUsage::DEPTH_ATTACHMENT |
TextureUsage::STENCIL_ATTACHMENT)));
assert_invariant(levels == 1);
assert_invariant(target == SamplerType::SAMPLER_2D);
assert_invariant(none(usage & TextureUsage::PROTECTED));
t->gl.internalFormat = internalFormat;
t->gl.target = GL_RENDERBUFFER;
glGenRenderbuffers(1, &t->gl.id);
@@ -932,24 +859,32 @@ void OpenGLDriver::importTextureR(Handle<HwTexture> th, intptr_t id,
t->gl.internalFormat = getInternalFormat(format);
assert_invariant(t->gl.internalFormat);
// We DO NOT update targetIndex at function exit to take advantage of the fact that
// getIndexForTextureTarget() is constexpr -- so all of this disappears at compile time.
switch (target) {
case SamplerType::SAMPLER_EXTERNAL:
t->gl.target = GL_TEXTURE_EXTERNAL_OES;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_EXTERNAL_OES);
break;
case SamplerType::SAMPLER_2D:
t->gl.target = GL_TEXTURE_2D;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_2D);
break;
case SamplerType::SAMPLER_3D:
t->gl.target = GL_TEXTURE_3D;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_3D);
break;
case SamplerType::SAMPLER_2D_ARRAY:
t->gl.target = GL_TEXTURE_2D_ARRAY;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_2D_ARRAY);
break;
case SamplerType::SAMPLER_CUBEMAP:
t->gl.target = GL_TEXTURE_CUBE_MAP;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_CUBE_MAP);
break;
case SamplerType::SAMPLER_CUBEMAP_ARRAY:
t->gl.target = GL_TEXTURE_CUBE_MAP_ARRAY;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_CUBE_MAP_ARRAY);
break;
}
@@ -960,6 +895,7 @@ void OpenGLDriver::importTextureR(Handle<HwTexture> th, intptr_t id,
if (gl.features.multisample_texture) {
// multi-sample texture on GL 3.2 / GLES 3.1 and above
t->gl.target = GL_TEXTURE_2D_MULTISAMPLE;
t->gl.targetIndex = OpenGLContext::getIndexForTextureTarget(GL_TEXTURE_2D_MULTISAMPLE);
} else {
// Turn off multi-sampling for that texture. It's just not supported.
}
@@ -970,18 +906,16 @@ void OpenGLDriver::importTextureR(Handle<HwTexture> th, intptr_t id,
}
void OpenGLDriver::updateVertexArrayObject(GLRenderPrimitive* rp, GLVertexBuffer const* vb) {
// NOTE: this is called often and must be as efficient as possible.
// NOTE: this is called from draw() and must be as efficient as possible.
auto& gl = mContext;
#ifndef NDEBUG
if (UTILS_LIKELY(gl.ext.OES_vertex_array_object)) {
// The VAO for the given render primitive must already be bound.
GLint vaoBinding;
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vaoBinding);
assert_invariant(vaoBinding == (GLint)rp->gl.vao[gl.contextIndex]);
}
#endif
if (UTILS_LIKELY(rp->gl.vertexBufferVersion == vb->bufferObjectsVersion &&
rp->gl.stateVersion == gl.state.age)) {
@@ -997,7 +931,7 @@ void OpenGLDriver::updateVertexArrayObject(GLRenderPrimitive* rp, GLVertexBuffer
// if a buffer is defined it must not be invalid.
assert_invariant(vb->gl.buffers[bi]);
// if we're on ES2, the user shouldn't use FLAG_INTEGER_TARGET
// if w're on ES2, the user shouldn't use FLAG_INTEGER_TARGET
assert_invariant(!(gl.isES2() && (attribute.flags & Attribute::FLAG_INTEGER_TARGET)));
gl.bindBuffer(GL_ARRAY_BUFFER, vb->gl.buffers[bi]);
@@ -1532,8 +1466,9 @@ void OpenGLDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow,
#if !defined(__EMSCRIPTEN__)
// note: in practice this should never happen on Android
FILAMENT_CHECK_POSTCONDITION(sc->swapChain) << "createSwapChain(" << nativeWindow << ", "
<< flags << ") failed. See logs for details.";
ASSERT_POSTCONDITION(sc->swapChain,
"createSwapChain(%p, 0x%lx) failed. See logs for details.",
nativeWindow, flags);
#endif
// See if we need the emulated rec709 output conversion
@@ -1552,9 +1487,9 @@ void OpenGLDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch,
#if !defined(__EMSCRIPTEN__)
// note: in practice this should never happen on Android
FILAMENT_CHECK_POSTCONDITION(sc->swapChain)
<< "createSwapChainHeadless(" << width << ", " << height << ", " << flags
<< ") failed. See logs for details.";
ASSERT_POSTCONDITION(sc->swapChain,
"createSwapChainHeadless(%u, %u, 0x%lx) failed. See logs for details.",
width, height, flags);
#endif
// See if we need the emulated rec709 output conversion
@@ -1850,6 +1785,7 @@ void OpenGLDriver::updateStreams(DriverApi* driver) {
// the target and id can be reset each time
t->gl.target = t->externalTexture->target;
t->gl.id = t->externalTexture->id;
t->gl.targetIndex = (uint8_t)OpenGLContext::getIndexForTextureTarget(t->gl.target);
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
}
}
@@ -2087,19 +2023,19 @@ bool OpenGLDriver::isProtectedContentSupported() {
return mPlatform.isProtectedContextSupported();
}
bool OpenGLDriver::isStereoSupported() {
bool OpenGLDriver::isStereoSupported(backend::StereoscopicType stereoscopicType) {
// Instanced-stereo requires instancing and EXT_clip_cull_distance.
// Multiview-stereo requires ES 3.0 and OVR_multiview2.
if (UTILS_UNLIKELY(mContext.isES2())) {
return false;
}
switch (mDriverConfig.stereoscopicType) {
case backend::StereoscopicType::INSTANCED:
return mContext.ext.EXT_clip_cull_distance;
case backend::StereoscopicType::MULTIVIEW:
return mContext.ext.OVR_multiview2;
case backend::StereoscopicType::NONE:
return false;
switch (stereoscopicType) {
case backend::StereoscopicType::INSTANCED:
return mContext.ext.EXT_clip_cull_distance;
case backend::StereoscopicType::MULTIVIEW:
return mContext.ext.OVR_multiview2;
default:
return false;
}
}
@@ -2111,10 +2047,6 @@ bool OpenGLDriver::isDepthStencilResolveSupported() {
return true;
}
bool OpenGLDriver::isDepthStencilBlitSupported(TextureFormat format) {
return true;
}
bool OpenGLDriver::isProtectedTexturesSupported() {
return getContext().ext.EXT_protected_textures;
}
@@ -2131,6 +2063,8 @@ bool OpenGLDriver::isWorkaroundNeeded(Workaround workaround) {
return mContext.bugs.disable_blit_into_texture_array;
case Workaround::POWER_VR_SHADER_WORKAROUNDS:
return mContext.bugs.powervr_shader_workarounds;
case Workaround::DISABLE_THREAD_AFFINITY:
return mContext.bugs.disable_thread_affinity;
default:
return false;
}
@@ -2210,10 +2144,6 @@ void OpenGLDriver::makeCurrent(Handle<HwSwapChain> schDraw, Handle<HwSwapChain>
// Updating driver objects
// ------------------------------------------------------------------------------------------------
void OpenGLDriver::setDebugTag(HandleBase::HandleId handleId, utils::CString tag) {
mHandleAllocator.associateTagToHandle(handleId, std::move(tag));
}
void OpenGLDriver::setVertexBufferObject(Handle<HwVertexBuffer> vbh,
uint32_t index, Handle<HwBufferObject> boh) {
DEBUG_MARKER()
@@ -2374,20 +2304,11 @@ void OpenGLDriver::updateSamplerGroup(Handle<HwSamplerGroup> sbh,
auto const* const pSamplers = (SamplerDescriptor const*)data.buffer;
for (size_t i = 0, c = sb->textureUnitEntries.size(); i < c; i++) {
GLuint samplerId = 0u;
Handle<HwTexture> th = pSamplers[i].t;
if (UTILS_LIKELY(th)) {
GLTexture const* const t = handle_cast<const GLTexture*>(th);
const GLTexture* t = nullptr;
if (UTILS_LIKELY(pSamplers[i].t)) {
t = handle_cast<const GLTexture*>(pSamplers[i].t);
assert_invariant(t);
if (UTILS_UNLIKELY(es2)
#if defined(GL_EXT_texture_filter_anisotropic)
|| UTILS_UNLIKELY(anisotropyWorkaround)
#endif
) {
// We must set texture parameters on the texture itself.
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
}
SamplerParams params = pSamplers[i].s;
if (UTILS_UNLIKELY(t->target == SamplerType::SAMPLER_EXTERNAL)) {
// From OES_EGL_image_external spec:
@@ -2422,7 +2343,7 @@ void OpenGLDriver::updateSamplerGroup(Handle<HwSamplerGroup> sbh,
#endif
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
if (UTILS_LIKELY(!es2)) {
samplerId = mContext.getSampler(params);
samplerId = getSampler(params);
} else
#endif
{
@@ -2441,7 +2362,7 @@ void OpenGLDriver::updateSamplerGroup(Handle<HwSamplerGroup> sbh,
// which is not an error.
}
sb->textureUnitEntries[i] = { th, samplerId };
sb->textureUnitEntries[i] = { t, samplerId };
}
scheduleDestroy(std::move(data));
}
@@ -2752,6 +2673,7 @@ void OpenGLDriver::setExternalImage(Handle<HwTexture> th, void* image) {
// the target and id can be reset each time
t->gl.target = t->externalTexture->target;
t->gl.id = t->externalTexture->id;
t->gl.targetIndex = (uint8_t)OpenGLContext::getIndexForTextureTarget(t->gl.target);
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
}
}
@@ -3146,10 +3068,11 @@ void OpenGLDriver::bindBufferRange(BufferObjectBinding bindingType, uint32_t ind
assert_invariant(offset + size <= ub->byteCount);
if (UTILS_UNLIKELY(ub->bindingType == BufferObjectBinding::UNIFORM && gl.isES2())) {
gl.setEs2UniformBinding(index,
mUniformBindings[index] = {
ub->gl.id,
static_cast<uint8_t const*>(ub->gl.buffer) + offset,
ub->age);
ub->age,
};
} else {
GLenum const target = GLUtils::getBufferBindingType(bindingType);
@@ -3167,7 +3090,7 @@ void OpenGLDriver::unbindBuffer(BufferObjectBinding bindingType, uint32_t index)
auto& gl = mContext;
if (UTILS_UNLIKELY(bindingType == BufferObjectBinding::UNIFORM && gl.isES2())) {
gl.setEs2UniformBinding(index, 0, nullptr, 0);
mUniformBindings[index] = {};
return;
}
@@ -3184,6 +3107,36 @@ void OpenGLDriver::bindSamplers(uint32_t index, Handle<HwSamplerGroup> sbh) {
CHECK_GL_ERROR(utils::slog.e)
}
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
GLuint OpenGLDriver::getSamplerSlow(SamplerParams params) const noexcept {
assert_invariant(mSamplerMap.find(params) == mSamplerMap.end());
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)
auto& gl = mContext;
if (gl.ext.EXT_texture_filter_anisotropic &&
!gl.bugs.texture_filter_anisotropic_broken_on_sampler) {
GLfloat const anisotropy = float(1u << params.anisotropyLog2);
glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY_EXT,
std::min(gl.gets.max_anisotropy, anisotropy));
}
#endif
CHECK_GL_ERROR(utils::slog.e)
mSamplerMap[params] = s;
return s;
}
#endif
void OpenGLDriver::insertEventMarker(char const* string, uint32_t len) {
#ifndef __EMSCRIPTEN__
#ifdef GL_EXT_debug_marker
@@ -3198,14 +3151,14 @@ void OpenGLDriver::insertEventMarker(char const* string, uint32_t len) {
void OpenGLDriver::pushGroupMarker(char const* string, uint32_t len) {
#ifndef __EMSCRIPTEN__
#ifdef GL_EXT_debug_marker
#if DEBUG_GROUP_MARKER_LEVEL & DEBUG_GROUP_MARKER_OPENGL
#if DEBUG_MARKER_LEVEL & DEBUG_MARKER_OPENGL
if (UTILS_LIKELY(mContext.ext.EXT_debug_marker)) {
glPushGroupMarkerEXT(GLsizei(len ? len : strlen(string)), string);
}
#endif
#endif
#if DEBUG_GROUP_MARKER_LEVEL & DEBUG_GROUP_MARKER_BACKEND
#if DEBUG_MARKER_LEVEL & DEBUG_MARKER_BACKEND
SYSTRACE_CONTEXT();
SYSTRACE_NAME_BEGIN(string);
#endif
@@ -3215,14 +3168,14 @@ void OpenGLDriver::pushGroupMarker(char const* string, uint32_t len) {
void OpenGLDriver::popGroupMarker(int) {
#ifndef __EMSCRIPTEN__
#ifdef GL_EXT_debug_marker
#if DEBUG_GROUP_MARKER_LEVEL & DEBUG_GROUP_MARKER_OPENGL
#if DEBUG_MARKER_LEVEL & DEBUG_MARKER_OPENGL
if (UTILS_LIKELY(mContext.ext.EXT_debug_marker)) {
glPopGroupMarkerEXT();
}
#endif
#endif
#if DEBUG_GROUP_MARKER_LEVEL & DEBUG_GROUP_MARKER_BACKEND
#if DEBUG_MARKER_LEVEL & DEBUG_MARKER_BACKEND
SYSTRACE_CONTEXT();
SYSTRACE_NAME_END();
#endif
@@ -3483,21 +3436,17 @@ void OpenGLDriver::executeGpuCommandsCompleteOps() noexcept {
void OpenGLDriver::tick(int) {
DEBUG_MARKER()
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
executeGpuCommandsCompleteOps();
#endif
executeEveryNowAndThenOps();
getShaderCompilerService().tick();
}
void OpenGLDriver::beginFrame(
UTILS_UNUSED int64_t monotonic_clock_ns,
UTILS_UNUSED int64_t refreshIntervalNs,
UTILS_UNUSED uint32_t frameId) {
DEBUG_MARKER()
auto& gl = mContext;
insertEventMarker("beginFrame");
mPlatform.beginFrame(monotonic_clock_ns, refreshIntervalNs, frameId);
if (UTILS_UNLIKELY(!mTexturesWithStreamsAttached.empty())) {
OpenGLPlatform& platform = mPlatform;
for (GLTexture const* t : mTexturesWithStreamsAttached) {
@@ -3506,7 +3455,7 @@ void OpenGLDriver::beginFrame(
assert_invariant(t->hwStream->stream);
platform.updateTexImage(t->hwStream->stream,
&static_cast<GLStream*>(t->hwStream)->user_thread.timestamp); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
// NOTE: We assume that OpenGLPlatform::updateTexImage() binds the texture on our behalf
// NOTE: We assume that updateTexImage() binds the texture on our behalf
gl.updateTexImage(GL_TEXTURE_EXTERNAL_OES, t->gl.id);
}
}
@@ -3514,12 +3463,12 @@ void OpenGLDriver::beginFrame(
}
void OpenGLDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch,
CallbackHandler* handler, FrameScheduledCallback&& callback) {
FrameScheduledCallback callback, void* user) {
DEBUG_MARKER()
}
void OpenGLDriver::setFrameCompletedCallback(Handle<HwSwapChain> sch,
CallbackHandler* handler, utils::Invocable<void(void)>&& callback) {
CallbackHandler* handler, CallbackHandler::Callback callback, void* user) {
DEBUG_MARKER()
}
@@ -3545,7 +3494,6 @@ void OpenGLDriver::endFrame(UTILS_UNUSED uint32_t frameId) {
#endif
//SYSTRACE_NAME("glFinish");
//glFinish();
mPlatform.endFrame(frameId);
insertEventMarker("endFrame");
}
@@ -3656,11 +3604,13 @@ void OpenGLDriver::resolve(
assert_invariant(s);
assert_invariant(d);
FILAMENT_CHECK_PRECONDITION(d->width == s->width && d->height == s->height)
<< "invalid resolve: src and dst sizes don't match";
ASSERT_PRECONDITION(
d->width == s->width && d->height == s->height,
"invalid resolve: src and dst sizes don't match");
FILAMENT_CHECK_PRECONDITION(s->samples > 1 && d->samples == 1)
<< "invalid resolve: src.samples=" << +s->samples << ", dst.samples=" << +d->samples;
ASSERT_PRECONDITION(s->samples > 1 && d->samples == 1,
"invalid resolve: src.samples=%u, dst.samples=%u",
+s->samples, +d->samples);
blit( dst, dstLevel, dstLayer, {},
src, srcLevel, srcLayer, {},
@@ -3755,7 +3705,7 @@ void OpenGLDriver::blit(
case SamplerType::SAMPLER_EXTERNAL:
break;
}
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_DRAW_FRAMEBUFFER)
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_READ_FRAMEBUFFER)
gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]);
switch (s->target) {
@@ -3781,7 +3731,7 @@ void OpenGLDriver::blit(
case SamplerType::SAMPLER_EXTERNAL:
break;
}
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_READ_FRAMEBUFFER)
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_DRAW_FRAMEBUFFER)
gl.disable(GL_SCISSOR_TEST);
glBlitFramebuffer(
@@ -3816,12 +3766,12 @@ void OpenGLDriver::blitDEPRECATED(TargetBufferFlags buffers,
UTILS_UNUSED_IN_RELEASE auto& gl = mContext;
assert_invariant(!gl.isES2());
FILAMENT_CHECK_PRECONDITION(buffers == TargetBufferFlags::COLOR0)
<< "blitDEPRECATED only supports COLOR0";
ASSERT_PRECONDITION(buffers == TargetBufferFlags::COLOR0,
"blitDEPRECATED only supports COLOR0");
FILAMENT_CHECK_PRECONDITION(
srcRect.left >= 0 && srcRect.bottom >= 0 && dstRect.left >= 0 && dstRect.bottom >= 0)
<< "Source and destination rects must be positive.";
ASSERT_PRECONDITION(srcRect.left >= 0 && srcRect.bottom >= 0 &&
dstRect.left >= 0 && dstRect.bottom >= 0,
"Source and destination rects must be positive.");
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
@@ -3895,7 +3845,7 @@ void OpenGLDriver::updateTextureLodRange(GLTexture* texture, int8_t targetLevel)
#endif
}
void OpenGLDriver::bindPipeline(PipelineState const& state) {
void OpenGLDriver::bindPipeline(PipelineState state) {
DEBUG_MARKER()
auto& gl = mContext;
setRasterState(state.rasterState);
@@ -3903,7 +3853,6 @@ void OpenGLDriver::bindPipeline(PipelineState const& state) {
gl.polygonOffset(state.polygonOffset.slope, state.polygonOffset.constant);
OpenGLProgram* const p = handle_cast<OpenGLProgram*>(state.program);
mValidProgram = useProgram(p);
(*mCurrentPushConstants) = p->getPushConstants();
}
void OpenGLDriver::bindRenderPrimitive(Handle<HwRenderPrimitive> rph) {
@@ -3928,42 +3877,25 @@ void OpenGLDriver::bindRenderPrimitive(Handle<HwRenderPrimitive> rph) {
}
void OpenGLDriver::draw2(uint32_t indexOffset, uint32_t indexCount, uint32_t instanceCount) {
DEBUG_MARKER()
GLRenderPrimitive const* const rp = mBoundRenderPrimitive;
if (UTILS_UNLIKELY(!rp || !mValidProgram)) {
return;
}
if (UTILS_LIKELY(instanceCount <= 1)) {
glDrawElements(GLenum(rp->type), (GLsizei)indexCount, rp->gl.getIndicesType(),
reinterpret_cast<const void*>(indexOffset * rp->gl.indicesSize));
} else {
assert_invariant(!mContext.isES2());
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
assert_invariant(!mContext.isES2());
glDrawElementsInstanced(GLenum(rp->type), (GLsizei)indexCount,
rp->gl.getIndicesType(),
reinterpret_cast<const void*>(indexOffset * rp->gl.indicesSize),
(GLsizei)instanceCount);
glDrawElementsInstanced(GLenum(rp->type), (GLsizei)indexCount,
rp->gl.getIndicesType(),
reinterpret_cast<const void*>(indexOffset * rp->gl.indicesSize),
(GLsizei)instanceCount);
#endif
#if FILAMENT_ENABLE_MATDBG
CHECK_GL_ERROR_NON_FATAL(utils::slog.e)
#else
CHECK_GL_ERROR(utils::slog.e)
#endif
}
void OpenGLDriver::draw2GLES2(uint32_t indexOffset, uint32_t indexCount, uint32_t instanceCount) {
DEBUG_MARKER()
GLRenderPrimitive const* const rp = mBoundRenderPrimitive;
if (UTILS_UNLIKELY(!rp || !mValidProgram)) {
return;
}
assert_invariant(mContext.isES2());
assert_invariant(instanceCount == 1);
glDrawElements(GLenum(rp->type), (GLsizei)indexCount, rp->gl.getIndicesType(),
reinterpret_cast<const void*>(indexOffset * rp->gl.indicesSize));
#if FILAMENT_ENABLE_MATDBG
#ifdef FILAMENT_ENABLE_MATDBG
CHECK_GL_ERROR_NON_FATAL(utils::slog.e)
#else
CHECK_GL_ERROR(utils::slog.e)
@@ -3971,7 +3903,6 @@ void OpenGLDriver::draw2GLES2(uint32_t indexOffset, uint32_t indexCount, uint32_
}
void OpenGLDriver::scissor(Viewport scissor) {
DEBUG_MARKER()
setScissor(scissor);
}
@@ -3983,15 +3914,10 @@ void OpenGLDriver::draw(PipelineState state, Handle<HwRenderPrimitive> rph,
state.vertexBufferInfo = rp->vbih;
bindPipeline(state);
bindRenderPrimitive(rph);
if (UTILS_UNLIKELY(mContext.isES2())) {
draw2GLES2(indexOffset, indexCount, instanceCount);
} else {
draw2(indexOffset, indexCount, instanceCount);
}
draw2(indexOffset, indexCount, instanceCount);
}
void OpenGLDriver::dispatchCompute(Handle<HwProgram> program, math::uint3 workGroupCount) {
DEBUG_MARKER()
getShaderCompilerService().tick();
OpenGLProgram* const p = handle_cast<OpenGLProgram*>(program);
@@ -4015,7 +3941,7 @@ void OpenGLDriver::dispatchCompute(Handle<HwProgram> program, math::uint3 workGr
glDispatchCompute(workGroupCount.x, workGroupCount.y, workGroupCount.z);
#endif // BACKEND_OPENGL_LEVEL_GLES31
#if FILAMENT_ENABLE_MATDBG
#ifdef FILAMENT_ENABLE_MATDBG
CHECK_GL_ERROR_NON_FATAL(utils::slog.e)
#else
CHECK_GL_ERROR(utils::slog.e)
+67 -20
View File
@@ -20,8 +20,6 @@
#include "DriverBase.h"
#include "OpenGLContext.h"
#include "OpenGLTimerQuery.h"
#include "GLBufferObject.h"
#include "GLTexture.h"
#include "ShaderCompilerService.h"
#include <backend/platforms/OpenGLPlatform.h>
@@ -66,9 +64,9 @@ namespace filament::backend {
class OpenGLPlatform;
class PixelBufferDescriptor;
struct TargetBufferInfo;
class OpenGLProgram;
class TimerQueryFactoryInterface;
struct PushConstantBundle;
class OpenGLDriver final : public DriverBase {
inline explicit OpenGLDriver(OpenGLPlatform* platform,
@@ -81,7 +79,7 @@ public:
const Platform::DriverConfig& driverConfig) noexcept;
class DebugMarker {
UTILS_UNUSED OpenGLDriver& driver;
OpenGLDriver& driver;
public:
DebugMarker(OpenGLDriver& driver, const char* string) noexcept;
~DebugMarker() noexcept;
@@ -94,6 +92,25 @@ 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 {
GLuint id;
union {
GLenum binding;
void* buffer;
};
} gl;
BufferUsage usage;
BufferObjectBinding bindingType;
uint16_t age = 0;
};
struct GLVertexBufferInfo : public HwVertexBufferInfo {
GLVertexBufferInfo() noexcept = default;
GLVertexBufferInfo(uint8_t bufferCount, uint8_t attributeCount,
@@ -123,10 +140,11 @@ public:
} gl;
};
struct GLTexture;
struct GLSamplerGroup : public HwSamplerGroup {
using HwSamplerGroup::HwSamplerGroup;
struct Entry {
Handle<HwTexture> th;
GLTexture const* texture = nullptr;
GLuint sampler = 0u;
};
utils::FixedCapacityVector<Entry> textureUnitEntries;
@@ -139,9 +157,27 @@ public:
Handle<HwVertexBufferInfo> vbih;
};
using GLBufferObject = filament::backend::GLBufferObject;
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 GLTexture = filament::backend::GLTexture;
// 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;
};
using GLTimerQuery = filament::backend::GLTimerQuery;
@@ -232,13 +268,13 @@ private:
HandleAllocatorGL mHandleAllocator;
template<typename D, typename ... ARGS>
Handle<D> initHandle(ARGS&& ... args) {
Handle<D> initHandle(ARGS&& ... args) noexcept {
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) {
construct(Handle<B> const& handle, ARGS&& ... args) noexcept {
return mHandleAllocator.destroyAndConstruct<D, B>(handle, std::forward<ARGS>(args) ...);
}
@@ -252,20 +288,15 @@ 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) {
handle_cast(Handle<B>& handle) noexcept {
return mHandleAllocator.handle_cast<Dp, B>(handle);
}
template<typename B>
bool is_valid(Handle<B>& handle) {
return mHandleAllocator.is_valid(handle);
}
template<typename Dp, typename B>
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) {
handle_cast(Handle<B> const& handle) noexcept {
return mHandleAllocator.handle_cast<Dp, B>(handle);
}
@@ -317,6 +348,22 @@ 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;
}
@@ -341,14 +388,16 @@ private:
void setScissor(Viewport const& scissor) noexcept;
void draw2GLES2(uint32_t indexOffset, uint32_t indexCount, uint32_t instanceCount);
// 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;
@@ -382,8 +431,6 @@ private:
// for ES2 sRGB support
GLSwapChain* mCurrentDrawSwapChain = nullptr;
bool mRec709OutputColorspace = false;
PushConstantBundle* mCurrentPushConstants = nullptr;
};
// ------------------------------------------------------------------------------------------------
@@ -55,16 +55,6 @@ uint32_t OpenGLPlatform::getDefaultFramebufferObject() noexcept {
return 0;
}
void OpenGLPlatform::beginFrame(int64_t monotonic_clock_ns, int64_t refreshIntervalNs,
uint32_t frameId) noexcept {
}
void OpenGLPlatform::endFrame(uint32_t frameId) noexcept {
}
void OpenGLPlatform::preCommit() noexcept {
}
OpenGLPlatform::ContextType OpenGLPlatform::getCurrentContextType() const noexcept {
return ContextType::UNPROTECTED;
}
+6 -28
View File
@@ -20,24 +20,21 @@
#include "OpenGLDriver.h"
#include "ShaderCompilerService.h"
#include <backend/DriverEnums.h>
#include <backend/Program.h>
#include <backend/Handle.h>
#include <utils/compiler.h>
#include <private/backend/BackendUtils.h>
#include <utils/debug.h>
#include <utils/FixedCapacityVector.h>
#include <utils/compiler.h>
#include <utils/Log.h>
#include <utils/Systrace.h>
#include <algorithm>
#include <array>
#include <string_view>
#include <utility>
#include <new>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -49,8 +46,6 @@ struct OpenGLProgram::LazyInitializationData {
Program::UniformBlockInfo uniformBlockInfo;
Program::SamplerGroupInfo samplerGroupInfo;
std::array<Program::UniformInfo, Program::UNIFORM_BINDING_COUNT> bindingUniformInfo;
utils::FixedCapacityVector<Program::PushConstant> vertexPushConstants;
utils::FixedCapacityVector<Program::PushConstant> fragmentPushConstants;
};
@@ -58,6 +53,7 @@ OpenGLProgram::OpenGLProgram() noexcept = default;
OpenGLProgram::OpenGLProgram(OpenGLDriver& gld, Program&& program) noexcept
: HwProgram(std::move(program.getName())) {
auto* const lazyInitializationData = new(std::nothrow) LazyInitializationData();
lazyInitializationData->samplerGroupInfo = std::move(program.getSamplerGroupInfo());
if (UTILS_UNLIKELY(gld.getContext().isES2())) {
@@ -65,8 +61,6 @@ OpenGLProgram::OpenGLProgram(OpenGLDriver& gld, Program&& program) noexcept
} else {
lazyInitializationData->uniformBlockInfo = std::move(program.getUniformBlockBindings());
}
lazyInitializationData->vertexPushConstants = std::move(program.getPushConstants(ShaderStage::VERTEX));
lazyInitializationData->fragmentPushConstants = std::move(program.getPushConstants(ShaderStage::FRAGMENT));
ShaderCompilerService& compiler = gld.getShaderCompilerService();
mToken = compiler.createProgram(name, std::move(program));
@@ -209,21 +203,6 @@ void OpenGLProgram::initializeProgramState(OpenGLContext& context, GLuint progra
}
}
mUsedBindingsCount = usedBindingCount;
auto& vertexConstants = lazyInitializationData.vertexPushConstants;
auto& fragmentConstants = lazyInitializationData.fragmentPushConstants;
size_t const totalConstantCount = vertexConstants.size() + fragmentConstants.size();
if (totalConstantCount > 0) {
mPushConstants.reserve(totalConstantCount);
mPushConstantFragmentStageOffset = vertexConstants.size();
auto const transformAndAdd = [&](Program::PushConstant const& constant) {
GLint const loc = glGetUniformLocation(program, constant.name.c_str());
mPushConstants.push_back({loc, constant.type});
};
std::for_each(vertexConstants.cbegin(), vertexConstants.cend(), transformAndAdd);
std::for_each(fragmentConstants.cbegin(), fragmentConstants.cend(), transformAndAdd);
}
}
void OpenGLProgram::updateSamplers(OpenGLDriver* const gld) const noexcept {
@@ -244,9 +223,8 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* const gld) const noexcept {
assert_invariant(sb);
if (!sb) continue; // should never happen, this would be a user error.
for (uint8_t j = 0, m = sb->textureUnitEntries.size(); j < m; ++j, ++tmu) { // "<=" on purpose here
Handle<HwTexture> th = sb->textureUnitEntries[j].th;
if (th) { // program may not use all samplers of sampler group
GLTexture const* const t = gld->handle_cast<GLTexture const*>(th);
const GLTexture* const t = sb->textureUnitEntries[j].texture;
if (t) { // program may not use all samplers of sampler group
gld->bindTexture(tmu, t);
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
if (UTILS_LIKELY(!es2)) {
+13 -47
View File
@@ -27,7 +27,6 @@
#include <utils/compiler.h>
#include <utils/FixedCapacityVector.h>
#include <utils/Slice.h>
#include <array>
#include <limits>
@@ -39,11 +38,6 @@ namespace filament::backend {
class OpenGLDriver;
struct PushConstantBundle {
utils::Slice<std::pair<GLint, ConstantType>> vertexConstants;
utils::Slice<std::pair<GLint, ConstantType>> fragmentConstants;
};
class OpenGLProgram : public HwProgram {
public:
@@ -53,19 +47,9 @@ public:
bool isValid() const noexcept { return mToken || gl.program != 0; }
bool use(OpenGLDriver* const gld, OpenGLContext& context) noexcept {
// both non-null is impossible by construction
assert_invariant(!mToken || !gl.program);
if (UTILS_UNLIKELY(mToken && !gl.program)) {
// first time a program is used
initialize(*gld);
}
void use(OpenGLDriver* const gld, OpenGLContext& context) noexcept {
if (UTILS_UNLIKELY(!gl.program)) {
// compilation failed (token should be null)
assert_invariant(!mToken);
return false;
initialize(*gld);
}
context.useProgram(gl.program);
@@ -84,25 +68,16 @@ public:
updateSamplers(gld);
}
return true;
}
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
PushConstantBundle getPushConstants() {
auto fragBegin = mPushConstants.begin() + mPushConstantFragmentStageOffset;
return {
.vertexConstants = utils::Slice(mPushConstants.begin(), fragBegin),
.fragmentConstants = utils::Slice(fragBegin, mPushConstants.end()),
};
}
private:
// keep these away from of other class attributes
struct LazyInitializationData;
@@ -114,20 +89,14 @@ 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[2] = {}; // 2 byte
// Push constant array offset for fragment stage constants.
uint8_t mPushConstantFragmentStageOffset = 0u; // 1 byte
// only needed for ES2
GLint mRec709Location = -1; // 4 bytes
using LocationInfo = utils::FixedCapacityVector<GLint>;
struct UniformsRecord {
Program::UniformInfo uniforms;
@@ -135,15 +104,12 @@ private:
mutable GLuint id = 0;
mutable uint16_t age = std::numeric_limits<uint16_t>::max();
};
UniformsRecord const* mUniformsRecords = nullptr; // 8 bytes
// Note that this can be replaced with a raw pointer and an uint8_t (for size) to reduce the
// size of the container to 9 bytes if there is a need in the future.
utils::FixedCapacityVector<std::pair<GLint, ConstantType>> mPushConstants;// 16 bytes
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); // currently 64 bytes
static_assert(sizeof(OpenGLProgram) <= 64);
} // namespace filament::backend
@@ -143,25 +143,21 @@ void TimerQueryNativeFactory::endTimeElapsedQuery(OpenGLDriver& driver, GLTimerQ
driver.runEveryNowAndThen([&context = mContext, weak]() -> bool {
auto state = weak.lock();
if (!state) {
// The timer query state has been destroyed on the way, very likely due to the IBL
// prefilter context destruction. We still return true to get this element removed from
// the query list.
return true;
if (state) {
GLuint available = 0;
context.procs.getQueryObjectuiv(state->gl.query, GL_QUERY_RESULT_AVAILABLE, &available);
CHECK_GL_ERROR(utils::slog.e)
if (!available) {
// we need to try this one again later
return false;
}
GLuint64 elapsedTime = 0;
// 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);
}
GLuint available = 0;
context.procs.getQueryObjectuiv(state->gl.query, GL_QUERY_RESULT_AVAILABLE, &available);
CHECK_GL_ERROR(utils::slog.e)
if (!available) {
// we need to try this one again later
return false;
}
GLuint64 elapsedTime = 0;
// 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);
return true;
});
}

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