Compare commits
118 Commits
idris/rend
...
idris/spec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e6fd9d044 | ||
|
|
d943293fd8 | ||
|
|
acc6c801ec | ||
|
|
a09ab9625d | ||
|
|
2c65946217 | ||
|
|
c166bea8fc | ||
|
|
b9be9b4f2d | ||
|
|
ce88a56579 | ||
|
|
689e769f9a | ||
|
|
2f0a8b19b5 | ||
|
|
1bed68afb7 | ||
|
|
130e02da5c | ||
|
|
8e06a68446 | ||
|
|
656b50b304 | ||
|
|
880db4ec43 | ||
|
|
2ce294720d | ||
|
|
eb07decb4b | ||
|
|
47930edf70 | ||
|
|
05b89905d8 | ||
|
|
3e0df36c1c | ||
|
|
c9ce384f14 | ||
|
|
6a6bdd5be7 | ||
|
|
d56ade924e | ||
|
|
fe561e3e27 | ||
|
|
1d98e350e4 | ||
|
|
d34e018acb | ||
|
|
169c8d57ff | ||
|
|
a1e0cfa33c | ||
|
|
6d44db3ca0 | ||
|
|
a261429d06 | ||
|
|
69d0de3c6d | ||
|
|
1305303f2e | ||
|
|
8532511107 | ||
|
|
b762ccb78c | ||
|
|
3296eb153c | ||
|
|
ae6d1028f7 | ||
|
|
92579b6307 | ||
|
|
315b53c339 | ||
|
|
c55d459986 | ||
|
|
7876695545 | ||
|
|
e1a1464c5d | ||
|
|
67ed5141bf | ||
|
|
b9d7a25b91 | ||
|
|
ba63ac63a0 | ||
|
|
1e77947758 | ||
|
|
53df4012fe | ||
|
|
d880fab93f | ||
|
|
fb8030b80a | ||
|
|
e2d009ff2a | ||
|
|
0a67ef4d80 | ||
|
|
79d6f46f1a | ||
|
|
6481fa2acf | ||
|
|
7638b3ddd9 | ||
|
|
fe474a9d7e | ||
|
|
81008abe06 | ||
|
|
ef1d079c53 | ||
|
|
5286dec70b | ||
|
|
d748dc590e | ||
|
|
93a0aec246 | ||
|
|
f3fa734793 | ||
|
|
33d3c3a897 | ||
|
|
bbabf3480b | ||
|
|
e7a8f471a1 | ||
|
|
d45a5cc926 | ||
|
|
361ba2afea | ||
|
|
78419cd992 | ||
|
|
cc7361dba5 | ||
|
|
5c0841ff56 | ||
|
|
10af183756 | ||
|
|
56e0e9a424 | ||
|
|
86a500c846 | ||
|
|
5b3f13fc1d | ||
|
|
1b1dfaa57c | ||
|
|
bf8c84bbe5 | ||
|
|
fb179cabbc | ||
|
|
a80ea743e8 | ||
|
|
97f8106909 | ||
|
|
d455899b93 | ||
|
|
63fe439a5e | ||
|
|
7847220aba | ||
|
|
d76ae4395b | ||
|
|
f994cb58ce | ||
|
|
52eb682498 | ||
|
|
5a5168a191 | ||
|
|
e85dfe75c8 | ||
|
|
6beb40b0a1 | ||
|
|
5cb96e5732 | ||
|
|
927aa57a4e | ||
|
|
36e775902d | ||
|
|
53e28f3b33 | ||
|
|
7ccbdb4633 | ||
|
|
f10d226565 | ||
|
|
28ecf5c35d | ||
|
|
9683eb649c | ||
|
|
3d10ae3ee3 | ||
|
|
44a75dd44b | ||
|
|
de7bcd2df7 | ||
|
|
6adf140fb4 | ||
|
|
b94c802076 | ||
|
|
b231de0b5b | ||
|
|
fca200d549 | ||
|
|
ba1d3f6c76 | ||
|
|
7734fd4ad9 | ||
|
|
7e6839f535 | ||
|
|
3d78322058 | ||
|
|
3e1ea7cdfd | ||
|
|
6d413a4faf | ||
|
|
af09c517b6 | ||
|
|
67b9c72442 | ||
|
|
c1a8d73384 | ||
|
|
2d98ac878e | ||
|
|
35ab5f768d | ||
|
|
705b3c39f4 | ||
|
|
56231db326 | ||
|
|
e97f7ef628 | ||
|
|
4570c2e710 | ||
|
|
4759237e66 | ||
|
|
543b93939a |
2
.github/actions/dep-versions/action.yml
vendored
2
.github/actions/dep-versions/action.yml
vendored
@@ -3,5 +3,5 @@ runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Set up dependency versions
|
||||
shell: bash
|
||||
shell: bash
|
||||
run: cat ./build/common/versions >> $GITHUB_ENV
|
||||
|
||||
16
.github/actions/web-prereq/action.yml
vendored
Normal file
16
.github/actions/web-prereq/action.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
name: 'Web Preqrequisites'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- uses: ./.github/actions/dep-versions
|
||||
- name: Cache EMSDK
|
||||
id: emsdk-cache
|
||||
uses: actions/cache@v4 # Use a specific version
|
||||
with:
|
||||
path: emsdk
|
||||
key: ${{ runner.os }}-emsdk-${{ env.GITHUB_EMSDK_VERSION }}
|
||||
- name: Install Web Prerequisites
|
||||
shell: bash
|
||||
run: |
|
||||
bash ./build/common/get-emscripten.sh
|
||||
echo "EMSDK=$PWD/emsdk" >> $GITHUB_ENV
|
||||
2
.github/workflows/mac-continuous.yml
vendored
2
.github/workflows/mac-continuous.yml
vendored
@@ -26,4 +26,4 @@ jobs:
|
||||
path: out/filament-release-darwin.tgz
|
||||
- name: Check public headers
|
||||
run: |
|
||||
build/common/check-headers.sh out/release/filament/include
|
||||
test/check-headers/test.sh out/release/filament/include
|
||||
|
||||
15
.github/workflows/presubmit.yml
vendored
15
.github/workflows/presubmit.yml
vendored
@@ -96,6 +96,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: ./.github/actions/linux-prereq
|
||||
- uses: ./.github/actions/web-prereq
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && printf "y" | ./build.sh presubmit
|
||||
@@ -123,13 +124,15 @@ jobs:
|
||||
- uses: ./.github/actions/mac-prereq
|
||||
- name: Cache Mesa and deps
|
||||
id: mesa-cache
|
||||
uses: actions/cache@v4 # Use a specific version
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: mesa
|
||||
key: ${{ runner.os }}-mesa-deps-2-${{ vars.MESA_VERSION }}
|
||||
- name: Get Mesa
|
||||
id: mesa-prereq
|
||||
run: bash test/utils/get_mesa.sh
|
||||
- name: Prerequisites
|
||||
id: prereqs
|
||||
run: |
|
||||
bash build/common/get-mesa.sh
|
||||
pip install tifffile numpy
|
||||
- name: Run Test
|
||||
run: bash test/renderdiff/test.sh
|
||||
- uses: actions/upload-artifact@v4
|
||||
@@ -150,8 +153,8 @@ jobs:
|
||||
- name: Run test
|
||||
run: ./out/cmake-debug/libs/filamat/test_filamat --gtest_filter=MaterialCompiler.Wgsl*
|
||||
|
||||
code-correcteness:
|
||||
name: code-correctness
|
||||
test-code-correctness:
|
||||
name: test-code-correctness
|
||||
runs-on: 'macos-14-xlarge'
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
|
||||
12
.github/workflows/release.yml
vendored
12
.github/workflows/release.yml
vendored
@@ -65,13 +65,9 @@ jobs:
|
||||
|
||||
build-mac:
|
||||
name: build-mac
|
||||
runs-on: ${{ matrix.os }}
|
||||
runs-on: macos-14-xlarge
|
||||
if: github.event_name == 'release' || github.event.inputs.platform == 'desktop'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-14-xlarge, ubuntu-22.04-32core]
|
||||
|
||||
steps:
|
||||
- name: Decide Git ref
|
||||
id: git_ref
|
||||
@@ -118,6 +114,7 @@ jobs:
|
||||
with:
|
||||
ref: ${{ steps.git_ref.outputs.ref }}
|
||||
- uses: ./.github/actions/linux-prereq
|
||||
- uses: ./.github/actions/web-prereq
|
||||
- name: Run build script
|
||||
env:
|
||||
TAG: ${{ steps.git_ref.outputs.tag }}
|
||||
@@ -166,6 +163,9 @@ jobs:
|
||||
mv out/filamat-android-release.aar out/filamat-${TAG}-android.aar
|
||||
mv out/gltfio-android-release.aar out/gltfio-${TAG}-android.aar
|
||||
mv out/filament-utils-android-release.aar out/filament-utils-${TAG}-android.aar
|
||||
cd out/android-release/filament
|
||||
tar -czf ../../filament-${TAG}-android-native.tgz .
|
||||
cd ../../..
|
||||
- name: Sign sample-gltf-viewer
|
||||
run: |
|
||||
echo "${APK_KEYSTORE_BASE64}" > filament.jks.base64
|
||||
@@ -187,7 +187,7 @@ jobs:
|
||||
script: |
|
||||
const upload = require('./build/common/upload-release-assets');
|
||||
const { TAG } = process.env;
|
||||
const globber = await glob.create(['out/*.aar', 'out/*.apk'].join('\n'));
|
||||
const globber = await glob.create(['out/*.aar', 'out/*.apk', 'out/*.tgz'].join('\n'));
|
||||
await upload({ github, context }, await globber.glob(), TAG);
|
||||
|
||||
build-ios:
|
||||
|
||||
1
.github/workflows/web-continuous.yml
vendored
1
.github/workflows/web-continuous.yml
vendored
@@ -17,6 +17,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: ./.github/actions/linux-prereq
|
||||
- uses: ./.github/actions/web-prereq
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/web && printf "y" | ./build.sh continuous
|
||||
|
||||
@@ -97,6 +97,10 @@ Make sure you've installed the following dependencies:
|
||||
- `libxcomposite-dev` (`libXcomposite-devel` on Fedora)
|
||||
- `libxxf86vm-dev` (`libXxf86vm-devel` on Fedora)
|
||||
|
||||
```shell
|
||||
sudo apt install clang-14 libglu1-mesa-dev libc++-14-dev libc++abi-14-dev ninja-build libxi-dev libxcomposite-dev libxxf86vm-dev -y
|
||||
```
|
||||
|
||||
After dependencies have been installed, we highly recommend using the [easy build](#easy-build)
|
||||
script.
|
||||
|
||||
@@ -363,6 +367,8 @@ python ./emsdk.py activate latest
|
||||
source ./emsdk_env.sh
|
||||
```
|
||||
|
||||
Alternatively, you can try running the script `build/common/get-emscripten.sh`.
|
||||
|
||||
After this you can invoke the [easy build](#easy-build) script as follows:
|
||||
|
||||
```shell
|
||||
|
||||
@@ -49,6 +49,10 @@ option(FILAMENT_SUPPORTS_OSMESA "Enable OSMesa (headless GL context) for Filamen
|
||||
|
||||
option(FILAMENT_ENABLE_FGVIEWER "Enable the frame graph viewer" OFF)
|
||||
|
||||
# This is to disable GTAO for the short-term while we investigate a way to better manage size increases.
|
||||
# On the regular filament build (where size is of less concern), we enable GTAO by default.
|
||||
option(FILAMENT_DISABLE_GTAO "Disable GTAO" OFF)
|
||||
|
||||
set(FILAMENT_NDK_VERSION "" CACHE STRING
|
||||
"Android NDK version or version prefix to be used when building for Android."
|
||||
)
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.59.4'
|
||||
implementation 'com.google.android.filament:filament-android:1.60.1'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```shell
|
||||
pod 'Filament', '~> 1.59.4'
|
||||
pod 'Filament', '~> 1.60.1'
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -7,6 +7,22 @@ A new header is inserted each time a *tag* is created.
|
||||
Instead, if you are authoring a PR for the main branch, add your release note to
|
||||
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
|
||||
|
||||
## v1.61.0
|
||||
|
||||
- materials: sampler now export their type in the material binary [⚠️ **New Material Version**]
|
||||
- samples/texturedquad.cpp now has CLI to select backend api
|
||||
- samples/hellopbr.cpp CLI now allows for selecting webgpu
|
||||
|
||||
## v1.60.1
|
||||
|
||||
|
||||
## v1.60.0
|
||||
|
||||
- materials: remove dependence on per-view descset layout from filamat. [⚠️ **New Material Version**]
|
||||
- matc non-functional change: Update GLSL postprocessor to
|
||||
isolate calls to SPVRemap from calls to SPIRV-Cross.
|
||||
|
||||
|
||||
## v1.59.5
|
||||
|
||||
|
||||
|
||||
@@ -1801,6 +1801,22 @@ public class View {
|
||||
* @see setAmbientOcclusionOptions()
|
||||
*/
|
||||
public static class AmbientOcclusionOptions {
|
||||
public enum AmbientOcclusionType {
|
||||
/**
|
||||
* use Scalable Ambient Occlusion
|
||||
*/
|
||||
SAO,
|
||||
/**
|
||||
* use Ground Truth-Based Ambient Occlusion
|
||||
*/
|
||||
GTAO,
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of ambient occlusion algorithm.
|
||||
*/
|
||||
@NonNull
|
||||
public AmbientOcclusionOptions.AmbientOcclusionType aoType = AmbientOcclusionOptions.AmbientOcclusionType.SAO;
|
||||
/**
|
||||
* Ambient Occlusion radius in meters, between 0 and ~10.
|
||||
*/
|
||||
@@ -1810,7 +1826,8 @@ public class View {
|
||||
*/
|
||||
public float power = 1.0f;
|
||||
/**
|
||||
* Self-occlusion bias in meters. Use to avoid self-occlusion. Between 0 and a few mm.
|
||||
* Self-occlusion bias in meters. Use to avoid self-occlusion.
|
||||
* Between 0 and a few mm. No effect when aoType set to GTAO
|
||||
*/
|
||||
public float bias = 0.0005f;
|
||||
/**
|
||||
@@ -1826,12 +1843,12 @@ public class View {
|
||||
*/
|
||||
public float bilateralThreshold = 0.05f;
|
||||
/**
|
||||
* affects # of samples used for AO.
|
||||
* affects # of samples used for AO and params for filtering
|
||||
*/
|
||||
@NonNull
|
||||
public QualityLevel quality = QualityLevel.LOW;
|
||||
/**
|
||||
* affects AO smoothness
|
||||
* affects AO smoothness. Recommend setting to HIGH when aoType set to GTAO.
|
||||
*/
|
||||
@NonNull
|
||||
public QualityLevel lowPassFilter = QualityLevel.MEDIUM;
|
||||
@@ -1849,7 +1866,7 @@ public class View {
|
||||
*/
|
||||
public boolean bentNormals = false;
|
||||
/**
|
||||
* min angle in radian to consider
|
||||
* min angle in radian to consider. No effect when aoType set to GTAO.
|
||||
*/
|
||||
public float minHorizonAngleRad = 0.0f;
|
||||
/**
|
||||
@@ -1904,6 +1921,19 @@ public class View {
|
||||
*/
|
||||
public boolean ssctEnabled = false;
|
||||
|
||||
/**
|
||||
* Ground Truth-base Ambient Occlusion (GTAO) options
|
||||
*/
|
||||
public int gtaoSampleSliceCount = 4;
|
||||
/**
|
||||
* Ground Truth-base Ambient Occlusion (GTAO) options
|
||||
*/
|
||||
public int gtaoSampleStepsPerSlice = 3;
|
||||
/**
|
||||
* Ground Truth-base Ambient Occlusion (GTAO) options
|
||||
*/
|
||||
public float gtaoThicknessHeuristic = 0.004f;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.59.4
|
||||
VERSION_NAME=1.60.1
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
12
build.sh
12
build.sh
@@ -151,7 +151,7 @@ function print_fgviewer_help {
|
||||
}
|
||||
|
||||
# Unless explicitly specified, NDK version will be selected as highest available version within same major release chain
|
||||
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/build/android/ndk.version | cut -f 1 -d ".")}
|
||||
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/build/common/versions | grep GITHUB_NDK_VERSION | sed s/GITHUB_NDK_VERSION=//g | cut -f 1 -d ".")}
|
||||
|
||||
# Requirements
|
||||
CMAKE_MAJOR=3
|
||||
@@ -463,16 +463,6 @@ function ensure_android_build {
|
||||
echo "Error: Android NDK side-by-side version ${FILAMENT_NDK_VERSION} or compatible must be installed, exiting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local cmake_version=$(cmake --version)
|
||||
if [[ "${cmake_version}" =~ ([0-9]+)\.([0-9]+)\.[0-9]+ ]]; then
|
||||
if [[ "${BASH_REMATCH[1]}" -lt "${CMAKE_MAJOR}" ]] || \
|
||||
[[ "${BASH_REMATCH[2]}" -lt "${CMAKE_MINOR}" ]]; then
|
||||
echo "Error: cmake version ${CMAKE_MAJOR}.${CMAKE_MINOR}+ is required," \
|
||||
"${BASH_REMATCH[1]}.${BASH_REMATCH[2]} installed, exiting"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function build_android {
|
||||
|
||||
@@ -1,28 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: the first argument selects the build type:
|
||||
# - release, to build release only
|
||||
# - debug, to build debug only
|
||||
# - continuous, to build release and debug
|
||||
# - presubmit, for presubmit builds
|
||||
#
|
||||
# The default is release
|
||||
|
||||
echo "This script is intended to run in a CI environment and may modify your current environment."
|
||||
echo "Please refer to BUILDING.md for more information."
|
||||
|
||||
read -r -p "Do you wish to proceed (y/n)? " choice
|
||||
case "${choice}" in
|
||||
y|Y)
|
||||
echo "Build will proceed..."
|
||||
;;
|
||||
n|N)
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
source `dirname $0`/../common/ci-check.sh
|
||||
|
||||
set -e
|
||||
set -x
|
||||
@@ -30,11 +8,6 @@ set -x
|
||||
UNAME=`echo $(uname)`
|
||||
LC_UNAME=`echo $UNAME | tr '[:upper:]' '[:lower:]'`
|
||||
|
||||
# build-common.sh will generate the following variables:
|
||||
# $GENERATE_ARCHIVES
|
||||
# $BUILD_DEBUG
|
||||
# $BUILD_RELEASE
|
||||
source `dirname $0`/../common/ci-common.sh
|
||||
source `dirname $0`/../common/build-common.sh
|
||||
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# build-common.sh will generate the following variables:
|
||||
# $GENERATE_ARCHIVES
|
||||
# $BUILD_DEBUG
|
||||
# $BUILD_RELEASE
|
||||
|
||||
# Typically a build script (build.sh) would source this script. For example,
|
||||
# source `dirname $0`/../common/build-common.sh
|
||||
|
||||
# Usage: the first argument selects the build type:
|
||||
# - release, to build release only
|
||||
# - debug, to build debug only
|
||||
# - continuous, to build release and debug
|
||||
# - presubmit, for presubmit builds
|
||||
#
|
||||
# The default is release
|
||||
if [[ ! "$TARGET" ]]; then
|
||||
if [[ "$1" ]]; then
|
||||
TARGET=$1
|
||||
|
||||
19
build/common/ci-check.sh
Normal file
19
build/common/ci-check.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
echo "This script is intended to run in a CI environment and may modify your current environment."
|
||||
echo "Please refer to BUILDING.md for more information."
|
||||
|
||||
read -r -p "Do you wish to proceed (y/n)? " choice
|
||||
case "${choice}" in
|
||||
y|Y)
|
||||
echo "Build will proceed..."
|
||||
;;
|
||||
n|N)
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
echo "Running workflow $GITHUB_WORKFLOW (event: $GITHUB_EVENT_NAME, action: $GITHUB_ACTION)"
|
||||
fi
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
echo "Running workflow $GITHUB_WORKFLOW (event: $GITHUB_EVENT_NAME, action: $GITHUB_ACTION)"
|
||||
fi
|
||||
22
build/common/get-emscripten.sh
Executable file
22
build/common/get-emscripten.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -d "./emsdk" ]; then
|
||||
echo "emsdk folder found. Assume emsdk has been installed."
|
||||
cd emsdk
|
||||
./emsdk activate latest
|
||||
source ./emsdk_env.sh
|
||||
export EMSDK="$PWD"
|
||||
cd ..
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Install emscripten.
|
||||
EMSDK_VERSION=${GITHUB_EMSDK_VERSION-3.1.60}
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/${EMSDK_VERSION}.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
./emsdk install latest
|
||||
./emsdk activate latest
|
||||
source ./emsdk_env.sh
|
||||
|
||||
export EMSDK="$PWD"
|
||||
cd ..
|
||||
@@ -14,9 +14,9 @@
|
||||
|
||||
#!/usr/bin/bash
|
||||
|
||||
set -x
|
||||
set -e
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
set -e
|
||||
set -x
|
||||
fi
|
||||
|
||||
OS_NAME=$(uname -s)
|
||||
@@ -35,7 +35,7 @@ source ${ORIG_DIR}/venv/bin/activate
|
||||
|
||||
NEEDED_PYTHON_DEPS=("mako" "setuptools" "pyyaml")
|
||||
for cmd in "${NEEDED_PYTHON_DEPS[@]}"; do
|
||||
if ! python3 -m pip show "${cmd}" >/dev/null 2>&1; then
|
||||
if ! python3 -m pip show -q "${cmd}" >/dev/null 2>&1; then
|
||||
python3 -m pip install ${cmd}
|
||||
fi
|
||||
done
|
||||
@@ -145,6 +145,6 @@ deactivate
|
||||
popd
|
||||
|
||||
if [[ "$GITHUB_WORKFLOW" ]]; then
|
||||
set +e
|
||||
set +x
|
||||
fi
|
||||
set +x
|
||||
set +e
|
||||
@@ -3,4 +3,5 @@ GITHUB_CMAKE_VERSION=3.19.5
|
||||
GITHUB_NINJA_VERSION=1.10.2
|
||||
GITHUB_MESA_VERSION=24.2.1
|
||||
GITHUB_LLVM_VERSION=16
|
||||
GITHUB_NDK_VERSION=27.0.11718014
|
||||
GITHUB_NDK_VERSION=27.0.11718014
|
||||
GITHUB_EMSDK_VERSION=3.1.60
|
||||
@@ -1,35 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: the first argument selects the build type:
|
||||
# - release, to build release only
|
||||
# - debug, to build debug only
|
||||
# - continuous, to build release and debug
|
||||
# - presubmit, for presubmit builds
|
||||
#
|
||||
# The default is release
|
||||
|
||||
echo "This script is intended to run in a CI environment and may modify your current environment."
|
||||
echo "Please refer to BUILDING.md for more information."
|
||||
|
||||
read -r -p "Do you wish to proceed (y/n)? " choice
|
||||
case "${choice}" in
|
||||
y|Y)
|
||||
echo "Build will proceed..."
|
||||
;;
|
||||
n|N)
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
source `dirname $0`/../common/ci-check.sh
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
source `dirname $0`/../common/ci-common.sh
|
||||
source `dirname $0`/../common/build-common.sh
|
||||
|
||||
pushd `dirname $0`/../.. > /dev/null
|
||||
|
||||
# If we're generating an archive for release or continuous builds, then we'll also build for the
|
||||
|
||||
@@ -1,38 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: the first argument selects the build type:
|
||||
# - release, to build release only
|
||||
# - debug, to build debug only
|
||||
# - continuous, to build release and debug
|
||||
# - presubmit, for presubmit builds
|
||||
#
|
||||
# The default is release
|
||||
|
||||
echo "This script is intended to run in a CI environment and may modify your current environment."
|
||||
echo "Please refer to BUILDING.md for more information."
|
||||
|
||||
read -r -p "Do you wish to proceed (y/n)? " choice
|
||||
case "${choice}" in
|
||||
y|Y)
|
||||
echo "Build will proceed..."
|
||||
;;
|
||||
n|N)
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
source `dirname $0`/../common/ci-check.sh
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# build-common.sh will generate the following variables:
|
||||
# $GENERATE_ARCHIVES
|
||||
# $BUILD_DEBUG
|
||||
# $BUILD_RELEASE
|
||||
source `dirname $0`/../common/ci-common.sh
|
||||
source `dirname $0`/../common/build-common.sh
|
||||
|
||||
pushd `dirname $0`/../.. > /dev/null
|
||||
|
||||
./build.sh -c $RUN_TESTS $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
|
||||
|
||||
@@ -1,34 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: the first argument selects the build type:
|
||||
# - release, to build release only
|
||||
# - debug, to build debug only
|
||||
# - continuous, to build release and debug
|
||||
# - presubmit, for presubmit builds
|
||||
#
|
||||
# The default is release
|
||||
|
||||
echo "This script is intended to run in a CI environment and may modify your current environment."
|
||||
echo "Please refer to BUILDING.md for more information."
|
||||
|
||||
read -r -p "Do you wish to proceed (y/n)? " choice
|
||||
case "${choice}" in
|
||||
y|Y)
|
||||
echo "Build will proceed..."
|
||||
;;
|
||||
n|N)
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
source `dirname $0`/../common/ci-check.sh
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
source `dirname $0`/../common/ci-common.sh
|
||||
source `dirname $0`/../common/build-common.sh
|
||||
|
||||
pushd `dirname $0`/../.. > /dev/null
|
||||
|
||||
./build.sh -c $RUN_TESTS $GENERATE_ARCHIVES $BUILD_DEBUG $BUILD_RELEASE
|
||||
|
||||
@@ -1,34 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: the first argument selects the build type:
|
||||
# - release, to build release only
|
||||
# - debug, to build debug only
|
||||
# - continuous, to build release and debug
|
||||
# - presubmit, for presubmit builds
|
||||
#
|
||||
# The default is release
|
||||
|
||||
echo "This script is intended to run in a CI environment and may modify your current environment."
|
||||
echo "Please refer to BUILDING.md for more information."
|
||||
|
||||
read -r -p "Do you wish to proceed (y/n)? " choice
|
||||
case "${choice}" in
|
||||
y|Y)
|
||||
echo "Build will proceed..."
|
||||
;;
|
||||
n|N)
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
source `dirname $0`/../common/ci-check.sh
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
source `dirname $0`/../common/ci-common.sh
|
||||
source `dirname $0`/ci-common.sh
|
||||
source `dirname $0`/../common/build-common.sh
|
||||
pushd `dirname $0`/../.. > /dev/null
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Install emscripten.
|
||||
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.60.zip > emsdk.zip
|
||||
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
|
||||
./emsdk install latest
|
||||
./emsdk activate latest
|
||||
source ./emsdk_env.sh
|
||||
|
||||
export EMSDK="$PWD"
|
||||
cd ..
|
||||
@@ -1023,8 +1023,12 @@ samplerCubemap | Cubemap texture
|
||||
[Table [materialParamsTypes]: Material parameter types]
|
||||
|
||||
Samplers
|
||||
: Sampler types can also specify a `format` which can be either `int` or `float` (defaults to
|
||||
`float`).
|
||||
: Sampler types can specify additional options:
|
||||
|
||||
- `format`: either `int` or `float` (defaults to `float`).
|
||||
- `stages`: array of strings containing the list of shader stages this
|
||||
sampler can be accessed from. Each entry must be either `vertex` or
|
||||
`fragment` (defaults to both).
|
||||
|
||||
Arrays
|
||||
: A parameter can define an array of values by appending `[size]` after the type name, where
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
- [Metal](./notes/metal_debugging.md)
|
||||
- [Vulkan](./notes/vulkan_debugging.md)
|
||||
- [SPIR-V](./notes/spirv_debugging.md)
|
||||
- [Running with ASAN and UBSAN](./notes/asan_ubsan.md)
|
||||
- [Using Instruments on macOS](./notes/instruments.md)
|
||||
- [Libraries](./notes/libs.md)
|
||||
- [bluegl](./dup/bluegl.md)
|
||||
- [bluevk](./dup/bluevk.md)
|
||||
|
||||
41
docs_src/src/notes/asan_ubsan.md
Normal file
41
docs_src/src/notes/asan_ubsan.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Running with ASAN/UBSAN
|
||||
|
||||
## Enabling
|
||||
|
||||
When building though build.sh, pass the `-b` flag. This sets the cmake variable
|
||||
`FILAMENT_ENABLE_ASAN_UBSAN=ON` which eventually passes `"-fsanitize=address -fsanitize=undefined"`
|
||||
to all compile and link operations.
|
||||
|
||||
If building through CMake directly, or an IDE like CLion that doesn't use build.sh, instead pass
|
||||
`-DFILAMENT_ENABLE_ASAN_UBSAN=ON` to cmake in order to get the same result.
|
||||
|
||||
## Getting memory leak detection on Mac
|
||||
|
||||
Memory leak detection isn't enabled by default on MacOS. There are two issues to address, first is
|
||||
using a version of clang that supports memory leak detection and second is enabling it at runtime.
|
||||
|
||||
The version of clang distributed by Apple (with a version like "Apple clang version 16.0.0") doesn't
|
||||
currently support leak detection at all. Instead you will need to get or build a different LLVM,
|
||||
such as the one distributed through homebrew and get CMake to use that instead.
|
||||
|
||||
Then during runtime you'll need to have the environment variable `ASAN_OPTIONS` include the option
|
||||
`detect_leaks=1`. Multiple `ASAN_OPTIONS` values are concatenated with `:`.
|
||||
|
||||
## Getting memory leak output in CLion
|
||||
|
||||
### Setting variables
|
||||
|
||||
Under `Settings | Build, Execution, Deployment | Dynamic Analysis Tools | Sanitizers` there is an
|
||||
ASAN Settings field that overrides whatever other `ASAN_OPTIONS` you might set elsewhere, so you
|
||||
must use that instead of setting it through your Run/Debug Configuration.
|
||||
|
||||
To pass `-DFILAMENT_ENABLE_ASAN_UBSAN=ON` to CMake you'll want to create a new CMake Profile and
|
||||
pass it as a CMake argument.
|
||||
|
||||
### Avoiding losing output
|
||||
|
||||
CMake will consume ASAN output and display it through a separate "Sanitizers" tab. Unfortunately
|
||||
certain leak detection errors that interrupt the executable seem to not show up in this tab, but are
|
||||
still removed from the user-visible console output. If this is happening and you need to see the
|
||||
unfiltered console output you'll need to go to `Settings | Build, Execution, Deployment | Dynamic
|
||||
Analysis Tools | Sanitizers` and uncheck "Use visual representation for Sanitizer's output".
|
||||
36
docs_src/src/notes/instruments.md
Normal file
36
docs_src/src/notes/instruments.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Using Instruments on macOS
|
||||
|
||||
When running a binary under Instruments on macOS, you may run into the following issue when
|
||||
launching or attaching to an executable:
|
||||
|
||||
```
|
||||
Failed to gain authorization
|
||||
Recovery Suggestion: Target binary needs to be debuggable and signed with 'get-task-allow'
|
||||
```
|
||||
|
||||
This is a security precaution; the solution is to code sign the binary with the
|
||||
`com.apple.security.get-task-allow` entitlement.
|
||||
|
||||
1. Create an `entitlements.plist` file with the following contents:
|
||||
|
||||
```
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.get-task-allow</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
2. Run the following command:
|
||||
|
||||
```
|
||||
codesign -s - --entitlements entitlements.plist <binary>
|
||||
```
|
||||
|
||||
Replace `<binary>` with the name of the binary, for example: `out/cmake-debug/samples/gltf_viewer`.
|
||||
|
||||
Afterwards, you should be able to successfully launch and attach to the executable using
|
||||
Instruments.
|
||||
@@ -265,6 +265,13 @@ set(MATERIAL_SRCS
|
||||
src/materials/vsmMipmap.mat
|
||||
)
|
||||
|
||||
if (NOT FILAMENT_DISABLE_GTAO)
|
||||
list(APPEND MATERIAL_SRCS
|
||||
src/materials/ssao/gtao.mat
|
||||
src/materials/ssao/gtaoBentNormals.mat
|
||||
)
|
||||
endif()
|
||||
|
||||
set(MATERIAL_FL0_SRCS
|
||||
src/materials/defaultMaterial.mat
|
||||
src/materials/skybox.mat
|
||||
@@ -314,12 +321,14 @@ if (FILAMENT_FORCE_PROFILING_MODE)
|
||||
add_definitions(-DFILAMENT_FORCE_PROFILING_MODE)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_DISABLE_GTAO)
|
||||
add_definitions(-DFILAMENT_DISABLE_GTAO)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Definitions
|
||||
# ==================================================================================================
|
||||
|
||||
# "2" corresponds to SYSTRACE_TAG_FILEMENT (See: utils/Systrace.h)
|
||||
add_definitions(-DSYSTRACE_TAG=2)
|
||||
add_definitions(-DFILAMENT_DFG_LUT_SIZE=${DFG_LUT_SIZE})
|
||||
add_definitions(
|
||||
-DFILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB=${FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB}
|
||||
@@ -463,6 +472,30 @@ add_custom_command(
|
||||
APPEND
|
||||
)
|
||||
|
||||
if (NOT FILAMENT_DISABLE_GTAO)
|
||||
add_custom_command(
|
||||
OUTPUT "${MATERIAL_DIR}/gtao.filamat"
|
||||
DEPENDS src/materials/ssao/ssaoUtils.fs
|
||||
DEPENDS src/materials/ssao/ssct.fs
|
||||
DEPENDS src/materials/utils/depthUtils.fs
|
||||
DEPENDS src/materials/utils/geometry.fs
|
||||
DEPENDS src/materials/ssao/gtaoImpl.fs
|
||||
DEPENDS src/materials/ssao/ssctImpl.fs
|
||||
APPEND
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${MATERIAL_DIR}/gtaoBentNormals.filamat"
|
||||
DEPENDS src/materials/ssao/ssaoUtils.fs
|
||||
DEPENDS src/materials/ssao/ssct.fs
|
||||
DEPENDS src/materials/utils/depthUtils.fs
|
||||
DEPENDS src/materials/utils/geometry.fs
|
||||
DEPENDS src/materials/ssao/gtaoImpl.fs
|
||||
DEPENDS src/materials/ssao/ssctImpl.fs
|
||||
APPEND
|
||||
)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "${MATERIAL_DIR}/bilateralBlur.filamat"
|
||||
DEPENDS src/materials/ssao/ssaoUtils.fs
|
||||
|
||||
@@ -261,6 +261,7 @@ if (FILAMENT_SUPPORTS_WEBGPU)
|
||||
src/webgpu/WebGPUHandles.h
|
||||
src/webgpu/WebGPUPipelineCreation.cpp
|
||||
src/webgpu/WebGPUPipelineCreation.h
|
||||
src/webgpu/WebGPUStrings.h
|
||||
src/webgpu/WebGPUSwapChain.cpp
|
||||
src/webgpu/WebGPUSwapChain.h
|
||||
src/webgpu/WGPUProgram.cpp
|
||||
@@ -290,12 +291,6 @@ if (ANDROID)
|
||||
list(APPEND SRCS src/BackendUtilsAndroid.cpp)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Definitions
|
||||
# ==================================================================================================
|
||||
# "2" corresponds to SYSTRACE_TAG_FILEMENT (See: utils/Systrace.h)
|
||||
add_definitions(-DSYSTRACE_TAG=2 )
|
||||
|
||||
# ==================================================================================================
|
||||
# Includes & target definition
|
||||
# ==================================================================================================
|
||||
|
||||
@@ -20,10 +20,15 @@
|
||||
#define TNT_FILAMENT_BACKEND_BUFFERDESCRIPTOR_H
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace utils::io {
|
||||
class ostream;
|
||||
} // namespace utils::io
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class CallbackHandler;
|
||||
@@ -89,8 +94,8 @@ public:
|
||||
* @param callback A callback used to release the CPU buffer from this BufferDescriptor
|
||||
* @param user An opaque user pointer passed to the callback function when it's called
|
||||
*/
|
||||
BufferDescriptor(void const* buffer, size_t size,
|
||||
Callback callback = nullptr, void* user = nullptr) noexcept
|
||||
BufferDescriptor(void const* buffer, size_t const size,
|
||||
Callback const callback = nullptr, void* user = nullptr) noexcept
|
||||
: buffer(const_cast<void*>(buffer)), size(size), mCallback(callback), mUser(user) {
|
||||
}
|
||||
|
||||
@@ -98,11 +103,12 @@ public:
|
||||
* Creates a BufferDescriptor that references a CPU memory-buffer
|
||||
* @param buffer Memory address of the CPU buffer to reference
|
||||
* @param size Size of the CPU buffer in bytes
|
||||
* @param handler A custom handler for the callback
|
||||
* @param callback A callback used to release the CPU buffer from this BufferDescriptor
|
||||
* @param user An opaque user pointer passed to the callback function when it's called
|
||||
*/
|
||||
BufferDescriptor(void const* buffer, size_t size,
|
||||
CallbackHandler* handler, Callback callback, void* user = nullptr) noexcept
|
||||
BufferDescriptor(void const* buffer, size_t const size,
|
||||
CallbackHandler* handler, Callback const callback, void* user = nullptr) noexcept
|
||||
: buffer(const_cast<void*>(buffer)), size(size),
|
||||
mCallback(callback), mUser(user), mHandler(handler) {
|
||||
}
|
||||
@@ -116,8 +122,9 @@ public:
|
||||
*
|
||||
* @param buffer Memory address of the CPU buffer to reference
|
||||
* @param size Size of the CPU buffer in bytes
|
||||
* @param data A pointer to the data
|
||||
* @param handler Handler to use to dispatch the callback, or nullptr for the default handler
|
||||
* @return a new BufferDescriptor
|
||||
* @return A new BufferDescriptor
|
||||
*/
|
||||
template<typename T, void(T::*method)(void const*, size_t)>
|
||||
static BufferDescriptor make(void const* buffer, size_t size, T* data,
|
||||
@@ -164,7 +171,7 @@ public:
|
||||
* @param callback The new callback function
|
||||
* @param user An opaque user pointer passed to the callbeck function when it's called
|
||||
*/
|
||||
void setCallback(Callback callback, void* user = nullptr) noexcept {
|
||||
void setCallback(Callback const callback, void* user = nullptr) noexcept {
|
||||
this->mCallback = callback;
|
||||
this->mUser = user;
|
||||
this->mHandler = nullptr;
|
||||
@@ -176,7 +183,7 @@ public:
|
||||
* @param callback The new callback function
|
||||
* @param user An opaque user pointer passed to the callbeck function when it's called
|
||||
*/
|
||||
void setCallback(CallbackHandler* handler, Callback callback, void* user = nullptr) noexcept {
|
||||
void setCallback(CallbackHandler* handler, Callback const callback, void* user = nullptr) noexcept {
|
||||
mCallback = callback;
|
||||
mUser = user;
|
||||
mHandler = handler;
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#include <backend/DriverApiForward.h>
|
||||
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
|
||||
@@ -28,6 +26,10 @@
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
namespace utils::io {
|
||||
class ostream;
|
||||
} // namespace utils::io
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
void* allocateFromCommandStream(DriverApi& driver, size_t size, size_t alignment) noexcept;
|
||||
|
||||
@@ -25,21 +25,26 @@
|
||||
#include <backend/PresentCallable.h>
|
||||
|
||||
#include <utils/BitmaskEnum.h>
|
||||
#include <utils/CString.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/Invocable.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/StaticString.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <math/vec4.h>
|
||||
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
#include <string_view>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace utils::io {
|
||||
class ostream;
|
||||
} // namespace utils::io
|
||||
|
||||
/**
|
||||
* Types and enums used by filament's driver.
|
||||
*
|
||||
@@ -158,7 +163,7 @@ enum class TimerQueryResult : int8_t {
|
||||
AVAILABLE = 1, // result is available
|
||||
};
|
||||
|
||||
static constexpr const char* backendToString(Backend backend) {
|
||||
constexpr std::string_view to_string(Backend const backend) noexcept {
|
||||
switch (backend) {
|
||||
case Backend::NOOP:
|
||||
return "Noop";
|
||||
@@ -170,9 +175,10 @@ static constexpr const char* backendToString(Backend backend) {
|
||||
return "Metal";
|
||||
case Backend::WEBGPU:
|
||||
return "WebGPU";
|
||||
default:
|
||||
return "Unknown";
|
||||
case Backend::DEFAULT:
|
||||
return "Default";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,7 +195,7 @@ enum class ShaderLanguage {
|
||||
WGSL = 5,
|
||||
};
|
||||
|
||||
static constexpr const char* shaderLanguageToString(ShaderLanguage shaderLanguage) {
|
||||
constexpr const char* shaderLanguageToString(ShaderLanguage shaderLanguage) noexcept {
|
||||
switch (shaderLanguage) {
|
||||
case ShaderLanguage::ESSL1:
|
||||
return "ESSL 1.0";
|
||||
@@ -204,6 +210,7 @@ static constexpr const char* shaderLanguageToString(ShaderLanguage shaderLanguag
|
||||
case ShaderLanguage::WGSL:
|
||||
return "WGSL";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
enum class ShaderStage : uint8_t {
|
||||
@@ -221,7 +228,7 @@ enum class ShaderStageFlags : uint8_t {
|
||||
ALL_SHADER_STAGE_FLAGS = VERTEX | FRAGMENT | COMPUTE
|
||||
};
|
||||
|
||||
static inline constexpr bool hasShaderType(ShaderStageFlags flags, ShaderStage type) noexcept {
|
||||
constexpr bool hasShaderType(ShaderStageFlags flags, ShaderStage type) noexcept {
|
||||
switch (type) {
|
||||
case ShaderStage::VERTEX:
|
||||
return bool(uint8_t(flags) & uint8_t(ShaderStageFlags::VERTEX));
|
||||
@@ -232,14 +239,239 @@ static inline constexpr bool hasShaderType(ShaderStageFlags flags, ShaderStage t
|
||||
}
|
||||
}
|
||||
|
||||
enum class DescriptorType : uint8_t {
|
||||
UNIFORM_BUFFER,
|
||||
SHADER_STORAGE_BUFFER,
|
||||
SAMPLER,
|
||||
INPUT_ATTACHMENT,
|
||||
SAMPLER_EXTERNAL
|
||||
enum class TextureType : uint8_t {
|
||||
FLOAT,
|
||||
INT,
|
||||
UINT,
|
||||
DEPTH,
|
||||
STENCIL,
|
||||
DEPTH_STENCIL
|
||||
};
|
||||
|
||||
constexpr std::string_view to_string(TextureType type) noexcept {
|
||||
switch (type) {
|
||||
case TextureType::FLOAT: return "FLOAT";
|
||||
case TextureType::INT: return "INT";
|
||||
case TextureType::UINT: return "UINT";
|
||||
case TextureType::DEPTH: return "DEPTH";
|
||||
case TextureType::STENCIL: return "STENCIL";
|
||||
case TextureType::DEPTH_STENCIL: return "DEPTH_STENCIL";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
enum class DescriptorType : uint8_t {
|
||||
SAMPLER_2D_FLOAT,
|
||||
SAMPLER_2D_INT,
|
||||
SAMPLER_2D_UINT,
|
||||
SAMPLER_2D_DEPTH,
|
||||
|
||||
SAMPLER_2D_ARRAY_FLOAT,
|
||||
SAMPLER_2D_ARRAY_INT,
|
||||
SAMPLER_2D_ARRAY_UINT,
|
||||
SAMPLER_2D_ARRAY_DEPTH,
|
||||
|
||||
SAMPLER_CUBE_FLOAT,
|
||||
SAMPLER_CUBE_INT,
|
||||
SAMPLER_CUBE_UINT,
|
||||
SAMPLER_CUBE_DEPTH,
|
||||
|
||||
SAMPLER_CUBE_ARRAY_FLOAT,
|
||||
SAMPLER_CUBE_ARRAY_INT,
|
||||
SAMPLER_CUBE_ARRAY_UINT,
|
||||
SAMPLER_CUBE_ARRAY_DEPTH,
|
||||
|
||||
SAMPLER_3D_FLOAT,
|
||||
SAMPLER_3D_INT,
|
||||
SAMPLER_3D_UINT,
|
||||
|
||||
SAMPLER_2D_MS_FLOAT,
|
||||
SAMPLER_2D_MS_INT,
|
||||
SAMPLER_2D_MS_UINT,
|
||||
|
||||
SAMPLER_2D_MS_ARRAY_FLOAT,
|
||||
SAMPLER_2D_MS_ARRAY_INT,
|
||||
SAMPLER_2D_MS_ARRAY_UINT,
|
||||
|
||||
SAMPLER_EXTERNAL,
|
||||
UNIFORM_BUFFER,
|
||||
SHADER_STORAGE_BUFFER,
|
||||
INPUT_ATTACHMENT,
|
||||
};
|
||||
|
||||
constexpr bool isDepthDescriptor(DescriptorType const type) noexcept {
|
||||
switch (type) {
|
||||
case DescriptorType::SAMPLER_2D_DEPTH:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_DEPTH:
|
||||
return true;
|
||||
default: ;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool isFloatDescriptor(DescriptorType const type) noexcept {
|
||||
switch (type) {
|
||||
case DescriptorType::SAMPLER_2D_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_3D_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_FLOAT:
|
||||
return true;
|
||||
default: ;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool isIntDescriptor(DescriptorType const type) noexcept {
|
||||
switch (type) {
|
||||
case DescriptorType::SAMPLER_2D_INT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_3D_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_INT:
|
||||
return true;
|
||||
default: ;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool isUnsignedIntDescriptor(DescriptorType const type) noexcept {
|
||||
switch (type) {
|
||||
case DescriptorType::SAMPLER_2D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_3D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_UINT:
|
||||
return true;
|
||||
default: ;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool is3dTypeDescriptor(DescriptorType const type) noexcept {
|
||||
switch (type) {
|
||||
case DescriptorType::SAMPLER_3D_FLOAT:
|
||||
case DescriptorType::SAMPLER_3D_INT:
|
||||
case DescriptorType::SAMPLER_3D_UINT:
|
||||
return true;
|
||||
default: ;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool is2dTypeDescriptor(DescriptorType const type) noexcept {
|
||||
switch (type) {
|
||||
case DescriptorType::SAMPLER_2D_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_INT:
|
||||
case DescriptorType::SAMPLER_2D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_DEPTH:
|
||||
case DescriptorType::SAMPLER_2D_MS_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_UINT:
|
||||
return true;
|
||||
default: ;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool is2dArrayTypeDescriptor(DescriptorType const type) noexcept {
|
||||
switch (type) {
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_UINT:
|
||||
return true;
|
||||
default: ;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool isCubeTypeDescriptor(DescriptorType const type) noexcept {
|
||||
switch (type) {
|
||||
case DescriptorType::SAMPLER_CUBE_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_DEPTH:
|
||||
return true;
|
||||
default: ;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool isCubeArrayTypeDescriptor(DescriptorType const type) noexcept {
|
||||
switch (type) {
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_DEPTH:
|
||||
return true;
|
||||
default: ;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr bool isMultiSampledTypeDescriptor(DescriptorType const type) noexcept {
|
||||
switch (type) {
|
||||
case DescriptorType::SAMPLER_2D_MS_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_UINT:
|
||||
return true;
|
||||
default: ;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
constexpr std::string_view to_string(DescriptorType type) noexcept {
|
||||
#define DESCRIPTOR_TYPE_CASE(TYPE) case DescriptorType::TYPE: return #TYPE;
|
||||
switch (type) {
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_FLOAT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_INT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_UINT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_DEPTH)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_ARRAY_FLOAT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_ARRAY_INT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_ARRAY_UINT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_ARRAY_DEPTH)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_CUBE_FLOAT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_CUBE_INT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_CUBE_UINT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_CUBE_DEPTH)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_CUBE_ARRAY_FLOAT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_CUBE_ARRAY_INT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_CUBE_ARRAY_UINT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_CUBE_ARRAY_DEPTH)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_3D_FLOAT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_3D_INT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_3D_UINT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_MS_FLOAT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_MS_INT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_MS_UINT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_MS_ARRAY_FLOAT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_MS_ARRAY_INT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_2D_MS_ARRAY_UINT)
|
||||
DESCRIPTOR_TYPE_CASE(SAMPLER_EXTERNAL)
|
||||
DESCRIPTOR_TYPE_CASE(UNIFORM_BUFFER)
|
||||
DESCRIPTOR_TYPE_CASE(SHADER_STORAGE_BUFFER)
|
||||
DESCRIPTOR_TYPE_CASE(INPUT_ATTACHMENT)
|
||||
}
|
||||
return "UNKNOWN";
|
||||
#undef DESCRIPTOR_TYPE_CASE
|
||||
}
|
||||
|
||||
enum class DescriptorFlags : uint8_t {
|
||||
NONE = 0x00,
|
||||
DYNAMIC_OFFSET = 0x01
|
||||
@@ -250,6 +482,13 @@ using descriptor_set_t = uint8_t;
|
||||
using descriptor_binding_t = uint8_t;
|
||||
|
||||
struct DescriptorSetLayoutBinding {
|
||||
static bool isSampler(DescriptorType type) noexcept {
|
||||
return int(type) <= int(DescriptorType::SAMPLER_EXTERNAL);
|
||||
}
|
||||
static bool isBuffer(DescriptorType type) noexcept {
|
||||
return type == DescriptorType::UNIFORM_BUFFER ||
|
||||
type == DescriptorType::SHADER_STORAGE_BUFFER;
|
||||
}
|
||||
DescriptorType type;
|
||||
ShaderStageFlags stageFlags;
|
||||
descriptor_binding_t binding;
|
||||
@@ -260,7 +499,7 @@ struct DescriptorSetLayoutBinding {
|
||||
// no uninitialized padding bytes.
|
||||
// uint8_t externalSamplerDataIndex = EXTERNAL_SAMPLER_DATA_INDEX_UNUSED;
|
||||
|
||||
friend inline bool operator==(DescriptorSetLayoutBinding const& lhs,
|
||||
friend bool operator==(DescriptorSetLayoutBinding const& lhs,
|
||||
DescriptorSetLayoutBinding const& rhs) noexcept {
|
||||
return lhs.type == rhs.type &&
|
||||
lhs.flags == rhs.flags &&
|
||||
@@ -293,7 +532,7 @@ enum class TargetBufferFlags : uint32_t {
|
||||
ALL = COLOR_ALL | DEPTH | STENCIL //!< Color, depth and stencil buffer selected.
|
||||
};
|
||||
|
||||
inline constexpr TargetBufferFlags getTargetBufferFlagsAt(size_t index) noexcept {
|
||||
constexpr TargetBufferFlags getTargetBufferFlagsAt(size_t index) noexcept {
|
||||
if (index == 0u) return TargetBufferFlags::COLOR0;
|
||||
if (index == 1u) return TargetBufferFlags::COLOR1;
|
||||
if (index == 2u) return TargetBufferFlags::COLOR2;
|
||||
@@ -450,6 +689,24 @@ enum class SamplerType : uint8_t {
|
||||
SAMPLER_CUBEMAP_ARRAY, //!< Cube map array texture (feature level 2)
|
||||
};
|
||||
|
||||
constexpr std::string_view to_string(SamplerType const type) noexcept {
|
||||
switch (type) {
|
||||
case SamplerType::SAMPLER_2D:
|
||||
return "SAMPLER_2D";
|
||||
case SamplerType::SAMPLER_2D_ARRAY:
|
||||
return "SAMPLER_2D_ARRAY";
|
||||
case SamplerType::SAMPLER_CUBEMAP:
|
||||
return "SAMPLER_CUBEMAP";
|
||||
case SamplerType::SAMPLER_EXTERNAL:
|
||||
return "SAMPLER_EXTERNAL";
|
||||
case SamplerType::SAMPLER_3D:
|
||||
return "SAMPLER_3D";
|
||||
case SamplerType::SAMPLER_CUBEMAP_ARRAY:
|
||||
return "SAMPLER_CUBEMAP_ARRAY";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
//! Subpass type
|
||||
enum class SubpassType : uint8_t {
|
||||
SUBPASS_INPUT
|
||||
@@ -463,6 +720,20 @@ enum class SamplerFormat : uint8_t {
|
||||
SHADOW = 3 //!< shadow sampler (PCF)
|
||||
};
|
||||
|
||||
constexpr std::string_view to_string(SamplerFormat const format) noexcept {
|
||||
switch (format) {
|
||||
case SamplerFormat::INT:
|
||||
return "INT";
|
||||
case SamplerFormat::UINT:
|
||||
return "UINT";
|
||||
case SamplerFormat::FLOAT:
|
||||
return "FLOAT";
|
||||
case SamplerFormat::SHADOW:
|
||||
return "SHADOW";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported element types
|
||||
*/
|
||||
@@ -502,6 +773,15 @@ enum class BufferObjectBinding : uint8_t {
|
||||
SHADER_STORAGE
|
||||
};
|
||||
|
||||
constexpr std::string_view to_string(BufferObjectBinding type) noexcept {
|
||||
switch (type) {
|
||||
case BufferObjectBinding::VERTEX: return "VERTEX";
|
||||
case BufferObjectBinding::UNIFORM: return "UNIFORM";
|
||||
case BufferObjectBinding::SHADER_STORAGE: return "SHADER_STORAGE";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
//! Face culling Mode
|
||||
enum class CullingMode : uint8_t {
|
||||
NONE, //!< No culling, front and back faces are visible
|
||||
@@ -763,6 +1043,8 @@ enum class TextureFormat : uint16_t {
|
||||
SRGB_ALPHA_BPTC_UNORM, // BC7 sRGB
|
||||
};
|
||||
|
||||
TextureType getTextureType(TextureFormat format) noexcept;
|
||||
|
||||
//! Bitmask describing the intended Texture Usage
|
||||
enum class TextureUsage : uint16_t {
|
||||
NONE = 0x0000,
|
||||
@@ -790,7 +1072,7 @@ enum class TextureSwizzle : uint8_t {
|
||||
};
|
||||
|
||||
//! returns whether this format a depth format
|
||||
static constexpr bool isDepthFormat(TextureFormat format) noexcept {
|
||||
constexpr bool isDepthFormat(TextureFormat format) noexcept {
|
||||
switch (format) {
|
||||
case TextureFormat::DEPTH32F:
|
||||
case TextureFormat::DEPTH24:
|
||||
@@ -803,7 +1085,7 @@ static constexpr bool isDepthFormat(TextureFormat format) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr bool isStencilFormat(TextureFormat format) noexcept {
|
||||
constexpr bool isStencilFormat(TextureFormat format) noexcept {
|
||||
switch (format) {
|
||||
case TextureFormat::STENCIL8:
|
||||
case TextureFormat::DEPTH24_STENCIL8:
|
||||
@@ -814,7 +1096,7 @@ static constexpr bool isStencilFormat(TextureFormat format) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
inline constexpr bool isColorFormat(TextureFormat format) noexcept {
|
||||
constexpr bool isColorFormat(TextureFormat format) noexcept {
|
||||
switch (format) {
|
||||
// Standard color formats
|
||||
case TextureFormat::R8:
|
||||
@@ -841,7 +1123,7 @@ inline constexpr bool isColorFormat(TextureFormat format) noexcept {
|
||||
return false;
|
||||
}
|
||||
|
||||
static constexpr bool isUnsignedIntFormat(TextureFormat format) {
|
||||
constexpr bool isUnsignedIntFormat(TextureFormat format) {
|
||||
switch (format) {
|
||||
case TextureFormat::R8UI:
|
||||
case TextureFormat::R16UI:
|
||||
@@ -862,7 +1144,7 @@ static constexpr bool isUnsignedIntFormat(TextureFormat format) {
|
||||
}
|
||||
}
|
||||
|
||||
static constexpr bool isSignedIntFormat(TextureFormat format) {
|
||||
constexpr bool isSignedIntFormat(TextureFormat format) {
|
||||
switch (format) {
|
||||
case TextureFormat::R8I:
|
||||
case TextureFormat::R16I:
|
||||
@@ -884,35 +1166,35 @@ static constexpr bool isSignedIntFormat(TextureFormat format) {
|
||||
}
|
||||
|
||||
//! returns whether this format is a compressed format
|
||||
static constexpr bool isCompressedFormat(TextureFormat format) noexcept {
|
||||
constexpr bool isCompressedFormat(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::EAC_R11;
|
||||
}
|
||||
|
||||
//! returns whether this format is an ETC2 compressed format
|
||||
static constexpr bool isETC2Compression(TextureFormat format) noexcept {
|
||||
constexpr bool isETC2Compression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::EAC_R11 && format <= TextureFormat::ETC2_EAC_SRGBA8;
|
||||
}
|
||||
|
||||
//! returns whether this format is an S3TC compressed format
|
||||
static constexpr bool isS3TCCompression(TextureFormat format) noexcept {
|
||||
constexpr bool isS3TCCompression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::DXT1_RGB && format <= TextureFormat::DXT5_SRGBA;
|
||||
}
|
||||
|
||||
static constexpr bool isS3TCSRGBCompression(TextureFormat format) noexcept {
|
||||
constexpr bool isS3TCSRGBCompression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::DXT1_SRGB && format <= TextureFormat::DXT5_SRGBA;
|
||||
}
|
||||
|
||||
//! returns whether this format is an RGTC compressed format
|
||||
static constexpr bool isRGTCCompression(TextureFormat format) noexcept {
|
||||
constexpr bool isRGTCCompression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::RED_RGTC1 && format <= TextureFormat::SIGNED_RED_GREEN_RGTC2;
|
||||
}
|
||||
|
||||
//! returns whether this format is an BPTC compressed format
|
||||
static constexpr bool isBPTCCompression(TextureFormat format) noexcept {
|
||||
constexpr bool isBPTCCompression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::RGB_BPTC_SIGNED_FLOAT && format <= TextureFormat::SRGB_ALPHA_BPTC_UNORM;
|
||||
}
|
||||
|
||||
static constexpr bool isASTCCompression(TextureFormat format) noexcept {
|
||||
constexpr bool isASTCCompression(TextureFormat format) noexcept {
|
||||
return format >= TextureFormat::RGBA_ASTC_4x4 && format <= TextureFormat::SRGB8_ALPHA8_ASTC_12x12;
|
||||
}
|
||||
|
||||
@@ -1033,19 +1315,23 @@ struct SamplerParams { // NOLINT
|
||||
assert_invariant(lhs.padding2 == 0);
|
||||
auto* pLhs = reinterpret_cast<uint32_t const*>(reinterpret_cast<char const*>(&lhs));
|
||||
auto* pRhs = reinterpret_cast<uint32_t const*>(reinterpret_cast<char const*>(&rhs));
|
||||
return *pLhs == *pRhs;
|
||||
return *pLhs < *pRhs;
|
||||
}
|
||||
};
|
||||
|
||||
bool isFiltered() const noexcept {
|
||||
return filterMag != SamplerMagFilter::NEAREST || filterMin != SamplerMinFilter::NEAREST;
|
||||
}
|
||||
|
||||
private:
|
||||
friend inline bool operator == (SamplerParams lhs, SamplerParams rhs) noexcept {
|
||||
return SamplerParams::EqualTo{}(lhs, rhs);
|
||||
friend bool operator == (SamplerParams lhs, SamplerParams rhs) noexcept {
|
||||
return EqualTo{}(lhs, rhs);
|
||||
}
|
||||
friend inline bool operator != (SamplerParams lhs, SamplerParams rhs) noexcept {
|
||||
return !SamplerParams::EqualTo{}(lhs, rhs);
|
||||
friend bool operator != (SamplerParams lhs, SamplerParams rhs) noexcept {
|
||||
return !EqualTo{}(lhs, rhs);
|
||||
}
|
||||
friend inline bool operator < (SamplerParams lhs, SamplerParams rhs) noexcept {
|
||||
return SamplerParams::LessThan{}(lhs, rhs);
|
||||
friend bool operator < (SamplerParams lhs, SamplerParams rhs) noexcept {
|
||||
return LessThan{}(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1095,15 +1381,15 @@ struct SamplerYcbcrConversion {// NOLINT
|
||||
};
|
||||
|
||||
private:
|
||||
friend inline bool operator == (SamplerYcbcrConversion lhs, SamplerYcbcrConversion rhs)
|
||||
friend bool operator == (SamplerYcbcrConversion lhs, SamplerYcbcrConversion rhs)
|
||||
noexcept {
|
||||
return SamplerYcbcrConversion::EqualTo{}(lhs, rhs);
|
||||
}
|
||||
friend inline bool operator != (SamplerYcbcrConversion lhs, SamplerYcbcrConversion rhs)
|
||||
friend bool operator != (SamplerYcbcrConversion lhs, SamplerYcbcrConversion rhs)
|
||||
noexcept {
|
||||
return !SamplerYcbcrConversion::EqualTo{}(lhs, rhs);
|
||||
}
|
||||
friend inline bool operator < (SamplerYcbcrConversion lhs, SamplerYcbcrConversion rhs)
|
||||
friend bool operator < (SamplerYcbcrConversion lhs, SamplerYcbcrConversion rhs)
|
||||
noexcept {
|
||||
return SamplerYcbcrConversion::LessThan{}(lhs, rhs);
|
||||
}
|
||||
@@ -1139,6 +1425,7 @@ struct ExternalSamplerDatum {
|
||||
static_assert(sizeof(ExternalSamplerDatum) == 12);
|
||||
|
||||
struct DescriptorSetLayout {
|
||||
std::variant<utils::StaticString, utils::CString, std::monostate> label;
|
||||
utils::FixedCapacityVector<DescriptorSetLayoutBinding> bindings;
|
||||
|
||||
// TODO: uncomment when needed
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
#ifndef TNT_FILAMENT_BACKEND_HANDLE_H
|
||||
#define TNT_FILAMENT_BACKEND_HANDLE_H
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
#include <utils/ostream.h>
|
||||
#endif
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <type_traits> // FIXME: STL headers are not allowed in public headers
|
||||
@@ -27,6 +24,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace utils::io {
|
||||
class ostream;
|
||||
} // namespace utils::io
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
struct HwBufferObject;
|
||||
|
||||
@@ -20,12 +20,14 @@
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace utils::io {
|
||||
class ostream;
|
||||
} // namespace utils::io
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
//! \privatesection
|
||||
|
||||
@@ -24,11 +24,14 @@
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace utils::io {
|
||||
class ostream;
|
||||
} // namespace utils::io
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
/**
|
||||
@@ -201,23 +204,15 @@ public:
|
||||
}, new T(std::forward<T>(functor))
|
||||
};
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Computes the size in bytes needed to fit an image of given dimensions and format
|
||||
* Computes the size in bytes for a pixel of given dimensions and format
|
||||
*
|
||||
* @param format Format of the image pixels
|
||||
* @param type Type of the image pixels
|
||||
* @param stride Stride of a row in pixels
|
||||
* @param height Height of the image in rows
|
||||
* @param alignment Alignment in bytes of pixel rows
|
||||
* @return The buffer size needed to fit this image in bytes
|
||||
* @return The size of the specified pixel in bytes
|
||||
*/
|
||||
static constexpr size_t computeDataSize(PixelDataFormat format, PixelDataType type,
|
||||
size_t stride, size_t height, size_t alignment) noexcept {
|
||||
assert_invariant(alignment);
|
||||
|
||||
static constexpr size_t computePixelSize(PixelDataFormat format, PixelDataType type) noexcept {
|
||||
if (type == PixelDataType::COMPRESSED) {
|
||||
return 0;
|
||||
}
|
||||
@@ -239,7 +234,7 @@ public:
|
||||
case PixelDataFormat::RGB_INTEGER:
|
||||
n = 3;
|
||||
break;
|
||||
case PixelDataFormat::UNUSED: // shouldn't happen (used to be rgbm)
|
||||
case PixelDataFormat::UNUSED:// shouldn't happen (used to be rgbm)
|
||||
case PixelDataFormat::RGBA:
|
||||
case PixelDataFormat::RGBA_INTEGER:
|
||||
n = 4;
|
||||
@@ -248,7 +243,7 @@ public:
|
||||
|
||||
size_t bpp = n;
|
||||
switch (type) {
|
||||
case PixelDataType::COMPRESSED: // Impossible -- to squash the IDE warnings
|
||||
case PixelDataType::COMPRESSED:// Impossible -- to squash the IDE warnings
|
||||
case PixelDataType::UBYTE:
|
||||
case PixelDataType::BYTE:
|
||||
// nothing to do
|
||||
@@ -279,16 +274,35 @@ public:
|
||||
bpp = 2;
|
||||
break;
|
||||
}
|
||||
return bpp;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Computes the size in bytes needed to fit an image of given dimensions and format
|
||||
*
|
||||
* @param format Format of the image pixels
|
||||
* @param type Type of the image pixels
|
||||
* @param stride Stride of a row in pixels
|
||||
* @param height Height of the image in rows
|
||||
* @param alignment Alignment in bytes of pixel rows
|
||||
* @return The buffer size needed to fit this image in bytes
|
||||
*/
|
||||
static constexpr size_t computeDataSize(PixelDataFormat format, PixelDataType type,
|
||||
size_t stride, size_t height, size_t alignment) noexcept {
|
||||
assert_invariant(alignment);
|
||||
|
||||
size_t bpp = computePixelSize(format, type);
|
||||
size_t const bpr = bpp * stride;
|
||||
size_t const bprAligned = (bpr + (alignment - 1)) & (~alignment + 1);
|
||||
return bprAligned * height;
|
||||
}
|
||||
|
||||
//! left coordinate in pixels
|
||||
uint32_t left = 0;
|
||||
uint32_t left = 0;
|
||||
//! top coordinate in pixels
|
||||
uint32_t top = 0;
|
||||
uint32_t top = 0;
|
||||
union {
|
||||
struct {
|
||||
//! stride in pixels
|
||||
|
||||
@@ -20,12 +20,10 @@
|
||||
#include <utils/CString.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/Invocable.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
@@ -33,6 +31,10 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace utils::io {
|
||||
class ostream;
|
||||
} // namespace utils::io
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class Program {
|
||||
@@ -44,8 +46,8 @@ public:
|
||||
|
||||
struct Descriptor {
|
||||
utils::CString name;
|
||||
backend::DescriptorType type;
|
||||
backend::descriptor_binding_t binding;
|
||||
DescriptorType type;
|
||||
descriptor_binding_t binding;
|
||||
};
|
||||
|
||||
struct SpecializationConstant {
|
||||
|
||||
@@ -19,22 +19,26 @@
|
||||
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <utils/ostream.h>
|
||||
#include <utility>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace utils::io {
|
||||
class ostream;
|
||||
} // namespace utils::io
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
//! \privatesection
|
||||
|
||||
struct TargetBufferInfo {
|
||||
// note: the parameters of this constructor are not in the order of this structure's fields
|
||||
TargetBufferInfo(Handle<HwTexture> handle, uint8_t level, uint16_t layer) noexcept
|
||||
: handle(handle), level(level), layer(layer) {
|
||||
TargetBufferInfo(Handle<HwTexture> handle, uint8_t const level, uint16_t const layer) noexcept
|
||||
: handle(std::move(handle)), level(level), layer(layer) {
|
||||
}
|
||||
|
||||
TargetBufferInfo(Handle<HwTexture> handle, uint8_t level) noexcept
|
||||
TargetBufferInfo(Handle<HwTexture> handle, uint8_t const level) noexcept
|
||||
: handle(handle), level(level) {
|
||||
}
|
||||
|
||||
@@ -70,11 +74,11 @@ private:
|
||||
TargetBufferInfo mInfos[MAX_SUPPORTED_RENDER_TARGET_COUNT];
|
||||
|
||||
public:
|
||||
TargetBufferInfo const& operator[](size_t i) const noexcept {
|
||||
TargetBufferInfo const& operator[](size_t const i) const noexcept {
|
||||
return mInfos[i];
|
||||
}
|
||||
|
||||
TargetBufferInfo& operator[](size_t i) noexcept {
|
||||
TargetBufferInfo& operator[](size_t const i) noexcept {
|
||||
return mInfos[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ public:
|
||||
*/
|
||||
virtual bool makeCurrent(ContextType type,
|
||||
SwapChain* UTILS_NONNULL drawSwapChain,
|
||||
SwapChain* UTILS_NONNULL readSwapChain) noexcept = 0;
|
||||
SwapChain* UTILS_NONNULL readSwapChain) = 0;
|
||||
|
||||
/**
|
||||
* Called by the driver to make the OpenGL context active on the calling thread and bind
|
||||
@@ -219,7 +219,7 @@ public:
|
||||
SwapChain* UTILS_NONNULL drawSwapChain,
|
||||
SwapChain* UTILS_NONNULL readSwapChain,
|
||||
utils::Invocable<void()> preContextChange,
|
||||
utils::Invocable<void(size_t index)> postContextChange) noexcept;
|
||||
utils::Invocable<void(size_t index)> postContextChange);
|
||||
|
||||
/**
|
||||
* Called by the backend just before calling commit()
|
||||
|
||||
@@ -58,7 +58,7 @@ protected:
|
||||
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
|
||||
void destroySwapChain(SwapChain* swapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) override;
|
||||
void commit(SwapChain* swapChain) noexcept override;
|
||||
ExternalTexture* createExternalImageTexture() noexcept override;
|
||||
void destroyExternalImageTexture(ExternalTexture* texture) noexcept override;
|
||||
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
|
||||
void destroySwapChain(SwapChain* swapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) override;
|
||||
void commit(SwapChain* swapChain) noexcept override;
|
||||
|
||||
ExternalTexture* createExternalImageTexture() noexcept override;
|
||||
|
||||
@@ -109,11 +109,11 @@ protected:
|
||||
|
||||
bool makeCurrent(ContextType type,
|
||||
SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) noexcept override;
|
||||
SwapChain* readSwapChain) override;
|
||||
|
||||
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain,
|
||||
utils::Invocable<void()> preContextChange,
|
||||
utils::Invocable<void(size_t index)> postContextChange) noexcept override;
|
||||
utils::Invocable<void(size_t index)> postContextChange) override;
|
||||
|
||||
void commit(SwapChain* swapChain) noexcept override;
|
||||
|
||||
@@ -148,12 +148,12 @@ protected:
|
||||
EGLContext getContextForType(ContextType type) const noexcept;
|
||||
|
||||
// makes the draw and read surface current without changing the current context
|
||||
EGLBoolean makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) noexcept {
|
||||
EGLBoolean makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) {
|
||||
return egl.makeCurrent(drawSurface, readSurface);
|
||||
}
|
||||
|
||||
// makes context current and set draw and read surfaces to EGL_NO_SURFACE
|
||||
EGLBoolean makeCurrent(EGLContext context) noexcept {
|
||||
EGLBoolean makeCurrent(EGLContext context) {
|
||||
return egl.makeCurrent(context, mEGLDummySurface, mEGLDummySurface);
|
||||
}
|
||||
|
||||
@@ -211,9 +211,9 @@ private:
|
||||
public:
|
||||
explicit EGL(EGLDisplay& dpy) : mEGLDisplay(dpy) {}
|
||||
EGLBoolean makeCurrent(EGLContext context,
|
||||
EGLSurface drawSurface, EGLSurface readSurface) noexcept;
|
||||
EGLSurface drawSurface, EGLSurface readSurface);
|
||||
|
||||
EGLBoolean makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) noexcept {
|
||||
EGLBoolean makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) {
|
||||
return makeCurrent(mCurrentContext, drawSurface, readSurface);
|
||||
}
|
||||
} egl{ mEGLDisplay };
|
||||
|
||||
@@ -127,7 +127,7 @@ protected:
|
||||
protected:
|
||||
bool makeCurrent(ContextType type,
|
||||
SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) noexcept override;
|
||||
SwapChain* readSwapChain) override;
|
||||
|
||||
private:
|
||||
struct InitializeJvmForPerformanceManagerIfNeeded {
|
||||
|
||||
@@ -51,7 +51,7 @@ protected:
|
||||
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
|
||||
void destroySwapChain(SwapChain* swapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) override;
|
||||
void commit(SwapChain* swapChain) noexcept override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -39,18 +39,40 @@ public:
|
||||
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
int getOSVersion() const noexcept override { return 0; }
|
||||
|
||||
/**
|
||||
* Optionally initializes the Metal platform by acquiring resources necessary for rendering.
|
||||
*
|
||||
* This method attempts to acquire a Metal device and command queue, returning true if both are
|
||||
* successfully obtained, or false otherwise. Typically, these objects are acquired when
|
||||
* the Metal backend is initialized. This method allows clients to check for their availability
|
||||
* earlier.
|
||||
*
|
||||
* Calling initialize() is optional and safe to do so multiple times. After initialize() returns
|
||||
* true, subsequent calls will continue to return true but have no effect.
|
||||
*
|
||||
* initialize() must be called from the main thread.
|
||||
*
|
||||
* @returns true if the device and command queue have been successfully obtained; false
|
||||
* otherwise.
|
||||
*/
|
||||
bool initialize() noexcept;
|
||||
|
||||
/**
|
||||
* Obtain the preferred Metal device object for the backend to use.
|
||||
*
|
||||
* On desktop platforms, there may be multiple GPUs suitable for rendering, and this method is
|
||||
* free to decide which one to use. On mobile systems with a single GPU, implementations should
|
||||
* simply return the result of MTLCreateSystemDefaultDevice();
|
||||
*
|
||||
* createDevice is called by the Metal backend from the backend thread.
|
||||
*/
|
||||
virtual void createDevice(MetalDevice& outDevice) noexcept;
|
||||
|
||||
/**
|
||||
* Create a command submission queue on the Metal device object.
|
||||
*
|
||||
* createCommandQueue is called by the Metal backend from the backend thread.
|
||||
*
|
||||
* @param device The device which was returned from createDevice()
|
||||
*/
|
||||
virtual void createCommandQueue(
|
||||
@@ -60,6 +82,8 @@ public:
|
||||
* Obtain a MTLCommandBuffer enqueued on this Platform's MTLCommandQueue. The command buffer is
|
||||
* guaranteed to execute before all subsequent command buffers created either by Filament, or
|
||||
* further calls to this method.
|
||||
*
|
||||
* createAndEnqueueCommandBuffer must be called from the main thread.
|
||||
*/
|
||||
void createAndEnqueueCommandBuffer(MetalCommandBuffer& outCommandBuffer) noexcept;
|
||||
|
||||
@@ -68,6 +92,8 @@ public:
|
||||
*
|
||||
* Each frame rendered requires a CAMetalDrawable texture, which is presented on-screen at the
|
||||
* completion of each frame. These are limited and provided round-robin style by the system.
|
||||
*
|
||||
* setDrawableFailureBehavior must be called from the main thread.
|
||||
*/
|
||||
enum class DrawableFailureBehavior : uint8_t {
|
||||
/**
|
||||
|
||||
@@ -56,7 +56,7 @@ protected:
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
|
||||
void destroySwapChain(SwapChain* swapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) noexcept override;
|
||||
SwapChain* readSwapChain) override;
|
||||
void commit(SwapChain* swapChain) noexcept override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -53,7 +53,7 @@ protected:
|
||||
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
|
||||
void destroySwapChain(SwapChain* swapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) override;
|
||||
void commit(SwapChain* swapChain) noexcept override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -46,7 +46,7 @@ protected:
|
||||
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
|
||||
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
|
||||
void destroySwapChain(SwapChain* swapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
|
||||
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) override;
|
||||
void commit(SwapChain* swapChain) noexcept override;
|
||||
};
|
||||
|
||||
|
||||
@@ -27,8 +27,11 @@
|
||||
#include <utils/Hash.h>
|
||||
#include <utils/PrivateImplementation.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
#include <unordered_set>
|
||||
#include <string>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <webgpu/webgpu_cpp.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
@@ -56,6 +57,10 @@ protected:
|
||||
const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
private:
|
||||
// returns adapter request option variations applicable for the particular
|
||||
// platform
|
||||
[[nodiscard]] static std::vector<wgpu::RequestAdapterOptions> getAdapterOptions();
|
||||
|
||||
// we may consider having the driver own this in the future
|
||||
wgpu::Instance mInstance;
|
||||
};
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
Range getBuffer() noexcept;
|
||||
|
||||
private:
|
||||
void* alloc(size_t size) noexcept;
|
||||
void* alloc(size_t size);
|
||||
void dealloc() noexcept;
|
||||
|
||||
// pointer to the beginning of the circular buffer (constant)
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
|
||||
// all commands buffers (Slices) written to this point are returned by waitForCommand(). This
|
||||
// call blocks until the CircularBuffer has at least mRequiredSize bytes available.
|
||||
void flush() noexcept;
|
||||
void flush();
|
||||
|
||||
// returns from waitForCommands() immediately.
|
||||
void requestExit();
|
||||
|
||||
@@ -27,13 +27,13 @@ namespace filament {
|
||||
class VirtualMachineEnv {
|
||||
public:
|
||||
// must be called before VirtualMachineEnv::get() from a thread that is attached to the JavaVM
|
||||
static jint JNI_OnLoad(JavaVM* vm) noexcept;
|
||||
static jint JNI_OnLoad(JavaVM* vm);
|
||||
|
||||
// must be called on backend thread
|
||||
static VirtualMachineEnv& get() noexcept;
|
||||
|
||||
// can be called from any thread that already has a JniEnv
|
||||
static JNIEnv* getThreadEnvironment() noexcept;
|
||||
static JNIEnv* getThreadEnvironment();
|
||||
|
||||
// must be called from the backend thread
|
||||
JNIEnv* getEnvironment() noexcept {
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
private:
|
||||
explicit VirtualMachineEnv(JavaVM* vm) noexcept;
|
||||
~VirtualMachineEnv() noexcept;
|
||||
JNIEnv* getEnvironmentSlow() noexcept;
|
||||
JNIEnv* getEnvironmentSlow();
|
||||
|
||||
static utils::Mutex sLock;
|
||||
static JavaVM* sVirtualMachine;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "DataReshaper.h"
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <utils/CString.h>
|
||||
|
||||
#include <string_view>
|
||||
@@ -223,6 +225,143 @@ size_t getFormatSize(TextureFormat format) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
TextureType getTextureType(TextureFormat const format) noexcept {
|
||||
switch (format) {
|
||||
case TextureFormat::UNUSED:
|
||||
// should not happen
|
||||
return TextureType::FLOAT;
|
||||
|
||||
case TextureFormat::R8:
|
||||
case TextureFormat::R16F:
|
||||
case TextureFormat::RG8:
|
||||
case TextureFormat::RGB565:
|
||||
case TextureFormat::RGB5_A1:
|
||||
case TextureFormat::RGBA4:
|
||||
case TextureFormat::R32F:
|
||||
case TextureFormat::RGB8:
|
||||
case TextureFormat::SRGB8:
|
||||
case TextureFormat::RG16F:
|
||||
case TextureFormat::R11F_G11F_B10F:
|
||||
case TextureFormat::RGB9_E5:
|
||||
case TextureFormat::RGBA8:
|
||||
case TextureFormat::SRGB8_A8:
|
||||
case TextureFormat::RGB10_A2:
|
||||
case TextureFormat::RGB16F:
|
||||
case TextureFormat::RG32F:
|
||||
case TextureFormat::RGBA16F:
|
||||
case TextureFormat::RGB32F:
|
||||
case TextureFormat::RGBA32F:
|
||||
return TextureType::FLOAT;
|
||||
|
||||
case TextureFormat::R8_SNORM:
|
||||
case TextureFormat::RG8_SNORM:
|
||||
case TextureFormat::RGB8_SNORM:
|
||||
case TextureFormat::RGBA8_SNORM:
|
||||
// SNORM are treated as float
|
||||
return TextureType::FLOAT;
|
||||
|
||||
case TextureFormat::R8UI:
|
||||
case TextureFormat::R16UI:
|
||||
case TextureFormat::RG8UI:
|
||||
case TextureFormat::RGB8UI:
|
||||
case TextureFormat::R32UI:
|
||||
case TextureFormat::RG16UI:
|
||||
case TextureFormat::RGBA8UI:
|
||||
case TextureFormat::RGB16UI:
|
||||
case TextureFormat::RG32UI:
|
||||
case TextureFormat::RGBA16UI:
|
||||
case TextureFormat::RGB32UI:
|
||||
case TextureFormat::RGBA32UI:
|
||||
return TextureType::UINT;
|
||||
|
||||
case TextureFormat::R8I:
|
||||
case TextureFormat::R16I:
|
||||
case TextureFormat::RG8I:
|
||||
case TextureFormat::RGB8I:
|
||||
case TextureFormat::R32I:
|
||||
case TextureFormat::RG16I:
|
||||
case TextureFormat::RGBA8I:
|
||||
case TextureFormat::RGB16I:
|
||||
case TextureFormat::RG32I:
|
||||
case TextureFormat::RGBA16I:
|
||||
case TextureFormat::RGB32I:
|
||||
case TextureFormat::RGBA32I:
|
||||
return TextureType::INT;
|
||||
|
||||
case TextureFormat::DEPTH16:
|
||||
case TextureFormat::DEPTH24:
|
||||
case TextureFormat::DEPTH32F:
|
||||
return TextureType::DEPTH;
|
||||
|
||||
case TextureFormat::STENCIL8:
|
||||
return TextureType::STENCIL;
|
||||
|
||||
case TextureFormat::DEPTH24_STENCIL8:
|
||||
case TextureFormat::DEPTH32F_STENCIL8:
|
||||
return TextureType::DEPTH_STENCIL;
|
||||
|
||||
// Compressed formats ---------------------------------------------------------------------
|
||||
|
||||
case TextureFormat::EAC_RG11:
|
||||
case TextureFormat::EAC_RG11_SIGNED:
|
||||
case TextureFormat::ETC2_EAC_RGBA8:
|
||||
case TextureFormat::ETC2_EAC_SRGBA8:
|
||||
case TextureFormat::EAC_R11:
|
||||
case TextureFormat::EAC_R11_SIGNED:
|
||||
case TextureFormat::ETC2_RGB8:
|
||||
case TextureFormat::ETC2_SRGB8:
|
||||
case TextureFormat::ETC2_RGB8_A1:
|
||||
case TextureFormat::ETC2_SRGB8_A1:
|
||||
case TextureFormat::DXT1_RGB:
|
||||
case TextureFormat::DXT1_RGBA:
|
||||
case TextureFormat::DXT1_SRGB:
|
||||
case TextureFormat::DXT1_SRGBA:
|
||||
case TextureFormat::DXT3_RGBA:
|
||||
case TextureFormat::DXT3_SRGBA:
|
||||
case TextureFormat::DXT5_RGBA:
|
||||
case TextureFormat::DXT5_SRGBA:
|
||||
case TextureFormat::RED_RGTC1:
|
||||
case TextureFormat::SIGNED_RED_RGTC1:
|
||||
case TextureFormat::RED_GREEN_RGTC2:
|
||||
case TextureFormat::SIGNED_RED_GREEN_RGTC2:
|
||||
case TextureFormat::RGB_BPTC_SIGNED_FLOAT:
|
||||
case TextureFormat::RGB_BPTC_UNSIGNED_FLOAT:
|
||||
case TextureFormat::RGBA_BPTC_UNORM:
|
||||
case TextureFormat::SRGB_ALPHA_BPTC_UNORM:
|
||||
case TextureFormat::RGBA_ASTC_4x4:
|
||||
case TextureFormat::RGBA_ASTC_5x4:
|
||||
case TextureFormat::RGBA_ASTC_5x5:
|
||||
case TextureFormat::RGBA_ASTC_6x5:
|
||||
case TextureFormat::RGBA_ASTC_6x6:
|
||||
case TextureFormat::RGBA_ASTC_8x5:
|
||||
case TextureFormat::RGBA_ASTC_8x6:
|
||||
case TextureFormat::RGBA_ASTC_8x8:
|
||||
case TextureFormat::RGBA_ASTC_10x5:
|
||||
case TextureFormat::RGBA_ASTC_10x6:
|
||||
case TextureFormat::RGBA_ASTC_10x8:
|
||||
case TextureFormat::RGBA_ASTC_10x10:
|
||||
case TextureFormat::RGBA_ASTC_12x10:
|
||||
case TextureFormat::RGBA_ASTC_12x12:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_4x4:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_5x4:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_5x5:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_6x5:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_6x6:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_8x5:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_8x6:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_8x8:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_10x5:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_10x6:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_10x8:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_10x10:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_12x10:
|
||||
case TextureFormat::SRGB8_ALPHA8_ASTC_12x12:
|
||||
return TextureType::FLOAT;
|
||||
}
|
||||
|
||||
return TextureType::FLOAT;
|
||||
}
|
||||
|
||||
size_t getFormatComponentCount(TextureFormat format) noexcept {
|
||||
switch (format) {
|
||||
case TextureFormat::R8:
|
||||
|
||||
@@ -65,7 +65,7 @@ CircularBuffer::~CircularBuffer() noexcept {
|
||||
// to each others and a special case in circularize()
|
||||
|
||||
UTILS_NOINLINE
|
||||
void* CircularBuffer::alloc(size_t size) noexcept {
|
||||
void* CircularBuffer::alloc(size_t size) {
|
||||
#if HAS_MMAP
|
||||
void* data = nullptr;
|
||||
void* vaddr = MAP_FAILED;
|
||||
|
||||
@@ -18,12 +18,13 @@
|
||||
#include "private/backend/CircularBuffer.h"
|
||||
#include "private/backend/CommandStream.h"
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Mutex.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Systrace.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -52,18 +53,18 @@ CommandBufferQueue::~CommandBufferQueue() {
|
||||
}
|
||||
|
||||
void CommandBufferQueue::requestExit() {
|
||||
std::lock_guard<utils::Mutex> const lock(mLock);
|
||||
std::lock_guard const lock(mLock);
|
||||
mExitRequested = EXIT_REQUESTED;
|
||||
mCondition.notify_one();
|
||||
}
|
||||
|
||||
bool CommandBufferQueue::isPaused() const noexcept {
|
||||
std::lock_guard<utils::Mutex> const lock(mLock);
|
||||
std::lock_guard const lock(mLock);
|
||||
return mPaused;
|
||||
}
|
||||
|
||||
void CommandBufferQueue::setPaused(bool paused) {
|
||||
std::lock_guard<utils::Mutex> const lock(mLock);
|
||||
std::lock_guard const lock(mLock);
|
||||
if (paused) {
|
||||
mPaused = true;
|
||||
} else {
|
||||
@@ -73,13 +74,13 @@ void CommandBufferQueue::setPaused(bool paused) {
|
||||
}
|
||||
|
||||
bool CommandBufferQueue::isExitRequested() const {
|
||||
std::lock_guard<utils::Mutex> const lock(mLock);
|
||||
return (bool)mExitRequested;
|
||||
std::lock_guard const lock(mLock);
|
||||
return bool(mExitRequested);
|
||||
}
|
||||
|
||||
|
||||
void CommandBufferQueue::flush() noexcept {
|
||||
SYSTRACE_CALL();
|
||||
void CommandBufferQueue::flush() {
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
|
||||
CircularBuffer& circularBuffer = mCircularBuffer;
|
||||
if (circularBuffer.empty()) {
|
||||
@@ -102,7 +103,7 @@ void CommandBufferQueue::flush() noexcept {
|
||||
static_cast<char const*>(begin), static_cast<char const*>(end));
|
||||
|
||||
|
||||
std::unique_lock<utils::Mutex> lock(mLock);
|
||||
std::unique_lock lock(mLock);
|
||||
|
||||
// circular buffer is too small, we corrupted the stream
|
||||
FILAMENT_CHECK_POSTCONDITION(used <= mFreeSpace) <<
|
||||
@@ -129,7 +130,7 @@ void CommandBufferQueue::flush() noexcept {
|
||||
mHighWatermark = std::max(mHighWatermark, totalUsed);
|
||||
#endif
|
||||
|
||||
SYSTRACE_NAME("waiting: CircularBuffer::flush()");
|
||||
FILAMENT_TRACING_NAME(FILAMENT_TRACING_CATEGORY_FILAMENT, "waiting: CircularBuffer::flush()");
|
||||
|
||||
FILAMENT_CHECK_POSTCONDITION(!mPaused) <<
|
||||
"CommandStream is full, but since the rendering thread is paused, "
|
||||
@@ -146,7 +147,7 @@ std::vector<CommandBufferQueue::Range> CommandBufferQueue::waitForCommands() con
|
||||
if (!UTILS_HAS_THREADING) {
|
||||
return std::move(mCommandBuffersToExecute);
|
||||
}
|
||||
std::unique_lock<utils::Mutex> lock(mLock);
|
||||
std::unique_lock lock(mLock);
|
||||
while ((mCommandBuffersToExecute.empty() || mPaused) && !mExitRequested) {
|
||||
mCondition.wait(lock);
|
||||
}
|
||||
@@ -156,7 +157,7 @@ std::vector<CommandBufferQueue::Range> CommandBufferQueue::waitForCommands() con
|
||||
void CommandBufferQueue::releaseBuffer(CommandBufferQueue::Range const& buffer) {
|
||||
size_t const used = std::distance(
|
||||
static_cast<char const*>(buffer.begin), static_cast<char const*>(buffer.end));
|
||||
std::lock_guard<utils::Mutex> const lock(mLock);
|
||||
std::lock_guard const lock(mLock);
|
||||
mFreeSpace += used;
|
||||
mCondition.notify_one();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#include "private/backend/CommandStream.h"
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#if DEBUG_COMMAND_STREAM
|
||||
#include <utils/CallStack.h>
|
||||
#endif
|
||||
@@ -24,7 +26,6 @@
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Profiler.h>
|
||||
#include <utils/Systrace.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
@@ -79,12 +80,13 @@ CommandStream::CommandStream(Driver& driver, CircularBuffer& buffer) noexcept
|
||||
}
|
||||
|
||||
void CommandStream::execute(void* buffer) {
|
||||
// NOTE: we can't use SYSTRACE_CALL() or similar here because, execute() below, also
|
||||
// NOTE: we can't use FILAMENT_TRACING_CALL() or similar here because, execute() below, also
|
||||
// uses systrace BEGIN/END and the END is not guaranteed to be happening in this scope.
|
||||
|
||||
Profiler profiler;
|
||||
|
||||
if constexpr (SYSTRACE_TAG) {
|
||||
|
||||
if constexpr (FILAMENT_TRACING_ENABLED) {
|
||||
if (UTILS_UNLIKELY(mUsePerformanceCounter)) {
|
||||
// we want to remove all this when tracing is completely disabled
|
||||
profiler.resetEvents(Profiler::EV_CPU_CYCLES | Profiler::EV_BPU_MISSES);
|
||||
@@ -100,17 +102,17 @@ void CommandStream::execute(void* buffer) {
|
||||
}
|
||||
});
|
||||
|
||||
if constexpr (SYSTRACE_TAG) {
|
||||
if constexpr (FILAMENT_TRACING_ENABLED) {
|
||||
if (UTILS_UNLIKELY(mUsePerformanceCounter)) {
|
||||
// we want to remove all this when tracing is completely disabled
|
||||
profiler.stop();
|
||||
UTILS_UNUSED Profiler::Counters const counters = profiler.readCounters();
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_VALUE32("GLThread (I)", counters.getInstructions());
|
||||
SYSTRACE_VALUE32("GLThread (C)", counters.getCpuCycles());
|
||||
SYSTRACE_VALUE32("GLThread (CPI x10)", counters.getCPI() * 10);
|
||||
SYSTRACE_VALUE32("GLThread (BPU miss)", counters.getBranchMisses());
|
||||
SYSTRACE_VALUE32("GLThread (I / BPU miss)",
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT, "GLThread (I)", counters.getInstructions());
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT, "GLThread (C)", counters.getCpuCycles());
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT, "GLThread (CPI x10)", counters.getCPI() * 10);
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT, "GLThread (BPU miss)", counters.getBranchMisses());
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT, "GLThread (I / BPU miss)",
|
||||
counters.getInstructions() / counters.getBranchMisses());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,9 @@
|
||||
#include "private/backend/Driver.h"
|
||||
#include "private/backend/CommandStream.h"
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Systrace.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
@@ -38,7 +39,7 @@
|
||||
#if DEBUG_LEVEL == DEBUG_LEVEL_NONE
|
||||
# define SYSTRACE()
|
||||
#elif DEBUG_LEVEL == DEBUG_LEVEL_SYSTRACE
|
||||
# define SYSTRACE() SYSTRACE_CALL();
|
||||
# define SYSTRACE() FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
#else
|
||||
# error "invalid debug level"
|
||||
#endif
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "CompilerThreadPool.h"
|
||||
|
||||
#include <utils/Systrace.h>
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -41,7 +41,7 @@ void CompilerThreadPool::init(uint32_t threadCount,
|
||||
|
||||
for (size_t i = 0; i < threadCount; i++) {
|
||||
mCompilerThreads.emplace_back([this, setup, cleanup]() {
|
||||
SYSTRACE_CONTEXT();
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
|
||||
(*setup)();
|
||||
|
||||
@@ -54,7 +54,7 @@ void CompilerThreadPool::init(uint32_t threadCount,
|
||||
[](auto&& q) { return q.empty(); }));
|
||||
});
|
||||
|
||||
SYSTRACE_VALUE32("CompilerThreadPool Jobs",
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT, "CompilerThreadPool Jobs",
|
||||
mQueues[0].size() + mQueues[1].size());
|
||||
|
||||
if (UTILS_LIKELY(!mExitRequested)) {
|
||||
|
||||
@@ -23,11 +23,12 @@
|
||||
#include <backend/BufferDescriptor.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Systrace.h>
|
||||
|
||||
#include <math/half.h>
|
||||
#include <math/vec2.h>
|
||||
@@ -151,30 +152,31 @@ void DriverBase::debugCommandBegin(CommandStream* cmds, bool synchronous, const
|
||||
utils::slog.d << methodName << utils::io::endl;
|
||||
}
|
||||
if constexpr (bool(FILAMENT_DEBUG_COMMANDS & FILAMENT_DEBUG_COMMANDS_SYSTRACE)) {
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_NAME_BEGIN(methodName);
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_NAME_BEGIN(FILAMENT_TRACING_CATEGORY_FILAMENT, methodName);
|
||||
|
||||
if (!synchronous) {
|
||||
cmds->queueCommand([=]() {
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_NAME_BEGIN(methodName);
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_NAME_BEGIN(FILAMENT_TRACING_CATEGORY_FILAMENT, methodName);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DriverBase::debugCommandEnd(CommandStream* cmds, bool synchronous, const char* methodName) noexcept {
|
||||
void DriverBase::debugCommandEnd(CommandStream* cmds, bool synchronous,
|
||||
const char* methodName) noexcept {
|
||||
if constexpr (bool(FILAMENT_DEBUG_COMMANDS > FILAMENT_DEBUG_COMMANDS_NONE)) {
|
||||
if constexpr (bool(FILAMENT_DEBUG_COMMANDS & FILAMENT_DEBUG_COMMANDS_SYSTRACE)) {
|
||||
if (!synchronous) {
|
||||
cmds->queueCommand([]() {
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_NAME_END();
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_NAME_END(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
});
|
||||
}
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_NAME_END();
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_NAME_END(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <backend/Platform.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <utility>
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
#include <private/backend/PlatformFactory.h>
|
||||
|
||||
#include <utils/Systrace.h>
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
// We need to keep this up top for the linux (X11) name collisions.
|
||||
@@ -85,7 +86,7 @@ namespace filament::backend {
|
||||
// responsible for destroying it. Initialization of the backend API is deferred until
|
||||
// createDriver(). The passed-in backend hint is replaced with the resolved backend.
|
||||
Platform* PlatformFactory::create(Backend* backend) noexcept {
|
||||
SYSTRACE_CALL();
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
assert_invariant(backend);
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#ifndef TNT_FILAMENT_BACKEND_SYSTRACEPROFILE_H
|
||||
#define TNT_FILAMENT_BACKEND_SYSTRACEPROFILE_H
|
||||
|
||||
#include <utils/Systrace.h>
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#define PROFILE_SCOPE(marker) SYSTRACE_NAME(marker)
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ JavaVM* VirtualMachineEnv::getVirtualMachine() {
|
||||
*/
|
||||
UTILS_PUBLIC
|
||||
UTILS_NOINLINE
|
||||
jint VirtualMachineEnv::JNI_OnLoad(JavaVM* vm) noexcept {
|
||||
jint VirtualMachineEnv::JNI_OnLoad(JavaVM* vm) {
|
||||
std::lock_guard const lock(sLock);
|
||||
if (sVirtualMachine) {
|
||||
// It doesn't make sense for JNI_OnLoad() to be called more than once
|
||||
@@ -77,7 +77,7 @@ VirtualMachineEnv& VirtualMachineEnv::get() noexcept {
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
JNIEnv* VirtualMachineEnv::getThreadEnvironment() noexcept {
|
||||
JNIEnv* VirtualMachineEnv::getThreadEnvironment() {
|
||||
JavaVM* const vm = getVirtualMachine();
|
||||
JNIEnv* env = nullptr;
|
||||
jint const result = vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
|
||||
@@ -101,7 +101,7 @@ VirtualMachineEnv::~VirtualMachineEnv() noexcept {
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
JNIEnv* VirtualMachineEnv::getEnvironmentSlow() noexcept {
|
||||
JNIEnv* VirtualMachineEnv::getEnvironmentSlow() {
|
||||
FILAMENT_CHECK_PRECONDITION(mVirtualMachine)
|
||||
<< "JNI_OnLoad() has not been called";
|
||||
|
||||
|
||||
@@ -218,11 +218,11 @@ void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, const BlitArgs
|
||||
}
|
||||
[encoder setFragmentTexture:srcTextureColor atIndex:0];
|
||||
|
||||
SamplerMinFilter filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST;
|
||||
SamplerMinFilter filterMin = SamplerMinFilter::LINEAR;
|
||||
if (args.filter == SamplerMagFilter::NEAREST) {
|
||||
filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST;
|
||||
filterMin = SamplerMinFilter::LINEAR;
|
||||
} else if (args.filter == SamplerMagFilter::LINEAR) {
|
||||
filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST;
|
||||
filterMin = SamplerMinFilter::LINEAR;
|
||||
}
|
||||
|
||||
SamplerState const s {
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "MetalContext.h"
|
||||
|
||||
#include <utils/Panic.h>
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
|
||||
|
||||
@@ -672,22 +672,8 @@ void MetalDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {
|
||||
// nothing to do, timer query was constructed in createTimerQueryS
|
||||
}
|
||||
|
||||
const char* toString(DescriptorType type) {
|
||||
switch (type) {
|
||||
case DescriptorType::UNIFORM_BUFFER:
|
||||
return "UNIFORM_BUFFER";
|
||||
case DescriptorType::SHADER_STORAGE_BUFFER:
|
||||
return "SHADER_STORAGE_BUFFER";
|
||||
case DescriptorType::SAMPLER:
|
||||
return "SAMPLER";
|
||||
case DescriptorType::INPUT_ATTACHMENT:
|
||||
return "INPUT_ATTACHMENT";
|
||||
case DescriptorType::SAMPLER_EXTERNAL:
|
||||
return "SAMPLER_EXTERNAL";
|
||||
}
|
||||
}
|
||||
|
||||
const char* toString(ShaderStageFlags flags) {
|
||||
UTILS_UNUSED
|
||||
static const char* toString(ShaderStageFlags flags) {
|
||||
std::vector<const char*> stages;
|
||||
if (any(flags & ShaderStageFlags::VERTEX)) {
|
||||
stages.push_back("VERTEX");
|
||||
@@ -721,15 +707,25 @@ const char* toString(DescriptorFlags flags) {
|
||||
|
||||
void MetalDriver::createDescriptorSetLayoutR(
|
||||
Handle<HwDescriptorSetLayout> dslh, DescriptorSetLayout&& info) {
|
||||
#if FILAMENT_METAL_DEBUG_LOG == 1
|
||||
const char* labelStr = "";
|
||||
std::visit([&labelStr](auto&& arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, utils::CString> || std::is_same_v<T, utils::StaticString>) {
|
||||
labelStr = arg.c_str();
|
||||
}
|
||||
}, info.label);
|
||||
std::sort(info.bindings.begin(), info.bindings.end(),
|
||||
[](const auto& a, const auto& b) { return a.binding < b.binding; });
|
||||
DEBUG_LOG("createDescriptorSetLayoutR(dslh = %d, info = {\n", dslh.getId());
|
||||
DEBUG_LOG("createDescriptorSetLayoutR(dslh = %d, info = { label = %s,\n", dslh.getId(),
|
||||
labelStr);
|
||||
for (size_t i = 0; i < info.bindings.size(); i++) {
|
||||
DEBUG_LOG(" {binding = %d, type = %s, count = %d, stage = %s, flags = %s},\n",
|
||||
info.bindings[i].binding, toString(info.bindings[i].type), info.bindings[i].count,
|
||||
toString(info.bindings[i].stageFlags), toString(info.bindings[i].flags));
|
||||
}
|
||||
DEBUG_LOG("})\n");
|
||||
#endif
|
||||
construct_handle<MetalDescriptorSetLayout>(dslh, std::move(info));
|
||||
}
|
||||
|
||||
@@ -1537,7 +1533,7 @@ void MetalDriver::readPixels(Handle<HwRenderTarget> src, uint32_t x, uint32_t y,
|
||||
id<MTLTexture> readPixelsTexture = [mContext->device newTextureWithDescriptor:textureDescriptor];
|
||||
|
||||
MetalBlitter::BlitArgs args{};
|
||||
args.filter = SamplerMagFilter::NEAREST;
|
||||
args.filter = SamplerMagFilter::LINEAR;
|
||||
args.source.level = miplevel;
|
||||
args.source.region = MTLRegionMake2D(0, 0, srcTexture.width >> miplevel, srcTexture.height >> miplevel);
|
||||
args.source.texture = srcTexture;
|
||||
@@ -1654,7 +1650,7 @@ void MetalDriver::blit(
|
||||
<< "Metal does not support blitting to/from non-2D textures.";
|
||||
|
||||
MetalBlitter::BlitArgs args{};
|
||||
args.filter = SamplerMagFilter::NEAREST;
|
||||
args.filter = SamplerMagFilter::LINEAR;
|
||||
args.source.region = MTLRegionMake2D(
|
||||
(NSUInteger)srcOrigin.x,
|
||||
std::max(srcTexture->height - (int64_t)srcOrigin.y - size.y, (int64_t)0),
|
||||
|
||||
@@ -185,6 +185,7 @@ inline MTLPixelFormat getMetalFormat(PixelDataFormat format, PixelDataType type)
|
||||
CONVERT(RGBA_INTEGER, UINT, RGBA32Uint);
|
||||
CONVERT(RGBA_INTEGER, INT, RGBA32Sint);
|
||||
CONVERT(RGBA, FLOAT, RGBA32Float);
|
||||
CONVERT(DEPTH_COMPONENT, FLOAT, Depth32Float);
|
||||
#undef CONVERT
|
||||
|
||||
return MTLPixelFormatInvalid;
|
||||
@@ -347,7 +348,7 @@ constexpr inline MTLSamplerMinMagFilter getFilter(SamplerMinFilter filter) noexc
|
||||
case SamplerMinFilter::NEAREST:
|
||||
case SamplerMinFilter::NEAREST_MIPMAP_NEAREST:
|
||||
case SamplerMinFilter::NEAREST_MIPMAP_LINEAR:
|
||||
return MTLSamplerMinMagFilterNearest;
|
||||
return MTLSamplerMinMagFilterLinear;
|
||||
case SamplerMinFilter::LINEAR_MIPMAP_NEAREST:
|
||||
case SamplerMinFilter::LINEAR:
|
||||
case SamplerMinFilter::LINEAR_MIPMAP_LINEAR:
|
||||
@@ -358,7 +359,7 @@ constexpr inline MTLSamplerMinMagFilter getFilter(SamplerMinFilter filter) noexc
|
||||
constexpr inline MTLSamplerMinMagFilter getFilter(SamplerMagFilter filter) noexcept {
|
||||
switch (filter) {
|
||||
case SamplerMagFilter::NEAREST:
|
||||
return MTLSamplerMinMagFilterNearest;
|
||||
return MTLSamplerMinMagFilterLinear;
|
||||
case SamplerMagFilter::LINEAR:
|
||||
return MTLSamplerMinMagFilterLinear;
|
||||
}
|
||||
@@ -368,10 +369,10 @@ constexpr inline MTLSamplerMipFilter getMipFilter(SamplerMinFilter filter) noexc
|
||||
switch (filter) {
|
||||
case SamplerMinFilter::NEAREST:
|
||||
case SamplerMinFilter::LINEAR:
|
||||
return MTLSamplerMipFilterNotMipmapped;
|
||||
return MTLSamplerMipFilterLinear;
|
||||
case SamplerMinFilter::NEAREST_MIPMAP_NEAREST:
|
||||
case SamplerMinFilter::LINEAR_MIPMAP_NEAREST:
|
||||
return MTLSamplerMipFilterNearest;
|
||||
return MTLSamplerMipFilterLinear;
|
||||
case SamplerMinFilter::NEAREST_MIPMAP_LINEAR:
|
||||
case SamplerMinFilter::LINEAR_MIPMAP_LINEAR:
|
||||
return MTLSamplerMipFilterLinear;
|
||||
|
||||
@@ -943,7 +943,7 @@ void MetalTexture::loadWithBlit(uint32_t level, uint32_t slice, MTLRegion region
|
||||
}
|
||||
|
||||
MetalBlitter::BlitArgs args{};
|
||||
args.filter = SamplerMagFilter::NEAREST;
|
||||
args.filter = SamplerMagFilter::LINEAR;
|
||||
args.source.level = 0;
|
||||
args.source.slice = 0;
|
||||
args.source.region = sourceRegion;
|
||||
@@ -1356,7 +1356,31 @@ id<MTLArgumentEncoder> MetalDescriptorSetLayout::getArgumentEncoderSlow(id<MTLDe
|
||||
[arguments addObject:bufferArgument];
|
||||
break;
|
||||
}
|
||||
case DescriptorType::SAMPLER:
|
||||
case DescriptorType::SAMPLER_2D_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_INT:
|
||||
case DescriptorType::SAMPLER_2D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_DEPTH:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_3D_FLOAT:
|
||||
case DescriptorType::SAMPLER_3D_INT:
|
||||
case DescriptorType::SAMPLER_3D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_EXTERNAL: {
|
||||
MTLArgumentDescriptor* textureArgument = [MTLArgumentDescriptor argumentDescriptor];
|
||||
textureArgument.index = binding.binding * 2;
|
||||
@@ -1382,6 +1406,9 @@ id<MTLArgumentEncoder> MetalDescriptorSetLayout::getArgumentEncoderSlow(id<MTLDe
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (arguments.count == 0) {
|
||||
return nil;
|
||||
}
|
||||
return [device newArgumentEncoderWithArguments:arguments];
|
||||
}
|
||||
|
||||
@@ -1442,6 +1469,9 @@ id<MTLBuffer> MetalDescriptorSet::finalizeAndGetBuffer(MetalDriver* driver, Shad
|
||||
|
||||
id<MTLArgumentEncoder> encoder =
|
||||
layout->getArgumentEncoder(context.device, stage, textureTypes);
|
||||
if (!encoder) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
{
|
||||
ScopedAllocationTimer timer("descriptor_set");
|
||||
@@ -1472,7 +1502,31 @@ id<MTLBuffer> MetalDescriptorSet::finalizeAndGetBuffer(MetalDriver* driver, Shad
|
||||
atIndex:binding.binding * 2];
|
||||
break;
|
||||
}
|
||||
case DescriptorType::SAMPLER:
|
||||
case DescriptorType::SAMPLER_2D_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_INT:
|
||||
case DescriptorType::SAMPLER_2D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_DEPTH:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_3D_FLOAT:
|
||||
case DescriptorType::SAMPLER_3D_INT:
|
||||
case DescriptorType::SAMPLER_3D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_EXTERNAL: {
|
||||
auto found = textures.find(binding.binding);
|
||||
if (found == textures.end()) {
|
||||
|
||||
@@ -20,18 +20,19 @@
|
||||
#include <Metal/Metal.h>
|
||||
|
||||
#include "private/backend/Driver.h"
|
||||
#include "backend/Program.h"
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Program.h>
|
||||
|
||||
#include <utils/bitset.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
|
||||
#include <memory>
|
||||
#include <tsl/robin_map.h>
|
||||
|
||||
#include <utils/Hash.h>
|
||||
#include <utils/Invocable.h>
|
||||
|
||||
#include <tsl/robin_map.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
|
||||
|
||||
@@ -24,14 +24,22 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
struct PlatformMetalImpl {
|
||||
std::mutex mLock; // locks mDevice and mCommandQueue
|
||||
id<MTLDevice> mDevice = nil;
|
||||
id<MTLCommandQueue> mCommandQueue = nil;
|
||||
|
||||
// read form driver thread, read/written to from client thread
|
||||
std::atomic<PlatformMetal::DrawableFailureBehavior> mDrawableFailureBehavior =
|
||||
PlatformMetal::DrawableFailureBehavior::PANIC;
|
||||
|
||||
// These methods must be called with mLock held
|
||||
void createDeviceImpl(MetalDevice& outDevice);
|
||||
void createCommandQueueImpl(MetalDevice& device, MetalCommandQueue& outCommandQueue);
|
||||
};
|
||||
|
||||
Platform* createDefaultMetalPlatform() {
|
||||
@@ -48,7 +56,59 @@ Driver* PlatformMetal::createDriver(void* /*sharedContext*/, const Platform::Dri
|
||||
return MetalDriverFactory::create(this, driverConfig);
|
||||
}
|
||||
|
||||
|
||||
bool PlatformMetal::initialize() noexcept {
|
||||
std::lock_guard<std::mutex> lock(pImpl->mLock);
|
||||
|
||||
MetalDevice device{};
|
||||
pImpl->createDeviceImpl(device);
|
||||
if (device.device == nil) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MetalCommandQueue commandQueue{};
|
||||
pImpl->createCommandQueueImpl(device, commandQueue);
|
||||
if (commandQueue.commandQueue == nil) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlatformMetal::createDevice(MetalDevice& outDevice) noexcept {
|
||||
std::lock_guard<std::mutex> lock(pImpl->mLock);
|
||||
pImpl->createDeviceImpl(outDevice);
|
||||
}
|
||||
|
||||
void PlatformMetal::createCommandQueue(
|
||||
MetalDevice& device, MetalCommandQueue& outCommandQueue) noexcept {
|
||||
std::lock_guard<std::mutex> lock(pImpl->mLock);
|
||||
pImpl->createCommandQueueImpl(device, outCommandQueue);
|
||||
}
|
||||
|
||||
void PlatformMetal::createAndEnqueueCommandBuffer(MetalCommandBuffer& outCommandBuffer) noexcept {
|
||||
std::lock_guard<std::mutex> lock(pImpl->mLock);
|
||||
id<MTLCommandBuffer> commandBuffer = [pImpl->mCommandQueue commandBuffer];
|
||||
[commandBuffer enqueue];
|
||||
outCommandBuffer.commandBuffer = commandBuffer;
|
||||
}
|
||||
|
||||
void PlatformMetal::setDrawableFailureBehavior(DrawableFailureBehavior behavior) noexcept {
|
||||
pImpl->mDrawableFailureBehavior = behavior;
|
||||
}
|
||||
|
||||
PlatformMetal::DrawableFailureBehavior PlatformMetal::getDrawableFailureBehavior() const noexcept {
|
||||
return pImpl->mDrawableFailureBehavior;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
void PlatformMetalImpl::createDeviceImpl(MetalDevice& outDevice) {
|
||||
if (mDevice) {
|
||||
outDevice.device = mDevice;
|
||||
return;
|
||||
}
|
||||
|
||||
id<MTLDevice> result;
|
||||
|
||||
#if !defined(FILAMENT_IOS)
|
||||
@@ -74,27 +134,17 @@ void PlatformMetal::createDevice(MetalDevice& outDevice) noexcept {
|
||||
<< utils::io::endl;
|
||||
|
||||
outDevice.device = result;
|
||||
mDevice = result;
|
||||
}
|
||||
|
||||
void PlatformMetal::createCommandQueue(
|
||||
MetalDevice& device, MetalCommandQueue& outCommandQueue) noexcept {
|
||||
pImpl->mCommandQueue = [device.device newCommandQueue];
|
||||
pImpl->mCommandQueue.label = @"Filament";
|
||||
outCommandQueue.commandQueue = pImpl->mCommandQueue;
|
||||
}
|
||||
|
||||
void PlatformMetal::createAndEnqueueCommandBuffer(MetalCommandBuffer& outCommandBuffer) noexcept {
|
||||
id<MTLCommandBuffer> commandBuffer = [pImpl->mCommandQueue commandBuffer];
|
||||
[commandBuffer enqueue];
|
||||
outCommandBuffer.commandBuffer = commandBuffer;
|
||||
}
|
||||
|
||||
void PlatformMetal::setDrawableFailureBehavior(DrawableFailureBehavior behavior) noexcept {
|
||||
pImpl->mDrawableFailureBehavior = behavior;
|
||||
}
|
||||
|
||||
PlatformMetal::DrawableFailureBehavior PlatformMetal::getDrawableFailureBehavior() const noexcept {
|
||||
return pImpl->mDrawableFailureBehavior;
|
||||
void PlatformMetalImpl::createCommandQueueImpl(MetalDevice& device, MetalCommandQueue& outCommandQueue) {
|
||||
if (mCommandQueue) {
|
||||
outCommandQueue.commandQueue = mCommandQueue;
|
||||
return;
|
||||
}
|
||||
mCommandQueue = [device.device newCommandQueue];
|
||||
mCommandQueue.label = @"Filament";
|
||||
outCommandQueue.commandQueue = mCommandQueue;
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -69,9 +69,8 @@ public:
|
||||
assert_invariant(set < MAX_DESCRIPTOR_SET_COUNT);
|
||||
assert_invariant(binding < MAX_DESCRIPTOR_COUNT);
|
||||
assert_invariant(entry.binding < 128); // we reserve 1 bit for the type right now
|
||||
mStorage[set][binding] = { (uint8_t)entry.binding,
|
||||
entry.type == DescriptorType::SAMPLER ||
|
||||
entry.type == DescriptorType::SAMPLER_EXTERNAL };
|
||||
mStorage[set][binding] = { uint8_t(entry.binding),
|
||||
DescriptorSetLayoutBinding::isSampler(entry.type) };
|
||||
mActiveDescriptors[set].set(binding);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,32 @@ GLDescriptorSet::GLDescriptorSet(OpenGLContext& gl, DescriptorSetLayoutHandle ds
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DescriptorType::SAMPLER:
|
||||
|
||||
case DescriptorType::SAMPLER_2D_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_INT:
|
||||
case DescriptorType::SAMPLER_2D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_DEPTH:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_3D_FLOAT:
|
||||
case DescriptorType::SAMPLER_3D_INT:
|
||||
case DescriptorType::SAMPLER_3D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_EXTERNAL:
|
||||
if (UTILS_UNLIKELY(gl.isES2())) {
|
||||
desc.emplace<SamplerGLES2>();
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <backend/Platform.h>
|
||||
#include <backend/Program.h>
|
||||
|
||||
#include <utils/Systrace.h>
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
@@ -36,7 +36,7 @@ OpenGLBlobCache::OpenGLBlobCache(OpenGLContext& gl) noexcept
|
||||
|
||||
GLuint OpenGLBlobCache::retrieve(BlobCacheKey* outKey, Platform& platform,
|
||||
Program const& program) const noexcept {
|
||||
SYSTRACE_CALL();
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
if (!mCachingSupported || !platform.hasRetrieveBlobFunc()) {
|
||||
// the key is never updated in that case
|
||||
return 0;
|
||||
@@ -68,7 +68,7 @@ GLuint OpenGLBlobCache::retrieve(BlobCacheKey* outKey, Platform& platform,
|
||||
programId = glCreateProgram();
|
||||
|
||||
{ // scope for systrace
|
||||
SYSTRACE_NAME("glProgramBinary");
|
||||
FILAMENT_TRACING_NAME(FILAMENT_TRACING_CATEGORY_FILAMENT, "glProgramBinary");
|
||||
glProgramBinary(programId, blob->format, blob->data, programBinarySize);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ GLuint OpenGLBlobCache::retrieve(BlobCacheKey* outKey, Platform& platform,
|
||||
|
||||
void OpenGLBlobCache::insert(Platform& platform,
|
||||
BlobCacheKey const& key, GLuint program) noexcept {
|
||||
SYSTRACE_CALL();
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
if (!mCachingSupported || !platform.hasInsertBlobFunc()) {
|
||||
// the key is never updated in that case
|
||||
return;
|
||||
@@ -100,7 +100,7 @@ void OpenGLBlobCache::insert(Platform& platform,
|
||||
GLenum format;
|
||||
GLint programBinarySize = 0;
|
||||
{ // scope for systrace
|
||||
SYSTRACE_NAME("glGetProgramiv");
|
||||
FILAMENT_TRACING_NAME(FILAMENT_TRACING_CATEGORY_FILAMENT, "glGetProgramiv");
|
||||
glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &programBinarySize);
|
||||
}
|
||||
if (programBinarySize) {
|
||||
@@ -108,7 +108,7 @@ void OpenGLBlobCache::insert(Platform& platform,
|
||||
std::unique_ptr<Blob, decltype(&::free)> blob{ (Blob*)malloc(size), &::free };
|
||||
if (UTILS_LIKELY(blob)) {
|
||||
{ // scope for systrace
|
||||
SYSTRACE_NAME("glGetProgramBinary");
|
||||
FILAMENT_TRACING_NAME(FILAMENT_TRACING_CATEGORY_FILAMENT, "glGetProgramBinary");
|
||||
glGetProgramBinary(program, programBinarySize,
|
||||
&programBinarySize, &format, blob->data);
|
||||
}
|
||||
|
||||
@@ -542,6 +542,13 @@ void OpenGLContext::initBugs(Bugs* bugs, Extensions const& exts,
|
||||
} else if (strstr(renderer, "Intel")) {
|
||||
// Intel GPU
|
||||
bugs->vao_doesnt_store_element_array_buffer_binding = true;
|
||||
|
||||
if (strstr(renderer, "Mesa")) {
|
||||
// Mesa Intel driver on Linux/Android
|
||||
// Renderer of the form [Mesa Intel(R) HD Graphics 505 (APL 3)]
|
||||
// b/405252622
|
||||
bugs->disable_invalidate_framebuffer = true;
|
||||
}
|
||||
} else if (strstr(renderer, "PowerVR")) {
|
||||
// PowerVR GPU
|
||||
// On PowerVR (Rogue GE8320) glFlush doesn't seem to do anything, in particular,
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include "private/backend/Dispatcher.h"
|
||||
#include "private/backend/DriverApi.h"
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <type_traits>
|
||||
#include <utils/BitmaskEnum.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
@@ -51,7 +53,6 @@
|
||||
#include <utils/Invocable.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Systrace.h>
|
||||
#include <utils/Slice.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
@@ -98,13 +99,13 @@
|
||||
|
||||
#define DEBUG_GROUP_MARKER_NONE 0x00 // no debug marker
|
||||
#define DEBUG_GROUP_MARKER_OPENGL 0x01 // markers in the gl command queue (req. driver support)
|
||||
#define DEBUG_GROUP_MARKER_BACKEND 0x02 // markers on the backend side (systrace)
|
||||
#define DEBUG_GROUP_MARKER_BACKEND 0x02 // markers on the backend side (perfetto)
|
||||
#define DEBUG_GROUP_MARKER_ALL 0xFF // all markers
|
||||
|
||||
#define DEBUG_MARKER_NONE 0x00 // no debug marker
|
||||
#define DEBUG_MARKER_OPENGL 0x01 // markers in the gl command queue (req. driver support)
|
||||
#define DEBUG_MARKER_BACKEND 0x02 // markers on the backend side (systrace)
|
||||
#define DEBUG_MARKER_PROFILE 0x04 // profiling on the backend side (systrace)
|
||||
#define DEBUG_MARKER_BACKEND 0x02 // markers on the backend side (perfetto)
|
||||
#define DEBUG_MARKER_PROFILE 0x04 // profiling on the backend side (perfetto)
|
||||
#define DEBUG_MARKER_ALL (0xFF & ~DEBUG_MARKER_PROFILE) // all markers
|
||||
|
||||
// set to the desired debug marker level (for user markers [default: All])
|
||||
@@ -248,8 +249,8 @@ OpenGLDriver::DebugMarker::DebugMarker(OpenGLDriver& driver, const char* string)
|
||||
#endif
|
||||
|
||||
#if DEBUG_MARKER_LEVEL & DEBUG_MARKER_BACKEND
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_NAME_BEGIN(string);
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_NAME_BEGIN(FILAMENT_TRACING_CATEGORY_FILAMENT, string);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -265,8 +266,8 @@ OpenGLDriver::DebugMarker::~DebugMarker() noexcept {
|
||||
#endif
|
||||
|
||||
#if DEBUG_MARKER_LEVEL & DEBUG_MARKER_BACKEND
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_NAME_END();
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_NAME_END(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -931,7 +932,12 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
|
||||
#if defined(BACKEND_OPENGL_LEVEL_GLES31)
|
||||
if (gl.features.multisample_texture) {
|
||||
// multi-sample texture on GL 3.2 / GLES 3.1 and above
|
||||
t->gl.target = GL_TEXTURE_2D_MULTISAMPLE;
|
||||
if (depth <= 1) {
|
||||
// We forcibly change the target to 2D-multisample only for flat texture.
|
||||
// A depth value greater than 1 may indicate multiview usage, which requires
|
||||
// GL_TEXTURE_2D_ARRAY. Also 2D MSAA won't work with non-flat texture anyway.
|
||||
t->gl.target = GL_TEXTURE_2D_MULTISAMPLE;
|
||||
}
|
||||
} else {
|
||||
// Turn off multi-sampling for that texture. It's just not supported.
|
||||
}
|
||||
@@ -1207,7 +1213,12 @@ void OpenGLDriver::importTextureR(Handle<HwTexture> th, intptr_t id,
|
||||
#if defined(BACKEND_OPENGL_LEVEL_GLES31)
|
||||
if (gl.features.multisample_texture) {
|
||||
// multi-sample texture on GL 3.2 / GLES 3.1 and above
|
||||
t->gl.target = GL_TEXTURE_2D_MULTISAMPLE;
|
||||
if (depth <= 1) {
|
||||
// We forcibly change the target to 2D-multisample only for flat texture.
|
||||
// A depth value greater than 1 may indicate multiview usage, which requires
|
||||
// GL_TEXTURE_2D_ARRAY. Also 2D MSAA won't work with non-flat texture anyway.
|
||||
t->gl.target = GL_TEXTURE_2D_MULTISAMPLE;
|
||||
}
|
||||
} else {
|
||||
// Turn off multi-sampling for that texture. It's just not supported.
|
||||
}
|
||||
@@ -1452,8 +1463,15 @@ void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
|
||||
#if !defined(__EMSCRIPTEN__) && !defined(FILAMENT_IOS)
|
||||
if (layerCount > 1) {
|
||||
// if layerCount > 1, it means we use the multiview extension.
|
||||
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, attachment,
|
||||
t->gl.id, 0, binfo.layer, layerCount);
|
||||
if (rt->gl.samples > 1) {
|
||||
// For MSAA
|
||||
glFramebufferTextureMultisampleMultiviewOVR(GL_FRAMEBUFFER, attachment,
|
||||
t->gl.id, 0, rt->gl.samples, binfo.layer, layerCount);
|
||||
}
|
||||
else {
|
||||
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, attachment, t->gl.id, 0,
|
||||
binfo.layer, layerCount);
|
||||
}
|
||||
} else
|
||||
#endif // !defined(__EMSCRIPTEN__) && !defined(FILAMENT_IOS)
|
||||
{
|
||||
@@ -3348,8 +3366,8 @@ void OpenGLDriver::pushGroupMarker(char const* string) {
|
||||
#endif
|
||||
|
||||
#if DEBUG_GROUP_MARKER_LEVEL & DEBUG_GROUP_MARKER_BACKEND
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_NAME_BEGIN(string);
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_NAME_BEGIN(FILAMENT_TRACING_CATEGORY_FILAMENT, string);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -3365,8 +3383,8 @@ void OpenGLDriver::popGroupMarker(int) {
|
||||
#endif
|
||||
|
||||
#if DEBUG_GROUP_MARKER_LEVEL & DEBUG_GROUP_MARKER_BACKEND
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_NAME_END();
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_NAME_END(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -3685,7 +3703,7 @@ void OpenGLDriver::endFrame(UTILS_UNUSED uint32_t frameId) {
|
||||
gl.depthFunc(GL_LESS);
|
||||
gl.disable(GL_SCISSOR_TEST);
|
||||
#endif
|
||||
//SYSTRACE_NAME("glFinish");
|
||||
//FILAMENT_TRACING_NAME(FILAMENT_TRACING_CATEGORY_FILAMENT, "glFinish");
|
||||
//glFinish();
|
||||
mPlatform.endFrame(frameId);
|
||||
insertEventMarker("endFrame");
|
||||
|
||||
@@ -64,7 +64,7 @@ utils::CString OpenGLPlatform::getRendererString(Driver const* driver) {
|
||||
}
|
||||
|
||||
void OpenGLPlatform::makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain,
|
||||
utils::Invocable<void()>, utils::Invocable<void(size_t)>) noexcept {
|
||||
utils::Invocable<void()>, utils::Invocable<void(size_t)>) {
|
||||
makeCurrent(getCurrentContextType(), drawSwapChain, readSwapChain);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,12 +25,13 @@
|
||||
#include <backend/Program.h>
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/BitmaskEnum.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Systrace.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
@@ -96,8 +97,7 @@ OpenGLProgram::~OpenGLProgram() noexcept {
|
||||
}
|
||||
|
||||
void OpenGLProgram::initialize(OpenGLDriver& gld) {
|
||||
|
||||
SYSTRACE_CALL();
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
|
||||
assert_invariant(gl.program == 0);
|
||||
assert_invariant(mToken);
|
||||
@@ -122,8 +122,7 @@ void OpenGLProgram::initialize(OpenGLDriver& gld) {
|
||||
*/
|
||||
void OpenGLProgram::initializeProgramState(OpenGLContext& context, GLuint program,
|
||||
LazyInitializationData& lazyInitializationData) noexcept {
|
||||
|
||||
SYSTRACE_CALL();
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
|
||||
// from the pipeline layout we compute a mapping from {set, binding} to {binding}
|
||||
// for both buffers and textures
|
||||
@@ -175,7 +174,31 @@ void OpenGLProgram::initializeProgramState(OpenGLContext& context, GLuint progra
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DescriptorType::SAMPLER:
|
||||
case DescriptorType::SAMPLER_2D_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_INT:
|
||||
case DescriptorType::SAMPLER_2D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_DEPTH:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_3D_FLOAT:
|
||||
case DescriptorType::SAMPLER_3D_INT:
|
||||
case DescriptorType::SAMPLER_3D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_EXTERNAL: {
|
||||
if (!entry.name.empty()) {
|
||||
GLint const loc = glGetUniformLocation(program, entry.name.c_str());
|
||||
|
||||
@@ -23,12 +23,13 @@
|
||||
#include <backend/platforms/OpenGLPlatform.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/JobSystem.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Mutex.h>
|
||||
#include <utils/Systrace.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
@@ -240,8 +241,8 @@ void TimerQueryFenceFactory::beginTimeElapsedQuery(GLTimerQuery* tq) {
|
||||
if (state) {
|
||||
platform.waitFence(fence, FENCE_WAIT_FOR_EVER);
|
||||
state->then = clock::now().time_since_epoch().count();
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_ASYNC_BEGIN("OpenGLTimerQueryFence", intptr_t(state.get()));
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_ASYNC_BEGIN(FILAMENT_TRACING_CATEGORY_FILAMENT, "OpenGLTimerQueryFence", intptr_t(state.get()));
|
||||
}
|
||||
platform.destroyFence(fence);
|
||||
});
|
||||
@@ -257,8 +258,8 @@ void TimerQueryFenceFactory::endTimeElapsedQuery(OpenGLDriver&, GLTimerQuery* tq
|
||||
platform.waitFence(fence, FENCE_WAIT_FOR_EVER);
|
||||
int64_t const now = clock::now().time_since_epoch().count();
|
||||
state->elapsed.store(now - state->then, std::memory_order_relaxed);
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_ASYNC_END("OpenGLTimerQueryFence", intptr_t(state.get()));
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_ASYNC_END(FILAMENT_TRACING_CATEGORY_FILAMENT, "OpenGLTimerQueryFence", intptr_t(state.get()));
|
||||
}
|
||||
platform.destroyFence(fence);
|
||||
});
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Program.h>
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/CString.h>
|
||||
#include <utils/debug.h>
|
||||
@@ -36,7 +38,6 @@
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Systrace.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
@@ -367,7 +368,7 @@ void ShaderCompilerService::notifyWhenAllProgramsAreReady(
|
||||
|
||||
GLuint ShaderCompilerService::initialize(program_token_t& token) {
|
||||
|
||||
SYSTRACE_CALL();
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
|
||||
assert_invariant(token);// This function should be called when the token is still alive.
|
||||
|
||||
@@ -454,8 +455,8 @@ void ShaderCompilerService::runAtNextTick(CompilerPriorityQueue priority,
|
||||
});
|
||||
ops.emplace(pos, priority, token, std::move(job));
|
||||
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_VALUE32("ShaderCompilerService Jobs", mRunAtNextTickOps.size());
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT, "ShaderCompilerService Jobs", mRunAtNextTickOps.size());
|
||||
}
|
||||
|
||||
bool ShaderCompilerService::cancelTickOp(program_token_t const& token) noexcept {
|
||||
@@ -468,8 +469,8 @@ bool ShaderCompilerService::cancelTickOp(program_token_t const& token) noexcept
|
||||
ops.erase(pos);
|
||||
return true;
|
||||
}
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_VALUE32("ShaderCompilerService Jobs", ops.size());
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT, "ShaderCompilerService Jobs", ops.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -485,15 +486,15 @@ void ShaderCompilerService::executeTickOps() noexcept {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
SYSTRACE_CONTEXT();
|
||||
SYSTRACE_VALUE32("ShaderCompilerService Jobs", ops.size());
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT, "ShaderCompilerService Jobs", ops.size());
|
||||
}
|
||||
|
||||
/* static */ void ShaderCompilerService::compileShaders(OpenGLContext& context,
|
||||
Program::ShaderSource shadersSource,
|
||||
FixedCapacityVector<Program::SpecializationConstant> const& specializationConstants,
|
||||
bool multiview, program_token_t const& token) noexcept {
|
||||
SYSTRACE_CALL();
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
|
||||
auto const appendSpecConstantString = +[](std::string& s, Program::SpecializationConstant const& sc) {
|
||||
s += "#define SPIRV_CROSS_CONSTANT_ID_" + std::to_string(sc.id) + ' ';
|
||||
@@ -616,7 +617,7 @@ void ShaderCompilerService::executeTickOps() noexcept {
|
||||
}
|
||||
|
||||
/* static */ void ShaderCompilerService::checkCompileStatus(program_token_t const& token) noexcept {
|
||||
SYSTRACE_CALL();
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
|
||||
UTILS_NOUNROLL
|
||||
for (size_t i = 0; i < Program::SHADER_TYPE_COUNT; i++) {
|
||||
@@ -639,7 +640,7 @@ void ShaderCompilerService::executeTickOps() noexcept {
|
||||
|
||||
/* static */ void ShaderCompilerService::linkProgram(OpenGLContext const& context,
|
||||
program_token_t const& token) noexcept {
|
||||
SYSTRACE_CALL();
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
|
||||
// Shader compilation should be completed by now. Check the status and log errors on failure.
|
||||
checkCompileStatus(token);
|
||||
@@ -675,7 +676,7 @@ void ShaderCompilerService::executeTickOps() noexcept {
|
||||
|
||||
/* static */ bool ShaderCompilerService::checkLinkStatusAndCleanupShaders(
|
||||
program_token_t const& token) noexcept {
|
||||
SYSTRACE_CALL();
|
||||
FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
assert_invariant(token->gl.program);
|
||||
|
||||
bool linked = true;
|
||||
|
||||
@@ -70,6 +70,9 @@ PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glMaxShaderCompilerThreadsKHR;
|
||||
#ifdef GL_OVR_multiview
|
||||
PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glFramebufferTextureMultiviewOVR;
|
||||
#endif
|
||||
#ifdef GL_OVR_multiview_multisampled_render_to_texture
|
||||
PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC glFramebufferTextureMultisampleMultiviewOVR;
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__) && !defined(FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2)
|
||||
// On Android, If we want to support a build system less than ANDROID_API 21, we need to
|
||||
@@ -123,6 +126,9 @@ void importGLESExtensionsEntryPoints() {
|
||||
#ifdef GL_OVR_multiview
|
||||
getProcAddress(glFramebufferTextureMultiviewOVR, "glFramebufferTextureMultiviewOVR");
|
||||
#endif
|
||||
#ifdef GL_OVR_multiview_multisampled_render_to_texture
|
||||
getProcAddress(glFramebufferTextureMultisampleMultiviewOVR, "glFramebufferTextureMultisampleMultiviewOVR");
|
||||
#endif
|
||||
#if defined(__ANDROID__) && !defined(FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2)
|
||||
getProcAddress(glDispatchCompute, "glDispatchCompute");
|
||||
#endif
|
||||
|
||||
@@ -154,6 +154,9 @@ extern PFNGLMAXSHADERCOMPILERTHREADSKHRPROC glMaxShaderCompilerThreadsKHR;
|
||||
#ifdef GL_OVR_multiview
|
||||
extern PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC glFramebufferTextureMultiviewOVR;
|
||||
#endif
|
||||
#ifdef GL_OVR_multiview_multisampled_render_to_texture
|
||||
extern PFNGLFRAMEBUFFERTEXTUREMULTISAMPLEMULTIVIEWOVRPROC glFramebufferTextureMultisampleMultiviewOVR;
|
||||
#endif
|
||||
#if defined(__ANDROID__) && !defined(FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2)
|
||||
extern PFNGLDISPATCHCOMPUTEPROC glDispatchCompute;
|
||||
#endif
|
||||
|
||||
@@ -54,7 +54,7 @@ struct PlatformCocoaGLImpl {
|
||||
CVOpenGLTextureCacheRef mTextureCache = nullptr;
|
||||
std::unique_ptr<CocoaExternalImage::SharedGl> mExternalImageSharedGl;
|
||||
void updateOpenGLContext(NSView *nsView, bool resetView, bool clearView);
|
||||
struct ExternalImageCocoaGL : public Platform::ExternalImage {
|
||||
struct ExternalImageCocoaGL final : public Platform::ExternalImage {
|
||||
CVPixelBufferRef cvBuffer;
|
||||
protected:
|
||||
~ExternalImageCocoaGL() noexcept final;
|
||||
@@ -255,7 +255,7 @@ void PlatformCocoaGL::destroySwapChain(Platform::SwapChain* swapChain) noexcept
|
||||
}
|
||||
|
||||
bool PlatformCocoaGL::makeCurrent(ContextType type, SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) noexcept {
|
||||
SwapChain* readSwapChain) {
|
||||
ASSERT_PRECONDITION_NON_FATAL(drawSwapChain == readSwapChain,
|
||||
"ContextManagerCocoa does not support using distinct draw/read swap chains.");
|
||||
CocoaGLSwapChain* swapChain = (CocoaGLSwapChain*)drawSwapChain;
|
||||
|
||||
@@ -155,7 +155,7 @@ uint32_t PlatformCocoaTouchGL::getDefaultFramebufferObject() noexcept {
|
||||
}
|
||||
|
||||
bool PlatformCocoaTouchGL::makeCurrent(ContextType type, SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) noexcept {
|
||||
SwapChain* readSwapChain) {
|
||||
ASSERT_PRECONDITION_NON_FATAL(drawSwapChain == readSwapChain,
|
||||
"PlatformCocoaTouchGL does not support using distinct draw/read swap chains.");
|
||||
CAEAGLLayer* const glLayer = (__bridge CAEAGLLayer*) drawSwapChain;
|
||||
|
||||
@@ -577,18 +577,18 @@ OpenGLPlatform::ContextType PlatformEGL::getCurrentContextType() const noexcept
|
||||
}
|
||||
|
||||
bool PlatformEGL::makeCurrent(ContextType type,
|
||||
SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept {
|
||||
SwapChain* drawSwapChain, SwapChain* readSwapChain) {
|
||||
SwapChainEGL const* const dsc = static_cast<SwapChainEGL const*>(drawSwapChain);
|
||||
SwapChainEGL const* const rsc = static_cast<SwapChainEGL const*>(readSwapChain);
|
||||
EGLContext context = getContextForType(type);
|
||||
EGLBoolean const success = egl.makeCurrent(context, dsc->sur, rsc->sur);
|
||||
return success == EGL_TRUE ? true : false;
|
||||
return success == EGL_TRUE;
|
||||
}
|
||||
|
||||
void PlatformEGL::makeCurrent(SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain,
|
||||
Invocable<void()> preContextChange,
|
||||
Invocable<void(size_t index)> postContextChange) noexcept {
|
||||
Invocable<void(size_t index)> postContextChange) {
|
||||
|
||||
assert_invariant(drawSwapChain);
|
||||
assert_invariant(readSwapChain);
|
||||
@@ -796,7 +796,7 @@ void PlatformEGL::Config::erase(EGLint name) noexcept {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
EGLBoolean PlatformEGL::EGL::makeCurrent(EGLContext context, EGLSurface drawSurface,
|
||||
EGLSurface readSurface) noexcept {
|
||||
EGLSurface readSurface) {
|
||||
if (UTILS_UNLIKELY((
|
||||
mCurrentContext != context ||
|
||||
drawSurface != mCurrentDrawSurface || readSurface != mCurrentReadSurface))) {
|
||||
|
||||
@@ -135,7 +135,7 @@ static constexpr const std::string_view kNativeWindowInvalidMsg =
|
||||
|
||||
bool PlatformEGLAndroid::makeCurrent(ContextType type,
|
||||
SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) noexcept {
|
||||
SwapChain* readSwapChain) {
|
||||
|
||||
// fast & safe path
|
||||
if (UTILS_LIKELY(!mAssertNativeWindowIsValid)) {
|
||||
@@ -255,6 +255,7 @@ Platform::ExternalImageHandle PlatformEGLAndroid::createExternalImage(AHardwareB
|
||||
p->height = hardwareBufferDescription.height;
|
||||
p->width = hardwareBufferDescription.width;
|
||||
auto textureFormat = mapToFilamentFormat(hardwareBufferDescription.format, sRGB);
|
||||
p->format = textureFormat;
|
||||
p->usage = mapToFilamentUsage(hardwareBufferDescription.usage, textureFormat);
|
||||
return ExternalImageHandle{ p };
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ void PlatformGLX::destroySwapChain(Platform::SwapChain* swapChain) noexcept {
|
||||
}
|
||||
|
||||
bool PlatformGLX::makeCurrent(ContextType type, SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) noexcept {
|
||||
SwapChain* readSwapChain) {
|
||||
g_glx.setCurrentContext(mGLXDisplay,
|
||||
(GLXDrawable)drawSwapChain, (GLXDrawable)readSwapChain, mGLXContext);
|
||||
return true;
|
||||
|
||||
@@ -169,7 +169,7 @@ void PlatformOSMesa::destroySwapChain(Platform::SwapChain* swapChain) noexcept {
|
||||
}
|
||||
|
||||
bool PlatformOSMesa::makeCurrent(ContextType type, SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) noexcept {
|
||||
SwapChain* readSwapChain) {
|
||||
OSMesaAPI* api = (OSMesaAPI*) mOsMesaApi;
|
||||
OSMesaSwapchain* impl = (OSMesaSwapchain*) drawSwapChain;
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ void PlatformWGL::destroySwapChain(Platform::SwapChain* swapChain) noexcept {
|
||||
}
|
||||
|
||||
bool PlatformWGL::makeCurrent(ContextType type, SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) noexcept {
|
||||
SwapChain* readSwapChain) {
|
||||
ASSERT_PRECONDITION_NON_FATAL(drawSwapChain == readSwapChain,
|
||||
"PlatformWGL does not support distinct draw/read swap chains.");
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ void PlatformWebGL::destroySwapChain(Platform::SwapChain* swapChain) noexcept {
|
||||
}
|
||||
|
||||
bool PlatformWebGL::makeCurrent(ContextType type, SwapChain* drawSwapChain,
|
||||
SwapChain* readSwapChain) noexcept {
|
||||
SwapChain* readSwapChain) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ VulkanBuffer::VulkanBuffer(VmaAllocator allocator, VulkanStagePool& stagePool,
|
||||
: mAllocator(allocator),
|
||||
mStagePool(stagePool),
|
||||
mUsage(usage),
|
||||
mUpdatedOffset(0),
|
||||
mUpdatedOffset(0),
|
||||
mUpdatedBytes(0) {
|
||||
// for now make sure that only 1 bit is set in usage
|
||||
// (because loadFromCpu() assumes that somewhat)
|
||||
@@ -56,11 +56,12 @@ void VulkanBuffer::loadFromCpu(VkCommandBuffer cmdbuf, const void* cpuData, uint
|
||||
vmaMapMemory(mAllocator, stage->memory, &mapped);
|
||||
memcpy(mapped, cpuData, numBytes);
|
||||
vmaUnmapMemory(mAllocator, stage->memory);
|
||||
vmaFlushAllocation(mAllocator, stage->memory, byteOffset, numBytes);
|
||||
vmaFlushAllocation(mAllocator, stage->memory, 0, numBytes);
|
||||
|
||||
// If there was a previous update, then we need to make sure the following write is properly
|
||||
// synced with the previous read.
|
||||
if (mUpdatedBytes > 0) {
|
||||
if (mUpdatedBytes > 0 &&
|
||||
(byteOffset >= mUpdatedOffset && byteOffset <= (mUpdatedOffset + mUpdatedBytes))) {
|
||||
VkAccessFlags srcAccess = 0;
|
||||
VkPipelineStageFlags srcStage = 0;
|
||||
if (mUsage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) {
|
||||
@@ -74,28 +75,28 @@ void VulkanBuffer::loadFromCpu(VkCommandBuffer cmdbuf, const void* cpuData, uint
|
||||
srcStage = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
||||
}
|
||||
|
||||
VkBufferMemoryBarrier barrier{
|
||||
VkBufferMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.srcAccessMask = srcAccess,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = mGpuBuffer,
|
||||
.offset = mUpdatedOffset,
|
||||
.size = mUpdatedBytes,
|
||||
.offset = byteOffset,
|
||||
.size = numBytes,
|
||||
};
|
||||
vkCmdPipelineBarrier(cmdbuf, srcStage, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
|
||||
&barrier, 0, nullptr);
|
||||
}
|
||||
|
||||
VkBufferCopy region {
|
||||
.srcOffset = 0,
|
||||
.dstOffset = byteOffset,
|
||||
.size = numBytes,
|
||||
VkBufferCopy region = {
|
||||
.srcOffset = 0,
|
||||
.dstOffset = byteOffset,
|
||||
.size = numBytes,
|
||||
};
|
||||
vkCmdCopyBuffer(cmdbuf, stage->buffer, mGpuBuffer, 1, ®ion);
|
||||
|
||||
mUpdatedOffset = byteOffset;
|
||||
mUpdatedOffset = byteOffset;
|
||||
mUpdatedBytes = numBytes;
|
||||
|
||||
// Firstly, ensure that the copy finishes before the next draw call.
|
||||
@@ -112,21 +113,21 @@ void VulkanBuffer::loadFromCpu(VkCommandBuffer cmdbuf, const void* cpuData, uint
|
||||
dstAccessMask |= VK_ACCESS_INDEX_READ_BIT;
|
||||
dstStageMask |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
||||
} else if (mUsage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) {
|
||||
dstAccessMask |= VK_ACCESS_UNIFORM_READ_BIT;
|
||||
dstStageMask |=
|
||||
(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
dstAccessMask |= VK_ACCESS_SHADER_READ_BIT;
|
||||
dstStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_VERTEX_SHADER_BIT;
|
||||
} else if (mUsage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) {
|
||||
// TODO: implement me
|
||||
}
|
||||
|
||||
VkBufferMemoryBarrier barrier{
|
||||
VkBufferMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = dstAccessMask,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.buffer = mGpuBuffer,
|
||||
.size = VK_WHOLE_SIZE,
|
||||
.offset = byteOffset,
|
||||
.size = numBytes,
|
||||
};
|
||||
|
||||
vkCmdPipelineBarrier(cmdbuf, VK_PIPELINE_STAGE_TRANSFER_BIT, dstStageMask, 0, 0, nullptr, 1,
|
||||
|
||||
@@ -151,13 +151,13 @@ static_assert(FVK_ENABLED(FVK_DEBUG_VALIDATION));
|
||||
|
||||
#elif FVK_ENABLED(FVK_DEBUG_SYSTRACE)
|
||||
|
||||
#include <utils/Systrace.h>
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#define FVK_SYSTRACE_CONTEXT() SYSTRACE_CONTEXT()
|
||||
#define FVK_SYSTRACE_START(marker) SYSTRACE_NAME_BEGIN(marker)
|
||||
#define FVK_SYSTRACE_END() SYSTRACE_NAME_END()
|
||||
#define FVK_SYSTRACE_SCOPE() SYSTRACE_CALL()
|
||||
#define FVK_PROFILE_MARKER(marker) SYSTRACE_CALL()
|
||||
#define FVK_SYSTRACE_CONTEXT() FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT)
|
||||
#define FVK_SYSTRACE_START(marker) FILAMENT_TRACING_NAME_BEGIN(FILAMENT_TRACING_CATEGORY_FILAMENT, marker)
|
||||
#define FVK_SYSTRACE_END() FILAMENT_TRACING_NAME_END(FILAMENT_TRACING_CATEGORY_FILAMENT)
|
||||
#define FVK_SYSTRACE_SCOPE() FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT)
|
||||
#define FVK_PROFILE_MARKER(marker) FILAMENT_TRACING_CALL(FILAMENT_TRACING_CATEGORY_FILAMENT)
|
||||
|
||||
#else
|
||||
#define FVK_SYSTRACE_CONTEXT()
|
||||
|
||||
@@ -142,6 +142,10 @@ public:
|
||||
return mPortabilitySubsetFeatures.imageView2DOn3DImage == VK_TRUE;
|
||||
}
|
||||
|
||||
inline bool isUnifiedMemoryArchitecture() const noexcept {
|
||||
return mIsUnifiedMemoryArchitecture;
|
||||
}
|
||||
|
||||
private:
|
||||
VkPhysicalDeviceMemoryProperties mMemoryProperties = {};
|
||||
VkPhysicalDeviceProperties2 mPhysicalDeviceProperties = {
|
||||
@@ -164,6 +168,7 @@ private:
|
||||
bool mDebugUtilsSupported = false;
|
||||
bool mLazilyAllocatedMemorySupported = false;
|
||||
bool mProtectedMemorySupported = false;
|
||||
bool mIsUnifiedMemoryArchitecture = false;
|
||||
|
||||
fvkutils::VkFormatList mDepthStencilFormats;
|
||||
fvkutils::VkFormatList mBlittableDepthStencilFormats;
|
||||
|
||||
@@ -358,12 +358,11 @@ void VulkanDescriptorSetCache::updateSamplerImpl(VkDescriptorSet vkset, uint8_t
|
||||
range.levelCount = 1;
|
||||
range.layerCount = 1;
|
||||
}
|
||||
VkDescriptorImageInfo info{
|
||||
VkDescriptorImageInfo info = {
|
||||
.sampler = sampler,
|
||||
.imageView = texture->getView(range),
|
||||
.imageLayout = fvkutils::getVkLayout(texture->getDefaultLayout()),
|
||||
.imageLayout = fvkutils::getVkLayout(texture->getSamplerLayout()),
|
||||
};
|
||||
|
||||
VkWriteDescriptorSet descriptorWrite = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.pNext = nullptr,
|
||||
|
||||
@@ -622,7 +622,7 @@ void VulkanDriver::createTextureExternalImage2R(Handle<HwTexture> th, backend::S
|
||||
auto& commands = mCommands.get();
|
||||
// Unlike uploaded textures or swapchains, we need to explicit transition this
|
||||
// texture into the read layout.
|
||||
texture->transitionLayout(&commands, texture->getPrimaryViewRange(), VulkanLayout::READ_ONLY);
|
||||
texture->transitionLayout(&commands, texture->getPrimaryViewRange(), VulkanLayout::FRAG_READ);
|
||||
|
||||
if (imgData.external.valid()) {
|
||||
mExternalImageManager.addExternallySampledTexture(texture, externalImage);
|
||||
|
||||
@@ -93,7 +93,32 @@ BitmaskGroup fromBackendLayout(DescriptorSetLayout const& layout) {
|
||||
case DescriptorType::SAMPLER_EXTERNAL:
|
||||
fromStageFlags(binding.stageFlags, binding.binding, mask.externalSampler);
|
||||
UTILS_FALLTHROUGH;
|
||||
case DescriptorType::SAMPLER: {
|
||||
|
||||
case DescriptorType::SAMPLER_2D_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_INT:
|
||||
case DescriptorType::SAMPLER_2D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_DEPTH:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_2D_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_DEPTH:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_UINT:
|
||||
case DescriptorType::SAMPLER_CUBE_ARRAY_DEPTH:
|
||||
case DescriptorType::SAMPLER_3D_FLOAT:
|
||||
case DescriptorType::SAMPLER_3D_INT:
|
||||
case DescriptorType::SAMPLER_3D_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_UINT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_FLOAT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_INT:
|
||||
case DescriptorType::SAMPLER_2D_MS_ARRAY_UINT: {
|
||||
fromStageFlags(binding.stageFlags, binding.binding, mask.sampler);
|
||||
break;
|
||||
}
|
||||
@@ -495,7 +520,8 @@ void VulkanRenderTarget::emitBarriersEndRenderPass(VulkanCommandBuffer& commands
|
||||
}
|
||||
} else {
|
||||
texture->setLayout(range, VulkanFboCache::FINAL_COLOR_ATTACHMENT_LAYOUT);
|
||||
if (!texture->transitionLayout(&commands, range, VulkanLayout::READ_WRITE)) {
|
||||
if (texture->isSampleable() &&
|
||||
!texture->transitionLayout(&commands, range, VulkanLayout::FRAG_READ)) {
|
||||
texture->attachmentToSamplerBarrier(&commands, range);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,6 +234,7 @@ void VulkanReadPixels::run(fvkmemory::resource_ptr<VulkanRenderTarget> srcTarget
|
||||
|
||||
VulkanAttachment const srcAttachment = srcTarget->getColor0();
|
||||
VkImageSubresourceRange const srcRange = srcAttachment.getSubresourceRange();
|
||||
VulkanLayout const srcLayout = srcAttachment.getLayout();
|
||||
srcTexture->transitionLayout(cmdbuffer, srcRange, VulkanLayout::TRANSFER_SRC);
|
||||
|
||||
VkImageCopy const imageCopyRegion = {
|
||||
@@ -270,7 +271,7 @@ void VulkanReadPixels::run(fvkmemory::resource_ptr<VulkanRenderTarget> srcTarget
|
||||
fvkutils::getVkLayout(VulkanLayout::TRANSFER_DST), 1, &imageCopyRegion);
|
||||
|
||||
// Restore the source image layout.
|
||||
srcTexture->transitionLayout(cmdbuffer, srcRange, srcTexture->getDefaultLayout());
|
||||
srcTexture->transitionLayout(cmdbuffer, srcRange, srcLayout);
|
||||
|
||||
vkEndCommandBuffer(cmdbuffer);
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ VulkanStageImage const* VulkanStagePool::acquireImage(PixelDataFormat format, Pi
|
||||
fvkutils::transitionLayout(cmdbuffer, {
|
||||
.image = image->image,
|
||||
.oldLayout = VulkanLayout::UNDEFINED,
|
||||
.newLayout = VulkanLayout::READ_WRITE, // (= VK_IMAGE_LAYOUT_GENERAL)
|
||||
.newLayout = VulkanLayout::STAGING, // (= VK_IMAGE_LAYOUT_GENERAL)
|
||||
.subresources = { aspectFlags, 0, 1, 0, 1 },
|
||||
});
|
||||
return image;
|
||||
|
||||
@@ -125,7 +125,7 @@ inline VulkanLayout getDefaultLayoutImpl(TextureUsage usage) {
|
||||
return VulkanLayout::COLOR_ATTACHMENT;
|
||||
}
|
||||
// Finally, the layout for an immutable texture is optimal read-only.
|
||||
return VulkanLayout::READ_ONLY;
|
||||
return VulkanLayout::FRAG_READ;
|
||||
}
|
||||
|
||||
inline VulkanLayout getDefaultLayoutImpl(VkImageUsageFlags vkusage) {
|
||||
@@ -187,7 +187,7 @@ VkImageUsageFlags getUsage(VulkanContext const& context, uint8_t samples,
|
||||
VkFormatProperties props;
|
||||
vkGetPhysicalDeviceFormatProperties(physicalDevice, vkFormat, &props);
|
||||
if (!(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
|
||||
FVK_LOGW << "Texture usage is SAMPLEABLE but format " << mState->mVkFormat << " is not "
|
||||
FVK_LOGW << "Texture usage is SAMPLEABLE but format " << vkFormat << " is not "
|
||||
"sampleable with optimal tiling." << utils::io::endl;
|
||||
}
|
||||
}
|
||||
@@ -691,6 +691,7 @@ bool VulkanTexture::transitionLayout(VkCommandBuffer cmdbuf, VkImageSubresourceR
|
||||
<< " is skipped because of no change in layout" << utils::io::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return hasTransitions;
|
||||
}
|
||||
|
||||
@@ -700,16 +701,15 @@ void VulkanTexture::samplerToAttachmentBarrier(VulkanCommandBuffer* commands,
|
||||
VkImageLayout const layout =
|
||||
fvkutils::getVkLayout(getLayout(range.baseArrayLayer, range.baseMipLevel));
|
||||
VkImageMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
||||
.dstAccessMask =
|
||||
VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.oldLayout = layout,
|
||||
.newLayout = layout,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = mState->mTextureImage,
|
||||
.subresourceRange = range,
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
||||
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.oldLayout = layout,
|
||||
.newLayout = layout,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = mState->mTextureImage,
|
||||
.subresourceRange = range,
|
||||
};
|
||||
vkCmdPipelineBarrier(cmdbuf, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
@@ -723,15 +723,15 @@ void VulkanTexture::attachmentToSamplerBarrier(VulkanCommandBuffer* commands,
|
||||
VkImageLayout const layout
|
||||
= fvkutils::getVkLayout(getLayout(range.baseArrayLayer, range.baseMipLevel));
|
||||
VkImageMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
||||
.oldLayout = layout,
|
||||
.newLayout = layout,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = mState->mTextureImage,
|
||||
.subresourceRange = range,
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccessMask = VK_ACCESS_SHADER_READ_BIT,
|
||||
.oldLayout = layout,
|
||||
.newLayout = layout,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = mState->mTextureImage,
|
||||
.subresourceRange = range,
|
||||
};
|
||||
vkCmdPipelineBarrier(cmdbuf, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user