Compare commits

..

65 Commits

Author SHA1 Message Date
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
09fe495384 Release Filament 1.21.0 2022-04-04 13:00:48 -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
Pavel Korolev
8457d6092d Use index offset provided by ImGui when rendering UI 2022-04-04 10:49:43 -07:00
Mathias Agopian
72c16e07ed remove Viewport::scale()
because a float->integer conversion is needed, it's better to let the
caller decide what they want.
2022-04-02 20:37:00 -07:00
Mathias Agopian
12b96cba04 minor cleanup: rename internal class attributes 2022-04-02 20:37:00 -07:00
Mathias Agopian
e4d943e942 update release nodes and bump material version 2022-04-02 20:36:40 -07:00
Ben Doherty
7fa66325f3 Fix Metal validation error when reading from default SwapChain (#5392) 2022-04-01 16:37:46 -07:00
Mathias Agopian
e188a7875e enable both screen-space refraction and reflection
Both "SSR" can now be used on the same material. This is made possible
by using a 2D array to store both buffers.
2022-04-01 16:22:10 -07:00
Mathias Agopian
ac9822b8c8 Fix a framegraph dependency bug when writing to subresources
The dependency graph was set incorrectly when writing to a subresource
of a subresource.
2022-04-01 16:22:10 -07:00
Mathias Agopian
edb5fddd03 one more step towards reflection+refraction support
With this change we are now generating refraction and reflections
buffer into their own layer of a 2D array -- so they can coexist.

This change doesn't actually enable both at the same time yet.

There are downsides to this approach:
- a 2d array of 2 layers is created even if only one of reflection or
  refraction is active. This could be fixed at the cost of more
  complexity.
- if reflections are active then refraction must use a RGBA16F texture
  instead of RGB_11_11_10, because they share the texture
2022-04-01 14:37:40 -07:00
Mathias Agopian
35f4a97e32 new framegraph API do add a pass without an execute stage 2022-04-01 14:37:40 -07:00
Mathias Agopian
487b10fdda repair and optimize matdbg
we add a checkProgramEdits() method that must be called periodically
on all materials. This is currently done at the beginning of a frame.
2022-03-31 16:52:26 -07:00
Mathias Agopian
271cda88aa Move vulkan backend implementation into the filament::backend namespace 2022-03-31 11:53:54 -07:00
Mathias Agopian
25b73ddcfa Move opengl backend implementation into the filament::backend namespace 2022-03-31 11:53:54 -07:00
Mathias Agopian
35b8146a87 move metal backend out of the metal namespace
this is to be consistent with other backends, which are all in
filament::backend.

had to rename metal::PipelineState to MetalPipelineState.
2022-03-31 11:53:54 -07:00
Mathias Agopian
091e5a33ac move Noop backend into filament::backend namespace 2022-03-31 11:53:54 -07:00
Ben Doherty
ffe4b7390d Correctly prepare color grading as subpass programs (#5384) 2022-03-30 16:25:27 -07:00
Mathias Agopian
604d3e34a4 avoid an extra copy during the screen-space reflection pass
unlike for refraction, the reflection buffer is distinct from "the"
color buffer, this allows an optimization (compared to ssr) when we
generate the mipmap chain -- we can allocate the mipmaped texture
and render the SSR pass directly into its level 0. This achieved
use the framegraph's forward resource feature.
2022-03-30 15:32:52 -07:00
Mathias Agopian
e116dd4aec Improve framegraph forward resource API
This add a couple methods to allow the creation and forwarding in a
single call.
2022-03-30 15:32:52 -07:00
Mathias Agopian
d53614fb0a fix a framegraph crash when forwarding a subresource
the crash would happen when forwarding a subresource of a subresource,
because in this case the parent's handle would be reset to the null
handle.
2022-03-30 15:32:30 -07:00
Mathias Agopian
c91e5df117 Add comment about how we calculate the viewport when upscaling 2022-03-30 08:58:50 -07:00
Philip Rideout
96574816b3 Fix 12x overallocation of memory in MorphTargetBuffer.
I noticed this while helping someone at Google understand our new API.
2022-03-30 08:24:40 -07:00
Mathias Agopian
b43a609ebc rename framegraph fg2/ folder to fg/ 2022-03-29 14:38:36 -07:00
Benjamin Doherty
2a35ee279b Bump version to 1.20.6 2022-03-28 18:47:38 -07:00
Benjamin Doherty
2c490ec799 Release Filament 1.20.5 2022-03-28 18:44:56 -07:00
Mathias Agopian
fbb08d338a repair the flare pass on WebGL 2022-03-28 17:01:07 -07:00
Mathias Agopian
8e1718458a remove all references to the "Blackboard" from PostPorcessManager
This makes the code simpler to follow.
2022-03-28 16:23:52 -07:00
Philip Rideout
6bcd709320 gltfio: add support for KHR_materials_emissive_strength 2022-03-28 12:57:08 -07:00
Mathias Agopian
1a6e3ec88e batch all program linking at begin renderpass time
With this change, shaders are compiled at program creation, programs
are linked at the start of the next render pass and queries are
deferred until first use.

This should improve overall performance on some drivers.
2022-03-26 13:36:35 -07:00
Mathias Agopian
f5f50eca06 programs must now be created outside of renderpasses
from now on, the backends can assume that programs are created outside
of begin/endRenderpass.
2022-03-26 13:35:48 -07:00
Mathias Agopian
886fb7fb94 fix build 2022-03-26 13:35:18 -07:00
Philip Rideout
a82b3bedb2 gltfio: material variants can now be applied to FilamentInstance. 2022-03-25 16:47:59 -07:00
Mathias Agopian
d879bbc80a Simplify OpenGLProgram sampler bindings
This reduces the size of OpenGLProgram from 64 to 32 bytes and
improves the code that sets new samplers.

The main simplification is that we're not trying to "pack" the 
texture units used in the program. For e.g. we could be using
units 0,3,4, where before it would be 0,1,2.
This allows us to do less tracking.

Another optimization is that we're discarding entirely a SamplerGroup 
if the program doesn't use any of its samplers. This helps remove
a test in updateSampler which in turn remove somem tracking data.
2022-03-25 15:35:53 -07:00
Mathias Agopian
bf437b7933 defer gl program link + query to first use (draw)
in an upcoming PR we'll move linking back a bit earlier to allow
more batching.
2022-03-25 13:47:31 -07:00
Mathias Agopian
49dff3c439 log shader source code in debug build on error 2022-03-25 09:40:11 -07:00
Mathias Agopian
0d6c017cfb cleanup OpenGLProgram
This is the first step before we defer a lot of the glGet* calls.
2022-03-25 09:40:11 -07:00
Philip Rideout
ba042db3f4 gltfio Java: add getMorphTargetNames for consistency with other methods.
Tested by hacking ModelViewer.
2022-03-24 19:23:14 -07:00
Philip Rideout
faeba6ad95 gltfio: add support for KHR_materials_variants
Tested the Java API by hacking ModelViewer.
Tested the JavaScript API by adding to filament-viewer-test.
2022-03-24 19:23:14 -07:00
Philip Rideout
163e28ca7a Update public web demos (fixes helmet demo) 2022-03-24 16:10:14 -07:00
Philip Rideout
3dbc168d76 Use newer package for LitElement. 2022-03-24 16:04:43 -07:00
Ben Doherty
fe49946852 Metal: support blitting from 2D texture arrays (#5357) 2022-03-24 11:38:51 -07:00
Mathias Agopian
6310ea46e3 fix dummy ssr history texture target type 2022-03-23 20:47:20 -07:00
LaiJF
ef8e3e5224 Fix typo. (#5355)
* Fix typo.

* Update filament/src/RenderPass.cpp

Co-authored-by: Romain Guy <romain.guy@gmail.com>

Co-authored-by: Mathias Agopian <pixelflinger@gmail.com>
Co-authored-by: Romain Guy <romain.guy@gmail.com>
2022-03-23 11:29:07 -07:00
Mathias Agopian
26cc722f74 remove SPVRemaper lib, fold it into glslang directly
This avoids a duplication of doc.cpp, the largest compilation unit
(about 650KiB).
2022-03-23 11:27:30 -07:00
Philip Rideout
043fdf7a51 Remove lite flavor from android-utils.
We noticed that the lite flavor isn't actually smaller, plus we need to
rework our Android library hierarchy anyway, so for now let's remove
this.
2022-03-23 11:18:25 -07:00
Mathias Agopian
c01105b49a Fix shadow frustum computation wrt projection matrix
Instead of recomputing the Frustum from its 8 vertices, we compute it
from the projection matrix directly. This ensures this works with any
projection matrix.  Building a Frustum object from 8 vertices required
these vertices to be given in a certain order which wasn't correct if
the projection was flipped for instance.

Removed the API to construct a Frustum from vertices.

fixes b/225975881
2022-03-23 09:41:14 -07:00
Philip Rideout
f56f5a300c Temporary workaround for WebGL builds on macOS.
Better fix is to replace etc2comp and astcenc with basis.
2022-03-22 22:21:57 -07:00
Mathias Agopian
8b79f3683e skip work when morphtarget weight is zero
fixes #5344
2022-03-22 22:21:41 -07:00
Benjamin Doherty
319bd123ce Fix, use zero texture array when SSR is of 2022-03-22 22:21:14 -07:00
Benjamin Doherty
e23243a65b Fix build breakage on Windows 2022-03-22 20:43:50 -07:00
Mathias Agopian
c4261a8c10 hide ostream implementation details into ostream.cpp
Fixes #5343
2022-03-22 16:14:13 -07:00
Mathias Agopian
009b58537e move BuilderBase to libutils and rename to PrivateImplementation 2022-03-22 16:14:13 -07:00
Mathias Agopian
e51709a4e8 Size optimizations in UniformInterfaceBlock 2022-03-22 15:28:40 -07:00
Mathias Agopian
78813ed9b7 get rid of ShaderStageFlags.h
move its content to DriverEnums.h, we do this because it is used
in libfilabridge, which has an unspoken rule that it only includes
DriverEnums.h.

filabridge also only has a header dependency, so it can't call any
method, not even operator<<.

Also cleanups and simplifications.
2022-03-22 15:28:40 -07:00
Mathias Agopian
2e649a9f16 size optimizations and cleanups of SamplerInterfaceBlock 2022-03-22 15:28:40 -07:00
Mathias Agopian
d36783cd1d cleanup a bit metal codegen for samplers
the main change here is that we actually go through all "binding points"
instead of hardcoding the ones we currently use.
2022-03-22 15:28:40 -07:00
Philip Rideout
101a59138c Update the zbloat tool
The tool now works with Python 3 and handles binaries that have multiple
embedded material archives.
2022-03-21 16:13:49 -07:00
Benjamin Doherty
3809259f47 Release Filament 1.20.4 2022-03-21 14:45:00 -07:00
246 changed files with 3014 additions and 2225 deletions

View File

@@ -50,8 +50,7 @@ jobs:
cd build/$WORKFLOW_OS && printf "y" | ./build.sh release
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
xargs -L 1 sudo pip3 install < build/common/requirements.txt
if [ -f out/filament-release-darwin.tgz ]; then mv out/filament-release-darwin.tgz out/filament-${TAG}-mac.tgz; fi;
if [ -f out/filament-release-linux.tgz ]; then mv out/filament-release-linux.tgz out/filament-${TAG}-linux.tgz; fi;
python3 build/common/upload-assets.py ${TAG} out/*.tgz
@@ -80,8 +79,7 @@ jobs:
cd build/web && printf "y" | ./build.sh release
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
xargs -L 1 sudo pip3 install < build/common/requirements.txt
mv out/filament-release-web.tgz out/filament-${TAG}-web.tgz
python3 build/common/upload-assets.py ${TAG} out/*.tgz
env:
@@ -123,15 +121,13 @@ jobs:
APK_KEYSTORE_PASS: ${{ secrets.APK_KEYSTORE_PASS }}
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
xargs -L 1 sudo pip3 install < build/common/requirements.txt
mv out/filament-android-release.aar out/filament-${TAG}-android.aar
mv out/filamat-android-release.aar out/filamat-${TAG}-android.aar
mv out/filamat-android-lite-release.aar out/filamat-${TAG}-lite-android.aar
mv out/gltfio-android-release.aar out/gltfio-${TAG}-android.aar
mv out/gltfio-android-lite-release.aar out/gltfio-${TAG}-lite-android.aar
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
mv out/filament-utils-android-lite-release.aar out/filament-utils-${TAG}-lite-android.aar
python3 build/common/upload-assets.py ${TAG} out/*.aar out/*.apk
env:
TAG: ${{ steps.git_ref.outputs.tag }}
@@ -158,8 +154,7 @@ jobs:
cd build/ios && printf "y" | ./build.sh release
- name: Upload release assets
run: |
pip3 install setuptools
pip3 install PyGithub
xargs -L 1 sudo pip3 install < build/common/requirements.txt
mv out/filament-release-ios.tgz out/filament-${TAG}-ios.tgz
python3 build/common/upload-assets.py ${TAG} out/*.tgz
env:

View File

@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.20.5'
implementation 'com.google.android.filament:filament-android:1.21.1'
}
```
@@ -43,7 +43,6 @@ Here are all the libraries available in the group `com.google.android.filament`:
| [![gltfio-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android/badge.svg?subject=gltfio-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
| [![gltfio-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite/badge.svg?subject=gltfio-android-lite)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite) | Trimmed version of `gltfio` that does not support some glTF extensions. |
| [![filament-utils-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android/badge.svg?subject=filament-utils-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
| [![filament-utils-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android-lite/badge.svg?subject=filament-utils-lite)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android-lite) | Trimmed version of `filament-utils` that does not support some glTF features. |
| [![filamat-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android/badge.svg?subject=filamat-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
| [![filamat-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite/badge.svg?subject=filamat-android-lite)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite) | A much smaller alternative to `filamat-android` that can only generate OpenGL shaders. It does not provide validation or optimizations. |
@@ -52,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:
```
pod 'Filament', '~> 1.20.5'
pod 'Filament', '~> 1.21.1'
```
### Snapshots
@@ -169,11 +168,13 @@ steps:
- [x] KHR_draco_mesh_compression
- [x] KHR_lights_punctual
- [x] KHR_materials_clearcoat
- [x] KHR_materials_emissive_strength
- [x] KHR_materials_ior
- [x] KHR_materials_pbrSpecularGlossiness
- [x] KHR_materials_sheen
- [x] KHR_materials_transmission
- [x] KHR_materials_unlit
- [x] KHR_materials_variants
- [x] KHR_materials_volume
- [x] KHR_mesh_quantization
- [x] KHR_texture_transform

View File

@@ -3,7 +3,24 @@
This file contains one line summaries of commits that are worthy of mentioning in release notes.
A new header is inserted each time a *tag* is created.
## v1.20.6 (currently main branch)
## v1.21.2 (currently main branch)
## v1.21.1
- engine: Allow both screen-space refraction and screen-space reflections on the same object [⚠️ **Material breakage**].
- engine: Optimizations for screen-space reflections.
- engine: Remove `Viewport::scale()` [⚠️ **API Change**].
- engine: Fix 12x overallocation of memory in `MorphTargetBuffer`.
- Metal: Fix validation error when reading from default `SwapChain`.
## v1.21.0
- engine: OpenGL performance improvements with some drivers.
- engine: Fix incorrect shadows with some custom projection matrices.
- engine: Fix low frame rates seen with a lot of morph targets.
- gltfio: Add support for KHR_materials_variants.
- gltfio: Add support for KHR_materials_emissive_strength.
- gltfio: Java now exposes morph target names as an array for consistency [⚠️ **API Change**].
## v1.20.5

View File

@@ -1,30 +1,16 @@
apply plugin: 'kotlin-android'
android {
flavorDimensions "functionality"
productFlavors {
full {
dimension "functionality"
}
lite {
dimension "functionality"
externalNativeBuild {
cmake {
// hack: this is needed because filament-utils-android/CMakeLists.txt builds
// gltfio from source, which needs this defined
arguments.add("-DGLTFIO_LITE=ON")
}
}
}
}
sourceSets {
main {
kotlin.srcDirs += "src/main/java"
}
}
defaultConfig {
missingDimensionStrategy 'functionality', 'full'
}
// No need to package up the following shared libs, which arise as a side effect of our
// externalNativeBuild dependencies. When clients pick and choose from project-level gradle
// dependencies, these shared libs already get pulled in, so we need to avoid the error:
@@ -55,9 +41,7 @@ dependencies {
implementation deps.coroutines.android
api project(':filament-android')
fullApi module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
liteApi module("com.google.android.filament:gltfio-android-lite:${VERSION_NAME}")
api module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
}
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
@@ -65,14 +49,9 @@ apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
afterEvaluate {
publishing {
publications {
fullRelease(MavenPublication) {
artifactId = POM_ARTIFACT_ID_FULL
from components.fullRelease
}
liteRelease(MavenPublication) {
artifactId = POM_ARTIFACT_ID_LITE
from components.liteRelease
release(MavenPublication) {
artifactId = POM_ARTIFACT_ID
from components.release
}
}
}

View File

@@ -1,4 +1,3 @@
POM_NAME=Filament Android Utilities
POM_ARTIFACT_ID_FULL=filament-utils-android
POM_ARTIFACT_ID_LITE=filament-utils-android-lite
POM_ARTIFACT_ID=filament-utils-android
POM_PACKAGING=aar

View File

@@ -215,15 +215,6 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetResourceUriCount(JNIEn
return (jint) asset->getResourceUriCount();
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMorphTargetNameAt(JNIEnv* env, jclass,
jlong nativeAsset, jint entityId, jint targetIndex) {
Entity entity = Entity::import(entityId);
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
const char* val = asset->getMorphTargetNameAt(entity, (size_t) targetIndex);
return val ? env->NewStringUTF(val) : nullptr;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetResourceUris(JNIEnv* env, jclass,
jlong nativeAsset,
@@ -235,6 +226,49 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetResourceUris(JNIEnv* e
}
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMorphTargetCount(JNIEnv*, jclass,
jlong nativeAsset, jint entityId) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
Entity entity = Entity::import(entityId);
return (jint) asset->getMorphTargetCountAt(entity);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMorphTargetNames(JNIEnv* env, jclass,
jlong nativeAsset, jint entityId, jobjectArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
Entity entity = Entity::import(entityId);
for (int i = 0, n = asset->getMorphTargetCountAt(entity); i < n; ++i) {
const char* name = asset->getMorphTargetNameAt(entity, i);
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
}
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialVariantCount(JNIEnv*, jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return (jint) asset->getMaterialVariantCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialVariantNames(JNIEnv* env, jclass,
jlong nativeAsset, jobjectArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
for (int i = 0; i < asset->getMaterialVariantCount(); ++i) {
const char* name = asset->getMaterialVariantName(i);
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
}
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nApplyMaterialVariant(JNIEnv* env, jclass,
jlong nativeAsset, jint variantIndex) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
asset->applyMaterialVariant(variantIndex);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nReleaseSourceData(JNIEnv* env, jclass,
jlong nativeAsset) {

View File

@@ -54,3 +54,10 @@ Java_com_google_android_filament_gltfio_FilamentInstance_nGetAnimator(JNIEnv* ,
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
return (jlong) instance->getAnimator();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nApplyMaterialVariant(JNIEnv* env, jclass,
jlong nativeInstance, jint variantIndex) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
instance->applyMaterialVariant(variantIndex);
}

View File

@@ -217,10 +217,12 @@ public class FilamentAsset {
}
/**
* Get the target name at target index in the given entity.
* Gets the names of all morph targets in the given entity.
*/
public String getMorphTargetNameAt(@Entity int entity, int targetIndex) {
return nGetMorphTargetNameAt(getNativeObject(), entity, targetIndex);
public @NonNull String[] getMorphTargetNames(@Entity int entity) {
String[] names = new String[nGetMorphTargetCount(mNativeObject, entity)];
nGetMorphTargetNames(mNativeObject, entity, names);
return names;
}
/**
@@ -232,6 +234,31 @@ public class FilamentAsset {
return uris;
}
/**
* Returns the names of all material variants.
*/
public @NonNull String[] getMaterialVariantNames() {
String[] names = new String[nGetMaterialVariantCount(mNativeObject)];
nGetMaterialVariantNames(mNativeObject, names);
return names;
}
/**
* Applies the given material variant to all primitives that it affects.
*
* This is efficient because it merely swaps around persistent MaterialInstances. If you change
* a material parameter while a certain variant is active, the updated value will be remembered
* after you re-apply that variant.
*
* If the asset is instanced, this affects all instances in the same way.
* To set the variant on an individual instance, use FilamentInstance#applyMaterialVariant.
*
* Ignored if variantIndex is out of bounds.
*/
public void applyMaterialVariant(@IntRange(from = 0) int variantIndex) {
nApplyMaterialVariant(getNativeObject(), variantIndex);
}
/**
* Reclaims CPU-side memory for URI strings, binding lists, and raw animation data.
*
@@ -268,11 +295,17 @@ public class FilamentAsset {
private static native int nGetMaterialInstanceCount(long nativeAsset);
private static native void nGetMaterialInstances(long nativeAsset, long[] nativeResults);
private static native int nGetMaterialVariantCount(long nativeAsset);
private static native void nGetMaterialVariantNames(long nativeAsset, String[] result);
private static native int nGetMorphTargetCount(long nativeAsset, int entity);
private static native void nGetMorphTargetNames(long nativeAsset, int entity, String[] result);
private static native void nGetBoundingBox(long nativeAsset, float[] box);
private static native String nGetName(long nativeAsset, int entity);
private static native String nGetExtras(long nativeAsset, int entity);
private static native long nGetAnimator(long nativeAsset);
private static native String nGetMorphTargetNameAt(long nativeAsset, int entity, int targetIndex);
private static native void nApplyMaterialVariant(long nativeAsset, int variantIndex);
private static native int nGetResourceUriCount(long nativeAsset);
private static native void nGetResourceUris(long nativeAsset, String[] result);
private static native void nReleaseSourceData(long nativeAsset);

View File

@@ -16,6 +16,7 @@
package com.google.android.filament.gltfio;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import com.google.android.filament.Entity;
@@ -84,8 +85,18 @@ public class FilamentInstance {
return mAnimator;
}
/**
* Applies the given material variant to all primitives in this instance.
*
* Ignored if variantIndex is out of bounds.
*/
void applyMaterialVariant(@IntRange(from = 0) int variantIndex) {
nApplyMaterialVariant(mNativeObject, variantIndex);
}
private static native int nGetRoot(long nativeAsset);
private static native int nGetEntityCount(long nativeAsset);
private static native void nGetEntities(long nativeAsset, int[] result);
private static native long nGetAnimator(long nativeAsset);
private static native void nApplyMaterialVariant(long nativeAsset, int variantIndex);
}

View File

@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.20.5
VERSION_NAME=1.21.1
POM_DESCRIPTION=Real-time physically based rendering engine for Android.

View File

@@ -487,8 +487,7 @@ function build_android {
cp gltfio-android/build/outputs/aar/gltfio-android-full-debug.aar ../out/gltfio-android-debug.aar
echo "Installing out/filament-utils-android-debug.aar..."
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-debug.aar ../out/
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-debug.aar ../out/filament-utils-android-debug.aar
cp filament-utils-android/build/outputs/aar/filament-utils-android-debug.aar ../out/filament-utils-android-debug.aar
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
for sample in ${ANDROID_SAMPLES}; do
@@ -536,8 +535,7 @@ function build_android {
cp gltfio-android/build/outputs/aar/gltfio-android-full-release.aar ../out/gltfio-android-release.aar
echo "Installing out/filament-utils-android-release.aar..."
cp filament-utils-android/build/outputs/aar/filament-utils-android-lite-release.aar ../out/
cp filament-utils-android/build/outputs/aar/filament-utils-android-full-release.aar ../out/filament-utils-android-release.aar
cp filament-utils-android/build/outputs/aar/filament-utils-android-release.aar ../out/filament-utils-android-release.aar
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
for sample in ${ANDROID_SAMPLES}; do

View File

@@ -0,0 +1,14 @@
setuptools==40.6.2
wheel==0.37.1
certifi==2021.10.8
cffi==1.15.0
charset-normalizer==2.0.12
Deprecated==1.2.13
idna==3.3
pycparser==2.21
PyGithub==1.55
PyJWT==2.3.0
PyNaCl==1.5.0
requests==2.27.1
urllib3==1.26.9
wrapt==1.14.0

View File

@@ -12,6 +12,25 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# requirements.txt created via:
#
# pip3 install virtualenv
# python3 -m venv env
# pip3 install PyGithub
# pip3 install wheel
# --all includes wheel and setuputils, which is needed for GitHub Actions
# pip3 freeze --all > requirements.txt
# Manually move 'setuptools' and 'wheel' lines to the beginning of the file.
# Manually remove the 'pip' line.
#
# Requirements are installed in GitHub Actions via:
# xargs -L 1 sudo pip3 install < build/common/requirements.txt
# xargs must be used because the ordering of the dependencies matters (namely, setuptools).
# sudo must be used to uninstall non-matching versions of packages.
# pip is removed to avoid conflicts with the pre-installed pip version on Actions.
# This technique does not work with Windows, unfortunately.
from github import Github
import os, sys

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -113,7 +113,7 @@ class App {
this.view = engine.createView();
this.view.setVignetteOptions({ midPoint: 0.8, enabled: true });
this.view.setBloomOptions({ stength: 0.2, enabled: true });
this.view.setBloomOptions({ strength: 0.2, enabled: true });
this.view.setCamera(this.camera);
this.view.setScene(this.scene);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -92,7 +92,6 @@ set(SRCS
src/UniformBuffer.cpp
src/VertexBuffer.cpp
src/View.cpp
src/Viewport.cpp
src/components/CameraManager.cpp
src/components/LightManager.cpp
src/components/RenderableManager.cpp
@@ -118,14 +117,14 @@ set(SRCS
src/details/Texture.cpp
src/details/VertexBuffer.cpp
src/details/View.cpp
src/fg2/Blackboard.cpp
src/fg2/DependencyGraph.cpp
src/fg2/FrameGraph.cpp
src/fg2/FrameGraphPass.cpp
src/fg2/FrameGraphResources.cpp
src/fg2/FrameGraphTexture.cpp
src/fg2/PassNode.cpp
src/fg2/ResourceNode.cpp
src/fg/Blackboard.cpp
src/fg/DependencyGraph.cpp
src/fg/FrameGraph.cpp
src/fg/FrameGraphPass.cpp
src/fg/FrameGraphResources.cpp
src/fg/FrameGraphTexture.cpp
src/fg/PassNode.cpp
src/fg/ResourceNode.cpp
src/fsr.cpp
)
@@ -177,19 +176,19 @@ set(PRIVATE_HDRS
src/details/Texture.h
src/details/VertexBuffer.h
src/details/View.h
src/fg2/Blackboard.h
src/fg2/FrameGraph.h
src/fg2/FrameGraphId.h
src/fg2/FrameGraphPass.h
src/fg2/FrameGraphRenderPass.h
src/fg2/FrameGraphResources.h
src/fg2/FrameGraphTexture.h
src/fg2/Resource.cpp
src/fg2/details/DependencyGraph.h
src/fg2/details/PassNode.h
src/fg2/details/Resource.h
src/fg2/details/ResourceNode.h
src/fg2/details/Utilities.h
src/fg/Blackboard.h
src/fg/FrameGraph.h
src/fg/FrameGraphId.h
src/fg/FrameGraphPass.h
src/fg/FrameGraphRenderPass.h
src/fg/FrameGraphResources.h
src/fg/FrameGraphTexture.h
src/fg/Resource.cpp
src/fg/details/DependencyGraph.h
src/fg/details/PassNode.h
src/fg/details/Resource.h
src/fg/details/ResourceNode.h
src/fg/details/Utilities.h
src/fsr.h
src/materials/fsr/ffx_a.h
src/materials/fsr/ffx_fsr1.h

View File

@@ -13,7 +13,6 @@ set(PUBLIC_HDRS
include/backend/CallbackHandler.h
include/backend/DriverEnums.h
include/backend/Handle.h
include/backend/ShaderStageFlags.h
include/backend/PipelineState.h
include/backend/PixelBufferDescriptor.h
include/backend/Platform.h
@@ -75,8 +74,8 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
src/opengl/OpenGLProgram.cpp
src/opengl/OpenGLProgram.h
src/opengl/OpenGLPlatform.cpp
src/opengl/TimerQuery.cpp
src/opengl/TimerQuery.h
src/opengl/OpenGLTimerQuery.cpp
src/opengl/OpenGLTimerQuery.h
include/private/backend/OpenGLPlatform.h
)
if (EGL)

View File

@@ -142,9 +142,9 @@ struct Viewport {
uint32_t width; //!< width in pixels
uint32_t height; //!< height in pixels
//! get the right coordinate in window space of the viewport
int32_t right() const noexcept { return left + width; }
int32_t right() const noexcept { return left + int32_t(width); }
//! get the top coordinate in window space of the viewport
int32_t top() const noexcept { return bottom + height; }
int32_t top() const noexcept { return bottom + int32_t(height); }
};
/**
@@ -906,6 +906,16 @@ enum ShaderType : uint8_t {
};
static constexpr size_t PIPELINE_STAGE_COUNT = 2;
struct ShaderStageFlags {
bool vertex : 1;
bool fragment : 1;
bool hasShaderType(ShaderType type) const {
return (vertex && type == ShaderType::VERTEX) ||
(fragment && type == ShaderType::FRAGMENT);
}
};
static constexpr ShaderStageFlags ALL_SHADER_STAGE_FLAGS = { .vertex = true, .fragment = true };
/**
* Selects which buffers to clear at the beginning of the render pass, as well as which buffers
* can be discarded at the beginning and end of the render pass.
@@ -1026,6 +1036,7 @@ utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend:
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::RasterState& rs);
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::RenderPassParams& b);
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::Viewport& v);
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::ShaderStageFlags stageFlags);
#endif
#endif // TNT_FILAMENT_BACKEND_DRIVERENUMS_H

View File

@@ -1,52 +0,0 @@
/*
* Copyright (C) 2022 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_SHADERSTAGEFLAGS_H
#define TNT_FILAMENT_BACKEND_SHADERSTAGEFLAGS_H
#include <backend/DriverEnums.h>
namespace filament::backend {
struct ShaderStageFlags {
bool vertex : 1;
bool fragment : 1;
inline bool hasShaderType(ShaderType type) const {
return (vertex && type == ShaderType::VERTEX) ||
(fragment && type == ShaderType::FRAGMENT);
}
};
constexpr ShaderStageFlags ALL_SHADER_STAGE_FLAGS = { .vertex = true, .fragment = true };
inline utils::io::ostream& operator<<(utils::io::ostream& stream, ShaderStageFlags stageFlags) {
stream << "{ ";
if (stageFlags.vertex) {
stream << "vertex";
}
if (stageFlags.fragment) {
if (stageFlags.vertex)
stream << " | ";
stream << "fragment";
}
stream << " }";
return stream;
}
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_SHADERSTAGEFLAGS_H

View File

@@ -25,7 +25,6 @@
#include <utils/ostream.h>
#include <backend/DriverEnums.h>
#include <backend/ShaderStageFlags.h>
#include <array>
@@ -94,13 +93,15 @@ public:
}
using ShaderBlob = utils::FixedCapacityVector<uint8_t>;
std::array<ShaderBlob, SHADER_TYPE_COUNT> const& getShadersSource() const noexcept {
return mShadersSource;
}
using ShaderSource = std::array<ShaderBlob, SHADER_TYPE_COUNT>;
ShaderSource const& getShadersSource() const noexcept { return mShadersSource; }
ShaderSource& getShadersSource() noexcept { return mShadersSource; }
UniformBlockInfo const& getUniformBlockInfo() const noexcept { return mUniformBlocks; }
UniformBlockInfo& getUniformBlockInfo() noexcept { return mUniformBlocks; }
SamplerGroupInfo const& getSamplerGroupInfo() const { return mSamplerGroups; }
SamplerGroupInfo& getSamplerGroupInfo() { return mSamplerGroups; }
const utils::CString& getName() const noexcept { return mName; }
@@ -111,7 +112,7 @@ private:
UniformBlockInfo mUniformBlocks = {};
SamplerGroupInfo mSamplerGroups = {};
std::array<ShaderBlob, SHADER_TYPE_COUNT> mShadersSource;
ShaderSource mShadersSource;
bool mHasSamplers = false;
utils::CString mName;
utils::Invocable<utils::io::ostream&(utils::io::ostream& out)> mLogger;

View File

@@ -98,12 +98,8 @@ struct HwRenderPrimitive : public HwBase {
};
struct HwProgram : public HwBase {
#ifndef NDEBUG
utils::CString name;
explicit HwProgram(utils::CString name) noexcept : name(std::move(name)) { }
#else
explicit HwProgram(const utils::CString&) noexcept { }
#endif
HwProgram() noexcept = default;
};

View File

@@ -28,7 +28,7 @@ namespace filament::backend {
#ifndef NDEBUG
static char const * const kOurNamespace = "filament::";
static char const * const kOurNamespace = "filament::backend";
// removes all occurrences of "what" from "str"
UTILS_NOINLINE

View File

@@ -25,8 +25,7 @@
using namespace utils;
namespace filament {
using namespace backend;
namespace filament::backend {
template <typename T>
static void loadSymbol(T*& pfn, const char *symbol) noexcept {
@@ -111,7 +110,7 @@ ExternalTextureManagerAndroid::~ExternalTextureManagerAndroid() noexcept {
}
// called on gl thread
backend::Platform::ExternalTexture* ExternalTextureManagerAndroid::createExternalTexture() noexcept {
Platform::ExternalTexture* ExternalTextureManagerAndroid::createExternalTexture() noexcept {
if (__builtin_available(android 26, *)) {
} else {
// initialize java stuff on-demand
@@ -132,21 +131,21 @@ backend::Platform::ExternalTexture* ExternalTextureManagerAndroid::createExterna
// called on app thread
void ExternalTextureManagerAndroid::reallocate(
backend::Platform::ExternalTexture* ets, uint32_t w, uint32_t h,
backend::TextureFormat format, uint64_t usage) noexcept {
Platform::ExternalTexture* ets, uint32_t w, uint32_t h,
TextureFormat format, uint64_t usage) noexcept {
destroyStorage(ets);
alloc(ets, w, h, format, usage);
}
// called on gl thread
void ExternalTextureManagerAndroid::destroy(backend::Platform::ExternalTexture* ets) noexcept {
void ExternalTextureManagerAndroid::destroy(Platform::ExternalTexture* ets) noexcept {
destroyStorage(ets);
delete static_cast<EGLExternalTexture*>(ets);
}
// called on app thread
void ExternalTextureManagerAndroid::alloc(
backend::Platform::ExternalTexture* t,
Platform::ExternalTexture* t,
uint32_t w, uint32_t h, TextureFormat format, uint64_t usage) noexcept {
EGLExternalTexture* ets = static_cast<EGLExternalTexture*>(t);
@@ -200,7 +199,7 @@ void ExternalTextureManagerAndroid::alloc(
}
// called on gl thread
void ExternalTextureManagerAndroid::destroyStorage(backend::Platform::ExternalTexture* t) noexcept {
void ExternalTextureManagerAndroid::destroyStorage(Platform::ExternalTexture* t) noexcept {
EGLExternalTexture* ets = static_cast<EGLExternalTexture*>(t);
if (__builtin_available(android 26, *)) {
// destroy the current storage if any
@@ -219,5 +218,5 @@ void ExternalTextureManagerAndroid::destroyStorage(backend::Platform::ExternalTe
}
}
} // namespace filament
} // namespace filament::backend

View File

@@ -25,7 +25,7 @@
#include <android/api-level.h>
#include <android/hardware_buffer.h>
namespace filament {
namespace filament::backend {
/*
* ExternalTextureManagerAndroid::ExternalTexture is basically a wrapper for AHardwareBuffer.
@@ -39,7 +39,7 @@ namespace filament {
class ExternalTextureManagerAndroid {
public:
struct ExternalTexture : public backend::Platform::ExternalTexture {
struct ExternalTexture : public Platform::ExternalTexture {
void* clientBuffer = nullptr;
AHardwareBuffer* hardwareBuffer = nullptr;
};
@@ -51,26 +51,26 @@ public:
static void destroy(ExternalTextureManagerAndroid* pExternalTextureManager) noexcept;
// must be called on backend thread (only because we don't synchronize
backend::Platform::ExternalTexture* createExternalTexture() noexcept;
Platform::ExternalTexture* createExternalTexture() noexcept;
// called on app thread
void reallocate(
backend::Platform::ExternalTexture* ets, uint32_t w, uint32_t h,
backend::TextureFormat format, uint64_t usage) noexcept;
Platform::ExternalTexture* ets, uint32_t w, uint32_t h,
TextureFormat format, uint64_t usage) noexcept;
// must be called on backend thread
void destroy(backend::Platform::ExternalTexture* ets) noexcept;
void destroy(Platform::ExternalTexture* ets) noexcept;
private:
ExternalTextureManagerAndroid() noexcept;
~ExternalTextureManagerAndroid() noexcept;
// called on app thread
void alloc(backend::Platform::ExternalTexture* ets,
uint32_t w, uint32_t h, backend::TextureFormat format, uint64_t usage) noexcept;
void alloc(Platform::ExternalTexture* ets,
uint32_t w, uint32_t h, TextureFormat format, uint64_t usage) noexcept;
// called on gl thread
void destroyStorage(backend::Platform::ExternalTexture* ets) noexcept;
void destroyStorage(Platform::ExternalTexture* ets) noexcept;
VirtualMachineEnv& mVm;
@@ -79,8 +79,6 @@ private:
jmethodID mGraphicBuffer_nDestroyGraphicBuffer = nullptr;
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_TEXTURE_MANAGER_ANDROID_H

View File

@@ -26,7 +26,6 @@
namespace filament {
namespace backend {
namespace metal {
struct MetalContext;
@@ -45,7 +44,7 @@ public:
uint32_t slice = 0; // must be 0 on source attachment
};
// Valid source formats: 2D, 2DMultisample, 3D
// Valid source formats: 2D, 2DArray, 2DMultisample, 3D
// Valid destination formats: 2D, 2DArray, 3D, Cube
Attachment source, destination;
SamplerMagFilter filter;
@@ -133,7 +132,6 @@ private:
};
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -17,12 +17,12 @@
#include "MetalBlitter.h"
#include "MetalContext.h"
#include "MetalUtils.h"
#include <utils/Panic.h>
namespace filament {
namespace backend {
namespace metal {
static const char* functionLibrary = R"(
#include <metal_stdlib>
@@ -145,8 +145,6 @@ void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args) {
bool blitColor = args.blitColor();
bool blitDepth = args.blitDepth();
ASSERT_PRECONDITION(args.source.slice == 0u, "Source attachment must have slice of 0.");
ASSERT_PRECONDITION(args.source.region.size.depth == args.destination.region.size.depth,
"Blitting requires the source and destination regions to have the same depth.");
@@ -223,7 +221,7 @@ void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
[blitEncoder copyFromTexture:args.source.color
sourceSlice:0
sourceSlice:args.source.slice
sourceLevel:args.source.level
sourceOrigin:args.source.region.origin
sourceSize:args.source.region.size
@@ -244,7 +242,7 @@ void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
[blitEncoder copyFromTexture:args.source.depth
sourceSlice:0
sourceSlice:args.source.slice
sourceLevel:args.source.level
sourceOrigin:args.source.region.origin
sourceSize:args.source.region.size
@@ -301,7 +299,7 @@ void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor
}
id<MTLFunction> fragmentFunction = getBlitFragmentFunction(key);
PipelineState pipelineState {
MetalPipelineState pipelineState {
.vertexFunction = getBlitVertexFunction(),
.fragmentFunction = fragmentFunction,
.vertexDescription = {},
@@ -323,12 +321,22 @@ void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor
id<MTLRenderPipelineState> pipeline = mContext.pipelineStateCache.getOrCreateState(pipelineState);
[encoder setRenderPipelineState:pipeline];
// For texture arrays, create a view of the texture at the given slice (layer).
id<MTLTexture> srcTextureColor = args.source.color;
if (srcTextureColor && srcTextureColor.textureType == MTLTextureType2DArray) {
srcTextureColor = createTextureViewWithSingleSlice(srcTextureColor, args.source.slice);
}
id<MTLTexture> srcTextureDepth = args.source.depth;
if (srcTextureDepth && srcTextureDepth.textureType == MTLTextureType2DArray) {
srcTextureDepth = createTextureViewWithSingleSlice(srcTextureDepth, args.source.slice);
}
if (blitColor) {
[encoder setFragmentTexture:args.source.color atIndex:0];
[encoder setFragmentTexture:srcTextureColor atIndex:0];
}
if (blitDepth) {
[encoder setFragmentTexture:args.source.depth atIndex:1];
[encoder setFragmentTexture:srcTextureDepth atIndex:1];
}
SamplerMinFilter filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST;
@@ -521,6 +529,5 @@ id<MTLFunction> MetalBlitter::getBlitFragmentFunction(BlitFunctionKey key) {
return function;
}
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -26,7 +26,6 @@
namespace filament {
namespace backend {
namespace metal {
class MetalBuffer {
public:
@@ -94,7 +93,6 @@ private:
void copyIntoStreamBuffer(void* src, size_t size);
};
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -22,7 +22,6 @@
namespace filament {
namespace backend {
namespace metal {
MetalBuffer::MetalBuffer(MetalContext& context, BufferUsage usage, size_t size, bool forceGpuBuffer)
: mBufferSize(size), mContext(context) {
@@ -206,6 +205,5 @@ void MetalBuffer::bindBuffers(id<MTLCommandBuffer> cmdBuffer, id<MTLRenderComman
}
}
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -25,7 +25,6 @@
namespace filament {
namespace backend {
namespace metal {
struct MetalContext;
@@ -78,7 +77,6 @@ private:
static constexpr uint32_t TIME_BEFORE_EVICTION = 10;
};
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -26,7 +26,6 @@
namespace filament {
namespace backend {
namespace metal {
MetalBufferPoolEntry const* MetalBufferPool::acquireBuffer(size_t numBytes) {
std::lock_guard<std::mutex> lock(mMutex);
@@ -110,6 +109,5 @@ void MetalBufferPool::reset() noexcept {
mFreeStages.clear();
}
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -36,14 +36,13 @@
namespace filament {
namespace backend {
namespace metal {
class MetalDriver;
class MetalBlitter;
class MetalBufferPool;
class MetalRenderTarget;
class MetalSwapChain;
class TimerQueryInterface;
class MetalTimerQueryInterface;
struct MetalUniformBuffer;
struct MetalIndexBuffer;
struct MetalSamplerGroup;
@@ -113,7 +112,7 @@ struct MetalContext {
MTLSharedEventListener* eventListener = nil;
uint64_t signalId = 1;
TimerQueryInterface* timerQueryImpl;
MetalTimerQueryInterface* timerQueryImpl;
std::stack<const char*> groupMarkers;
@@ -134,7 +133,6 @@ id<MTLTexture> getOrCreateEmptyTexture(MetalContext* context);
bool isInRenderPass(MetalContext* context);
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -25,7 +25,6 @@
namespace filament {
namespace backend {
namespace metal {
void initializeSupportedGpuFamilies(MetalContext* context) {
auto& highestSupportedFamily = context->highestSupportedGpuFamily;
@@ -145,6 +144,5 @@ bool isInRenderPass(MetalContext* context) {
return context->currentRenderPassEncoder != nil;
}
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -31,8 +31,6 @@ namespace backend {
class MetalPlatform;
namespace metal {
class MetalBuffer;
struct MetalUniformBuffer;
struct MetalContext;
@@ -44,17 +42,17 @@ struct UniformBufferState;
#endif
class MetalDriver final : public DriverBase {
explicit MetalDriver(backend::MetalPlatform* platform) noexcept;
explicit MetalDriver(MetalPlatform* platform) noexcept;
~MetalDriver() noexcept override;
public:
static Driver* create(backend::MetalPlatform* platform);
static Driver* create(MetalPlatform* platform);
private:
friend class MetalSwapChain;
backend::MetalPlatform& mPlatform;
MetalPlatform& mPlatform;
MetalContext* mContext;
@@ -68,7 +66,7 @@ private:
*/
template<typename T>
friend class backend::ConcreteDispatcher;
friend class ConcreteDispatcher;
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
UTILS_ALWAYS_INLINE inline void methodName(paramsDecl);
@@ -86,7 +84,7 @@ private:
* Memory management
*/
backend::HandleAllocatorMTL mHandleAllocator;
HandleAllocatorMTL mHandleAllocator;
template<typename D>
Handle<D> alloc_handle() {
@@ -126,7 +124,6 @@ private:
};
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -41,18 +41,16 @@ namespace filament {
namespace backend {
Driver* MetalDriverFactory::create(MetalPlatform* const platform) {
return metal::MetalDriver::create(platform);
return MetalDriver::create(platform);
}
namespace metal {
UTILS_NOINLINE
Driver* MetalDriver::create(MetalPlatform* const platform) {
assert_invariant(platform);
return new MetalDriver(platform);
}
MetalDriver::MetalDriver(backend::MetalPlatform* platform) noexcept
MetalDriver::MetalDriver(MetalPlatform* platform) noexcept
: DriverBase(new ConcreteDispatcher<MetalDriver>()),
mPlatform(*platform),
mContext(new MetalContext),
@@ -108,7 +106,7 @@ MetalDriver::MetalDriver(backend::MetalPlatform* platform) noexcept
mContext->blitter = new MetalBlitter(*mContext);
if (@available(iOS 12, *)) {
mContext->timerQueryImpl = new TimerQueryFence(*mContext);
mContext->timerQueryImpl = new MetalTimerQueryFence(*mContext);
} else {
mContext->timerQueryImpl = new TimerQueryNoop();
}
@@ -149,13 +147,13 @@ void MetalDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) {
}
void MetalDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch,
backend::FrameScheduledCallback callback, void* user) {
FrameScheduledCallback callback, void* user) {
auto* swapChain = handle_cast<MetalSwapChain>(sch);
swapChain->setFrameScheduledCallback(callback, user);
}
void MetalDriver::setFrameCompletedCallback(Handle<HwSwapChain> sch,
backend::FrameCompletedCallback callback, void* user) {
FrameCompletedCallback callback, void* user) {
auto* swapChain = handle_cast<MetalSwapChain>(sch);
swapChain->setFrameCompletedCallback(callback, user);
}
@@ -291,7 +289,7 @@ void MetalDriver::createDefaultRenderTargetR(Handle<HwRenderTarget> rth, int dum
void MetalDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
TargetBufferFlags targetBufferFlags, uint32_t width, uint32_t height,
uint8_t samples, backend::MRT color,
uint8_t samples, MRT color,
TargetBufferInfo depth, TargetBufferInfo stencil) {
// Clamp sample count to what the device supports.
auto& sc = mContext->sampleCountLookup;
@@ -344,7 +342,7 @@ void MetalDriver::createSyncR(Handle<HwSync> sh, int) {
}
void MetalDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow, uint64_t flags) {
if (UTILS_UNLIKELY(flags & backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER)) {
if (UTILS_UNLIKELY(flags & SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER)) {
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef) nativeWindow;
construct_handle<MetalSwapChain>(sch, *mContext, pixelBuffer, flags);
} else {
@@ -569,7 +567,7 @@ Handle<HwStream> MetalDriver::createStreamAcquired() {
}
void MetalDriver::setAcquiredImage(Handle<HwStream> sh, void* image,
backend::CallbackHandler* handler, backend::StreamCallback cb, void* userData) {
CallbackHandler* handler, StreamCallback cb, void* userData) {
}
void MetalDriver::setStreamDimensions(Handle<HwStream> stream, uint32_t width,
@@ -581,7 +579,7 @@ int64_t MetalDriver::getStreamTimestamp(Handle<HwStream> stream) {
return 0;
}
void MetalDriver::updateStreams(backend::DriverApi* driver) {
void MetalDriver::updateStreams(DriverApi* driver) {
}
@@ -1058,8 +1056,8 @@ void MetalDriver::readStreamPixels(Handle<HwStream> sh, uint32_t x, uint32_t y,
}
void MetalDriver::blit(TargetBufferFlags buffers,
Handle<HwRenderTarget> dst, backend::Viewport dstRect,
Handle<HwRenderTarget> src, backend::Viewport srcRect,
Handle<HwRenderTarget> dst, Viewport dstRect,
Handle<HwRenderTarget> src, Viewport srcRect,
SamplerMagFilter filter) {
// If we're the in middle of a render pass, finish it.
// This condition should only occur during copyFrame. It's okay to end the render pass because
@@ -1099,7 +1097,8 @@ void MetalDriver::blit(TargetBufferFlags buffers,
dstRect.width, dstRect.height);
auto isBlitableTextureType = [](MTLTextureType t) {
return t == MTLTextureType2D || t == MTLTextureType2DMultisample;
return t == MTLTextureType2D || t == MTLTextureType2DMultisample ||
t == MTLTextureType2DArray;
};
MetalBlitter::BlitArgs args;
@@ -1121,6 +1120,8 @@ void MetalDriver::blit(TargetBufferFlags buffers,
args.destination.color = dstColorAttachment.getTexture();
args.source.level = srcColorAttachment.level;
args.destination.level = dstColorAttachment.level;
args.source.slice = srcColorAttachment.layer;
args.destination.slice = dstColorAttachment.layer;
}
}
@@ -1137,25 +1138,33 @@ void MetalDriver::blit(TargetBufferFlags buffers,
args.destination.depth = dstDepthAttachment.getTexture();
if (args.blitColor()) {
// If blitting color, we've already set the source and destination levels.
// Check that they match the requested depth levels.
// If blitting color, we've already set the source and destination levels and slices.
// Check that they match the requested depth levels/slices.
ASSERT_PRECONDITION(args.source.level == srcDepthAttachment.level,
"Color and depth source LOD must match. (%d != %d)",
args.source.level, srcDepthAttachment.level);
ASSERT_PRECONDITION(args.destination.level == dstDepthAttachment.level,
"Color and depth destination LOD must match. (%d != %d)",
args.destination.level, dstDepthAttachment.level);
ASSERT_PRECONDITION(args.source.slice == srcDepthAttachment.layer,
"Color and depth source layer must match. (%d != %d)",
args.source.slice, srcDepthAttachment.layer);
ASSERT_PRECONDITION(args.destination.slice == dstDepthAttachment.layer,
"Color and depth destination layer must match. (%d != %d)",
args.destination.slice, dstDepthAttachment.layer);
}
args.source.level = srcDepthAttachment.level;
args.destination.level = dstDepthAttachment.level;
args.source.slice = srcDepthAttachment.layer;
args.destination.slice = dstDepthAttachment.layer;
}
}
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
}
void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t instanceCount) {
void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t instanceCount) {
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr,
"Attempted to draw without a valid command encoder.");
auto primitive = handle_cast<MetalRenderPrimitive>(rph);
@@ -1185,7 +1194,7 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
if (depthAttachment) {
depthPixelFormat = depthAttachment.getPixelFormat();
}
metal::PipelineState pipelineState {
MetalPipelineState pipelineState {
.vertexFunction = program->vertexFunction,
.fragmentFunction = program->fragmentFunction,
.vertexDescription = primitive->vertexDescription,
@@ -1293,15 +1302,15 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
return mContext->samplerStateCache.getOrCreateState(s);
};
id<MTLTexture> texturesToBindVertex[backend::MAX_VERTEX_SAMPLER_COUNT] = {};
id<MTLSamplerState> samplersToBindVertex[backend::MAX_VERTEX_SAMPLER_COUNT] = {};
id<MTLTexture> texturesToBindVertex[MAX_VERTEX_SAMPLER_COUNT] = {};
id<MTLSamplerState> samplersToBindVertex[MAX_VERTEX_SAMPLER_COUNT] = {};
enumerateSamplerGroups(program, ShaderType::VERTEX,
[this, &getTextureToBind, &getSamplerToBind, &texturesToBindVertex, &samplersToBindVertex](
const SamplerGroup::Sampler* sampler, uint8_t binding) {
// We currently only support a max of MAX_VERTEX_SAMPLER_COUNT samplers. Ignore any additional
// samplers that may be bound.
if (binding >= backend::MAX_VERTEX_SAMPLER_COUNT) {
if (binding >= MAX_VERTEX_SAMPLER_COUNT) {
return;
}
@@ -1325,21 +1334,21 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
}
}
NSRange vertexSamplerRange = NSMakeRange(0, backend::MAX_VERTEX_SAMPLER_COUNT);
NSRange vertexSamplerRange = NSMakeRange(0, MAX_VERTEX_SAMPLER_COUNT);
[mContext->currentRenderPassEncoder setVertexTextures:texturesToBindVertex
withRange:vertexSamplerRange];
[mContext->currentRenderPassEncoder setVertexSamplerStates:samplersToBindVertex
withRange:vertexSamplerRange];
id<MTLTexture> texturesToBindFragment[backend::MAX_FRAGMENT_SAMPLER_COUNT] = {};
id<MTLSamplerState> samplersToBindFragment[backend::MAX_FRAGMENT_SAMPLER_COUNT] = {};
id<MTLTexture> texturesToBindFragment[MAX_FRAGMENT_SAMPLER_COUNT] = {};
id<MTLSamplerState> samplersToBindFragment[MAX_FRAGMENT_SAMPLER_COUNT] = {};
enumerateSamplerGroups(program, ShaderType::FRAGMENT,
[this, &getTextureToBind, &getSamplerToBind, &texturesToBindFragment, &samplersToBindFragment](
const SamplerGroup::Sampler* sampler, uint8_t binding) {
// We currently only support a max of MAX_FRAGMENT_SAMPLER_COUNT samplers. Ignore any additional
// samplers that may be bound.
if (binding >= backend::MAX_FRAGMENT_SAMPLER_COUNT) {
if (binding >= MAX_FRAGMENT_SAMPLER_COUNT) {
return;
}
@@ -1363,7 +1372,7 @@ void MetalDriver::draw(backend::PipelineState ps, Handle<HwRenderPrimitive> rph,
}
}
NSRange fragmentSamplerRange = NSMakeRange(0, backend::MAX_FRAGMENT_SAMPLER_COUNT);
NSRange fragmentSamplerRange = NSMakeRange(0, MAX_FRAGMENT_SAMPLER_COUNT);
[mContext->currentRenderPassEncoder setFragmentTextures:texturesToBindFragment
withRange:fragmentSamplerRange];
[mContext->currentRenderPassEncoder setFragmentSamplerStates:samplersToBindFragment
@@ -1468,10 +1477,8 @@ void MetalDriver::enumerateBoundUniformBuffers(
}
}
} // namespace metal
// explicit instantiation of the Dispatcher
template class ConcreteDispatcher<metal::MetalDriver>;
template class ConcreteDispatcher<MetalDriver>;
} // namespace backend
} // namespace filament

View File

@@ -24,7 +24,7 @@ class Driver;
class MetalDriverFactory {
public:
static Driver* create(backend::MetalPlatform* platform);
static Driver* create(MetalPlatform* platform);
};
} // namespace backend

View File

@@ -27,7 +27,6 @@
namespace filament {
namespace backend {
namespace metal {
struct MetalContext;
@@ -405,7 +404,6 @@ inline MTLTextureSwizzleChannels getSwizzleChannels(TextureSwizzle r, TextureSwi
getSwizzle(a));
}
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -20,7 +20,6 @@
namespace filament {
namespace backend {
namespace metal {
MTLPixelFormat getMetalFormat(MetalContext* context, TextureFormat format) noexcept {
switch (format) {
@@ -207,6 +206,5 @@ MTLPixelFormat getMetalFormat(MetalContext* context, TextureFormat format) noexc
return MTLPixelFormatInvalid;
}
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -24,7 +24,6 @@
namespace filament {
namespace backend {
namespace metal {
struct MetalContext;
@@ -129,7 +128,6 @@ private:
} mSwizzle;
};
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -32,7 +32,6 @@
namespace filament {
namespace backend {
namespace metal {
static const auto cvBufferDeleter = [](const void* buffer) {
CVBufferRelease((CVMetalTextureRef) buffer);
@@ -300,6 +299,5 @@ id<MTLCommandBuffer> MetalExternalImage::encodeColorConversionPass(id<MTLTexture
return commandBuffer;
}
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -40,7 +40,6 @@
namespace filament {
namespace backend {
namespace metal {
class MetalSwapChain : public HwSwapChain {
public:
@@ -357,7 +356,6 @@ struct MetalTimerQuery : public HwTimerQuery {
std::shared_ptr<Status> status;
};
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -32,7 +32,6 @@
namespace filament {
namespace backend {
namespace metal {
static inline MTLTextureUsage getMetalTextureUsage(TextureUsage usage) {
NSUInteger u = 0;
@@ -68,9 +67,8 @@ MetalSwapChain::MetalSwapChain(MetalContext& context, CAMetalLayer* nativeWindow
}
// Needed so we can use the SwapChain as a blit source.
if (flags & SwapChain::CONFIG_READABLE) {
nativeWindow.framebufferOnly = NO;
}
// Also needed for rendering directly into the SwapChain during refraction.
nativeWindow.framebufferOnly = NO;
layer.device = context.device;
}
@@ -81,7 +79,7 @@ MetalSwapChain::MetalSwapChain(MetalContext& context, int32_t width, int32_t hei
MetalSwapChain::MetalSwapChain(MetalContext& context, CVPixelBufferRef pixelBuffer, uint64_t flags)
: context(context), externalImage(context), type(SwapChainType::CVPIXELBUFFERREF) {
assert_invariant(flags & backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER);
assert_invariant(flags & SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER);
MetalExternalImage::assertWritableImage(pixelBuffer);
externalImage.set(pixelBuffer);
assert_invariant(externalImage.isValid());
@@ -224,7 +222,7 @@ void MetalSwapChain::scheduleFrameScheduledCallback() {
}
assert_invariant(drawable);
backend::FrameScheduledCallback callback = frameScheduledCallback;
FrameScheduledCallback callback = frameScheduledCallback;
// This block strongly captures drawable to keep it alive until the handler executes.
// We cannot simply reference this->drawable inside the block because the block would then only
// capture the _this_ pointer (MetalSwapChain*) instead of the drawable.
@@ -245,12 +243,12 @@ void MetalSwapChain::scheduleFrameCompletedCallback() {
return;
}
backend::FrameCompletedCallback callback = frameCompletedCallback;
FrameCompletedCallback callback = frameCompletedCallback;
void* userData = frameCompletedUserData;
[getPendingCommandBuffer(&context) addCompletedHandler:^(id<MTLCommandBuffer> cb) {
struct CallbackData {
void* userData;
backend::FrameCompletedCallback callback;
FrameCompletedCallback callback;
};
CallbackData* data = new CallbackData();
data->userData = userData;
@@ -1024,6 +1022,5 @@ FenceStatus MetalFence::wait(uint64_t timeoutNs) {
return FenceStatus::ERROR;
}
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -20,7 +20,6 @@
namespace filament {
namespace backend {
namespace metal {
bool MetalResourceTracker::trackResource(CommandBuffer buffer, Resource resource,
ResourceDeleter deleter) {
@@ -53,6 +52,5 @@ void MetalResourceTracker::clearResources(CommandBuffer buffer) {
mResources.erase(found);
}
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -25,7 +25,6 @@
namespace filament {
namespace backend {
namespace metal {
/**
* MetalResourceTracker is a simple utility that maps individual command buffers to a set of
@@ -76,7 +75,6 @@ private:
std::mutex mMutex;
};
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -31,24 +31,21 @@
namespace filament {
namespace backend {
inline bool operator==(const backend::SamplerParams& lhs, const backend::SamplerParams& rhs) {
inline bool operator==(const SamplerParams& lhs, const SamplerParams& rhs) {
return lhs.u == rhs.u;
}
namespace metal {
static constexpr uint32_t MAX_VERTEX_ATTRIBUTE_COUNT = backend::MAX_VERTEX_ATTRIBUTE_COUNT;
static constexpr uint32_t SAMPLER_GROUP_COUNT = Program::BINDING_COUNT;
static constexpr uint32_t SAMPLER_BINDING_COUNT = backend::MAX_SAMPLER_COUNT;
static constexpr uint32_t SAMPLER_BINDING_COUNT = MAX_SAMPLER_COUNT;
static constexpr uint32_t VERTEX_BUFFER_START = Program::BINDING_COUNT;
// The "zero" buffer is a small buffer for missing attributes that resides in the vertex slot
// immediately following any user-provided vertex buffers.
static constexpr uint32_t ZERO_VERTEX_BUFFER = backend::MAX_VERTEX_BUFFER_COUNT;
static constexpr uint32_t ZERO_VERTEX_BUFFER = MAX_VERTEX_BUFFER_COUNT;
// The total number of vertex buffer "slots" that the Metal backend can bind.
// + 1 to account for the zero buffer.
static constexpr uint32_t VERTEX_BUFFER_COUNT = backend::MAX_VERTEX_BUFFER_COUNT + 1;
static constexpr uint32_t VERTEX_BUFFER_COUNT = MAX_VERTEX_BUFFER_COUNT + 1;
// Forward declarations necessary here, definitions at end of file.
inline bool operator==(const MTLViewport& lhs, const MTLViewport& rhs);
@@ -212,7 +209,7 @@ private:
// Pipeline state
struct PipelineState {
struct MetalPipelineState {
id<MTLFunction> vertexFunction = nil; // 8 bytes
id<MTLFunction> fragmentFunction = nil; // 8 bytes
VertexDescription vertexDescription; // 528 bytes
@@ -223,7 +220,7 @@ struct PipelineState {
bool colorWrite = true; // 1 byte
char padding[7] = { 0 }; // 7 bytes
bool operator==(const PipelineState& rhs) const noexcept {
bool operator==(const MetalPipelineState& rhs) const noexcept {
return (
this->vertexFunction == rhs.vertexFunction &&
this->fragmentFunction == rhs.fragmentFunction &&
@@ -237,23 +234,23 @@ struct PipelineState {
);
}
bool operator!=(const PipelineState& rhs) const noexcept {
bool operator!=(const MetalPipelineState& rhs) const noexcept {
return !operator==(rhs);
}
};
// This assert checks that the struct is the size we expect without any "hidden" padding bytes
// inserted by the compiler.
static_assert(sizeof(PipelineState) == 688, "PipelineState unexpected size.");
static_assert(sizeof(MetalPipelineState) == 688, "MetalPipelineState unexpected size.");
struct PipelineStateCreator {
id<MTLRenderPipelineState> operator()(id<MTLDevice> device, const PipelineState& state)
id<MTLRenderPipelineState> operator()(id<MTLDevice> device, const MetalPipelineState& state)
noexcept;
};
using PipelineStateTracker = StateTracker<PipelineState>;
using PipelineStateTracker = StateTracker<MetalPipelineState>;
using PipelineStateCache = StateCache<PipelineState, id<MTLRenderPipelineState>,
using PipelineStateCache = StateCache<MetalPipelineState, id<MTLRenderPipelineState>,
PipelineStateCreator>;
// Depth-stencil State
@@ -315,7 +312,7 @@ using UniformBufferStateTracker = StateTracker<UniformBufferState>;
// Sampler states
struct SamplerState {
backend::SamplerParams samplerParams;
SamplerParams samplerParams;
uint32_t minLod = 0;
uint32_t maxLod = UINT_MAX;
@@ -343,7 +340,6 @@ using SamplerStateCache = StateCache<SamplerState, id<MTLSamplerState>, SamplerS
using CullModeStateTracker = StateTracker<MTLCullMode>;
using WindingStateTracker = StateTracker<MTLWinding>;
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -20,10 +20,9 @@
namespace filament {
namespace backend {
namespace metal {
id<MTLRenderPipelineState> PipelineStateCreator::operator()(id<MTLDevice> device,
const PipelineState& state) noexcept {
const MetalPipelineState& state) noexcept {
MTLRenderPipelineDescriptor* descriptor = [MTLRenderPipelineDescriptor new];
// Shader Functions
@@ -105,7 +104,7 @@ id<MTLDepthStencilState> DepthStateCreator::operator()(id<MTLDevice> device,
id<MTLSamplerState> SamplerStateCreator::operator()(id<MTLDevice> device,
const SamplerState& state) noexcept {
backend::SamplerParams params = state.samplerParams;
SamplerParams params = state.samplerParams;
MTLSamplerDescriptor* samplerDescriptor = [MTLSamplerDescriptor new];
samplerDescriptor.minFilter = getFilter(params.filterMin);
samplerDescriptor.magFilter = getFilter(params.filterMag);
@@ -133,6 +132,5 @@ id<MTLSamplerState> SamplerStateCreator::operator()(id<MTLDevice> device,
return [device newSamplerStateWithDescriptor:samplerDescriptor];
}
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -23,14 +23,13 @@
namespace filament {
namespace backend {
namespace metal {
struct MetalTimerQuery;
struct MetalContext;
class TimerQueryInterface {
class MetalTimerQueryInterface {
public:
virtual ~TimerQueryInterface();
virtual ~MetalTimerQueryInterface();
virtual void beginTimeElapsedQuery(MetalTimerQuery* query) = 0;
virtual void endTimeElapsedQuery(MetalTimerQuery* query) = 0;
virtual bool getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) = 0;
@@ -41,9 +40,9 @@ protected:
// Uses MTLSharedEvents to implement timer queries.
// Only available on >= iOS 12.0.
class API_AVAILABLE(ios(12.0)) TimerQueryFence : public TimerQueryInterface {
class API_AVAILABLE(ios(12.0)) MetalTimerQueryFence : public MetalTimerQueryInterface {
public:
explicit TimerQueryFence(MetalContext& context) : mContext(context) {}
explicit MetalTimerQueryFence(MetalContext& context) : mContext(context) {}
void beginTimeElapsedQuery(MetalTimerQuery* query) override;
void endTimeElapsedQuery(MetalTimerQuery* query) override;
@@ -53,14 +52,13 @@ private:
MetalContext& mContext;
};
class TimerQueryNoop : public TimerQueryInterface {
class TimerQueryNoop : public MetalTimerQueryInterface {
public:
void beginTimeElapsedQuery(MetalTimerQuery* query) override {}
void endTimeElapsedQuery(MetalTimerQuery* query) override {}
bool getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) override;
};
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -20,11 +20,10 @@
namespace filament {
namespace backend {
namespace metal {
TimerQueryInterface::~TimerQueryInterface() = default;
MetalTimerQueryInterface::~MetalTimerQueryInterface() = default;
void TimerQueryFence::beginTimeElapsedQuery(MetalTimerQuery* query) {
void MetalTimerQueryFence::beginTimeElapsedQuery(MetalTimerQuery* query) {
auto* fence = new MetalFence(mContext);
fence->encode();
query->status->elapsed = 0;
@@ -41,7 +40,7 @@ void TimerQueryFence::beginTimeElapsedQuery(MetalTimerQuery* query) {
});
}
void TimerQueryFence::endTimeElapsedQuery(MetalTimerQuery* query) {
void MetalTimerQueryFence::endTimeElapsedQuery(MetalTimerQuery* query) {
auto* fence = new MetalFence(mContext);
fence->encode();
@@ -57,7 +56,7 @@ void TimerQueryFence::endTimeElapsedQuery(MetalTimerQuery* query) {
});
}
bool TimerQueryFence::getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) {
bool MetalTimerQueryFence::getQueryResult(MetalTimerQuery* query, uint64_t* outElapsedTime) {
if (!query->status->available.load()) {
return false;
}
@@ -71,6 +70,5 @@ bool TimerQueryNoop::getQueryResult(MetalTimerQuery* query, uint64_t* outElapsed
return false;
}
} // namespace metal
} // namespace backend
} // namespace filament

View File

@@ -19,7 +19,7 @@
#include <Metal/Metal.h>
namespace filament::backend::metal {
namespace filament::backend {
/**
* Creates a texture view of the passed-in texture with the given swizzle. If swizzle is the default
@@ -29,6 +29,19 @@ API_AVAILABLE(ios(13.0))
id<MTLTexture> createTextureViewWithSwizzle(id<MTLTexture> texture,
MTLTextureSwizzleChannels swizzle);
} // namespace filament::backend::metal
/**
* Creates a texture view of the passed-in texture with the given layer.
*
* The returned MTLTexture will have a type of MTLTextureType2D.
* The following MTLTextureTypes are supported:
* - MTLTextureType2D (this is a no-op)
* - MTLTextureType2DArray
* - MTLTextureTypeCube
*
* All other MTLTextureTypes are unsupported.
*/
id<MTLTexture> createTextureViewWithSingleSlice(id<MTLTexture> texture, NSUInteger slice);
} // namespace filament::backend
#endif //TNT_FILAMENT_DRIVER_METALUTILS_H

View File

@@ -16,7 +16,7 @@
#include "MetalUtils.h"
namespace filament::backend::metal {
namespace filament::backend {
id<MTLTexture> createTextureViewWithSwizzle(id<MTLTexture> texture,
MTLTextureSwizzleChannels swizzle) {
@@ -37,4 +37,15 @@ id<MTLTexture> createTextureViewWithSwizzle(id<MTLTexture> texture,
swizzle:swizzle];
}
id<MTLTexture> createTextureViewWithSingleSlice(id<MTLTexture> texture, NSUInteger slice) {
if (texture.textureType == MTLTextureType2D) {
return texture;
}
NSUInteger mips = texture.mipmapLevelCount;
return [texture newTextureViewWithPixelFormat:texture.pixelFormat
textureType:MTLTextureType2D
levels:NSMakeRange(0, mips)
slices:NSMakeRange(slice, 1)];
}
} // namespace filament::backend

View File

@@ -17,9 +17,7 @@
#include "noop/NoopDriver.h"
#include "CommandStreamDispatcher.h"
namespace filament {
using namespace backend;
namespace filament::backend {
Driver* NoopDriver::create() {
return new NoopDriver();
@@ -30,7 +28,7 @@ NoopDriver::NoopDriver() noexcept : DriverBase(new ConcreteDispatcher<NoopDriver
NoopDriver::~NoopDriver() noexcept = default;
backend::ShaderModel NoopDriver::getShaderModel() const noexcept {
ShaderModel NoopDriver::getShaderModel() const noexcept {
#if defined(__ANDROID__) || defined(IOS) || defined(__EMSCRIPTEN__)
return ShaderModel::GL_ES_30;
#else
@@ -39,7 +37,7 @@ backend::ShaderModel NoopDriver::getShaderModel() const noexcept {
}
// explicit instantiation of the Dispatcher
template class backend::ConcreteDispatcher<NoopDriver>;
template class ConcreteDispatcher<NoopDriver>;
void NoopDriver::terminate() {
@@ -52,12 +50,12 @@ void NoopDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) {
}
void NoopDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch,
backend::FrameScheduledCallback callback, void* user) {
FrameScheduledCallback callback, void* user) {
}
void NoopDriver::setFrameCompletedCallback(Handle<HwSwapChain> sch,
backend::FrameCompletedCallback callback, void* user) {
FrameCompletedCallback callback, void* user) {
}
@@ -118,7 +116,7 @@ Handle<HwStream> NoopDriver::createStreamAcquired() {
}
void NoopDriver::setAcquiredImage(Handle<HwStream> sh, void* image,
backend::CallbackHandler* handler, backend::StreamCallback cb, void* userData) {
CallbackHandler* handler, StreamCallback cb, void* userData) {
}
void NoopDriver::setStreamDimensions(Handle<HwStream> sh, uint32_t width, uint32_t height) {
@@ -148,7 +146,7 @@ bool NoopDriver::isTextureSwizzleSupported() {
return true;
}
bool NoopDriver::isTextureFormatMipmappable(backend::TextureFormat format) {
bool NoopDriver::isTextureFormatMipmappable(TextureFormat format) {
return true;
}
@@ -181,7 +179,7 @@ math::float2 NoopDriver::getClipSpaceParams() {
}
uint8_t NoopDriver::getMaxDrawBuffers() {
return backend::MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT;
return MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT;
}
void NoopDriver::updateIndexBuffer(Handle<HwIndexBuffer> ibh, BufferDescriptor&& p,
@@ -313,8 +311,8 @@ void NoopDriver::readStreamPixels(Handle<HwStream> sh, uint32_t x, uint32_t y, u
}
void NoopDriver::blit(TargetBufferFlags buffers,
Handle<HwRenderTarget> dst, backend::Viewport dstRect,
Handle<HwRenderTarget> src, backend::Viewport srcRect,
Handle<HwRenderTarget> dst, Viewport dstRect,
Handle<HwRenderTarget> src, Viewport srcRect,
SamplerMagFilter filter) {
}

View File

@@ -14,32 +14,32 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_NOOPDRIVER_H
#define TNT_FILAMENT_DRIVER_NOOPDRIVER_H
#ifndef TNT_FILAMENT_BACKEND_NOOPDRIVER_H
#define TNT_FILAMENT_BACKEND_NOOPDRIVER_H
#include "private/backend/Driver.h"
#include "DriverBase.h"
#include <utils/compiler.h>
namespace filament {
namespace filament::backend {
class NoopDriver final : public backend::DriverBase {
class NoopDriver final : public DriverBase {
NoopDriver() noexcept;
~NoopDriver() noexcept override;
public:
static backend::Driver* create();
static Driver* create();
private:
backend::ShaderModel getShaderModel() const noexcept final;
ShaderModel getShaderModel() const noexcept final;
/*
* Driver interface
*/
template<typename T>
friend class backend::ConcreteDispatcher;
friend class ConcreteDispatcher;
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
UTILS_ALWAYS_INLINE inline void methodName(paramsDecl);
@@ -57,4 +57,4 @@ private:
} // namespace filament
#endif // TNT_FILAMENT_DRIVER_NOOPDRIVER_H
#endif // TNT_FILAMENT_BACKEND_NOOPDRIVER_H

View File

@@ -18,9 +18,9 @@
#include "noop/NoopDriver.h"
namespace filament {
namespace filament::backend {
backend::Driver* PlatformNoop::createDriver(void* const sharedGLContext) noexcept {
Driver* PlatformNoop::createDriver(void* const sharedGLContext) noexcept {
return NoopDriver::create();
}

View File

@@ -14,15 +14,15 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_NOOP_PLATFORM_NOOP_H
#define TNT_FILAMENT_DRIVER_NOOP_PLATFORM_NOOP_H
#ifndef TNT_FILAMENT_BACKEND_NOOP_PLATFORM_NOOP_H
#define TNT_FILAMENT_BACKEND_NOOP_PLATFORM_NOOP_H
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
namespace filament {
namespace filament::backend {
class PlatformNoop final : public backend::DefaultPlatform {
class PlatformNoop final : public DefaultPlatform {
public:
int getOSVersion() const noexcept final { return 0; }
@@ -31,9 +31,9 @@ public:
protected:
backend::Driver* createDriver(void* sharedContext) noexcept override;
Driver* createDriver(void* sharedContext) noexcept override;
};
} // namespace filament
#endif // TNT_FILAMENT_DRIVER_NOOP_PLATFORM_NOOP_H
#endif // TNT_FILAMENT_BACKEND_NOOP_PLATFORM_NOOP_H

View File

@@ -20,7 +20,7 @@
#include "private/backend/Driver.h"
namespace filament {
namespace filament::backend {
using namespace backend;
using namespace utils;
@@ -122,4 +122,4 @@ void assertFramebufferStatus(io::ostream& out, GLenum target, const char* functi
}
} // namespace GLUtils
} // namespace filament
} // namespace filament::backend

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_GLUTILS_H
#define TNT_FILAMENT_DRIVER_GLUTILS_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_GLUTILS_H
#define TNT_FILAMENT_BACKEND_OPENGL_GLUTILS_H
#include <utils/compiler.h>
#include <utils/Log.h>
@@ -29,7 +29,7 @@
#include "gl_headers.h"
namespace filament {
namespace filament::backend {
namespace GLUtils {
const char* getGLError(GLenum error) noexcept;
@@ -51,8 +51,8 @@ void assertFramebufferStatus(utils::io::ostream& out, GLenum target, const char*
# define CHECK_GL_FRAMEBUFFER_STATUS(out, target) { GLUtils::checkFramebufferStatus(out, target, __PRETTY_FUNCTION__, __LINE__); }
#endif
constexpr inline GLuint getComponentCount(backend::ElementType type) noexcept {
using ElementType = backend::ElementType;
constexpr inline GLuint getComponentCount(ElementType type) noexcept {
using ElementType = ElementType;
switch (type) {
case ElementType::BYTE:
case ElementType::UBYTE:
@@ -91,35 +91,35 @@ constexpr inline GLuint getComponentCount(backend::ElementType type) noexcept {
// Our enums to GLenum conversions
// ------------------------------------------------------------------------------------------------
constexpr inline GLbitfield getAttachmentBitfield(backend::TargetBufferFlags flags) noexcept {
constexpr inline GLbitfield getAttachmentBitfield(TargetBufferFlags flags) noexcept {
GLbitfield mask = 0;
if (any(flags & backend::TargetBufferFlags::COLOR_ALL)) {
if (any(flags & TargetBufferFlags::COLOR_ALL)) {
mask |= (GLbitfield)GL_COLOR_BUFFER_BIT;
}
if (any(flags & backend::TargetBufferFlags::DEPTH)) {
if (any(flags & TargetBufferFlags::DEPTH)) {
mask |= (GLbitfield)GL_DEPTH_BUFFER_BIT;
}
if (any(flags & backend::TargetBufferFlags::STENCIL)) {
if (any(flags & TargetBufferFlags::STENCIL)) {
mask |= (GLbitfield)GL_STENCIL_BUFFER_BIT;
}
return mask;
}
constexpr inline GLenum getBufferUsage(backend::BufferUsage usage) noexcept {
constexpr inline GLenum getBufferUsage(BufferUsage usage) noexcept {
switch (usage) {
case backend::BufferUsage::STATIC:
case BufferUsage::STATIC:
return GL_STATIC_DRAW;
case backend::BufferUsage::DYNAMIC:
case backend::BufferUsage::STREAM:
case BufferUsage::DYNAMIC:
case BufferUsage::STREAM:
return GL_DYNAMIC_DRAW;
}
}
constexpr inline GLenum getBufferBindingType(backend::BufferObjectBinding bindingType) noexcept {
constexpr inline GLenum getBufferBindingType(BufferObjectBinding bindingType) noexcept {
switch (bindingType) {
case backend::BufferObjectBinding::VERTEX:
case BufferObjectBinding::VERTEX:
return GL_ARRAY_BUFFER;
case backend::BufferObjectBinding::UNIFORM:
case BufferObjectBinding::UNIFORM:
return GL_UNIFORM_BUFFER;
}
}
@@ -128,8 +128,8 @@ constexpr inline GLboolean getNormalization(bool normalized) noexcept {
return GLboolean(normalized ? GL_TRUE : GL_FALSE);
}
constexpr inline GLenum getComponentType(backend::ElementType type) noexcept {
using ElementType = backend::ElementType;
constexpr inline GLenum getComponentType(ElementType type) noexcept {
using ElementType = ElementType;
switch (type) {
case ElementType::BYTE:
case ElementType::BYTE2:
@@ -173,8 +173,8 @@ constexpr inline GLenum getCubemapTarget(uint16_t layer) noexcept {
return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
}
constexpr inline GLenum getWrapMode(backend::SamplerWrapMode mode) noexcept {
using SamplerWrapMode = backend::SamplerWrapMode;
constexpr inline GLenum getWrapMode(SamplerWrapMode mode) noexcept {
using SamplerWrapMode = SamplerWrapMode;
switch (mode) {
case SamplerWrapMode::REPEAT:
return GL_REPEAT;
@@ -185,8 +185,8 @@ constexpr inline GLenum getWrapMode(backend::SamplerWrapMode mode) noexcept {
}
}
constexpr inline GLenum getTextureFilter(backend::SamplerMinFilter filter) noexcept {
using SamplerMinFilter = backend::SamplerMinFilter;
constexpr inline GLenum getTextureFilter(SamplerMinFilter filter) noexcept {
using SamplerMinFilter = SamplerMinFilter;
switch (filter) {
case SamplerMinFilter::NEAREST:
case SamplerMinFilter::LINEAR:
@@ -200,13 +200,13 @@ constexpr inline GLenum getTextureFilter(backend::SamplerMinFilter filter) noexc
}
}
constexpr inline GLenum getTextureFilter(backend::SamplerMagFilter filter) noexcept {
constexpr inline GLenum getTextureFilter(SamplerMagFilter filter) noexcept {
return GL_NEAREST + GLenum(filter);
}
constexpr inline GLenum getBlendEquationMode(backend::BlendEquation mode) noexcept {
using BlendEquation = backend::BlendEquation;
constexpr inline GLenum getBlendEquationMode(BlendEquation mode) noexcept {
using BlendEquation = BlendEquation;
switch (mode) {
case BlendEquation::ADD: return GL_FUNC_ADD;
case BlendEquation::SUBTRACT: return GL_FUNC_SUBTRACT;
@@ -216,8 +216,8 @@ constexpr inline GLenum getBlendEquationMode(backend::BlendEquation mode) noexce
}
}
constexpr inline GLenum getBlendFunctionMode(backend::BlendFunction mode) noexcept {
using BlendFunction = backend::BlendFunction;
constexpr inline GLenum getBlendFunctionMode(BlendFunction mode) noexcept {
using BlendFunction = BlendFunction;
switch (mode) {
case BlendFunction::ZERO: return GL_ZERO;
case BlendFunction::ONE: return GL_ONE;
@@ -233,13 +233,13 @@ constexpr inline GLenum getBlendFunctionMode(backend::BlendFunction mode) noexce
}
}
constexpr inline GLenum getTextureCompareMode(backend::SamplerCompareMode mode) noexcept {
return mode == backend::SamplerCompareMode::NONE ?
constexpr inline GLenum getTextureCompareMode(SamplerCompareMode mode) noexcept {
return mode == SamplerCompareMode::NONE ?
GL_NONE : GL_COMPARE_REF_TO_TEXTURE;
}
constexpr inline GLenum getTextureCompareFunc(backend::SamplerCompareFunc func) noexcept {
using SamplerCompareFunc = backend::SamplerCompareFunc;
constexpr inline GLenum getTextureCompareFunc(SamplerCompareFunc func) noexcept {
using SamplerCompareFunc = SamplerCompareFunc;
switch (func) {
case SamplerCompareFunc::LE: return GL_LEQUAL;
case SamplerCompareFunc::GE: return GL_GEQUAL;
@@ -252,12 +252,12 @@ constexpr inline GLenum getTextureCompareFunc(backend::SamplerCompareFunc func)
}
}
constexpr inline GLenum getDepthFunc(backend::SamplerCompareFunc func) noexcept {
constexpr inline GLenum getDepthFunc(SamplerCompareFunc func) noexcept {
return getTextureCompareFunc(func);
}
constexpr inline GLenum getFormat(backend::PixelDataFormat format) noexcept {
using PixelDataFormat = backend::PixelDataFormat;
constexpr inline GLenum getFormat(PixelDataFormat format) noexcept {
using PixelDataFormat = PixelDataFormat;
switch (format) {
case PixelDataFormat::R: return GL_RED;
case PixelDataFormat::R_INTEGER: return GL_RED_INTEGER;
@@ -274,8 +274,8 @@ constexpr inline GLenum getFormat(backend::PixelDataFormat format) noexcept {
}
}
constexpr inline GLenum getType(backend::PixelDataType type) noexcept {
using PixelDataType = backend::PixelDataType;
constexpr inline GLenum getType(PixelDataType type) noexcept {
using PixelDataType = PixelDataType;
switch (type) {
case PixelDataType::UBYTE: return GL_UNSIGNED_BYTE;
case PixelDataType::BYTE: return GL_BYTE;
@@ -292,8 +292,8 @@ constexpr inline GLenum getType(backend::PixelDataType type) noexcept {
}
}
constexpr inline GLenum getSwizzleChannel(backend::TextureSwizzle c) noexcept {
using TextureSwizzle = backend::TextureSwizzle;
constexpr inline GLenum getSwizzleChannel(TextureSwizzle c) noexcept {
using TextureSwizzle = TextureSwizzle;
switch (c) {
case TextureSwizzle::SUBSTITUTE_ZERO:
return GL_ZERO;
@@ -313,8 +313,8 @@ constexpr inline GLenum getSwizzleChannel(backend::TextureSwizzle c) noexcept {
// clang looses it on this one, and generates a huge jump table when
// inlined. So we don't mark it as inline (only constexpr) which solves the problem,
// strangely, when not inlined, clang simply generates an array lookup.
constexpr /* inline */ GLenum getInternalFormat(backend::TextureFormat format) noexcept {
using TextureFormat = backend::TextureFormat;
constexpr /* inline */ GLenum getInternalFormat(TextureFormat format) noexcept {
using TextureFormat = TextureFormat;
switch (format) {
// 8-bits per element
case TextureFormat::R8: return GL_R8;
@@ -530,6 +530,6 @@ inline unordered_string_set split(const char* spacedList) {
}
} // namespace GLUtils
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_GLUTILS_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_GLUTILS_H

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_NULLGLES_H
#define TNT_FILAMENT_DRIVER_NULLGLES_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_NULLGLES_H
#define TNT_FILAMENT_BACKEND_OPENGL_NULLGLES_H
/*
* This is used for debugging (stubbing out GLES calls)
@@ -27,7 +27,7 @@
*
*/
namespace filament {
namespace filament::backend {
namespace nullgles {
inline void glScissor(GLint, GLint, GLsizei, GLsizei) { }
@@ -81,6 +81,6 @@ inline GLenum glGetError() { return GL_NO_ERROR; }
// turn GLES calls defined above into no-ops
//using namespace nullgles;
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_NULLGLES_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_NULLGLES_H

View File

@@ -27,7 +27,7 @@
using namespace filament::math;
using namespace utils;
namespace filament {
namespace filament::backend {
static const char s_vertexES[] = R"SHADER(#version 300 es
in vec4 pos;
@@ -212,4 +212,4 @@ void OpenGLBlitter::State::restore() noexcept {
CHECK_GL_ERROR(utils::slog.e)
}
} // namespace filament
} // namespace filament::backend

View File

@@ -14,13 +14,13 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGLBLITTER_H
#define TNT_FILAMENT_DRIVER_OPENGLBLITTER_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGLBLITTER_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGLBLITTER_H
#include <utils/compiler.h>
#include "gl_headers.h"
namespace filament {
namespace filament::backend {
class OpenGLContext;
@@ -62,6 +62,6 @@ private:
GLuint mFBO{};
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_OPENGLBLITTER_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGLBLITTER_H

View File

@@ -22,7 +22,7 @@
using namespace utils;
namespace filament {
namespace filament::backend {
using namespace backend;

View File

@@ -30,11 +30,11 @@
#include <set>
#include <utility>
namespace filament {
namespace filament::backend {
class OpenGLContext {
public:
static constexpr const size_t MAX_TEXTURE_UNIT_COUNT = backend::MAX_SAMPLER_COUNT;
static constexpr const size_t MAX_TEXTURE_UNIT_COUNT = MAX_SAMPLER_COUNT;
static constexpr const size_t MAX_BUFFER_BINDINGS = 32;
typedef math::details::TVec4<GLint> vec4gli;
typedef math::details::TVec2<GLclampf> vec2glf;
@@ -51,7 +51,7 @@ public:
// The optional 32-bit handle to a GLVertexBuffer is necessary only if the referenced
// VertexBuffer supports buffer objects. If this is zero, then the VBO handles array is
// immutable.
backend::Handle<backend::HwVertexBuffer> vertexBufferWithObjects = {};
Handle<HwVertexBuffer> vertexBufferWithObjects = {};
// If this version number does not match vertexBufferWithObjects->bufferObjectsVersion,
// then the VAO needs to be updated.
@@ -70,7 +70,7 @@ public:
constexpr inline size_t getIndexForCap(GLenum cap) noexcept;
constexpr static inline size_t getIndexForBufferTarget(GLenum target) noexcept;
backend::ShaderModel getShaderModel() const noexcept { return mShaderModel; }
ShaderModel getShaderModel() const noexcept { return mShaderModel; }
inline void useProgram(GLuint program) noexcept;
@@ -256,7 +256,7 @@ public:
void resetProgram() noexcept { state.program.use = 0; }
private:
backend::ShaderModel mShaderModel;
ShaderModel mShaderModel;
// Try to keep the State structure sorted by data-access patterns
struct State {

View File

@@ -23,7 +23,7 @@
#include "OpenGLBlitter.h"
#include "OpenGLDriverFactory.h"
#include "OpenGLProgram.h"
#include "TimerQuery.h"
#include "OpenGLTimerQuery.h"
#include "OpenGLContext.h"
#include <utils/compiler.h>
@@ -61,17 +61,13 @@
using namespace filament::math;
using namespace utils;
namespace filament {
namespace backend {
namespace filament::backend {
Driver* OpenGLDriverFactory::create(
OpenGLPlatform* const platform, void* const sharedGLContext) noexcept {
return OpenGLDriver::create(platform, sharedGLContext);
}
} // namespace backend
using namespace backend;
using namespace GLUtils;
// ------------------------------------------------------------------------------------------------
@@ -92,12 +88,12 @@ Driver* OpenGLDriver::create(
// GLBufferObject : 24 many
// GLSync : 24 few
// GLTimerQuery : 32 few
// OpenGLProgram : 32 moderate
// GLRenderPrimitive : 48 many
// OpenGLProgram : 48 moderate
// -- less than or equal 64 bytes
// GLTexture : 72 moderate
// GLRenderTarget : 112 few
// GLStream : 168 few
// GLStream : 184 few
// GLVertexBuffer : 200 moderate
// -- less than or equal to 208 bytes
@@ -151,7 +147,8 @@ Driver* OpenGLDriver::create(
OpenGLDriver::DebugMarker::DebugMarker(OpenGLDriver& driver, const char* string) noexcept
: driver(driver) {
const char* const begin = string + sizeof("virtual void filament::OpenGLDriver::") - 1;
// FIXME: this is not safe nor portable
const char* const begin = string + sizeof("virtual void filament::backend::OpenGLDriver::") - 1;
const char* const end = strchr(begin, '(');
driver.pushGroupMarker(begin, end - begin);
}
@@ -188,14 +185,14 @@ OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform) noexcept
// timer queries are available
if (mContext.bugs.dont_use_timer_query && mPlatform.canCreateFence()) {
// however, they don't work well, revert to using fences if we can.
mTimerQueryImpl = new TimerQueryFence(mPlatform);
mTimerQueryImpl = new OpenGLTimerQueryFence(mPlatform);
} else {
mTimerQueryImpl = new TimerQueryNative(mContext);
}
mFrameTimeSupported = true;
} else if (mPlatform.canCreateFence()) {
// no timer queries, but we can use fences
mTimerQueryImpl = new TimerQueryFence(mPlatform);
mTimerQueryImpl = new OpenGLTimerQueryFence(mPlatform);
mFrameTimeSupported = true;
} else {
// no queries, no fences -- that's a problem
@@ -244,7 +241,7 @@ ShaderModel OpenGLDriver::getShaderModel() const noexcept {
// Change and track GL state
// ------------------------------------------------------------------------------------------------
void OpenGLDriver::bindSampler(GLuint unit, backend::SamplerParams params) noexcept {
void OpenGLDriver::bindSampler(GLuint unit, SamplerParams params) noexcept {
mContext.bindSampler(unit, getSampler(params));
}
@@ -254,9 +251,8 @@ void OpenGLDriver::bindTexture(GLuint unit, GLTexture const* t) noexcept {
}
void OpenGLDriver::useProgram(OpenGLProgram* p) noexcept {
mContext.useProgram(p->gl.program);
// set-up textures and samplers in the proper TMUs (as specified in setSamplers)
p->use(this);
p->use(this, mContext);
}
@@ -450,7 +446,7 @@ void OpenGLDriver::createRenderPrimitiveR(Handle<HwRenderPrimitive> rph, int) {
void OpenGLDriver::createProgramR(Handle<HwProgram> ph, Program&& program) {
DEBUG_MARKER()
construct<OpenGLProgram>(ph, this, program);
construct<OpenGLProgram>(ph, *this, std::move(program));
CHECK_GL_ERROR(utils::slog.e)
}
@@ -714,7 +710,7 @@ void OpenGLDriver::updateVertexArrayObject(GLRenderPrimitive* rp, GLVertexBuffer
}
}
void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo,
void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
GLRenderTarget const* rt, GLenum attachment) noexcept {
#if !defined(NDEBUG)
@@ -1010,7 +1006,7 @@ void OpenGLDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
uint32_t width,
uint32_t height,
uint8_t samples,
backend::MRT color,
MRT color,
TargetBufferInfo depth,
TargetBufferInfo stencil) {
DEBUG_MARKER()
@@ -1216,6 +1212,7 @@ void OpenGLDriver::destroyProgram(Handle<HwProgram> ph) {
DEBUG_MARKER()
if (ph) {
OpenGLProgram* p = handle_cast<OpenGLProgram*>(ph);
cancelRunAtNextPassOp(p);
destruct(ph, p);
}
}
@@ -1360,7 +1357,7 @@ Handle<HwStream> OpenGLDriver::createStreamAcquired() {
// called only once per frame. If the user pushes images to the same stream multiple times in a
// single frame, we emit a warning and honor only the final image, but still invoke all callbacks.
void OpenGLDriver::setAcquiredImage(Handle<HwStream> sh, void* hwbuffer,
backend::CallbackHandler* handler, backend::StreamCallback cb, void* userData) {
CallbackHandler* handler, StreamCallback cb, void* userData) {
GLStream* glstream = handle_cast<GLStream*>(sh);
if (glstream->user_thread.pending.image) {
scheduleRelease(glstream->user_thread.pending);
@@ -1684,7 +1681,7 @@ void OpenGLDriver::updateBufferObject(
CHECK_GL_ERROR(utils::slog.e)
}
void OpenGLDriver::updateBuffer(GLBufferObject* buffer, backend::BufferDescriptor const& p,
void OpenGLDriver::updateBuffer(GLBufferObject* buffer, BufferDescriptor const& p,
uint32_t byteOffset, uint32_t alignment) noexcept {
assert_invariant(buffer->byteCount >= p.size);
assert_invariant(buffer->gl.id);
@@ -2223,6 +2220,9 @@ SyncStatus OpenGLDriver::getSyncStatus(Handle<HwSync> sh) {
void OpenGLDriver::beginRenderPass(Handle<HwRenderTarget> rth,
const RenderPassParams& params) {
DEBUG_MARKER()
executeRenderPassOps();
auto& gl = mContext;
mRenderPassTarget = rth;
@@ -2345,7 +2345,7 @@ void OpenGLDriver::nextSubpass(int) {}
void OpenGLDriver::resolvePass(ResolveAction action, GLRenderTarget const* rt,
backend::TargetBufferFlags discardFlags) noexcept {
TargetBufferFlags discardFlags) noexcept {
assert_invariant(rt->gl.fbo_read);
auto& gl = mContext;
const TargetBufferFlags resolve = rt->gl.resolve & ~discardFlags;
@@ -2928,6 +2928,25 @@ void OpenGLDriver::executeEveryNowAndThenOps() noexcept {
}
}
void OpenGLDriver::runAtNextRenderPass(void* token, std::function<void()> fn) noexcept {
assert_invariant(mRunAtNextRenderPassOps.find(token) == mRunAtNextRenderPassOps.end());
mRunAtNextRenderPassOps[token] = std::move(fn);
}
void OpenGLDriver::cancelRunAtNextPassOp(void* token) noexcept {
mRunAtNextRenderPassOps.erase(token);
}
void OpenGLDriver::executeRenderPassOps() noexcept {
auto& ops = mRunAtNextRenderPassOps;
if (!ops.empty()) {
for (auto& item: ops) {
item.second();
}
ops.clear();
}
}
// ------------------------------------------------------------------------------------------------
// Rendering ops
// ------------------------------------------------------------------------------------------------
@@ -2956,12 +2975,12 @@ void OpenGLDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) {
}
void OpenGLDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch,
backend::FrameScheduledCallback callback, void* user) {
FrameScheduledCallback callback, void* user) {
}
void OpenGLDriver::setFrameCompletedCallback(Handle<HwSwapChain> sch,
backend::FrameCompletedCallback callback, void* user) {
FrameCompletedCallback callback, void* user) {
}
@@ -3205,6 +3224,6 @@ void OpenGLDriver::draw(PipelineState state, Handle<HwRenderPrimitive> rph, uint
}
// explicit instantiation of the Dispatcher
template class backend::ConcreteDispatcher<OpenGLDriver>;
template class ConcreteDispatcher<OpenGLDriver>;
} // namespace filament
} // namespace filament::backend

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGLDRIVER_H
#define TNT_FILAMENT_DRIVER_OPENGLDRIVER_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGLDRIVER_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGLDRIVER_H
#include "private/backend/Driver.h"
#include "DriverBase.h"
@@ -39,24 +39,22 @@
# define FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB 4
#endif
namespace filament {
namespace filament::backend {
namespace backend {
class OpenGLPlatform;
class PixelBufferDescriptor;
struct TargetBufferInfo;
} // namespace backend
class OpenGLProgram;
class OpenGLBlitter;
class TimerQueryInterface;
class OpenGLTimerQueryInterface;
class OpenGLDriver final : public backend::DriverBase {
inline explicit OpenGLDriver(backend::OpenGLPlatform* platform) noexcept;
class OpenGLDriver final : public DriverBase {
inline explicit OpenGLDriver(OpenGLPlatform* platform) noexcept;
~OpenGLDriver() noexcept final;
public:
static backend::Driver* create(backend::OpenGLPlatform* platform, void* sharedGLContext) noexcept;
static Driver* create(OpenGLPlatform* platform, void* sharedGLContext) noexcept;
class DebugMarker {
OpenGLDriver& driver;
@@ -67,10 +65,10 @@ public:
// OpenGLDriver specific fields
struct GLBufferObject : public backend::HwBufferObject {
struct GLBufferObject : public HwBufferObject {
using HwBufferObject::HwBufferObject;
GLBufferObject(uint32_t size,
backend::BufferObjectBinding bindingType, backend::BufferUsage usage) noexcept
BufferObjectBinding bindingType, BufferUsage usage) noexcept
: HwBufferObject(size), usage(usage) {
gl.binding = GLUtils::getBufferBindingType(bindingType);
}
@@ -80,34 +78,34 @@ public:
} gl;
uint32_t base = 0;
uint32_t size = 0;
backend::BufferUsage usage = {};
BufferUsage usage = {};
};
struct GLVertexBuffer : public backend::HwVertexBuffer {
struct GLVertexBuffer : public HwVertexBuffer {
using HwVertexBuffer::HwVertexBuffer;
struct {
// 4 * MAX_VERTEX_ATTRIBUTE_COUNT bytes
std::array<GLuint, backend::MAX_VERTEX_ATTRIBUTE_COUNT> buffers{};
std::array<GLuint, MAX_VERTEX_ATTRIBUTE_COUNT> buffers{};
} gl;
};
struct GLIndexBuffer : public backend::HwIndexBuffer {
struct GLIndexBuffer : public HwIndexBuffer {
using HwIndexBuffer::HwIndexBuffer;
struct {
GLuint buffer{};
} gl;
};
struct GLSamplerGroup : public backend::HwSamplerGroup {
struct GLSamplerGroup : public HwSamplerGroup {
using HwSamplerGroup::HwSamplerGroup;
};
struct GLRenderPrimitive : public backend::HwRenderPrimitive {
struct GLRenderPrimitive : public HwRenderPrimitive {
using HwRenderPrimitive::HwRenderPrimitive;
OpenGLContext::RenderPrimitive gl;
};
struct GLTexture : public backend::HwTexture {
struct GLTexture : public HwTexture {
using HwTexture::HwTexture;
struct GL {
GL() noexcept : imported(false), sidecarSamples(1), reserved(0) {}
@@ -130,7 +128,7 @@ public:
void* platformPImpl = nullptr;
};
struct GLTimerQuery : public backend::HwTimerQuery {
struct GLTimerQuery : public HwTimerQuery {
struct State {
std::atomic<uint64_t> elapsed{};
std::atomic_bool available{};
@@ -143,12 +141,12 @@ public:
std::atomic<uint64_t> elapsed{};
};
struct GLStream : public backend::HwStream {
struct GLStream : public HwStream {
static constexpr size_t ROUND_ROBIN_TEXTURE_COUNT = 3; // 3 maximum
using HwStream::HwStream;
struct Info {
// storage for the read/write textures below
backend::Platform::ExternalTexture* ets = nullptr;
Platform::ExternalTexture* ets = nullptr;
GLuint width = 0;
GLuint height = 0;
};
@@ -177,27 +175,27 @@ public:
Info infos[ROUND_ROBIN_TEXTURE_COUNT]; // 48 bytes
int64_t timestamp = 0;
uint8_t cur = 0;
backend::AcquiredImage acquired;
backend::AcquiredImage pending;
AcquiredImage acquired;
AcquiredImage pending;
} user_thread;
};
struct GLRenderTarget : public backend::HwRenderTarget {
struct GLRenderTarget : public HwRenderTarget {
using HwRenderTarget::HwRenderTarget;
struct {
// field ordering to optimize size on 64-bits
GLTexture* color[backend::MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT];
GLTexture* color[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT];
GLTexture* depth;
GLTexture* stencil;
GLuint fbo = 0;
mutable GLuint fbo_read = 0;
mutable backend::TargetBufferFlags resolve = backend::TargetBufferFlags::NONE; // attachments in fbo_draw to resolve
mutable TargetBufferFlags resolve = TargetBufferFlags::NONE; // attachments in fbo_draw to resolve
uint8_t samples = 1;
} gl;
backend::TargetBufferFlags targets = {};
TargetBufferFlags targets = {};
};
struct GLSync : public backend::HwSync {
struct GLSync : public HwSync {
using HwSync::HwSync;
struct State {
std::atomic<GLenum> status{ GL_TIMEOUT_EXPIRED };
@@ -216,14 +214,14 @@ private:
OpenGLContext& getContext() noexcept { return mContext; }
backend::ShaderModel getShaderModel() const noexcept final;
ShaderModel getShaderModel() const noexcept final;
/*
* Driver interface
*/
template<typename T>
friend class backend::ConcreteDispatcher;
friend class ConcreteDispatcher;
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
UTILS_ALWAYS_INLINE inline void methodName(paramsDecl);
@@ -240,22 +238,22 @@ private:
// Memory management...
// See also the explicit template instantiation in HandleAllocator.cpp
backend::HandleAllocatorGL mHandleAllocator;
HandleAllocatorGL mHandleAllocator;
template<typename D, typename ... ARGS>
backend::Handle<D> initHandle(ARGS&& ... args) noexcept {
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(backend::Handle<B> const& handle, ARGS&& ... args) noexcept {
construct(Handle<B> const& handle, ARGS&& ... args) noexcept {
return mHandleAllocator.destroyAndConstruct<D, B>(handle, std::forward<ARGS>(args) ...);
}
template<typename B, typename D,
typename = typename std::enable_if<std::is_base_of<B, D>::value, D>::type>
void destruct(backend::Handle<B>& handle, D const* p) noexcept {
void destruct(Handle<B>& handle, D const* p) noexcept {
return mHandleAllocator.deallocate(handle, p);
}
@@ -263,7 +261,7 @@ private:
typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(backend::Handle<B>& handle) noexcept {
handle_cast(Handle<B>& handle) noexcept {
return mHandleAllocator.handle_cast<Dp, B>(handle);
}
@@ -271,7 +269,7 @@ private:
inline typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(backend::Handle<B> const& handle) noexcept {
handle_cast(Handle<B> const& handle) noexcept {
return mHandleAllocator.handle_cast<Dp, B>(handle);
}
@@ -287,11 +285,11 @@ private:
void updateVertexArrayObject(GLRenderPrimitive* rp, GLVertexBuffer const* vb);
void framebufferTexture(backend::TargetBufferInfo const& binfo,
void framebufferTexture(TargetBufferInfo const& binfo,
GLRenderTarget const* rt, GLenum attachment) noexcept;
void setRasterStateSlow(backend::RasterState rs) noexcept;
void setRasterState(backend::RasterState rs) noexcept {
void setRasterStateSlow(RasterState rs) noexcept;
void setRasterState(RasterState rs) noexcept {
mRenderPassColorWrite |= rs.colorWrite;
mRenderPassDepthWrite |= rs.depthWrite;
if (UTILS_UNLIKELY(rs != mRasterState)) {
@@ -303,13 +301,13 @@ private:
uint32_t level,
uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
uint32_t width, uint32_t height, uint32_t depth,
backend::PixelBufferDescriptor&& data, backend::FaceOffsets const* faceOffsets);
PixelBufferDescriptor&& data, FaceOffsets const* faceOffsets);
void setCompressedTextureData(GLTexture* t,
uint32_t level,
uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
uint32_t width, uint32_t height, uint32_t depth,
backend::PixelBufferDescriptor&& data, backend::FaceOffsets const* faceOffsets);
PixelBufferDescriptor&& data, FaceOffsets const* faceOffsets);
void renderBufferStorage(GLuint rbo, GLenum internalformat, uint32_t width,
uint32_t height, uint8_t samples) const noexcept;
@@ -320,16 +318,16 @@ private:
/* State tracking GL wrappers... */
void bindTexture(GLuint unit, GLTexture const* t) noexcept;
void bindSampler(GLuint unit, backend::SamplerParams params) noexcept;
void bindSampler(GLuint unit, SamplerParams params) noexcept;
inline void useProgram(OpenGLProgram* p) noexcept;
enum class ResolveAction { LOAD, STORE };
void resolvePass(ResolveAction action, GLRenderTarget const* rt,
backend::TargetBufferFlags discardFlags) noexcept;
TargetBufferFlags discardFlags) noexcept;
GLuint getSamplerSlow(backend::SamplerParams sp) const noexcept;
GLuint getSamplerSlow(SamplerParams sp) const noexcept;
inline GLuint getSampler(backend::SamplerParams sp) const noexcept {
inline GLuint getSampler(SamplerParams sp) const noexcept {
assert_invariant(!sp.padding0);
assert_invariant(!sp.padding1);
assert_invariant(!sp.padding2);
@@ -341,29 +339,29 @@ private:
return pos->second;
}
const std::array<backend::HwSamplerGroup*, backend::Program::BINDING_COUNT>& getSamplerBindings() const {
const std::array<HwSamplerGroup*, Program::BINDING_COUNT>& getSamplerBindings() const {
return mSamplerBindings;
}
using AttachmentArray = std::array<GLenum, backend::MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT + 2>;
using AttachmentArray = std::array<GLenum, MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT + 2>;
static GLsizei getAttachments(AttachmentArray& attachments,
GLRenderTarget const* rt, backend::TargetBufferFlags buffers) noexcept;
GLRenderTarget const* rt, TargetBufferFlags buffers) noexcept;
backend::RasterState mRasterState;
RasterState mRasterState;
// state required to represent the current render pass
backend::Handle<backend::HwRenderTarget> mRenderPassTarget;
backend::RenderPassParams mRenderPassParams;
Handle<HwRenderTarget> mRenderPassTarget;
RenderPassParams mRenderPassParams;
GLboolean mRenderPassColorWrite{};
GLboolean mRenderPassDepthWrite{};
void clearWithRasterPipe(backend::TargetBufferFlags clearFlags,
void clearWithRasterPipe(TargetBufferFlags clearFlags,
math::float4 const& linearColor, GLfloat depth, GLint stencil) noexcept;
void setViewportScissor(backend::Viewport const& viewportScissor) noexcept;
void setViewportScissor(Viewport const& viewportScissor) noexcept;
// sampler buffer binding points (nullptr if not used)
std::array<backend::HwSamplerGroup*, backend::Program::BINDING_COUNT> mSamplerBindings = {}; // 8 pointers
std::array<HwSamplerGroup*, Program::BINDING_COUNT> mSamplerBindings = {}; // 8 pointers
mutable tsl::robin_map<uint32_t, GLuint> mSamplerMap;
mutable std::vector<GLTexture*> mExternalStreams;
@@ -372,12 +370,12 @@ private:
void detachStream(GLTexture* t) noexcept;
void replaceStream(GLTexture* t, GLStream* stream) noexcept;
backend::OpenGLPlatform& mPlatform;
OpenGLPlatform& mPlatform;
OpenGLBlitter* mOpenGLBlitter = nullptr;
void updateStreamTexId(GLTexture* t, backend::DriverApi* driver) noexcept;
void updateStreamAcquired(GLTexture* t, backend::DriverApi* driver) noexcept;
void updateBuffer(GLBufferObject* buffer, backend::BufferDescriptor const& p,
void updateStreamTexId(GLTexture* t, DriverApi* driver) noexcept;
void updateStreamAcquired(GLTexture* t, DriverApi* driver) noexcept;
void updateBuffer(GLBufferObject* buffer, BufferDescriptor const& p,
uint32_t byteOffset, uint32_t alignment = 16) noexcept;
void updateTextureLodRange(GLTexture* texture, int8_t targetLevel) noexcept;
@@ -393,14 +391,19 @@ private:
void executeEveryNowAndThenOps() noexcept;
std::vector<std::function<bool()>> mEveryNowAndThenOps;
void runAtNextRenderPass(void* token, std::function<void()> fn) noexcept;
void executeRenderPassOps() noexcept;
void cancelRunAtNextPassOp(void* token) noexcept;
tsl::robin_map<void*, std::function<void()>> mRunAtNextRenderPassOps;
// timer query implementation
TimerQueryInterface* mTimerQueryImpl = nullptr;
OpenGLTimerQueryInterface* mTimerQueryImpl = nullptr;
bool mFrameTimeSupported = false;
};
// ------------------------------------------------------------------------------------------------
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_OPENGLDRIVER_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGLDRIVER_H

View File

@@ -14,21 +14,19 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGLDRIVERFACTORY_H
#define TNT_FILAMENT_DRIVER_OPENGLDRIVERFACTORY_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGLDRIVERFACTORY_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGLDRIVERFACTORY_H
namespace filament {
namespace filament::backend {
namespace backend {
class OpenGLPlatform;
class Driver;
class OpenGLDriverFactory {
public:
static backend::Driver* create(backend::OpenGLPlatform* platform, void* sharedGLContext) noexcept;
static Driver* create(OpenGLPlatform* platform, void* sharedGLContext) noexcept;
};
} // namespace backend
} // namespace filament
} // namespace filament::backend
#endif //TNT_FILAMENT_DRIVER_OPENGLDRIVERFACTORY_H
#endif //TNT_FILAMENT_BACKEND_OPENGL_OPENGLDRIVERFACTORY_H

View File

@@ -18,8 +18,7 @@
#include "OpenGLDriverFactory.h"
namespace filament {
namespace backend {
namespace filament::backend {
OpenGLPlatform::~OpenGLPlatform() noexcept = default;
@@ -27,5 +26,4 @@ Driver* OpenGLPlatform::createDefaultDriver(OpenGLPlatform* platform, void* shar
return OpenGLDriverFactory::create(platform, sharedContext);
}
} // namespace backend
} // namespace filament
} // namespace filament::backend

View File

@@ -27,51 +27,104 @@
#include <ctype.h>
namespace filament {
namespace filament::backend {
using namespace filament::math;
using namespace utils;
using namespace backend;
static void logCompilationError(utils::io::ostream& out,
backend::Program::Shader shaderType, const char* name,
GLuint shaderId, std::string_view source) noexcept;
Program::Shader shaderType, const char* name,
GLuint shaderId, CString const& sourceCode) noexcept;
static void logProgramLinkError(utils::io::ostream& out,
const char* name, GLuint program) noexcept;
OpenGLProgram::OpenGLProgram(OpenGLDriver* gl, const Program& programBuilder) noexcept
: HwProgram(programBuilder.getName()), mIsValid(false) {
OpenGLProgram::OpenGLProgram() noexcept
: mInitialized(false), mValid(true), mLazyInitializationData(nullptr) {
}
using Shader = Program::Shader;
OpenGLProgram::OpenGLProgram(OpenGLDriver& gld, Program&& programBuilder) noexcept
: HwProgram(programBuilder.getName()),
mInitialized(false), mValid(true),
mLazyInitializationData{ new(LazyInitializationData) } {
const auto& shadersSource = programBuilder.getShadersSource();
OpenGLContext& context = gl->getContext();
OpenGLContext& context = gld.getContext();
mLazyInitializationData->uniformBlockInfo = std::move(programBuilder.getUniformBlockInfo());
mLazyInitializationData->samplerGroupInfo = std::move(programBuilder.getSamplerGroupInfo());
// this cannot fail because we check compilation status after linking the program
// shaders[] is filled with id of shader stages present.
OpenGLProgram::compileShaders(context, programBuilder.getShadersSource(),
gl.shaders, mLazyInitializationData->shaderSourceCode);
gld.runAtNextRenderPass(this, [this]() {
// by this point we must not have a GL program
assert_invariant(!gl.program);
// we also can't be in the initialized state
assert_invariant(!mInitialized);
// we must have our lazy initialization data
assert_invariant(mLazyInitializationData);
// link the program, this also cannot fail because status is checked later.
gl.program = OpenGLProgram::linkProgram(gl.shaders);
});
}
OpenGLProgram::~OpenGLProgram() noexcept {
if (!mInitialized) {
// mLazyInitializationData is aliased with mIndicesRuns
delete mLazyInitializationData;
}
const GLuint program = gl.program;
UTILS_NOUNROLL
for (GLuint shader: gl.shaders) {
if (shader) {
if (program) {
glDetachShader(program, shader);
}
glDeleteShader(shader);
}
}
if (program) {
glDeleteProgram(program);
}
}
/*
* Compile shaders in the ShaderSource. This cannot fail because compilation failures are not
* checked until after the program is linked.
* This always returns the GL shader IDs or zero a shader stage is not present.
*/
void OpenGLProgram::compileShaders(OpenGLContext& context,
Program::ShaderSource shadersSource,
GLuint shaderIds[Program::SHADER_TYPE_COUNT],
std::array<CString, Program::SHADER_TYPE_COUNT>& outShaderSourceCode) noexcept {
// build all shaders
#pragma nounroll
UTILS_NOUNROLL
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
Program::Shader type = static_cast<Program::Shader>(i);
GLenum glShaderType;
Shader type = (Shader)i;
switch (type) {
case Shader::VERTEX:
case Program::Shader::VERTEX:
glShaderType = GL_VERTEX_SHADER;
break;
case Shader::FRAGMENT:
case Program::Shader::FRAGMENT:
glShaderType = GL_FRAGMENT_SHADER;
break;
}
if (!shadersSource[i].empty()) {
GLint status;
Program::ShaderBlob shader = shadersSource[i];
if (UTILS_LIKELY(!shadersSource[i].empty())) {
Program::ShaderBlob const& shader = shadersSource[i];
std::string_view shaderView(reinterpret_cast<const char*>(shader.data()), shader.size());
std::string temp;
std::string_view shaderView((const char*)shader.data(), shader.size());
if (!context.ext.GOOGLE_cpp_style_line_directive) {
// If usages of the Google-style line directive are present, remove them, as some
// drivers don't allow the quotation marks.
if (UTILS_UNLIKELY(requestsGoogleLineDirectivesExtension(shaderView.data(), shaderView.size()))) {
if (UTILS_UNLIKELY(requestsGoogleLineDirectivesExtension(
shaderView.data(), shaderView.size()))) {
temp = shaderView; // copy string
removeGoogleLineDirectives(temp.data(), temp.size()); // length is unaffected
shaderView = temp;
@@ -136,159 +189,179 @@ highp uint packHalf2x16(vec2 v) {
const GLint length = (GLint)shaderView.length();
glShaderSource(shaderId, 1, &source, &length);
glCompileShader(shaderId);
#ifndef NDEBUG
outShaderSourceCode[i] = { source, static_cast<size_t>(length) };
#endif
}
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &status);
if (UTILS_UNLIKELY(status != GL_TRUE)) {
logCompilationError(slog.e, type,
programBuilder.getName().c_str_safe(), shaderId, shaderView);
glDeleteShader(shaderId);
return;
}
this->gl.shaders[i] = shaderId;
mValidShaderSet |= 1U << i;
shaderIds[i] = shaderId;
}
}
// we need at least a vertex and fragment program
const uint8_t validShaderSet = mValidShaderSet;
const uint8_t mask = VERTEX_SHADER_BIT | FRAGMENT_SHADER_BIT;
if (UTILS_LIKELY((mValidShaderSet & mask) == mask)) {
GLint status;
GLuint program = glCreateProgram();
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
if (validShaderSet & (1U << i)) {
glAttachShader(program, this->gl.shaders[i]);
}
}
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (UTILS_UNLIKELY(status != GL_TRUE)) {
logProgramLinkError(slog.e, programBuilder.getName().c_str_safe(), program);
glDeleteProgram(program);
return;
}
this->gl.program = program;
// Associate each UniformBlock in the program to a known binding.
auto const& uniformBlockInfo = programBuilder.getUniformBlockInfo();
#pragma nounroll
for (GLuint binding = 0, n = uniformBlockInfo.size(); binding < n; binding++) {
auto const& name = uniformBlockInfo[binding];
if (!name.empty()) {
GLint index = glGetUniformBlockIndex(program, name.c_str());
if (index >= 0) {
glUniformBlockBinding(program, GLuint(index), binding);
}
CHECK_GL_ERROR(utils::slog.e)
}
}
if (programBuilder.hasSamplers()) {
// if we have samplers, we need to do a bit of extra work
// activate this program so we can set all its samplers once and for all (glUniform1i)
context.useProgram(program);
auto const& samplerGroupInfo = programBuilder.getSamplerGroupInfo();
auto& indicesRun = mIndicesRuns;
uint8_t numUsedBindings = 0;
uint8_t tmu = 0;
#pragma nounroll
for (size_t i = 0, c = samplerGroupInfo.size(); i < c; i++) {
auto const& groupInfo = samplerGroupInfo[i];
auto const& samplers = groupInfo.samplers;
if (!samplers.empty()) {
// Cache the sampler uniform locations for each interface block
BlockInfo& info = mBlockInfos[numUsedBindings];
info.binding = uint8_t(i);
uint8_t count = 0;
for (uint8_t j = 0, m = uint8_t(samplers.size()); j < m; ++j) {
// find its location and associate a TMU to it
GLint loc = glGetUniformLocation(program, samplers[j].name.c_str());
if (loc >= 0) {
glUniform1i(loc, tmu);
indicesRun[tmu] = j;
count++;
tmu++;
} else {
// glGetUniformLocation could fail if the uniform is not used
// in the program. We should just ignore the error in that case.
}
}
if (count > 0) {
numUsedBindings++;
info.count = uint8_t(count - 1);
}
}
}
mUsedBindingsCount = numUsedBindings;
}
mIsValid = true;
}
// Failing to compile a program can't be fatal, because this will happen a lot in
// the material tools. We need to have a better way to handle these errors and
// return to the editor. Also note the early "return" statements in this function.
if (UTILS_UNLIKELY(!isValid())) {
PANIC_LOG("Failed to compile GLSL program.");
}
}
OpenGLProgram::~OpenGLProgram() noexcept {
const size_t validShaderSet = mValidShaderSet;
const bool isValid = mIsValid;
GLuint program = gl.program;
if (validShaderSet) {
UTILS_NOUNROLL
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
if (validShaderSet & (1U << i)) {
const GLuint shader = gl.shaders[i];
if (isValid) {
glDetachShader(program, shader);
}
glDeleteShader(shader);
}
/*
* Create a program from the given shader IDs and links it. This cannot fail because errors
* are checked later. This always returns a valid GL program ID (which doesn't mean the
* program itself is valid).
*/
GLuint OpenGLProgram::linkProgram(const GLuint shaderIds[Program::SHADER_TYPE_COUNT]) noexcept {
GLuint program = glCreateProgram();
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
if (shaderIds[i]) {
glAttachShader(program, shaderIds[i]);
}
}
if (isValid) {
glDeleteProgram(program);
glLinkProgram(program);
return program;
}
/*
* Checks a program link status and logs errors and frees resources on failure.
* Returns true on success.
*/
bool OpenGLProgram::checkProgramStatus(const char* name,
GLuint& program, GLuint shaderIds[Program::SHADER_TYPE_COUNT],
std::array<CString, 2> const& shaderSourceCode) noexcept {
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (UTILS_LIKELY(status == GL_TRUE)) {
return true;
}
// only if the link fails, we check the compilation status
UTILS_NOUNROLL
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
const Program::Shader type = static_cast<Program::Shader>(i);
const GLuint shader = shaderIds[i];
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
logCompilationError(slog.e, type, name, shader, shaderSourceCode[i]);
}
glDetachShader(program, shader);
glDeleteShader(shader);
shaderIds[i] = 0;
}
// log the link error as well
logProgramLinkError(slog.e, name, program);
glDeleteProgram(program);
program = 0;
return false;
}
void OpenGLProgram::initialize(OpenGLContext& context) {
// by this point we must have a GL program
assert_invariant(gl.program);
// we also can't be in the initialized state
assert_invariant(!mInitialized);
// we must have our lazy initialization data
assert_invariant(mLazyInitializationData);
// we must copy mLazyInitializationData locally because it is aliased with mIndicesRuns
auto* const initializationData = mLazyInitializationData;
// check status of program linking and shader compilation, logs error and free all resources
// in case of error.
mValid = OpenGLProgram::checkProgramStatus(name.c_str_safe(),
gl.program, gl.shaders, initializationData->shaderSourceCode);
if (mValid) {
initializeProgramState(context, gl.program,
initializationData->uniformBlockInfo,
initializationData->samplerGroupInfo);
}
// and destroy all temporary init data
delete initializationData;
// mInitialized means mLazyInitializationData is no more valid
mInitialized = true;
}
/*
* Initializes our internal state from a valid program. This must only be called after
* checkProgramStatus() has been successfully called.
*/
void OpenGLProgram::initializeProgramState(OpenGLContext& context, GLuint program,
Program::UniformBlockInfo const& uniformBlockInfo,
Program::SamplerGroupInfo const& samplerGroupInfo) noexcept {
// Associate each UniformBlock in the program to a known binding.
UTILS_NOUNROLL
for (GLuint binding = 0, n = uniformBlockInfo.size(); binding < n; binding++) {
auto const& name = uniformBlockInfo[binding];
if (!name.empty()) {
GLint index = glGetUniformBlockIndex(program, name.c_str());
if (index >= 0) {
glUniformBlockBinding(program, GLuint(index), binding);
}
CHECK_GL_ERROR(utils::slog.e)
}
}
uint8_t usedBindingCount = 0;
uint8_t tmu = 0;
UTILS_NOUNROLL
for (size_t i = 0, c = samplerGroupInfo.size(); i < c; i++) {
auto const& samplers = samplerGroupInfo[i].samplers;
if (samplers.empty()) {
// this binding point doesn't have any samplers, skip it.
continue;
}
// keep this in the loop, so we skip it in the rare case a program doesn't have
// sampler. The context cache will prevent repeated calls to GL.
context.useProgram(program);
bool atLeastOneSamplerUsed = false;
UTILS_NOUNROLL
for (const Program::Sampler& sampler: samplers) {
// find its location and associate a TMU to it
GLint loc = glGetUniformLocation(program, sampler.name.c_str());
if (loc >= 0) {
// this can fail if the program doesn't use this sampler
glUniform1i(loc, tmu);
atLeastOneSamplerUsed = true;
}
tmu++;
}
// if this program doesn't use any sampler from this SamplerGroup, just cancel the
// whole group.
if (atLeastOneSamplerUsed) {
// Cache the sampler uniform locations for each interface block
mUsedBindingPoints[usedBindingCount] = i;
usedBindingCount++;
} else {
tmu -= samplers.size();
}
}
mUsedBindingsCount = usedBindingCount;
}
void OpenGLProgram::updateSamplers(OpenGLDriver* gld) noexcept {
using GLTexture = OpenGLDriver::GLTexture;
// cache a few member variable locally, outside of the loop
OpenGLContext& glc = gld->getContext();
const bool anisotropyWorkaround = glc.ext.EXT_texture_filter_anisotropic &&
glc.bugs.texture_filter_anisotropic_broken_on_sampler;
auto const& UTILS_RESTRICT samplerBindings = gld->getSamplerBindings();
auto const& UTILS_RESTRICT indicesRun = mIndicesRuns;
auto const& UTILS_RESTRICT blockInfos = mBlockInfos;
UTILS_ASSUME(mUsedBindingsCount > 0);
for (uint8_t i = 0, tmu = 0, n = mUsedBindingsCount; i < n; i++) {
BlockInfo blockInfo = blockInfos[i];
HwSamplerGroup const * const UTILS_RESTRICT hwsb = samplerBindings[blockInfo.binding];
if (UTILS_UNLIKELY(!hwsb)) {
tmu += blockInfo.count + 1;
continue;
}
SamplerGroup const& UTILS_RESTRICT sb = *(hwsb->sb);
SamplerGroup::Sampler const* const UTILS_RESTRICT samplers = sb.getSamplers();
for (uint8_t j = 0, m = blockInfo.count ; j <= m; ++j, ++tmu) { // "<=" on purpose here
const uint8_t index = indicesRun[tmu];
assert_invariant(index < sb.getSize());
Handle<HwTexture> th = samplers[index].t;
if (UTILS_UNLIKELY(!th)) {
#ifndef NDEBUG
slog.w << "In material " << name.c_str()
<< ": no texture bound to unit " << +index << io::endl;
// cache a few member variable locally, outside the loop
OpenGLContext& context = gld->getContext();
#if defined(GL_EXT_texture_filter_anisotropic)
const bool anisotropyWorkaround = context.ext.EXT_texture_filter_anisotropic &&
context.bugs.texture_filter_anisotropic_broken_on_sampler;
#endif
auto const& UTILS_RESTRICT samplerBindings = gld->getSamplerBindings();
auto const& UTILS_RESTRICT usedBindingPoints = mUsedBindingPoints;
for (uint8_t i = 0, tmu = 0, n = mUsedBindingsCount; i < n; i++) {
const auto binding = usedBindingPoints[i];
HwSamplerGroup const * const hwsb = samplerBindings[binding];
assert_invariant(hwsb);
SamplerGroup const& sb = *(hwsb->sb);
SamplerGroup::Sampler const* const samplers = sb.getSamplers();
for (uint8_t j = 0, m = sb.getSize(); j < m; ++j, ++tmu) { // "<=" on purpose here
Handle<HwTexture> th = samplers[j].t;
if (!th) {
// this happens if the program doesn't use all samplers of a sampler group,
// which is not an error.
continue;
}
@@ -299,7 +372,7 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* gld) noexcept {
t->gl.fence = nullptr;
}
SamplerParams params{ samplers[index].s };
SamplerParams params{ samplers[j].s };
if (UTILS_UNLIKELY(t->target == SamplerType::SAMPLER_EXTERNAL)) {
// From OES_EGL_image_external spec:
// "The default s and t wrap modes are CLAMP_TO_EDGE and it is an INVALID_ENUM
@@ -316,9 +389,9 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* gld) noexcept {
&& params.filterMag != SamplerMagFilter::NEAREST
&& params.filterMin != SamplerMinFilter::NEAREST
&& params.filterMin != SamplerMinFilter::NEAREST_MIPMAP_NEAREST) {
slog.w << "In material " << name.c_str()
slog.w << "In program " << name.c_str()
<< ": depth texture used with filtering sampler, tmu = "
<< +index << io::endl;
<< +tmu << io::endl;
}
#endif
gld->bindTexture(tmu, t);
@@ -331,7 +404,7 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* gld) noexcept {
// The texture is already bound here.
GLfloat anisotropy = float(1u << params.anisotropyLog2);
glTexParameterf(t->gl.target, GL_TEXTURE_MAX_ANISOTROPY_EXT,
std::min(glc.gets.max_anisotropy, anisotropy));
std::min(context.gets.max_anisotropy, anisotropy));
}
#endif
}
@@ -341,7 +414,7 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* gld) noexcept {
UTILS_NOINLINE
void logCompilationError(io::ostream& out, Program::Shader shaderType,
const char* name, GLuint shaderId, std::string_view shader) noexcept {
const char* name, GLuint shaderId, CString const& sourceCode) noexcept {
auto to_string = [](Program::Shader type) -> const char* {
switch (type) {
@@ -350,13 +423,20 @@ void logCompilationError(io::ostream& out, Program::Shader shaderType,
}
};
char error[1024];
glGetShaderInfoLog(shaderId, sizeof(error), nullptr, error);
{ // scope for the temporary string storage
GLint length = 0;
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &length);
out << "Compilation error in " << to_string(shaderType) << " shader \"" << name << "\":\n"
<< "\"" << error << "\""
<< io::endl;
CString infoLog(length);
glGetShaderInfoLog(shaderId, length, nullptr, infoLog.data());
out << "Compilation error in " << to_string(shaderType) << " shader \"" << name << "\":\n"
<< "\"" << infoLog.c_str() << "\""
<< io::endl;
}
#ifndef NDEBUG
std::string_view shader{ sourceCode.data(), sourceCode.size() };
size_t lc = 1;
size_t start = 0;
std::string line;
@@ -367,23 +447,27 @@ void logCompilationError(io::ostream& out, Program::Shader shaderType,
} else {
line = shader.substr(start, end - start);
}
out << lc++ << ": "<< line.c_str() << '\n';
out << lc++ << ": " << line.c_str() << '\n';
if (end == std::string::npos) {
break;
}
start = end + 1;
}
out << io::endl;
#endif
}
UTILS_NOINLINE
void logProgramLinkError(io::ostream& out, char const* name, GLuint program) noexcept {
char error[1024];
glGetProgramInfoLog(program, sizeof(error), nullptr, error);
GLint length = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
CString infoLog(length);
glGetProgramInfoLog(program, length, nullptr, infoLog.data());
out << "Link error in \"" << name << "\":\n"
<< "\"" << error << "\""
<< "\"" << infoLog.c_str() << "\""
<< io::endl;
}
} // namespace filament
} // namespace filament::backend

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGLPROGRAM_H
#define TNT_FILAMENT_DRIVER_OPENGLPROGRAM_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGLPROGRAM_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGLPROGRAM_H
#include "DriverBase.h"
#include "OpenGLDriver.h"
@@ -32,18 +32,23 @@
#include <stdint.h>
namespace filament {
namespace filament::backend {
class OpenGLProgram : public backend::HwProgram {
class OpenGLProgram : public HwProgram {
public:
OpenGLProgram() noexcept = default;
OpenGLProgram(OpenGLDriver* gl, const backend::Program& builder) noexcept;
OpenGLProgram() noexcept;
OpenGLProgram(OpenGLDriver& gld, Program&& builder) noexcept;
~OpenGLProgram() noexcept;
bool isValid() const noexcept { return mIsValid; }
bool isValid() const noexcept { return mValid; }
void use(OpenGLDriver* const gl) noexcept {
void use(OpenGLDriver* const gld, OpenGLContext& context) noexcept {
if (UTILS_UNLIKELY(!mInitialized)) {
initialize(context);
}
context.useProgram(gl.program);
if (UTILS_UNLIKELY(mUsedBindingsCount)) {
// We rely on GL state tracking to avoid unnecessary glBindTexture / glBindSampler
// calls.
@@ -57,49 +62,67 @@ public:
// a bit less. Compared to what updateSamplers() actually does, which is
// pretty little, I'm not sure we'll get ahead.
updateSamplers(gl);
updateSamplers(gld);
}
}
struct {
GLuint shaders[backend::Program::SHADER_TYPE_COUNT];
GLuint program;
GLuint shaders[Program::SHADER_TYPE_COUNT] = {};
GLuint program = 0;
} gl; // 12 bytes
private:
static constexpr uint8_t TEXTURE_UNIT_COUNT = OpenGLContext::MAX_TEXTURE_UNIT_COUNT;
static constexpr uint8_t VERTEX_SHADER_BIT = uint8_t(1) << size_t(backend::Program::Shader::VERTEX);
static constexpr uint8_t FRAGMENT_SHADER_BIT = uint8_t(1) << size_t(backend::Program::Shader::FRAGMENT);
static constexpr uint8_t VERTEX_SHADER_BIT = uint8_t(1) << size_t(Program::Shader::VERTEX);
static constexpr uint8_t FRAGMENT_SHADER_BIT = uint8_t(1) << size_t(Program::Shader::FRAGMENT);
struct BlockInfo {
uint8_t binding : 3; // binding (i.e.: index in mSamplerBindings)
uint8_t count : 5; // number of TMUs actually used minus 1
static void compileShaders(OpenGLContext& context,
Program::ShaderSource shadersSource,
GLuint shaderIds[Program::SHADER_TYPE_COUNT],
std::array<utils::CString, Program::SHADER_TYPE_COUNT>& outShaderSourceCode) noexcept;
// if TEXTURE_UNIT_COUNT > 32, the count bitfield must be increased accordingly
static_assert(TEXTURE_UNIT_COUNT <= 32, "TEXTURE_UNIT_COUNT must be <= 32");
static GLuint linkProgram(const GLuint shaderIds[Program::SHADER_TYPE_COUNT]) noexcept;
// if SAMPLER_BINDING_COUNT > 8, the binding bitfield must be increased accordingly
static_assert(backend::Program::BINDING_COUNT <= 8, "BINDING_COUNT must be <= 8");
};
static bool checkProgramStatus(const char* name,
GLuint& program, GLuint shaderIds[Program::SHADER_TYPE_COUNT],
std::array<utils::CString, 2> const& shaderSourceCode) noexcept;
// This assert checks that the struct is the size we expect without any "hidden" padding bytes
// inserted by the compiler.
static_assert(sizeof(BlockInfo) == sizeof(uint8_t), "BlockInfo must be 8 bits");
void initialize(OpenGLContext& context);
uint8_t mUsedBindingsCount = 0;
uint8_t mValidShaderSet = 0;
bool mIsValid = false;
// information about each USED sampler buffer (no gaps)
std::array<BlockInfo, backend::Program::BINDING_COUNT> mBlockInfos; // 8 bytes
// runs of indices into SamplerGroup -- run start index and size given by BlockInfo
std::array<uint8_t, TEXTURE_UNIT_COUNT> mIndicesRuns; // 16 bytes
void initializeProgramState(OpenGLContext& context, GLuint program,
Program::UniformBlockInfo const& uniformBlockInfo,
Program::SamplerGroupInfo const& samplerGroupInfo) noexcept;
void updateSamplers(OpenGLDriver* gld) noexcept;
// keep these away from of other class attributes
struct LazyInitializationData {
Program::UniformBlockInfo uniformBlockInfo;
Program::SamplerGroupInfo samplerGroupInfo;
std::array<utils::CString, Program::SHADER_TYPE_COUNT> shaderSourceCode;
};
// number of bindings actually used by this program
uint8_t mUsedBindingsCount = 0u;
// whether lazy initialization has been performed
bool mInitialized : 1;
// whether lazy initialization was successful
bool mValid : 1;
UTILS_UNUSED uint8_t padding[2] = {};
union {
// when mInitialized == true:
// information about each USED sampler buffer per binding (no gaps)
std::array<uint8_t, Program::BINDING_COUNT> mUsedBindingPoints; // 8 bytes
// when mInitialized == false:
// lazy initialization data pointer
LazyInitializationData* mLazyInitializationData;
};
};
// if OpenGLProgram is larger tha 64 bytes, it'll fall in a larger Handle bucket.
static_assert(sizeof(OpenGLProgram) <= 64);
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_OPENGLPROGRAM_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGLPROGRAM_H

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "TimerQuery.h"
#include "OpenGLTimerQuery.h"
#include "private/backend/OpenGLPlatform.h"
@@ -23,14 +23,14 @@
#include <utils/Systrace.h>
#include <utils/debug.h>
namespace filament {
namespace filament::backend {
using namespace backend;
using namespace GLUtils;
// ------------------------------------------------------------------------------------------------
TimerQueryInterface::~TimerQueryInterface() = default;
OpenGLTimerQueryInterface::~OpenGLTimerQueryInterface() = default;
// ------------------------------------------------------------------------------------------------
@@ -72,7 +72,7 @@ uint64_t TimerQueryNative::queryResult(GLTimerQuery* query) {
// ------------------------------------------------------------------------------------------------
TimerQueryFence::TimerQueryFence(backend::OpenGLPlatform& platform)
OpenGLTimerQueryFence::OpenGLTimerQueryFence(OpenGLPlatform& platform)
: mPlatform(platform) {
mQueue.reserve(2);
mThread = std::thread([this]() {
@@ -94,7 +94,7 @@ TimerQueryFence::TimerQueryFence(backend::OpenGLPlatform& platform)
});
}
TimerQueryFence::~TimerQueryFence() {
OpenGLTimerQueryFence::~OpenGLTimerQueryFence() {
if (mThread.joinable()) {
std::unique_lock<utils::Mutex> lock(mLock);
mExitRequested = true;
@@ -104,13 +104,13 @@ TimerQueryFence::~TimerQueryFence() {
}
}
void TimerQueryFence::enqueue(TimerQueryFence::Job&& job) {
void OpenGLTimerQueryFence::enqueue(OpenGLTimerQueryFence::Job&& job) {
std::unique_lock<utils::Mutex> lock(mLock);
mQueue.push_back(std::forward<Job>(job));
mCondition.notify_one();
}
void TimerQueryFence::flush() {
void OpenGLTimerQueryFence::flush() {
// Use calls to flush() as a proxy for when the GPU work started.
GLTimerQuery* query = mActiveQuery;
if (query) {
@@ -124,7 +124,7 @@ void TimerQueryFence::flush() {
}
}
void TimerQueryFence::beginTimeElapsedQuery(GLTimerQuery* query) {
void OpenGLTimerQueryFence::beginTimeElapsedQuery(GLTimerQuery* query) {
assert_invariant(!mActiveQuery);
// We can't use a fence to figure out when a GPU operation starts (only when it finishes)
// so instead, we use when glFlush() was issued as a proxy.
@@ -136,7 +136,7 @@ void TimerQueryFence::beginTimeElapsedQuery(GLTimerQuery* query) {
mActiveQuery = query;
}
void TimerQueryFence::endTimeElapsedQuery(GLTimerQuery* query) {
void OpenGLTimerQueryFence::endTimeElapsedQuery(GLTimerQuery* query) {
assert_invariant(mActiveQuery);
Platform::Fence* fence = mPlatform.createFence();
std::weak_ptr<GLTimerQuery::State> weak = query->gl.emulation;
@@ -157,11 +157,11 @@ void TimerQueryFence::endTimeElapsedQuery(GLTimerQuery* query) {
});
}
bool TimerQueryFence::queryResultAvailable(GLTimerQuery* query) {
bool OpenGLTimerQueryFence::queryResultAvailable(GLTimerQuery* query) {
return query->gl.emulation->available.load();
}
uint64_t TimerQueryFence::queryResult(GLTimerQuery* query) {
uint64_t OpenGLTimerQueryFence::queryResult(GLTimerQuery* query) {
return query->gl.emulation->elapsed;
}
@@ -174,7 +174,7 @@ TimerQueryFallback::~TimerQueryFallback() = default;
void TimerQueryFallback::flush() {
}
void TimerQueryFallback::beginTimeElapsedQuery(TimerQueryInterface::GLTimerQuery* query) {
void TimerQueryFallback::beginTimeElapsedQuery(OpenGLTimerQueryInterface::GLTimerQuery* query) {
if (!query->gl.emulation) {
query->gl.emulation = std::make_shared<GLTimerQuery::State>();
}
@@ -183,18 +183,18 @@ void TimerQueryFallback::beginTimeElapsedQuery(TimerQueryInterface::GLTimerQuery
query->gl.emulation->elapsed = clock::now().time_since_epoch().count();
}
void TimerQueryFallback::endTimeElapsedQuery(TimerQueryInterface::GLTimerQuery* query) {
void TimerQueryFallback::endTimeElapsedQuery(OpenGLTimerQueryInterface::GLTimerQuery* query) {
// this implementation clearly doesn't work at all, but we have no h/w support
query->gl.emulation->elapsed = clock::now().time_since_epoch().count() - query->gl.emulation->elapsed;
query->gl.emulation->available.store(true, std::memory_order_relaxed);
}
bool TimerQueryFallback::queryResultAvailable(TimerQueryInterface::GLTimerQuery* query) {
bool TimerQueryFallback::queryResultAvailable(OpenGLTimerQueryInterface::GLTimerQuery* query) {
return query->gl.emulation->available.load(std::memory_order_relaxed);
}
uint64_t TimerQueryFallback::queryResult(TimerQueryInterface::GLTimerQuery* query) {
uint64_t TimerQueryFallback::queryResult(OpenGLTimerQueryInterface::GLTimerQuery* query) {
return query->gl.emulation->elapsed;
}
} // namespace filament
} // namespace filament::backend

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_TIMERQUERY_H
#define TNT_FILAMENT_DRIVER_TIMERQUERY_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_TIMERQUERY_H
#define TNT_FILAMENT_BACKEND_OPENGL_TIMERQUERY_H
#include "OpenGLDriver.h"
@@ -24,7 +24,7 @@
#include <thread>
#include <vector>
namespace filament {
namespace filament::backend {
/*
* we need two implementation of timer queries (only elapsed time), because
@@ -34,13 +34,13 @@ namespace filament {
* These classes implement the various strategies...
*/
class TimerQueryInterface {
class OpenGLTimerQueryInterface {
protected:
using GLTimerQuery = OpenGLDriver::GLTimerQuery;
using clock = std::chrono::steady_clock;
public:
virtual ~TimerQueryInterface();
virtual ~OpenGLTimerQueryInterface();
virtual void flush() = 0;
virtual void beginTimeElapsedQuery(GLTimerQuery* query) = 0;
virtual void endTimeElapsedQuery(GLTimerQuery* query) = 0;
@@ -48,7 +48,7 @@ public:
virtual uint64_t queryResult(GLTimerQuery* query) = 0;
};
class TimerQueryNative : public TimerQueryInterface {
class TimerQueryNative : public OpenGLTimerQueryInterface {
public:
explicit TimerQueryNative(OpenGLContext& context);
~TimerQueryNative() override;
@@ -61,10 +61,10 @@ private:
OpenGLContext& gl;
};
class TimerQueryFence : public TimerQueryInterface {
class OpenGLTimerQueryFence : public OpenGLTimerQueryInterface {
public:
explicit TimerQueryFence(backend::OpenGLPlatform& platform);
~TimerQueryFence() override;
explicit OpenGLTimerQueryFence(OpenGLPlatform& platform);
~OpenGLTimerQueryFence() override;
private:
using Job = std::function<void()>;
void flush() override;
@@ -79,7 +79,7 @@ private:
enqueue(Job(std::bind(std::forward<CALLABLE>(func), std::forward<ARGS>(args)...)));
}
backend::OpenGLPlatform& mPlatform;
OpenGLPlatform& mPlatform;
std::thread mThread;
mutable utils::Mutex mLock;
mutable utils::Condition mCondition;
@@ -88,7 +88,7 @@ private:
GLTimerQuery* mActiveQuery = nullptr;
};
class TimerQueryFallback : public TimerQueryInterface {
class TimerQueryFallback : public OpenGLTimerQueryInterface {
public:
explicit TimerQueryFallback();
~TimerQueryFallback() override;
@@ -100,6 +100,6 @@ private:
uint64_t queryResult(GLTimerQuery* query) override;
};
} // namespace filament
} // namespace filament::backend
#endif //TNT_FILAMENT_DRIVER_TIMERQUERY_H
#endif //TNT_FILAMENT_BACKEND_OPENGL_TIMERQUERY_H

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_GL_HEADERS_H
#define TNT_FILAMENT_DRIVER_GL_HEADERS_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_GL_HEADERS_H
#define TNT_FILAMENT_BACKEND_OPENGL_GL_HEADERS_H
#if defined(__ANDROID__) || defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(__EMSCRIPTEN__)
@@ -144,4 +144,4 @@
#define GL41_HEADERS false
#endif
#endif // TNT_FILAMENT_DRIVER_GL_HEADERS_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_GL_HEADERS_H

View File

@@ -21,7 +21,7 @@
#include <CoreVideo/CoreVideo.h>
namespace filament {
namespace filament::backend {
class CocoaTouchExternalImage final {
public:
@@ -95,6 +95,6 @@ private:
};
} // namespace filament
} // namespace filament::backend
#endif

View File

@@ -29,7 +29,7 @@
#include <utils/Panic.h>
#include <utils/debug.h>
namespace filament {
namespace filament::backend {
static const char* s_vertexES = R"SHADER(#version 300 es
in vec4 pos;
@@ -317,4 +317,4 @@ void CocoaTouchExternalImage::State::restore() noexcept {
}
}
} // namespace filament
} // namespace filament::backend

View File

@@ -26,7 +26,7 @@
using namespace utils;
namespace filament {
namespace filament::backend {
using namespace backend;
using Stream = Platform::Stream;
@@ -166,4 +166,4 @@ void ExternalStreamManagerAndroid::updateTexImage(Stream* handle, int64_t* times
}
}
} // namespace filament
} // namespace filament::backend

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_STREAM_MANAGER_ANDROID_H
#define TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_STREAM_MANAGER_ANDROID_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_ANDROID_EXTERNAL_STREAM_MANAGER_ANDROID_H
#define TNT_FILAMENT_BACKEND_OPENGL_ANDROID_EXTERNAL_STREAM_MANAGER_ANDROID_H
#include "private/backend/VirtualMachineEnv.h"
@@ -29,7 +29,7 @@ struct ASurfaceTexture;
typedef struct ASurfaceTexture ASurfaceTexture;
#endif
namespace filament {
namespace filament::backend {
/*
* ExternalStreamManagerAndroid::Stream is basically a wrapper for SurfaceTexture.
@@ -38,7 +38,7 @@ namespace filament {
*/
class ExternalStreamManagerAndroid {
public:
using Stream = backend::Platform::Stream;
using Stream = Platform::Stream;
// must be called on GLES thread
static ExternalStreamManagerAndroid& create() noexcept;
@@ -86,6 +86,6 @@ private:
jmethodID mSurfaceTextureClass_detachFromGLContext{};
};
} // namespace filament
} // namespace filament::backend
#endif //TNT_FILAMENT_DRIVER_ANDROID_EXTERNAL_STREAM_MANAGER_ANDROID_H
#endif //TNT_FILAMENT_BACKEND_OPENGL_ANDROID_EXTERNAL_STREAM_MANAGER_ANDROID_H

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_COCOA_GL_H
#define TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_COCOA_GL_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#include <stdint.h>
@@ -23,16 +23,16 @@
#include "private/backend/OpenGLPlatform.h"
namespace filament {
namespace filament::backend {
struct PlatformCocoaGLImpl;
class PlatformCocoaGL final : public backend::OpenGLPlatform {
class PlatformCocoaGL final : public OpenGLPlatform {
public:
PlatformCocoaGL();
~PlatformCocoaGL() noexcept final;
backend::Driver* createDriver(void* sharedContext) noexcept override;
Driver* createDriver(void* sharedContext) noexcept override;
void terminate() noexcept final;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept final;
@@ -43,8 +43,8 @@ public:
Fence* createFence() noexcept final { return nullptr; }
void destroyFence(Fence* fence) noexcept final {}
backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final {
return backend::FenceStatus::ERROR;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final {
return FenceStatus::ERROR;
}
void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept final {}
@@ -57,7 +57,7 @@ public:
ExternalTexture* createExternalTextureStorage() noexcept final { return nullptr; }
void reallocateExternalStorage(ExternalTexture* ets,
uint32_t w, uint32_t h, backend::TextureFormat format) noexcept final { }
uint32_t w, uint32_t h, TextureFormat format) noexcept final { }
void destroyExternalTextureStorage(ExternalTexture* ets) noexcept final { }
int getOSVersion() const noexcept final { return 0; }
@@ -68,6 +68,6 @@ private:
PlatformCocoaGLImpl* pImpl = nullptr;
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_COCOA_GL_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H

View File

@@ -30,7 +30,7 @@
#include <vector>
namespace filament {
namespace filament::backend {
using namespace backend;
@@ -171,7 +171,7 @@ void PlatformCocoaGL::terminate() noexcept {
Platform::SwapChain* PlatformCocoaGL::createSwapChain(void* nativewindow, uint64_t& flags) noexcept {
// Transparent SwapChain is not supported
flags &= ~backend::SWAP_CHAIN_CONFIG_TRANSPARENT;
flags &= ~SWAP_CHAIN_CONFIG_TRANSPARENT;
NSView* nsView = (__bridge NSView*)nativewindow;
CocoaGLSwapChain* swapChain = new CocoaGLSwapChain( nsView );
@@ -295,6 +295,6 @@ void PlatformCocoaGLImpl::updateOpenGLContext(NSView *nsView, bool resetView,
}
}
} // namespace filament
} // namespace filament::backend
#pragma clang diagnostic pop

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#define TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#include <stdint.h>
@@ -23,16 +23,16 @@
#include "private/backend/OpenGLPlatform.h"
namespace filament {
namespace filament::backend {
struct PlatformCocoaTouchGLImpl;
class PlatformCocoaTouchGL final : public backend::OpenGLPlatform {
class PlatformCocoaTouchGL final : public OpenGLPlatform {
public:
PlatformCocoaTouchGL();
~PlatformCocoaTouchGL() noexcept final;
backend::Driver* createDriver(void* sharedGLContext) noexcept override;
Driver* createDriver(void* sharedGLContext) noexcept override;
void terminate() noexcept final;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept final;
@@ -44,8 +44,8 @@ public:
uint32_t& depthbuffer) noexcept final;
Fence* createFence() noexcept final { return nullptr; }
void destroyFence(Fence* fence) noexcept final {}
backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final {
return backend::FenceStatus::ERROR;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final {
return FenceStatus::ERROR;
}
void setPresentationTime(int64_t time) noexcept final override {}
@@ -58,7 +58,7 @@ public:
ExternalTexture* createExternalTextureStorage() noexcept final { return nullptr; }
void reallocateExternalStorage(ExternalTexture* ets,
uint32_t w, uint32_t h, backend::TextureFormat format) noexcept final { }
uint32_t w, uint32_t h, TextureFormat format) noexcept final { }
void destroyExternalTextureStorage(ExternalTexture* ets) noexcept final { }
int getOSVersion() const noexcept final { return 0; }
@@ -73,8 +73,8 @@ private:
PlatformCocoaTouchGLImpl* pImpl = nullptr;
};
using ContextManager = filament::PlatformCocoaTouchGL;
using ContextManager = PlatformCocoaTouchGL;
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H

View File

@@ -35,7 +35,7 @@
#include "../OpenGLDriver.h"
#include "CocoaTouchExternalImage.h"
namespace filament {
namespace filament::backend {
using namespace backend;
@@ -103,7 +103,7 @@ void PlatformCocoaTouchGL::terminate() noexcept {
Platform::SwapChain* PlatformCocoaTouchGL::createSwapChain(void* nativewindow, uint64_t& flags) noexcept {
// Transparent swap chain is not supported
flags &= ~backend::SWAP_CHAIN_CONFIG_TRANSPARENT;
flags &= ~SWAP_CHAIN_CONFIG_TRANSPARENT;
return (SwapChain*) nativewindow;
}
@@ -206,4 +206,4 @@ void PlatformCocoaTouchGL::destroyExternalImage(void* texture) noexcept {
delete p;
}
} // namespace filament
} // namespace filament::backend

View File

@@ -16,12 +16,12 @@
#include "PlatformDummyGL.h"
namespace filament {
namespace filament::backend {
Driver* PlatformDummyGL::createDriver(void* const sharedGLContext) noexcept {
return nullptr;
}
} // namespace filament
} // namespace filament::backend
// ---------------------------------------------------------------------------------------------

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_DUMMY_GL_H
#define TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_DUMMY_GL_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_DUMMY_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_DUMMY_GL_H
#include <stdint.h>
@@ -23,12 +23,12 @@
#include "private/backend/OpenGLPlatform.h"
namespace filament {
namespace filament::backend {
class PlatformDummyGL final : public backend::OpenGLPlatform {
class PlatformDummyGL final : public OpenGLPlatform {
public:
backend::Driver* createDriver(void* const sharedGLContext) noexcept override;
Driver* createDriver(void* const sharedGLContext) noexcept override;
void terminate() noexcept override { }
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept final override {
@@ -41,8 +41,8 @@ public:
Fence* createFence() noexcept final override { return nullptr; }
void destroyFence(Fence* fence) noexcept final override {}
backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final override {
return backend::FenceStatus::ERROR;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final override {
return FenceStatus::ERROR;
}
Stream* createStream(void* nativeStream) noexcept final override { return nullptr; }
@@ -53,12 +53,12 @@ public:
ExternalTexture* createExternalTextureStorage() noexcept final override { return nullptr; }
void reallocateExternalStorage(ExternalTexture* ets,
uint32_t w, uint32_t h, backend::TextureFormat format) noexcept final override { }
uint32_t w, uint32_t h, TextureFormat format) noexcept final override { }
void destroyExternalTextureStorage(ExternalTexture* ets) noexcept final override { }
int getOSVersion() const noexcept final override { return 0; }
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_DUMMY_GL_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_DUMMY_GL_H

View File

@@ -28,7 +28,7 @@
using namespace utils;
namespace filament {
namespace filament::backend {
using namespace backend;
// The Android NDK doesn't exposes extensions, fake it with eglGetProcAddress
@@ -259,7 +259,7 @@ void PlatformEGL::terminate() noexcept {
Platform::SwapChain* PlatformEGL::createSwapChain(
void* nativeWindow, uint64_t& flags) noexcept {
EGLSurface sur = eglCreateWindowSurface(mEGLDisplay,
(flags & backend::SWAP_CHAIN_CONFIG_TRANSPARENT) ?
(flags & SWAP_CHAIN_CONFIG_TRANSPARENT) ?
mEGLTransparentConfig : mEGLConfig,
(EGLNativeWindowType)nativeWindow, nullptr);
@@ -284,7 +284,7 @@ Platform::SwapChain* PlatformEGL::createSwapChain(
};
EGLSurface sur = eglCreatePbufferSurface(mEGLDisplay,
(flags & backend::SWAP_CHAIN_CONFIG_TRANSPARENT) ?
(flags & SWAP_CHAIN_CONFIG_TRANSPARENT) ?
mEGLTransparentConfig : mEGLConfig, attribs);
if (UTILS_UNLIKELY(sur == EGL_NO_SURFACE)) {
@@ -335,7 +335,7 @@ void PlatformEGL::destroyFence(Platform::Fence* fence) noexcept {
#endif
}
backend::FenceStatus PlatformEGL::waitFence(
FenceStatus PlatformEGL::waitFence(
Platform::Fence* fence, uint64_t timeout) noexcept {
#ifdef EGL_KHR_reusable_sync
EGLSyncKHR sync = (EGLSyncKHR) fence;
@@ -383,6 +383,6 @@ void PlatformEGL::initializeGlExtensions() noexcept {
ext.OES_EGL_image_external_essl3 = glExtensions.has("GL_OES_EGL_image_external_essl3");
}
} // namespace filament
} // namespace filament::backend
// ---------------------------------------------------------------------------------------------

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_EGL_H
#define TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_EGL_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H
#include <stdint.h>
@@ -26,14 +26,14 @@
#include "private/backend/OpenGLPlatform.h"
namespace filament {
namespace filament::backend {
class PlatformEGL : public backend::OpenGLPlatform {
class PlatformEGL : public OpenGLPlatform {
public:
PlatformEGL() noexcept;
backend::Driver* createDriver(void* sharedContext) noexcept override;
Driver* createDriver(void* sharedContext) noexcept override;
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept override;
@@ -45,7 +45,7 @@ public:
bool canCreateFence() noexcept override { return true; }
Fence* createFence() noexcept override;
void destroyFence(Fence* fence) noexcept override;
backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
void createExternalImageTexture(void* texture) noexcept override;
void destroyExternalImage(void* texture) noexcept override;
@@ -64,7 +64,7 @@ public:
ExternalTexture* createExternalTextureStorage() noexcept override { return nullptr; }
void reallocateExternalStorage(ExternalTexture* ets,
uint32_t w, uint32_t h, backend::TextureFormat format) noexcept override {}
uint32_t w, uint32_t h, TextureFormat format) noexcept override {}
void destroyExternalTextureStorage(ExternalTexture* ets) noexcept override {}
protected:
@@ -87,6 +87,6 @@ protected:
} ext;
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_EGL_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H

View File

@@ -45,7 +45,7 @@
using namespace utils;
namespace filament {
namespace filament::backend {
using namespace backend;
// The Android NDK doesn't exposes extensions, fake it with eglGetProcAddress
@@ -245,6 +245,6 @@ AcquiredImage PlatformEGLAndroid::transformAcquiredImage(AcquiredImage source) n
return { eglImage, patchedCallback, closure, source.handler };
}
} // namespace filament
} // namespace filament::backend
// ---------------------------------------------------------------------------------------------

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_EGL_ANDROID_H
#define TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_EGL_ANDROID_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#include "PlatformEGL.h"
namespace filament {
namespace filament::backend {
class ExternalStreamManagerAndroid;
class ExternalTextureManagerAndroid;
@@ -32,7 +32,7 @@ public:
void terminate() noexcept override;
backend::Driver* createDriver(void* sharedContext) noexcept final;
Driver* createDriver(void* sharedContext) noexcept final;
int getOSVersion() const noexcept final;
@@ -46,10 +46,10 @@ public:
ExternalTexture* createExternalTextureStorage() noexcept final;
void reallocateExternalStorage(ExternalTexture* ets,
uint32_t w, uint32_t h, backend::TextureFormat format) noexcept final;
uint32_t w, uint32_t h, TextureFormat format) noexcept final;
void destroyExternalTextureStorage(ExternalTexture* ets) noexcept final;
backend::AcquiredImage transformAcquiredImage(backend::AcquiredImage source) noexcept final;
AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept final;
private:
int mOSVersion;
@@ -57,6 +57,6 @@ private:
ExternalTextureManagerAndroid& mExternalTextureManager;
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_EGL_ANDROID_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H

View File

@@ -126,7 +126,7 @@ static bool loadLibraries() {
return true;
}
namespace filament {
namespace filament::backend {
using namespace backend;
@@ -242,14 +242,14 @@ void PlatformGLX::terminate() noexcept {
Platform::SwapChain* PlatformGLX::createSwapChain(void* nativeWindow, uint64_t& flags) noexcept {
// Transparent swap chain is not supported
flags &= ~backend::SWAP_CHAIN_CONFIG_TRANSPARENT;
flags &= ~SWAP_CHAIN_CONFIG_TRANSPARENT;
return (SwapChain*)nativeWindow;
}
Platform::SwapChain* PlatformGLX::createSwapChain(
uint32_t width, uint32_t height, uint64_t& flags) noexcept {
// Transparent swap chain is not supported
flags &= ~backend::SWAP_CHAIN_CONFIG_TRANSPARENT;
flags &= ~SWAP_CHAIN_CONFIG_TRANSPARENT;
int pbufferAttribs[] = {
GLX_PBUFFER_WIDTH, int(width),
GLX_PBUFFER_HEIGHT, int(height),
@@ -290,8 +290,8 @@ void PlatformGLX::destroyFence(Fence* fence) noexcept {
delete fence;
}
backend::FenceStatus PlatformGLX::waitFence(Fence* fence, uint64_t timeout) noexcept {
return backend::FenceStatus::CONDITION_SATISFIED;
FenceStatus PlatformGLX::waitFence(Fence* fence, uint64_t timeout) noexcept {
return FenceStatus::CONDITION_SATISFIED;
}
} // namespace filament
} // namespace filament::backend

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_GLX_H
#define TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_GLX_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_GLX_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_GLX_H
#include <stdint.h>
@@ -28,12 +28,12 @@
#include <vector>
namespace filament {
namespace filament::backend {
class PlatformGLX final : public backend::OpenGLPlatform {
class PlatformGLX final : public OpenGLPlatform {
public:
backend::Driver* createDriver(void* const sharedGLContext) noexcept override;
Driver* createDriver(void* const sharedGLContext) noexcept override;
void terminate() noexcept override;
@@ -45,7 +45,7 @@ public:
Fence* createFence() noexcept override;
void destroyFence(Fence* fence) noexcept override;
backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
void setPresentationTime(int64_t time) noexcept final override {}
@@ -57,7 +57,7 @@ public:
ExternalTexture* createExternalTextureStorage() noexcept final override { return nullptr; }
void reallocateExternalStorage(ExternalTexture* ets,
uint32_t w, uint32_t h, backend::TextureFormat format) noexcept final override { }
uint32_t w, uint32_t h, TextureFormat format) noexcept final override { }
void destroyExternalTextureStorage(ExternalTexture* ets) noexcept final override { }
int getOSVersion() const noexcept final override { return 0; }
@@ -70,6 +70,6 @@ private:
std::vector<GLXPbuffer> mPBuffers;
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_GLX_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_GLX_H

View File

@@ -66,7 +66,7 @@ void reportLastWindowsError() {
} // namespace
namespace filament {
namespace filament::backend {
using namespace backend;
@@ -265,8 +265,8 @@ Platform::Fence* PlatformWGL::createFence() noexcept {
void PlatformWGL::destroyFence(Fence* fence) noexcept {
}
backend::FenceStatus PlatformWGL::waitFence(Fence* fence, uint64_t timeout) noexcept {
return backend::FenceStatus::ERROR;
FenceStatus PlatformWGL::waitFence(Fence* fence, uint64_t timeout) noexcept {
return FenceStatus::ERROR;
}
} // namespace filament
} // namespace filament::backend

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_WGL_H
#define TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_WGL_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WGL_H
#include <stdint.h>
@@ -26,11 +26,11 @@
#include "private/backend/OpenGLPlatform.h"
namespace filament {
namespace filament::backend {
class PlatformWGL final : public backend::OpenGLPlatform {
class PlatformWGL final : public OpenGLPlatform {
public:
backend::Driver* createDriver(void* const sharedGLContext) noexcept override;
Driver* createDriver(void* const sharedGLContext) noexcept override;
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept override;
@@ -41,7 +41,7 @@ public:
Fence* createFence() noexcept override;
void destroyFence(Fence* fence) noexcept override;
backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
void setPresentationTime(int64_t time) noexcept final override {}
@@ -53,7 +53,7 @@ public:
ExternalTexture* createExternalTextureStorage() noexcept final override { return nullptr; }
void reallocateExternalStorage(ExternalTexture* ets,
uint32_t w, uint32_t h, backend::TextureFormat format) noexcept final override { }
uint32_t w, uint32_t h, TextureFormat format) noexcept final override { }
void destroyExternalTextureStorage(ExternalTexture* ets) noexcept final override { }
int getOSVersion() const noexcept final override { return 0; }
@@ -65,6 +65,6 @@ private:
PIXELFORMATDESCRIPTOR mPfd = {};
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_GLX_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_GLX_H

View File

@@ -17,7 +17,7 @@
#include "PlatformWebGL.h"
#include "../OpenGLDriverFactory.h"
namespace filament {
namespace filament::backend {
using namespace backend;
@@ -58,8 +58,8 @@ void PlatformWebGL::destroyFence(Fence* fence) noexcept {
delete fence;
}
backend::FenceStatus PlatformWebGL::waitFence(Fence* fence, uint64_t timeout) noexcept {
return backend::FenceStatus::CONDITION_SATISFIED;
FenceStatus PlatformWebGL::waitFence(Fence* fence, uint64_t timeout) noexcept {
return FenceStatus::CONDITION_SATISFIED;
}
} // namespace filament
} // namespace filament::backend

View File

@@ -14,8 +14,8 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_WEBGL_H
#define TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_WEBGL_H
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
#include <stdint.h>
@@ -26,12 +26,12 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
namespace filament {
namespace filament::backend {
class PlatformWebGL final : public backend::OpenGLPlatform {
class PlatformWebGL final : public OpenGLPlatform {
public:
backend::Driver* createDriver(void* const sharedGLContext) noexcept override;
Driver* createDriver(void* const sharedGLContext) noexcept override;
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept final override;
@@ -42,7 +42,7 @@ public:
Fence* createFence() noexcept final override;
void destroyFence(Fence* fence) noexcept final override;
backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept final override;
void setPresentationTime(int64_t time) noexcept final override {}
@@ -54,12 +54,12 @@ public:
ExternalTexture* createExternalTextureStorage() noexcept final override { return nullptr; }
void reallocateExternalStorage(ExternalTexture* ets,
uint32_t w, uint32_t h, backend::TextureFormat format) noexcept final override { }
uint32_t w, uint32_t h, TextureFormat format) noexcept final override { }
void destroyExternalTextureStorage(ExternalTexture* ets) noexcept final override { }
int getOSVersion() const noexcept final override { return 0; }
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_OPENGL_PLATFORM_WEBGL_H
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H

View File

@@ -28,7 +28,7 @@ using namespace utils;
// ------------------------------------------------------------------------------------------------
// Stream operators for all types in DriverEnums.h
// (These must live outside of the filament namespace)
// (These must live outside the filament namespace)
// ------------------------------------------------------------------------------------------------
#if !defined(NDEBUG)
@@ -497,6 +497,18 @@ io::ostream& operator<<(io::ostream& out, MRT const& mrt) {
return out;
}
io::ostream& operator<<(io::ostream& stream, ShaderStageFlags stageFlags) {
unsigned int v = +stageFlags.vertex + 2u * +stageFlags.fragment;
const char* str = nullptr;
switch (v & 3) {
case 0: str = "{ }"; break;
case 1: str = "{ vertex }"; break;
case 2: str = "{ fragment }"; break;
case 3: str = "{ vertex | fragment }"; break;
}
return stream << str;
}
#undef CASE
#endif // !NDEBUG

View File

@@ -27,9 +27,7 @@
using namespace bluevk;
namespace filament {
using namespace backend;
namespace filament::backend {
Driver* PlatformVkAndroid::createDriver(void* const sharedContext) noexcept {
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
@@ -50,4 +48,4 @@ void* PlatformVkAndroid::createVkSurfaceKHR(void* nativeWindow, void* vkinstance
return (void*) surface;
}
} // namespace filament
} // namespace filament::backend

View File

@@ -14,26 +14,26 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_VULKAN_PLATFORM_VK_ANDROID_H
#define TNT_FILAMENT_DRIVER_VULKAN_PLATFORM_VK_ANDROID_H
#ifndef TNT_FILAMENT_BACKEND_VULKAN_PLATFORM_VK_ANDROID_H
#define TNT_FILAMENT_BACKEND_VULKAN_PLATFORM_VK_ANDROID_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include "VulkanPlatform.h"
namespace filament {
namespace filament::backend {
class PlatformVkAndroid final : public backend::VulkanPlatform {
class PlatformVkAndroid final : public VulkanPlatform {
public:
backend::Driver* createDriver(void* const sharedContext) noexcept override;
Driver* createDriver(void* const sharedContext) noexcept override;
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
int getOSVersion() const noexcept override { return 0; }
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_VULKAN_PLATFORM_VK_ANDROID_H
#endif // TNT_FILAMENT_BACKEND_VULKAN_PLATFORM_VK_ANDROID_H

View File

@@ -14,23 +14,23 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_VULKAN_PLATFORM_VK_COCOA_H
#define TNT_FILAMENT_DRIVER_VULKAN_PLATFORM_VK_COCOA_H
#ifndef TNT_FILAMENT_BACKEND_VULKAN_PLATFORM_VK_COCOA_H
#define TNT_FILAMENT_BACKEND_VULKAN_PLATFORM_VK_COCOA_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include "VulkanPlatform.h"
namespace filament {
namespace filament::backend {
class PlatformVkCocoa final : public backend::VulkanPlatform {
class PlatformVkCocoa final : public VulkanPlatform {
public:
backend::Driver* createDriver(void* sharedContext) noexcept override;
Driver* createDriver(void* sharedContext) noexcept override;
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
int getOSVersion() const noexcept override { return 0; }
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_VULKAN_PLATFORM_VK_COCOA_H
#endif // TNT_FILAMENT_BACKEND_VULKAN_PLATFORM_VK_COCOA_H

View File

@@ -32,9 +32,7 @@
using namespace bluevk;
namespace filament {
using namespace backend;
namespace filament::backend {
Driver* PlatformVkCocoa::createDriver(void* sharedContext) noexcept {
ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts.");
@@ -61,4 +59,4 @@ void* PlatformVkCocoa::createVkSurfaceKHR(void* nativeWindow, void* instance, ui
return surface;
}
} // namespace filament
} // namespace filament::backend

View File

@@ -14,23 +14,23 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_DRIVER_VULKAN_PLATFORM_VK_COCOA_TOUCH_H
#define TNT_FILAMENT_DRIVER_VULKAN_PLATFORM_VK_COCOA_TOUCH_H
#ifndef TNT_FILAMENT_BACKEND_VULKAN_PLATFORM_VK_COCOA_TOUCH_H
#define TNT_FILAMENT_BACKEND_VULKAN_PLATFORM_VK_COCOA_TOUCH_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include "VulkanPlatform.h"
namespace filament {
namespace filament::backend {
class PlatformVkCocoaTouch final : public backend::VulkanPlatform {
class PlatformVkCocoaTouch final : public VulkanPlatform {
public:
backend::Driver* createDriver(void* const sharedContext) noexcept override;
Driver* createDriver(void* const sharedContext) noexcept override;
void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept override;
int getOSVersion() const noexcept override { return 0; }
};
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_DRIVER_VULKAN_CONTEXTMANAGERVKCOCOATOUCH_H
#endif // TNT_FILAMENT_BACKEND_VULKAN_CONTEXTMANAGERVKCOCOATOUCH_H

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