Compare commits
53
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b236bd4f50 | ||
|
|
b7b7afb62a | ||
|
|
957380b258 | ||
|
|
fe3f16924d | ||
|
|
ffc3128377 | ||
|
|
c05e2ec47d | ||
|
|
9768f49714 | ||
|
|
6c54cfe88a | ||
|
|
2dc8d6bcc0 | ||
|
|
08dc398452 | ||
|
|
cd180c9a44 | ||
|
|
0a7fe52124 | ||
|
|
b71faf47cc | ||
|
|
67babceb73 | ||
|
|
8e13fc86d5 | ||
|
|
351c8e0972 | ||
|
|
dc44e20be0 | ||
|
|
e64b498d6e | ||
|
|
31ab4a13c9 | ||
|
|
e9728dcc8d | ||
|
|
40a3644086 | ||
|
|
41ef71abdf | ||
|
|
3b40e52c98 | ||
|
|
de8c7969f3 | ||
|
|
f2c049222b | ||
|
|
be30ac1fcb | ||
|
|
c5cc7fe26a | ||
|
|
d04b0a5c73 | ||
|
|
72ab2aef0a | ||
|
|
1527bb7ad3 | ||
|
|
8cb26fc9ac | ||
|
|
c21794d0a0 | ||
|
|
1a6338569a | ||
|
|
c5ebe1a88a | ||
|
|
a3f2028ae4 | ||
|
|
c393ee4591 | ||
|
|
83a82ae10e | ||
|
|
676694e458 | ||
|
|
2ca218928f | ||
|
|
776ce223fc | ||
|
|
0d4d1f55c9 | ||
|
|
d6dba71ace | ||
|
|
61ee11ae6c | ||
|
|
90f32e7277 | ||
|
|
b85d9afdb3 | ||
|
|
4297d43d9a | ||
|
|
cfcf714c21 | ||
|
|
f7cfc6a65e | ||
|
|
4ead3bcebf | ||
|
|
21e0677039 | ||
|
|
107b5a4854 | ||
|
|
9761b65137 | ||
|
|
b1831d2786 |
+9
-16
@@ -337,19 +337,23 @@ endif()
|
||||
# ==================================================================================================
|
||||
# Release compiler flags
|
||||
# ==================================================================================================
|
||||
if (NOT MSVC)
|
||||
if (NOT MSVC AND NOT IOS)
|
||||
# Omitting stack frame pointers prevents the generation of readable stack traces in crash reports on iOS
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer")
|
||||
|
||||
# These aren't compatible with -fembed-bitcode (and seem to have no effect on Apple platforms anyway)
|
||||
if (NOT IOS)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections")
|
||||
endif()
|
||||
|
||||
# On Android RELEASE builds, we disable exceptions and RTTI to save some space (about 75 KiB
|
||||
# saved by -fno-exception and 10 KiB saved by -fno-rtti).
|
||||
if (ANDROID OR IOS OR WEBGL)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-rtti")
|
||||
|
||||
if (ANDROID OR WEBGL)
|
||||
# Omitting unwind info prevents the generation of readable stack traces in crash reports on iOS
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-unwind-tables -fno-asynchronous-unwind-tables")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# With WebGL, we disable RTTI even for debug builds because we pass emscripten::val back and forth
|
||||
@@ -459,13 +463,6 @@ else()
|
||||
option(FILAMENT_ENABLE_MATDBG "Enable the material debugger" OFF)
|
||||
endif()
|
||||
|
||||
# By default, link in fgdbg for Desktop + Debug
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND IS_HOST_PLATFORM)
|
||||
option(FILAMENT_ENABLE_FGDBG "Enable the framegraph debugger" ON)
|
||||
else()
|
||||
option(FILAMENT_ENABLE_FGDBG "Enable the framegraph debugger" OFF)
|
||||
endif()
|
||||
|
||||
# Only optimize materials in Release mode (so error message lines match the source code)
|
||||
if (CMAKE_BUILD_TYPE MATCHES Release)
|
||||
option(FILAMENT_DISABLE_MATOPT "Disable material optimizations" OFF)
|
||||
@@ -692,10 +689,6 @@ if (FILAMENT_BUILD_FILAMAT OR IS_HOST_PLATFORM)
|
||||
if (FILAMENT_ENABLE_MATDBG OR IS_HOST_PLATFORM)
|
||||
add_subdirectory(${LIBRARIES}/matdbg)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_ENABLE_FGDBG OR IS_HOST_PLATFORM)
|
||||
add_subdirectory(${LIBRARIES}/fgdbg)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (FILAMENT_SUPPORTS_VULKAN)
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.28.0'
|
||||
implementation 'com.google.android.filament:filament-android:1.29.0'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -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:
|
||||
|
||||
```
|
||||
pod 'Filament', '~> 1.28.0'
|
||||
pod 'Filament', '~> 1.29.0'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
@@ -313,7 +313,6 @@ and tools.
|
||||
- `bluegl`: OpenGL bindings for macOS, Linux and Windows
|
||||
- `bluevk`: Vulkan bindings for macOS, Linux, Windows and Android
|
||||
- `camutils`: Camera manipulation utilities
|
||||
- `fgdbg`: Frame Graph inspector and debugger (debug builds only)
|
||||
- `filabridge`: Library shared by the Filament engine and host tools
|
||||
- `filaflat`: Serialization/deserialization library used for materials
|
||||
- `filagui`: Helper library for [Dear ImGui](https://github.com/ocornut/imgui)
|
||||
|
||||
@@ -5,6 +5,21 @@ A new header is inserted each time a *tag* is created.
|
||||
|
||||
## main branch
|
||||
|
||||
## v1.29.0
|
||||
|
||||
- gltfio: calculate primitive's AABB correctly.
|
||||
- gltfio: recompute bounding boxes with morph targets
|
||||
- engine: add missing getters on `MaterialInstance`
|
||||
- WebGL: add missing `ColorGrading` JS bindings
|
||||
- engine: improvements/cleanup of Shadow mapping code [⚠️ **Recompile Materials**]
|
||||
|
||||
## v1.28.3
|
||||
|
||||
- backend: add support for GGP platform
|
||||
- engine: primitives with `CullingMode::FRONT_AND_BACK` are now skipped.
|
||||
|
||||
## v1.28.2
|
||||
|
||||
- gltfio: support EXT_meshopt_compression
|
||||
- release packaging: fixed location of default IBL file
|
||||
|
||||
|
||||
@@ -452,3 +452,84 @@ Java_com_google_android_filament_MaterialInstance_nDuplicate(JNIEnv* env, jclass
|
||||
}
|
||||
return (jlong)mi;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nGetMaskThreshold(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
// TODO: implement nGetMaskThreshold()
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->getMaskThreshold();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nGetSpecularAntiAliasingVariance(JNIEnv* env,
|
||||
jclass clazz, jlong nativeMaterialInstance) {
|
||||
// TODO: implement nGetSpecularAntiAliasingVariance()
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->getSpecularAntiAliasingVariance();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jfloat JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nGetSpecularAntiAliasingThreshold(JNIEnv* env,
|
||||
jclass clazz, jlong nativeMaterialInstance) {
|
||||
// TODO: implement nGetSpecularAntiAliasingThreshold()
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->getSpecularAntiAliasingThreshold();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nIsDoubleSided(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
// TODO: implement nIsDoubleSided()
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->isDoubleSided();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nGetCullingMode(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
// TODO: implement nGetCullingMode()
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return (jint)instance->getCullingMode();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nIsColorWriteEnabled(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
// TODO: implement nIsColorWriteEnabled()
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->isColorWriteEnabled();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nIsDepthWriteEnabled(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
// TODO: implement nIsDepthWriteEnabled()
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->isDepthWriteEnabled();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nIsStencilWriteEnabled(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
// TODO: implement nIsStencilWriteEnabled()
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->isStencilWriteEnabled();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nIsDepthCullingEnabled(JNIEnv* env, jclass clazz,
|
||||
jlong nativeMaterialInstance) {
|
||||
// TODO: implement nIsDepthCullingEnabled()
|
||||
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
|
||||
return instance->isDepthCullingEnabled();
|
||||
}
|
||||
|
||||
+84
-1
@@ -24,6 +24,7 @@ import com.google.android.filament.proguard.UsedByNative;
|
||||
|
||||
@UsedByNative("AssetLoader.cpp")
|
||||
public class MaterialInstance {
|
||||
private static final Material.CullingMode[] sCullingModeValues = Material.CullingMode.values();
|
||||
private Material mMaterial;
|
||||
private String mName;
|
||||
private long mNativeObject;
|
||||
@@ -473,6 +474,14 @@ public class MaterialInstance {
|
||||
nSetMaskThreshold(getNativeObject(), threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum alpha value a fragment must have to not be discarded when the blend
|
||||
* mode is MASKED
|
||||
*/
|
||||
public float getMaskThreshold() {
|
||||
return nGetMaskThreshold(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the screen space variance of the filter kernel used when applying specular
|
||||
* anti-aliasing. The default value is set to 0.15. The specified value should be between
|
||||
@@ -486,6 +495,14 @@ public class MaterialInstance {
|
||||
nSetSpecularAntiAliasingVariance(getNativeObject(), variance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the screen space variance of the filter kernel used when applying specular
|
||||
* anti-aliasing.
|
||||
*/
|
||||
public float getSpecularAntiAliasingVariance() {
|
||||
return nGetSpecularAntiAliasingVariance(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the clamping threshold used to suppress estimation errors when applying specular
|
||||
* anti-aliasing. The default value is set to 0.2. The specified value should be between 0
|
||||
@@ -499,6 +516,14 @@ public class MaterialInstance {
|
||||
nSetSpecularAntiAliasingThreshold(getNativeObject(), threshold);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clamping threshold used to suppress estimation errors when applying specular
|
||||
* anti-aliasing.
|
||||
*/
|
||||
public float getSpecularAntiAliasingThreshold() {
|
||||
return nGetSpecularAntiAliasingThreshold(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables double-sided lighting if the parent Material has double-sided capability,
|
||||
* otherwise prints a warning. If double-sided lighting is enabled, backface culling is
|
||||
@@ -512,6 +537,14 @@ public class MaterialInstance {
|
||||
nSetDoubleSided(getNativeObject(), doubleSided);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether double-sided lighting is enabled when the parent Material has double-sided
|
||||
* capability.
|
||||
*/
|
||||
public boolean isDoubleSided() {
|
||||
return nIsDoubleSided(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default triangle culling state that was set on the material.
|
||||
*
|
||||
@@ -519,10 +552,18 @@ public class MaterialInstance {
|
||||
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:culling">
|
||||
* Rasterization: culling</a>
|
||||
*/
|
||||
public void setCullingMode(Material.CullingMode mode) {
|
||||
public void setCullingMode(@NonNull Material.CullingMode mode) {
|
||||
nSetCullingMode(getNativeObject(), mode.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the face culling mode.
|
||||
*/
|
||||
@NonNull
|
||||
public Material.CullingMode getCullingMode() {
|
||||
return sCullingModeValues[nGetCullingMode(getNativeObject())];
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default color-buffer write state that was set on the material.
|
||||
*
|
||||
@@ -534,6 +575,13 @@ public class MaterialInstance {
|
||||
nSetColorWrite(getNativeObject(), enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether color write is enabled.
|
||||
*/
|
||||
public boolean isColorWriteEnabled() {
|
||||
return nIsColorWriteEnabled(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default depth-buffer write state that was set on the material.
|
||||
*
|
||||
@@ -545,10 +593,27 @@ public class MaterialInstance {
|
||||
nSetDepthWrite(getNativeObject(), enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether depth write is enabled.
|
||||
*/
|
||||
public boolean isDepthWriteEnabled() {
|
||||
return nIsDepthWriteEnabled(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or Disable stencil writes
|
||||
*/
|
||||
public void setStencilWrite(boolean enable) {
|
||||
nSetStencilWrite(getNativeObject(), enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether stencil write is enabled.
|
||||
*/
|
||||
public boolean isStencilWriteEnabled() {
|
||||
return nIsStencilWriteEnabled(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the default depth testing state that was set on the material.
|
||||
*
|
||||
@@ -560,6 +625,13 @@ public class MaterialInstance {
|
||||
nSetDepthCulling(getNativeObject(), enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether depth culling is enabled.
|
||||
*/
|
||||
public boolean isDepthCullingEnabled() {
|
||||
return nIsDepthCullingEnabled(getNativeObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stencil comparison function (default is {@link TextureSampler.CompareFunction#ALWAYS}).
|
||||
*
|
||||
@@ -856,4 +928,15 @@ public class MaterialInstance {
|
||||
private static native long nGetMaterial(long nativeMaterialInstance);
|
||||
|
||||
private static native long nDuplicate(long otherNativeMaterialInstance, String name);
|
||||
|
||||
|
||||
private static native float nGetMaskThreshold(long nativeMaterialInstance);
|
||||
private static native float nGetSpecularAntiAliasingVariance(long nativeMaterialInstance);
|
||||
private static native float nGetSpecularAntiAliasingThreshold(long nativeMaterialInstance);
|
||||
private static native boolean nIsDoubleSided(long nativeMaterialInstance);
|
||||
private static native int nGetCullingMode(long nativeMaterialInstance);
|
||||
private static native boolean nIsColorWriteEnabled(long nativeMaterialInstance);
|
||||
private static native boolean nIsDepthWriteEnabled(long nativeMaterialInstance);
|
||||
private static native boolean nIsStencilWriteEnabled(long nativeMaterialInstance);
|
||||
private static native boolean nIsDepthCullingEnabled(long nativeMaterialInstance);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.28.0
|
||||
VERSION_NAME=1.29.0
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
@@ -162,8 +162,6 @@ EGL_ON_LINUX_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_LINUX=OFF"
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
|
||||
MATDBG_GRADLE_OPTION=""
|
||||
|
||||
FGDBG_OPTION="-DFILAMENT_ENABLE_FGDBG=OFF"
|
||||
|
||||
IOS_BUILD_SIMULATOR=false
|
||||
BUILD_UNIVERSAL_LIBRARIES=false
|
||||
|
||||
@@ -223,7 +221,6 @@ function build_desktop_target {
|
||||
${SWIFTSHADER_OPTION} \
|
||||
${EGL_ON_LINUX_OPTION} \
|
||||
${MATDBG_OPTION} \
|
||||
${FGDBG_OPTION} \
|
||||
${deployment_target} \
|
||||
${architectures} \
|
||||
../..
|
||||
@@ -350,7 +347,6 @@ function build_android_target {
|
||||
-DCMAKE_INSTALL_PREFIX="../android-${lc_target}/filament" \
|
||||
-DCMAKE_TOOLCHAIN_FILE="../../build/toolchain-${arch}-linux-android.cmake" \
|
||||
${MATDBG_OPTION} \
|
||||
${FGDBG_OPTION} \
|
||||
${VULKAN_ANDROID_OPTION} \
|
||||
../..
|
||||
fi
|
||||
@@ -580,7 +576,6 @@ function build_ios_target {
|
||||
-DIOS=1 \
|
||||
-DCMAKE_TOOLCHAIN_FILE=../../third_party/clang/iOS.cmake \
|
||||
${MATDBG_OPTION} \
|
||||
${FGDBG_OPTION} \
|
||||
../..
|
||||
fi
|
||||
|
||||
@@ -765,7 +760,6 @@ while getopts ":hacCfijmp:q:uvslwtedk:" opt; do
|
||||
PRINT_MATDBG_HELP=true
|
||||
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON, -DFILAMENT_BUILD_FILAMAT=ON"
|
||||
MATDBG_GRADLE_OPTION="-Pcom.google.android.filament.matdbg"
|
||||
FGDBG_OPTION="-DFILAMENT_ENABLE_FGDBG=ON"
|
||||
;;
|
||||
f)
|
||||
ISSUE_CMAKE_ALWAYS=true
|
||||
|
||||
Executable
+99
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
function print_help {
|
||||
local self_name=$(basename "$0")
|
||||
echo "This tool verifies that every Metal shader in the given Filament material file(s) successfully compiles."
|
||||
echo "Requires the matinfo tool and xcrun to be on the system PATH."
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo " $self_name [options] [<material> ...]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -h"
|
||||
echo " Print this help message."
|
||||
echo " -w"
|
||||
echo " Pass the -w flag to the Metal compiler, to disable warnings."
|
||||
echo ""
|
||||
}
|
||||
|
||||
COMP_FLAGS=""
|
||||
while getopts ":hw" opt; do
|
||||
case ${opt} in
|
||||
h)
|
||||
print_help
|
||||
exit 1
|
||||
;;
|
||||
w)
|
||||
COMP_FLAGS="${COMP_FLAGS} -w"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [[ "$#" == "0" ]]; then
|
||||
print_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make sure matinfo and xcrun are available.
|
||||
if [[ ! $(command -v matinfo) ]]; then
|
||||
echo "Error: matinfo not on PATH."
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! $(command -v xcrun) ]]; then
|
||||
echo "Error: xcrun not on PATH."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function check_material {
|
||||
local material="$1"
|
||||
|
||||
tmpdir="$(mktemp -d /tmp/check_metal_shaders.XXXXX)"
|
||||
|
||||
# First check that the material is valid.
|
||||
if [[ ! $(matinfo "${material}") ]]; then
|
||||
echo "Invalid material file: ${material}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Checking that Metal shaders compile: ${material}"
|
||||
|
||||
set +e
|
||||
local i=0
|
||||
while true; do
|
||||
# The file must have a .metal extension.
|
||||
metalFile="${tmpdir}/${i}.metal"
|
||||
|
||||
# Extract shader i. matinfo will return a non-zero exit code if the shader doesn't exist,
|
||||
# which means we're finished with this material.
|
||||
matinfo --print-metal=${i} "${material}" > "${metalFile}" 2> /dev/null
|
||||
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
break
|
||||
fi
|
||||
|
||||
echo "Testing Metal shader ${i}"
|
||||
|
||||
# Attempt to compile the Metal shader.
|
||||
xcrun -sdk macosx metal ${COMP_FLAGS} -c "${metalFile}" -o /dev/null
|
||||
|
||||
if [[ "$?" -ne 0 ]]; then
|
||||
echo "Error compiling Metal shader: ${metalFile}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
((i++))
|
||||
done
|
||||
set -e
|
||||
|
||||
rm -r "${tmpdir}"
|
||||
}
|
||||
|
||||
for material in "$@"
|
||||
do
|
||||
check_material "${material}"
|
||||
done
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
setuptools==40.6.2
|
||||
setuptools==58.0.4
|
||||
wheel==0.37.1
|
||||
certifi==2021.10.8
|
||||
cffi==1.15.0
|
||||
charset-normalizer==2.0.12
|
||||
certifi==2022.9.24
|
||||
cffi==1.15.1
|
||||
charset-normalizer==2.1.1
|
||||
Deprecated==1.2.13
|
||||
idna==3.3
|
||||
idna==3.4
|
||||
pycparser==2.21
|
||||
PyGithub==1.55
|
||||
PyJWT==2.4.0
|
||||
PyGithub==1.56
|
||||
PyJWT==2.6.0
|
||||
PyNaCl==1.5.0
|
||||
requests==2.27.1
|
||||
urllib3==1.26.9
|
||||
wrapt==1.14.0
|
||||
requests==2.28.1
|
||||
urllib3==1.26.12
|
||||
wrapt==1.14.1
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+11
-12
@@ -1432,12 +1432,13 @@ non-shader data.
|
||||
|
||||
</p><dl><table><tbody><tr valign="top"><td><dt>Type</dt></td><td><dd><p> <code>number</code>
|
||||
|
||||
</p></dd></td></tr><tr valign="top"><td><dt>Value</dt></td><td><dd><p> An integer value, either 1 or 2. Defaults to 1.
|
||||
</p></dd></td></tr><tr valign="top"><td><dt>Value</dt></td><td><dd><p> An integer value, either 1, 2 or 3. Defaults to 1.
|
||||
|
||||
</p></dd></td></tr></tbody></table></dl><div class="table">
|
||||
<table class="table"><tbody><tr><th style="text-align:left"> Feature Level </th><th style="text-align:left"> Guaranteed features </th></tr>
|
||||
<tr><td style="text-align:left"> 1 </td><td style="text-align:left"> 9 textures per material </td></tr>
|
||||
<tr><td style="text-align:left"> 2 </td><td style="text-align:left"> 12 textures per material, cubemap arrays, ESSL 3.10 </td></tr>
|
||||
<tr><td style="text-align:left"> 2 </td><td style="text-align:left"> 9 textures per material, cubemap arrays, ESSL 3.10 </td></tr>
|
||||
<tr><td style="text-align:left"> 3 </td><td style="text-align:left"> 12 textures per material, cubemap arrays, ESSL 3.10 </td></tr>
|
||||
</tbody></table><center><div class="tablecaption"><a class="target" name="table_featurelevels"> </a><b style="font-style:normal;">Table 13:</b> Feature levels</div></center></div>
|
||||
|
||||
<p></p><p>
|
||||
@@ -2036,23 +2037,21 @@ and sorting issues are minimized or eliminated</span></center></div></center>
|
||||
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
|
||||
</p></dd><dt>Description</dt><dd><p> Only available in the <code>unlit</code> shading model. If this property is enabled, the final color
|
||||
computed by the material is multiplied by the shadowing factor (or visibility). This allows to
|
||||
create transparent shadow-receiving objects (for instance an invisible ground plane in AR).
|
||||
This is only supported with shadows from directional lights.
|
||||
</p></dd><dt>Description</dt><dd><p> Enables two-sided rendering and its capability to be toggled at run time. When set to <code>true</code>,
|
||||
<code>culling</code> is automatically set to <code>none</code>; if the triangle is back-facing, the triangle's
|
||||
normal is flipped to become front-facing. When explicitly set to <code>false</code>, this allows the
|
||||
double-sidedness to be toggled at run time.
|
||||
|
||||
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
|
||||
<span class="line"> name : <span class="hljs-string">"Invisible shadow plane"</span>,</span>
|
||||
<span class="line"> shadingModel : unlit,</span>
|
||||
<span class="line"> shadowMultiplier : <span class="hljs-literal">true</span>,</span>
|
||||
<span class="line"> blending : transparent</span>
|
||||
<span class="line"> name : <span class="hljs-string">"Double sided material"</span>,</span>
|
||||
<span class="line"> shadingModel : lit,</span>
|
||||
<span class="line"> doubleSided : <span class="hljs-literal">true</span></span>
|
||||
<span class="line">}</span>
|
||||
<span class="line"></span>
|
||||
<span class="line">fragment {</span>
|
||||
<span class="line"> void material(inout MaterialInputs material) {</span>
|
||||
<span class="line"> prepareMaterial(material);</span>
|
||||
<span class="line"> <span class="hljs-comment">// baseColor defines the color and opacity of the final shadow</span></span>
|
||||
<span class="line"> material.baseColor = vec4(0.0, 0.0, 0.0, 0.7);</span>
|
||||
<span class="line"> material.baseColor = materialParams.albedo;</span>
|
||||
<span class="line"> }</span>
|
||||
<span class="line">}</span></code></pre>
|
||||
<a class="target" name="lighting:reflections"> </a><a class="target" name="materialdefinitions/materialblock/lighting:reflections"> </a><a class="target" name="toc4.2.25"> </a><h3>Lighting: reflections</h3>
|
||||
|
||||
+8
-10
@@ -1582,24 +1582,22 @@ Value
|
||||
: `true` or `false`. Defaults to `false`.
|
||||
|
||||
Description
|
||||
: Only available in the `unlit` shading model. If this property is enabled, the final color
|
||||
computed by the material is multiplied by the shadowing factor (or visibility). This allows to
|
||||
create transparent shadow-receiving objects (for instance an invisible ground plane in AR).
|
||||
This is only supported with shadows from directional lights.
|
||||
: Enables two-sided rendering and its capability to be toggled at run time. When set to `true`,
|
||||
`culling` is automatically set to `none`; if the triangle is back-facing, the triangle's
|
||||
normal is flipped to become front-facing. When explicitly set to `false`, this allows the
|
||||
double-sidedness to be toggled at run time.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
name : "Invisible shadow plane",
|
||||
shadingModel : unlit,
|
||||
shadowMultiplier : true,
|
||||
blending : transparent
|
||||
name : "Double sided material",
|
||||
shadingModel : lit,
|
||||
doubleSided : true
|
||||
}
|
||||
|
||||
fragment {
|
||||
void material(inout MaterialInputs material) {
|
||||
prepareMaterial(material);
|
||||
// baseColor defines the color and opacity of the final shadow
|
||||
material.baseColor = vec4(0.0, 0.0, 0.0, 0.7);
|
||||
material.baseColor = materialParams.albedo;
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -48,6 +48,7 @@ set(PUBLIC_HDRS
|
||||
)
|
||||
|
||||
set(SRCS
|
||||
src/AtlasAllocator.cpp
|
||||
src/Box.cpp
|
||||
src/BufferObject.cpp
|
||||
src/Camera.cpp
|
||||
@@ -72,6 +73,7 @@ set(SRCS
|
||||
src/MaterialParser.cpp
|
||||
src/MorphTargetBuffer.cpp
|
||||
src/PerViewUniforms.cpp
|
||||
src/PerShadowMapUniforms.cpp
|
||||
src/PostProcessManager.cpp
|
||||
src/RenderPass.cpp
|
||||
src/RenderPrimitive.cpp
|
||||
@@ -145,6 +147,7 @@ set(PRIVATE_HDRS
|
||||
src/Intersections.h
|
||||
src/MaterialParser.h
|
||||
src/PerViewUniforms.h
|
||||
src/PerShadowMapUniforms.h
|
||||
src/PIDController.h
|
||||
src/PostProcessManager.h
|
||||
src/RendererUtils.h
|
||||
@@ -537,13 +540,6 @@ target_link_libraries(${TARGET} PUBLIC filaflat)
|
||||
target_link_libraries(${TARGET} PUBLIC filabridge)
|
||||
target_link_libraries(${TARGET} PUBLIC ibl-lite)
|
||||
|
||||
if (FILAMENT_ENABLE_FGDBG)
|
||||
target_link_libraries(${TARGET} PUBLIC fgdbg)
|
||||
add_definitions(-DFILAMENT_ENABLE_FGDBG=1)
|
||||
else()
|
||||
add_definitions(-DFILAMENT_ENABLE_FGDBG=0)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_ENABLE_MATDBG)
|
||||
target_link_libraries(${TARGET} PUBLIC matdbg)
|
||||
add_definitions(-DFILAMENT_ENABLE_MATDBG=1)
|
||||
|
||||
@@ -405,6 +405,7 @@ if (APPLE)
|
||||
backend
|
||||
getopt
|
||||
gtest
|
||||
filamat
|
||||
SPIRV
|
||||
spirv-cross-glsl)
|
||||
|
||||
|
||||
@@ -220,8 +220,7 @@ enum class PrimitiveType : uint8_t {
|
||||
LINES = 1, //!< lines
|
||||
LINE_STRIP = 3, //!< line strip
|
||||
TRIANGLES = 4, //!< triangles
|
||||
TRIANGLE_STRIP = 5, //!< triangle strip
|
||||
NONE = 0xFF
|
||||
TRIANGLE_STRIP = 5 //!< triangle strip
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,7 +42,9 @@
|
||||
#include "vulkan/PlatformVkCocoa.h"
|
||||
#endif
|
||||
#elif defined(__linux__)
|
||||
#if defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
#if defined(FILAMENT_SUPPORTS_GGP)
|
||||
#include "vulkan/PlatformVkLinuxGGP.h"
|
||||
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
|
||||
#include "vulkan/PlatformVkLinuxWayland.h"
|
||||
#endif
|
||||
@@ -120,7 +122,9 @@ DefaultPlatform* DefaultPlatform::create(Backend* backend) noexcept {
|
||||
#elif defined(IOS)
|
||||
return new PlatformVkCocoaTouch();
|
||||
#elif defined(__linux__)
|
||||
#if defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
#if defined(FILAMENT_SUPPORTS_GGP)
|
||||
return new PlatformVkLinuxGGP();
|
||||
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
return new PlatformVkLinuxWayland();
|
||||
#elif defined(FILAMENT_SUPPORTS_X11)
|
||||
return new PlatformVkLinuxX11();
|
||||
|
||||
@@ -91,12 +91,14 @@ blitterFrag(VertexOut in [[stage_in]],
|
||||
{
|
||||
FragmentOut out = {};
|
||||
|
||||
#if defined(BLIT_COLOR) || defined(BLIT_DEPTH)
|
||||
// These coordinates match the Vulkan vkCmdBlitImage spec:
|
||||
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdBlitImage.html
|
||||
float2 uvbase = in.position.xy; // unnormalized coordinates at center of texel: (1.5, 2.5, etc)
|
||||
float2 uvoffset = uvbase - args->dstOffset;
|
||||
float2 uvscaled = uvoffset * args->scale;
|
||||
float2 uv = uvscaled + args->srcOffset;
|
||||
#endif
|
||||
|
||||
#ifdef BLIT_COLOR
|
||||
#ifdef MSAA_COLOR_SOURCE
|
||||
|
||||
@@ -64,6 +64,7 @@ struct MetalContext {
|
||||
|
||||
// Supported features.
|
||||
bool supportsTextureSwizzling = false;
|
||||
bool supportsAutoDepthResolve = false;
|
||||
bool supportsMemorylessRenderTargets = false;
|
||||
uint8_t maxColorRenderTargets = 4;
|
||||
struct {
|
||||
@@ -95,6 +96,8 @@ struct MetalContext {
|
||||
SamplerStateCache samplerStateCache;
|
||||
ArgumentEncoderCache argumentEncoderCache;
|
||||
|
||||
PolygonOffset currentPolygonOffset = {0.0f, 0.0f};
|
||||
|
||||
MetalSamplerGroup* samplerBindings[Program::SAMPLER_BINDING_COUNT] = {};
|
||||
|
||||
// Keeps track of sampler groups we've finalized for the current render pass.
|
||||
|
||||
@@ -92,6 +92,13 @@ MetalDriver::MetalDriver(MetalPlatform* platform, const Platform::DriverConfig&
|
||||
mContext->highestSupportedGpuFamily.mac >= 2; // newer macOS GPUs
|
||||
}
|
||||
|
||||
// In order to support resolve store action on depth attachment, the GPU needs to support it.
|
||||
// Note that support for depth resolve implies support for stencil resolve using .sample0 resolve filter.
|
||||
// (Other resolve filters are supported starting .apple5 and .mac2 families).
|
||||
mContext->supportsAutoDepthResolve =
|
||||
mContext->highestSupportedGpuFamily.apple >= 3 ||
|
||||
mContext->highestSupportedGpuFamily.mac >= 2;
|
||||
|
||||
// In order to support memoryless render targets, an Apple GPU is needed.
|
||||
// Available starting macOS 11.0, the first version to run on Apple GPUs.
|
||||
// On iOS, it's available on all OS versions.
|
||||
@@ -696,7 +703,7 @@ bool MetalDriver::isFrameTimeSupported() {
|
||||
}
|
||||
|
||||
bool MetalDriver::isAutoDepthResolveSupported() {
|
||||
return true;
|
||||
return mContext->supportsAutoDepthResolve;
|
||||
}
|
||||
|
||||
bool MetalDriver::isWorkaroundNeeded(Workaround workaround) {
|
||||
@@ -893,7 +900,7 @@ void MetalDriver::updateSamplerGroup(Handle<HwSamplerGroup> sbh, BufferDescripto
|
||||
auto& encoderCache = mContext->argumentEncoderCache;
|
||||
id<MTLArgumentEncoder> encoder =
|
||||
encoderCache.getOrCreateState(ArgumentEncoderState(std::move(textureTypes)));
|
||||
sb->reset(getPendingCommandBuffer(mContext), encoder);
|
||||
sb->reset(getPendingCommandBuffer(mContext), encoder, mContext->device);
|
||||
|
||||
// In a perfect world, all the MTLTexture bindings would be known at updateSamplerGroup time.
|
||||
// However, there are two special cases preventing this:
|
||||
@@ -998,6 +1005,7 @@ void MetalDriver::beginRenderPass(Handle<HwRenderTarget> rth,
|
||||
mContext->depthStencilState.invalidate();
|
||||
mContext->cullModeState.invalidate();
|
||||
mContext->windingState.invalidate();
|
||||
mContext->currentPolygonOffset = {0.0f, 0.0f};
|
||||
|
||||
mContext->finalizedSamplerGroups.clear();
|
||||
}
|
||||
@@ -1176,8 +1184,12 @@ void MetalDriver::startCapture(int) {
|
||||
if (@available(iOS 13, *)) {
|
||||
MTLCaptureDescriptor* descriptor = [MTLCaptureDescriptor new];
|
||||
descriptor.captureObject = mContext->device;
|
||||
#if defined(IOS)
|
||||
descriptor.destination = MTLCaptureDestinationDeveloperTools;
|
||||
#else
|
||||
descriptor.destination = MTLCaptureDestinationGPUTraceDocument;
|
||||
descriptor.outputURL = [[NSURL alloc] initFileURLWithPath:@"filament.gputrace"];
|
||||
#endif
|
||||
NSError* error = nil;
|
||||
[[MTLCaptureManager sharedCaptureManager] startCaptureWithDescriptor:descriptor
|
||||
error:&error];
|
||||
@@ -1579,10 +1591,12 @@ void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t
|
||||
[mContext->currentRenderPassEncoder setDepthStencilState:state];
|
||||
}
|
||||
|
||||
if (ps.polygonOffset.constant != 0.0 || ps.polygonOffset.slope != 0.0) {
|
||||
if (ps.polygonOffset.constant != mContext->currentPolygonOffset.constant ||
|
||||
ps.polygonOffset.slope != mContext->currentPolygonOffset.slope) {
|
||||
[mContext->currentRenderPassEncoder setDepthBias:ps.polygonOffset.constant
|
||||
slopeScale:ps.polygonOffset.slope
|
||||
clamp:0.0];
|
||||
mContext->currentPolygonOffset = ps.polygonOffset;
|
||||
}
|
||||
|
||||
// Set scissor-rectangle.
|
||||
|
||||
@@ -337,8 +337,6 @@ constexpr inline MTLPrimitiveType getMetalPrimitiveType(PrimitiveType type) noex
|
||||
case PrimitiveType::LINE_STRIP: return MTLPrimitiveTypeLineStrip;
|
||||
case PrimitiveType::TRIANGLES: return MTLPrimitiveTypeTriangle;
|
||||
case PrimitiveType::TRIANGLE_STRIP: return MTLPrimitiveTypeTriangleStrip;
|
||||
case PrimitiveType::NONE:
|
||||
ASSERT_POSTCONDITION(false, "NONE is not a valid primitive type.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@ public:
|
||||
// the texture types have changed.
|
||||
// Mutate re-encodes the current set of samplers/textures into the new argument
|
||||
// buffer.
|
||||
void reset(id<MTLCommandBuffer> cmdBuffer, id<MTLArgumentEncoder> e);
|
||||
void reset(id<MTLCommandBuffer> cmdBuffer, id<MTLArgumentEncoder> e, id<MTLDevice> device);
|
||||
void mutate(id<MTLCommandBuffer> cmdBuffer);
|
||||
|
||||
id<MTLBuffer> getArgumentBuffer() const {
|
||||
|
||||
@@ -828,7 +828,8 @@ void MetalSamplerGroup::finalize() {
|
||||
finalized = true;
|
||||
}
|
||||
|
||||
void MetalSamplerGroup::reset(id<MTLCommandBuffer> cmdBuffer, id<MTLArgumentEncoder> e) {
|
||||
void MetalSamplerGroup::reset(id<MTLCommandBuffer> cmdBuffer, id<MTLArgumentEncoder> e,
|
||||
id<MTLDevice> device) {
|
||||
encoder = e;
|
||||
|
||||
// The number of slots in the ring buffer we use to manage argument buffer allocations.
|
||||
@@ -846,7 +847,7 @@ void MetalSamplerGroup::reset(id<MTLCommandBuffer> cmdBuffer, id<MTLArgumentEnco
|
||||
// Chances are, even though the MTLArgumentEncoder might change, the required size and alignment
|
||||
// probably won't. So we can re-use the previous ring buffer.
|
||||
if (UTILS_UNLIKELY(!argBuffer || !argBuffer->canAccomodateLayout(argBufferLayout))) {
|
||||
argBuffer = std::make_unique<MetalRingBuffer>(encoder.device, MTLResourceStorageModeShared,
|
||||
argBuffer = std::make_unique<MetalRingBuffer>(device, MTLResourceStorageModeShared,
|
||||
argBufferLayout, METAL_ARGUMENT_BUFFER_SLOTS);
|
||||
} else {
|
||||
argBuffer->createNewAllocation(cmdBuffer);
|
||||
@@ -1053,6 +1054,7 @@ void MetalRenderTarget::setUpRenderPassAttachments(MTLRenderPassDescriptor* desc
|
||||
descriptor.depthAttachment.slice = 0;
|
||||
const bool discard = any(discardFlags & TargetBufferFlags::DEPTH);
|
||||
if (!discard) {
|
||||
assert_invariant(context->supportsAutoDepthResolve);
|
||||
descriptor.depthAttachment.resolveTexture = depthAttachment.getTexture();
|
||||
descriptor.depthAttachment.resolveLevel = depthAttachment.level;
|
||||
descriptor.depthAttachment.resolveSlice = depthAttachment.layer;
|
||||
@@ -1085,10 +1087,14 @@ void MetalRenderTarget::setUpRenderPassAttachments(MTLRenderPassDescriptor* desc
|
||||
descriptor.stencilAttachment.slice = 0;
|
||||
const bool discard = any(discardFlags & TargetBufferFlags::STENCIL);
|
||||
if (!discard) {
|
||||
assert_invariant(context->supportsAutoDepthResolve);
|
||||
descriptor.stencilAttachment.resolveTexture = stencilAttachment.getTexture();
|
||||
descriptor.stencilAttachment.resolveLevel = stencilAttachment.level;
|
||||
descriptor.stencilAttachment.resolveSlice = stencilAttachment.layer;
|
||||
descriptor.stencilAttachment.storeAction = MTLStoreActionMultisampleResolve;
|
||||
if (@available(iOS 12.0, *)) {
|
||||
descriptor.stencilAttachment.stencilResolveFilter = MTLMultisampleStencilResolveFilterSample0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ io::ostream& operator<<(io::ostream& out, PrimitiveType type) {
|
||||
CASE(PrimitiveType, LINES)
|
||||
CASE(PrimitiveType, LINE_STRIP)
|
||||
CASE(PrimitiveType, POINTS)
|
||||
CASE(PrimitiveType, NONE)
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "vulkan/PlatformVkLinuxGGP.h"
|
||||
|
||||
#include <bluevk/BlueVK.h>
|
||||
#if defined(FILAMENT_SUPPORTS_GGP)
|
||||
#include <ggp_c/ggp.h>
|
||||
#endif
|
||||
#include <utils/Panic.h>
|
||||
|
||||
#include "VulkanDriverFactory.h"
|
||||
|
||||
using namespace bluevk;
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
Driver* PlatformVkLinuxGGP::createDriver(
|
||||
void* const sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept {
|
||||
#if defined(FILAMENT_SUPPORTS_GGP)
|
||||
ASSERT_PRECONDITION(sharedContext == nullptr,
|
||||
"Vulkan does not support shared contexts.");
|
||||
const char* requiredInstanceExtensions[] = {
|
||||
VK_GGP_STREAM_DESCRIPTOR_SURFACE_EXTENSION_NAME};
|
||||
return VulkanDriverFactory::create(this, requiredInstanceExtensions,
|
||||
sizeof(requiredInstanceExtensions) /
|
||||
sizeof(requiredInstanceExtensions[0]),
|
||||
driverConfig);
|
||||
#else
|
||||
PANIC_PRECONDITION("Filament does not support GGP.");
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void* PlatformVkLinuxGGP::createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept {
|
||||
#if defined(FILAMENT_SUPPORTS_GGP)
|
||||
VkStreamDescriptorSurfaceCreateInfoGGP surface_create_info = {
|
||||
VK_STRUCTURE_TYPE_STREAM_DESCRIPTOR_SURFACE_CREATE_INFO_GGP};
|
||||
surface_create_info.streamDescriptor = kGgpPrimaryStreamDescriptor;
|
||||
PFN_vkCreateStreamDescriptorSurfaceGGP fpCreateStreamDescriptorSurfaceGGP =
|
||||
reinterpret_cast<PFN_vkCreateStreamDescriptorSurfaceGGP>(
|
||||
vkGetInstanceProcAddr(static_cast<VkInstance>(instance),
|
||||
"vkCreateStreamDescriptorSurfaceGGP"));
|
||||
ASSERT_PRECONDITION(fpCreateStreamDescriptorSurfaceGGP != nullptr,
|
||||
"Error getting VkInstance "
|
||||
"function vkCreateStreamDescriptorSurfaceGGP");
|
||||
VkSurfaceKHR surface = nullptr;
|
||||
VkResult res = fpCreateStreamDescriptorSurfaceGGP(
|
||||
static_cast<VkInstance>(instance), &surface_create_info, nullptr,
|
||||
&surface);
|
||||
ASSERT_PRECONDITION(res == VK_SUCCESS, "Error in vulkan: %d", res);
|
||||
return surface;
|
||||
#else
|
||||
PANIC_PRECONDITION("Filament does not support GGP.");
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace filament::backend
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_BACKEND_VULKAN_PLATFORM_VK_LINUX_GGP_H
|
||||
#define TNT_FILAMENT_BACKEND_VULKAN_PLATFORM_VK_LINUX_GGP_H
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "VulkanPlatform.h"
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
class PlatformVkLinuxGGP final : public VulkanPlatform {
|
||||
public:
|
||||
Driver* createDriver(
|
||||
void* const sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept override;
|
||||
|
||||
void* createVkSurfaceKHR(void* nativeWindow, void* instance,
|
||||
uint64_t flags) noexcept override;
|
||||
|
||||
int getOSVersion() const noexcept override { return 0; }
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_VULKAN_PLATFORM_VK_LINUX_GGP_H
|
||||
@@ -263,7 +263,6 @@ VulkanBufferObject::VulkanBufferObject(VulkanContext& context, VulkanStagePool&
|
||||
void VulkanRenderPrimitive::setPrimitiveType(PrimitiveType pt) {
|
||||
this->type = pt;
|
||||
switch (pt) {
|
||||
case PrimitiveType::NONE:
|
||||
case PrimitiveType::POINTS:
|
||||
primitiveTopology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
break;
|
||||
|
||||
@@ -22,8 +22,12 @@
|
||||
#include <spirv_glsl.hpp>
|
||||
#include <spirv_msl.hpp>
|
||||
|
||||
#include "../src/GLSLPostProcessor.h"
|
||||
|
||||
#include "builtinResource.h"
|
||||
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -59,38 +63,6 @@ void SpvToGlsl(const SpirvBlob* spirv, std::string* outGlsl) {
|
||||
*outGlsl = glslCompiler.compile();
|
||||
}
|
||||
|
||||
void SpvToMsl(const SpirvBlob* spirv, std::string* outMsl) {
|
||||
CompilerMSL mslCompiler(*spirv);
|
||||
mslCompiler.set_msl_options(CompilerMSL::Options {
|
||||
.msl_version = CompilerMSL::Options::make_msl_version(1, 1)
|
||||
});
|
||||
|
||||
auto executionModel = mslCompiler.get_execution_model();
|
||||
|
||||
auto duplicateResourceBinding = [executionModel, &mslCompiler](const auto& resource) {
|
||||
auto set = mslCompiler.get_decoration(resource.id, spv::DecorationDescriptorSet);
|
||||
auto binding = mslCompiler.get_decoration(resource.id, spv::DecorationBinding);
|
||||
MSLResourceBinding newBinding;
|
||||
newBinding.stage = executionModel;
|
||||
newBinding.desc_set = set;
|
||||
newBinding.binding = binding;
|
||||
newBinding.msl_texture = binding;
|
||||
newBinding.msl_sampler = binding;
|
||||
newBinding.msl_buffer = binding;
|
||||
mslCompiler.add_msl_resource_binding(newBinding);
|
||||
};
|
||||
|
||||
auto resources = mslCompiler.get_shader_resources();
|
||||
for (const auto& resource : resources.sampled_images) {
|
||||
duplicateResourceBinding(resource);
|
||||
}
|
||||
for (const auto& resource : resources.uniform_buffers) {
|
||||
duplicateResourceBinding(resource);
|
||||
}
|
||||
|
||||
*outMsl = mslCompiler.compile();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void ShaderGenerator::init() {
|
||||
@@ -102,15 +74,16 @@ void ShaderGenerator::shutdown() {
|
||||
}
|
||||
|
||||
ShaderGenerator::ShaderGenerator(std::string vertex, std::string fragment,
|
||||
Backend backend, bool isMobile) noexcept
|
||||
Backend backend, bool isMobile, const filament::SamplerInterfaceBlock* sib) noexcept
|
||||
: mBackend(backend),
|
||||
mVertexBlob(transpileShader(ShaderStage::VERTEX, std::move(vertex), backend, isMobile)),
|
||||
mVertexBlob(transpileShader(ShaderStage::VERTEX, std::move(vertex), backend, isMobile, sib)),
|
||||
mFragmentBlob(transpileShader(ShaderStage::FRAGMENT, std::move(fragment), backend,
|
||||
isMobile)) {
|
||||
isMobile, sib)) {
|
||||
}
|
||||
|
||||
ShaderGenerator::Blob ShaderGenerator::transpileShader(
|
||||
ShaderStage stage, std::string shader, Backend backend, bool isMobile) noexcept {
|
||||
ShaderStage stage, std::string shader, Backend backend, bool isMobile,
|
||||
const filament::SamplerInterfaceBlock* sib) noexcept {
|
||||
TProgram program;
|
||||
const EShLanguage language = stage == ShaderStage::VERTEX ? EShLangVertex : EShLangFragment;
|
||||
TShader tShader(language);
|
||||
@@ -173,7 +146,10 @@ ShaderGenerator::Blob ShaderGenerator::transpileShader(
|
||||
}
|
||||
return { result.c_str(), result.c_str() + result.length() + 1 };
|
||||
} else if (backend == Backend::METAL) {
|
||||
SpvToMsl(&spirv, &result);
|
||||
const auto sm = isMobile ? ShaderModel::MOBILE : ShaderModel::DESKTOP;
|
||||
filamat::SibVector sibs = filamat::SibVector::with_capacity(1);
|
||||
if (sib) { sibs.emplace_back(0, sib); }
|
||||
filamat::GLSLPostProcessor::spirvToMsl(&spirv, &result, sm, false, sibs, nullptr);
|
||||
return { result.c_str(), result.c_str() + result.length() + 1 };
|
||||
} else if (backend == Backend::VULKAN) {
|
||||
return { (uint8_t*)spirv.data(), (uint8_t*)(spirv.data() + spirv.size()) };
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "PlatformRunner.h"
|
||||
|
||||
#include "private/filament/SamplerInterfaceBlock.h"
|
||||
#include "private/backend/DriverApi.h"
|
||||
#include "backend/Program.h"
|
||||
|
||||
@@ -38,7 +39,8 @@ public:
|
||||
* @param vertex The vertex shader, written in GLSL 450 core.
|
||||
* @param fragment The fragment shader, written in GLSL 450 core.
|
||||
*/
|
||||
ShaderGenerator(std::string vertex, std::string fragment, Backend backend, bool isMobile) noexcept;
|
||||
ShaderGenerator(std::string vertex, std::string fragment, Backend backend, bool isMobile,
|
||||
const filament::SamplerInterfaceBlock* sib = nullptr) noexcept;
|
||||
|
||||
ShaderGenerator(const ShaderGenerator& rhs) = delete;
|
||||
ShaderGenerator& operator=(const ShaderGenerator& rhs) = delete;
|
||||
@@ -50,7 +52,7 @@ private:
|
||||
|
||||
using Blob = std::vector<char>;
|
||||
static Blob transpileShader(ShaderStage stage, std::string shader, Backend backend,
|
||||
bool isMobile) noexcept;
|
||||
bool isMobile, const filament::SamplerInterfaceBlock* sib = nullptr) noexcept;
|
||||
|
||||
Backend mBackend;
|
||||
|
||||
|
||||
@@ -133,7 +133,12 @@ TEST_F(BackendTest, FeedbackLoops) {
|
||||
// Create a program.
|
||||
ProgramHandle program;
|
||||
{
|
||||
ShaderGenerator shaderGen(fullscreenVs, fullscreenFs, sBackend, sIsMobilePlatform);
|
||||
SamplerInterfaceBlock sib = filament::SamplerInterfaceBlock::Builder()
|
||||
.name("backend_test_sib")
|
||||
.stageFlags(backend::ShaderStageFlags::ALL_SHADER_STAGE_FLAGS)
|
||||
.add( {{"tex", SamplerType::SAMPLER_2D, SamplerFormat::FLOAT, Precision::HIGH }} )
|
||||
.build();
|
||||
ShaderGenerator shaderGen(fullscreenVs, fullscreenFs, sBackend, sIsMobilePlatform, &sib);
|
||||
Program prog = shaderGen.getProgram(api);
|
||||
Program::Sampler psamplers[] = { utils::CString("tex"), 0 };
|
||||
prog.setSamplerGroup(0, ShaderStageFlags::ALL_SHADER_STAGE_FLAGS, psamplers, sizeof(psamplers) / sizeof(psamplers[0]));
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "ShaderGenerator.h"
|
||||
#include "TrianglePrimitive.h"
|
||||
|
||||
#include "private/filament/SamplerInterfaceBlock.h"
|
||||
#include "private/backend/SamplerGroup.h"
|
||||
|
||||
#include <math/half.h>
|
||||
@@ -54,7 +55,7 @@ layout(location = 0) out vec4 fragColor;
|
||||
|
||||
// Filament's Vulkan backend requires a descriptor set index of 1 for all samplers.
|
||||
// This parameter is ignored for other backends.
|
||||
layout(location = 0, set = 1) uniform {samplerType} tex;
|
||||
layout(location = 0, set = 1) uniform {samplerType} test_tex;
|
||||
|
||||
void main() {
|
||||
vec2 fbsize = vec2(512);
|
||||
@@ -62,7 +63,7 @@ void main() {
|
||||
#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT)
|
||||
uv.y = 1.0 - uv.y;
|
||||
#endif
|
||||
fragColor = vec4(texture(tex, uv).rgb, 1.0f);
|
||||
fragColor = vec4(texture(test_tex, uv).rgb, 1.0f);
|
||||
}
|
||||
|
||||
)");
|
||||
@@ -72,8 +73,7 @@ std::string fragmentUpdateImage3DTemplate (R"(#version 450 core
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
// Filament's Vulkan backend requires a descriptor set index of 1 for all samplers.
|
||||
// This parameter is ignored for other backends.
|
||||
layout(location = 0, set = 1) uniform {samplerType} tex;
|
||||
layout(location = 0, set = 1) uniform {samplerType} test_tex;
|
||||
|
||||
float getLayer(in sampler3D s) { return 2.5f / 4.0f; }
|
||||
float getLayer(in sampler2DArray s) { return 2.0f; }
|
||||
@@ -84,7 +84,7 @@ void main() {
|
||||
#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT)
|
||||
uv.y = 1.0 - uv.y;
|
||||
#endif
|
||||
fragColor = vec4(texture(tex, vec3(uv, getLayer(tex))).rgb, 1.0f);
|
||||
fragColor = vec4(texture(test_tex, vec3(uv, getLayer(test_tex))).rgb, 1.0f);
|
||||
}
|
||||
|
||||
)");
|
||||
@@ -94,8 +94,7 @@ std::string fragmentUpdateImageMip (R"(#version 450 core
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
// Filament's Vulkan backend requires a descriptor set index of 1 for all samplers.
|
||||
// This parameter is ignored for other backends.
|
||||
layout(location = 0, set = 1) uniform sampler2D tex;
|
||||
layout(location = 0, set = 1) uniform sampler2D test_tex;
|
||||
|
||||
void main() {
|
||||
vec2 fbsize = vec2(512);
|
||||
@@ -103,7 +102,7 @@ void main() {
|
||||
#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT)
|
||||
uv.y = 1.0 - uv.y;
|
||||
#endif
|
||||
fragColor = vec4(textureLod(tex, uv, 1.0f).rgb, 1.0f);
|
||||
fragColor = vec4(textureLod(test_tex, uv, 1.0f).rgb, 1.0f);
|
||||
}
|
||||
|
||||
)");
|
||||
@@ -345,10 +344,15 @@ TEST_F(BackendTest, UpdateImage2D) {
|
||||
auto defaultRenderTarget = api.createDefaultRenderTarget(0);
|
||||
|
||||
// Create a program.
|
||||
SamplerInterfaceBlock sib = filament::SamplerInterfaceBlock::Builder()
|
||||
.name("Test")
|
||||
.stageFlags(backend::ShaderStageFlags::ALL_SHADER_STAGE_FLAGS)
|
||||
.add( {{"tex", SamplerType::SAMPLER_2D, SamplerFormat::FLOAT, Precision::HIGH }} )
|
||||
.build();
|
||||
ProgramHandle program;
|
||||
std::string fragment = stringReplace("{samplerType}",
|
||||
getSamplerTypeName(t.textureFormat), fragmentTemplate);
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform);
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform, &sib);
|
||||
Program prog = shaderGen.getProgram(api);
|
||||
Program::Sampler psamplers[] = { utils::CString("tex"), 0 };
|
||||
prog.setSamplerGroup(0, ShaderStageFlags::ALL_SHADER_STAGE_FLAGS, psamplers, sizeof(psamplers) / sizeof(psamplers[0]));
|
||||
@@ -425,9 +429,14 @@ TEST_F(BackendTest, UpdateImageSRGB) {
|
||||
auto defaultRenderTarget = api.createDefaultRenderTarget(0);
|
||||
|
||||
// Create a program.
|
||||
SamplerInterfaceBlock sib = filament::SamplerInterfaceBlock::Builder()
|
||||
.name("Test")
|
||||
.stageFlags(backend::ShaderStageFlags::ALL_SHADER_STAGE_FLAGS)
|
||||
.add( {{"tex", SamplerType::SAMPLER_2D, SamplerFormat::FLOAT, Precision::HIGH }} )
|
||||
.build();
|
||||
std::string fragment = stringReplace("{samplerType}",
|
||||
getSamplerTypeName(textureFormat), fragmentTemplate);
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform);
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform, &sib);
|
||||
Program prog = shaderGen.getProgram(api);
|
||||
Program::Sampler psamplers[] = { utils::CString("tex"), 0 };
|
||||
prog.setSamplerGroup(0, ShaderStageFlags::ALL_SHADER_STAGE_FLAGS, psamplers, sizeof(psamplers) / sizeof(psamplers[0]));
|
||||
@@ -511,9 +520,14 @@ TEST_F(BackendTest, UpdateImageMipLevel) {
|
||||
auto defaultRenderTarget = api.createDefaultRenderTarget(0);
|
||||
|
||||
// Create a program.
|
||||
SamplerInterfaceBlock sib = filament::SamplerInterfaceBlock::Builder()
|
||||
.name("Test")
|
||||
.stageFlags(backend::ShaderStageFlags::ALL_SHADER_STAGE_FLAGS)
|
||||
.add( {{"tex", SamplerType::SAMPLER_3D, SamplerFormat::FLOAT, Precision::HIGH }} )
|
||||
.build();
|
||||
std::string fragment = stringReplace("{samplerType}",
|
||||
getSamplerTypeName(textureFormat), fragmentUpdateImageMip);
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform);
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform, &sib);
|
||||
Program prog = shaderGen.getProgram(api);
|
||||
Program::Sampler psamplers[] = { utils::CString("tex"), 0 };
|
||||
prog.setSamplerGroup(0, ShaderStageFlags::ALL_SHADER_STAGE_FLAGS, psamplers, sizeof(psamplers) / sizeof(psamplers[0]));
|
||||
@@ -583,9 +597,14 @@ TEST_F(BackendTest, UpdateImage3D) {
|
||||
auto defaultRenderTarget = api.createDefaultRenderTarget(0);
|
||||
|
||||
// Create a program.
|
||||
SamplerInterfaceBlock sib = filament::SamplerInterfaceBlock::Builder()
|
||||
.name("Test")
|
||||
.stageFlags(backend::ShaderStageFlags::ALL_SHADER_STAGE_FLAGS)
|
||||
.add( {{"tex", SamplerType::SAMPLER_3D, SamplerFormat::FLOAT, Precision::HIGH }} )
|
||||
.build();
|
||||
std::string fragment = stringReplace("{samplerType}",
|
||||
getSamplerTypeName(samplerType), fragmentUpdateImage3DTemplate);
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform);
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform, &sib);
|
||||
Program prog = shaderGen.getProgram(api);
|
||||
Program::Sampler psamplers[] = { utils::CString("tex"), 0 };
|
||||
prog.setSamplerGroup(0, ShaderStageFlags::ALL_SHADER_STAGE_FLAGS, psamplers, sizeof(psamplers) / sizeof(psamplers[0]));
|
||||
|
||||
@@ -45,7 +45,7 @@ std::string fragment (R"(#version 450 core
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
layout(location = 0) in vec2 uv;
|
||||
|
||||
layout(set = 1, binding = 6) uniform sampler2D tex;
|
||||
layout(location = 0, set = 1) uniform sampler2D tex;
|
||||
|
||||
void main() {
|
||||
fragColor = texture(tex, uv);
|
||||
@@ -65,11 +65,16 @@ TEST_F(BackendTest, RenderExternalImageWithoutSet) {
|
||||
|
||||
auto swapChain = createSwapChain();
|
||||
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform);
|
||||
SamplerInterfaceBlock sib = filament::SamplerInterfaceBlock::Builder()
|
||||
.name("backend_test_sib")
|
||||
.stageFlags(backend::ShaderStageFlags::ALL_SHADER_STAGE_FLAGS)
|
||||
.add( {{"tex", SamplerType::SAMPLER_EXTERNAL, SamplerFormat::FLOAT, Precision::HIGH }} )
|
||||
.build();
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform, &sib);
|
||||
|
||||
// Create a program that samples a texture.
|
||||
Program p = shaderGen.getProgram(getDriverApi());
|
||||
Program::Sampler sampler { utils::CString("tex"), 6 };
|
||||
Program::Sampler sampler { utils::CString("tex"), 0 };
|
||||
p.setSamplerGroup(0, ShaderStageFlags::ALL_SHADER_STAGE_FLAGS, &sampler, 1);
|
||||
backend::Handle<HwProgram> program = getDriverApi().createProgram(std::move(p));
|
||||
|
||||
@@ -139,11 +144,16 @@ TEST_F(BackendTest, RenderExternalImage) {
|
||||
|
||||
auto swapChain = createSwapChain();
|
||||
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform);
|
||||
SamplerInterfaceBlock sib = filament::SamplerInterfaceBlock::Builder()
|
||||
.name("backend_test_sib")
|
||||
.stageFlags(backend::ShaderStageFlags::ALL_SHADER_STAGE_FLAGS)
|
||||
.add( {{"tex", SamplerType::SAMPLER_EXTERNAL, SamplerFormat::FLOAT, Precision::HIGH }} )
|
||||
.build();
|
||||
ShaderGenerator shaderGen(vertex, fragment, sBackend, sIsMobilePlatform, &sib);
|
||||
|
||||
// Create a program that samples a texture.
|
||||
Program p = shaderGen.getProgram(getDriverApi());
|
||||
Program::Sampler sampler { utils::CString("tex"), 6 };
|
||||
Program::Sampler sampler { utils::CString("tex"), 0 };
|
||||
p.setSamplerGroup(0, ShaderStageFlags::ALL_SHADER_STAGE_FLAGS, &sampler, 1);
|
||||
auto program = getDriverApi().createProgram(std::move(p));
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</style>
|
||||
|
||||
**Vulkan Backend**
|
||||
*Last updated: 11 June 2021*
|
||||
*Last updated: 26 October 2022*
|
||||
|
||||

|
||||
|
||||
@@ -47,7 +47,7 @@ single `VkDevice` and `VkInstance`.
|
||||
* | | | | *
|
||||
* |------------------------------------------| |-----------------------------------------| *
|
||||
* | | | | *
|
||||
* | Helpers VulkanContext | | SwapContext SwapContext | *
|
||||
* | Helpers VulkanContext | | VulkanTexture VulkanTexture | *
|
||||
* | .--------------. .---------------. | | .----------------+----------------. | *
|
||||
* | | PipelineCache| | VkDevice | | | | VkImage | VkImage | | *
|
||||
* | +--------------+ | VkInstance | | | | VkImageView | VkImageView | | *
|
||||
@@ -91,13 +91,14 @@ that are defined in `DriverBase.h`.
|
||||
|
||||
Most of the handle types do not contain much logic, but they often do more than mere wrapping of
|
||||
Vk objects. Notably, `VulkanRenderTarget` does not have a straightforward mapping to any one Vk
|
||||
object. See its class comment for details.
|
||||
object. See its class comment for details. Also, `VulkanTexture` and `VulkanSwapChain` have their
|
||||
own cpps file because of complexity around layouts and subresources.
|
||||
|
||||
VulkanProgram
|
||||
: Descends from `HwProgram`, owns a pair of `VkShaderModule`.
|
||||
|
||||
VulkanRenderTarget
|
||||
: Descends from `HwRenderTarget`, contains references to `VkImage` objects.
|
||||
: Descends from `HwRenderTarget`, contains references to `VulkanTexture` objects.
|
||||
|
||||
VulkanSwapChain
|
||||
: Descends from `HwSwapChain`, has a reference to `VkSurfaceKHR` and `VkSwapchainKHR`.
|
||||
@@ -127,14 +128,16 @@ they do follow a common set of conventions. For example, most of them implement
|
||||
that is called once per frame to free unused objects.
|
||||
|
||||
VulkanPipelineCache
|
||||
: Cache of VkDescriptorSet and VkPipeline.
|
||||
: Cache of VkDescriptorSet, VkPipeline, and VkPipelineLayout.
|
||||
|
||||
VulkanDisposer
|
||||
: Holds reference counts to Vulkan objects in order to defer their destruction.
|
||||
|
||||
VulkanFboCache
|
||||
: Cache of VkRenderPass and VkFramebuffer. Contains weak references to VkImage handles, but does not
|
||||
own any pixel data.
|
||||
own any pixel data. The cache key for render passes is quite complex because it needs to include
|
||||
image layout information in a compact way. For details see the comments in the `RenderPassKey`
|
||||
declaration.
|
||||
|
||||
VulkanStagePool
|
||||
: Pool of VkBuffer objects that can be memory mapped (shared between host and device).
|
||||
@@ -149,6 +152,71 @@ no subfolders. All backend-specific types and functions live directly in the `fi
|
||||
namespace, and we simply prefix our names with "Vulkan" when necessary to avoid ambiguation with
|
||||
OpenGL.
|
||||
|
||||
# Image Layout Strategy
|
||||
|
||||
Adhering to a coherent strategy for image layout transitions is crucial. Without this, validation
|
||||
errors (and actual black screens with some GPU vendors) occur far too easily and can feel like
|
||||
whack-a-mole.
|
||||
|
||||
Vulkan provides several mechanisms for transitioning layout (render passes, barriers) so the
|
||||
strategy outlined below specifies which mechanism should be used in various scenarios.
|
||||
|
||||
The current image layouts are tracked at the subresource level in `VulkanTexture` using a
|
||||
specialized STL-ish container that we designed for this purpose:
|
||||
[RangeMap](https://github.com/google/filament/blob/main/libs/utils/include/utils/RangeMap.h).
|
||||
|
||||
In the past we tried to avoid tracking since it theoritically duplicates state that exists in the
|
||||
GPU vendor's driver. However in practice this was impossible to manage, because complex logic was
|
||||
required to deduce the current layout. Also, tracking lets us use `assert_invariant` in many places
|
||||
to ensure that the behavior described in this document is implemented properly. It is much easier
|
||||
to catch errors with asserts than with validation.
|
||||
|
||||
As of this writing, the current rules are:
|
||||
|
||||
(1) **Read-Only Color Textures**
|
||||
|
||||
These should be created in an UNDEFINED state and stay that way until data gets uploaded into them,
|
||||
at which point the appropriate subresources are transitioned to TRANSFER_DST_OPTIMAL for the upload,
|
||||
then to SHADER_READ_ONLY_OPTIMAL, both times using a barrier. Note that a subresource might be
|
||||
updated several times; each time it undergoes these two transitions.
|
||||
|
||||
If a shader samples from a texture whose mipmaps are only partially loaded, we might see validation
|
||||
warnings about how some subresources are in an UNDEFINED layout. However if we are properly using
|
||||
the `setMinMaxLevels` driver API, then the Vulkan backend will not bind those particular
|
||||
subresources, so validation should not complain.
|
||||
|
||||
(2) **Writeable Color Textures**
|
||||
|
||||
During construction of the HwTexture, these are transitioned to GENERAL using a barrier.
|
||||
|
||||
GENERAL layout is not recommended by AMD best practices but in our case we wish to avoid thrashing
|
||||
the layout between COLOR_ATTACHMENT_OPTIMAL and SHADER_READ_ONLY_OPTIMAL for post-processing
|
||||
effects. Moreover we do not have a priori knowledge about blitting and read pixels usage.
|
||||
|
||||
(3) **Depth Textures**
|
||||
|
||||
During construction of the HwTexture, these are transitioned to GENERAL using a barrier.
|
||||
|
||||
Note that some post-processing passes (e.g. SSAO) sample from the depth buffer while also enabling
|
||||
depth testing. Using GENERAL makes this legal.
|
||||
|
||||
(4) **Swap Chain Textures**
|
||||
|
||||
During construction, these are transitioned to GENERAL using a barrier. They are then transitioned
|
||||
to PRESENT at the end of the frame using a barrier, and transitioned back to GENERAL using the first
|
||||
render pass of the frame.
|
||||
|
||||
Note that we transition to PRESENT using a barrier, but with some GPU vendors it might be preferable
|
||||
to transition them using the last render pass. However we have no way of knowing ahead of time which
|
||||
pass is last.
|
||||
|
||||
Note that Filament allows swap chains to be used as blit targets and blit sources (e.g. for
|
||||
ReadPixels). Using GENERAL makes this easier to manage.
|
||||
|
||||
(5) **Headless Swap Chain Textures**
|
||||
|
||||
These follow the same rules as writeable color texture and depth textures.
|
||||
|
||||
# VulkanPipelineCache
|
||||
|
||||
Uniforms, samplers, and shaders are not directly bindable in Vulkan; instead they are bound through
|
||||
@@ -161,8 +229,6 @@ public methods. See its header file for details.
|
||||
|
||||
The pipeline cache also manages the *layout objects*, which constrain the number of uniform buffers
|
||||
and samplers that can be bound simultaneously (see `VkDescriptorSetLayout` and `VkPipelineLayout`).
|
||||
Here we take advantage of Filament's opinionated shading model in order to keep things simple, which
|
||||
allows us to create only one layout for the entire lifetime of the app.
|
||||
|
||||
# Memory Allocation
|
||||
|
||||
@@ -196,7 +262,8 @@ Here we list some of the most significant issues and to-be-done items for the Vu
|
||||
|
||||
- Improve the UBO strategy
|
||||
- Currently we use staging buffers and perform lots of copies (host-to-host, then host-to-device)
|
||||
- Consider an approach similar to MetalDriver, which effectively implements double-buffering using a pool of shared mem buffers
|
||||
- Consider an approach similar to MetalDriver, which effectively implements double-buffering
|
||||
using a pool of shared mem buffers
|
||||
- Consider using subpasses for the depth prepass
|
||||
- We lazily create pipeline objects
|
||||
1. This is notoriously slow in Vulkan
|
||||
|
||||
@@ -277,6 +277,12 @@ public:
|
||||
*/
|
||||
void setMaskThreshold(float threshold) noexcept;
|
||||
|
||||
/**
|
||||
* Gets the minimum alpha value a fragment must have to not be discarded when the blend
|
||||
* mode is MASKED
|
||||
*/
|
||||
float getMaskThreshold() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the screen space variance of the filter kernel used when applying specular
|
||||
* anti-aliasing. The default value is set to 0.15. The specified value should be between
|
||||
@@ -284,6 +290,12 @@ public:
|
||||
*/
|
||||
void setSpecularAntiAliasingVariance(float variance) noexcept;
|
||||
|
||||
/**
|
||||
* Gets the screen space variance of the filter kernel used when applying specular
|
||||
* anti-aliasing.
|
||||
*/
|
||||
float getSpecularAntiAliasingVariance() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the clamping threshold used to suppress estimation errors when applying specular
|
||||
* anti-aliasing. The default value is set to 0.2. The specified value should be between 0
|
||||
@@ -291,6 +303,12 @@ public:
|
||||
*/
|
||||
void setSpecularAntiAliasingThreshold(float threshold) noexcept;
|
||||
|
||||
/**
|
||||
* Gets the clamping threshold used to suppress estimation errors when applying specular
|
||||
* anti-aliasing.
|
||||
*/
|
||||
float getSpecularAntiAliasingThreshold() const noexcept;
|
||||
|
||||
/**
|
||||
* Enables or disables double-sided lighting if the parent Material has double-sided capability,
|
||||
* otherwise prints a warning. If double-sided lighting is enabled, backface culling is
|
||||
@@ -298,36 +316,72 @@ public:
|
||||
*/
|
||||
void setDoubleSided(bool doubleSided) noexcept;
|
||||
|
||||
/**
|
||||
* Returns whether double-sided lighting is enabled when the parent Material has double-sided
|
||||
* capability.
|
||||
*/
|
||||
bool isDoubleSided() const noexcept;
|
||||
|
||||
/**
|
||||
* Specifies how transparent objects should be rendered (default is DEFAULT).
|
||||
*/
|
||||
void setTransparencyMode(TransparencyMode mode) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the transparency mode.
|
||||
*/
|
||||
TransparencyMode getTransparencyMode() const noexcept;
|
||||
|
||||
/**
|
||||
* Overrides the default triangle culling state that was set on the material.
|
||||
*/
|
||||
void setCullingMode(CullingMode culling) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the face culling mode.
|
||||
*/
|
||||
CullingMode getCullingMode() const noexcept;
|
||||
|
||||
/**
|
||||
* Overrides the default color-buffer write state that was set on the material.
|
||||
*/
|
||||
void setColorWrite(bool enable) noexcept;
|
||||
|
||||
/**
|
||||
* Returns whether color write is enabled.
|
||||
*/
|
||||
bool isColorWriteEnabled() const noexcept;
|
||||
|
||||
/**
|
||||
* Overrides the default depth-buffer write state that was set on the material.
|
||||
*/
|
||||
void setDepthWrite(bool enable) noexcept;
|
||||
|
||||
/**
|
||||
* Returns whether depth write is enabled.
|
||||
*/
|
||||
bool isDepthWriteEnabled() const noexcept;
|
||||
|
||||
/**
|
||||
* Overrides the default depth testing state that was set on the material.
|
||||
*/
|
||||
void setDepthCulling(bool enable) noexcept;
|
||||
|
||||
/**
|
||||
* Returns whether depth culling is enabled.
|
||||
*/
|
||||
bool isDepthCullingEnabled() const noexcept;
|
||||
|
||||
/**
|
||||
* Overrides the default stencil-buffer write state that was set on the material.
|
||||
*/
|
||||
void setStencilWrite(bool enable) noexcept;
|
||||
|
||||
/**
|
||||
* Returns whether stencil write is enabled.
|
||||
*/
|
||||
bool isStencilWriteEnabled() const noexcept;
|
||||
|
||||
/**
|
||||
* Sets the stencil comparison function (default is StencilCompareFunc::A).
|
||||
*
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "AtlasAllocator.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
namespace filament {
|
||||
|
||||
using namespace utils;
|
||||
|
||||
static inline constexpr std::pair<uint8_t, uint8_t> unmorton(uint16_t m) noexcept {
|
||||
uint32_t r = (m | (uint32_t(m) << 15u)) & 0x55555555u;
|
||||
r = (r | (r >> 1u)) & 0x33333333u;
|
||||
r = (r | (r >> 2u)) & 0x0f0f0f0fu;
|
||||
r = r | (r >> 4u);
|
||||
return { uint8_t(r), uint8_t(r >> 16u) };
|
||||
}
|
||||
|
||||
AtlasAllocator::AtlasAllocator(size_t maxTextureSize) noexcept {
|
||||
// round to power-of-two immediately inferior or equal to the size specified.
|
||||
mMaxTextureSizePot = (sizeof(maxTextureSize) * 8 - 1u) - utils::clz(maxTextureSize);
|
||||
}
|
||||
|
||||
Viewport AtlasAllocator::allocate(size_t textureSize) noexcept {
|
||||
Viewport result{};
|
||||
const size_t powerOfTwo = (sizeof(textureSize) * 8 - 1u) - utils::clz(textureSize);
|
||||
|
||||
// asked for a texture size too large
|
||||
if (UTILS_UNLIKELY(powerOfTwo > mMaxTextureSizePot)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// asked for a texture size too small
|
||||
if (UTILS_UNLIKELY(mMaxTextureSizePot - powerOfTwo >= QuadTree::height())) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const size_t layer = mMaxTextureSizePot - powerOfTwo;
|
||||
const NodeId loc = allocateInLayer(layer);
|
||||
if (loc.l >= 0) {
|
||||
assert_invariant(loc.l == int8_t(layer));
|
||||
size_t dimension = 1u << powerOfTwo;
|
||||
// find the location of in the texture from the morton code (quadtree position)
|
||||
auto [x, y] = unmorton(loc.code);
|
||||
// scale to our maximum allocation size
|
||||
result.left = int32_t(x) << powerOfTwo;
|
||||
result.bottom = int32_t(y) << powerOfTwo;
|
||||
result.width = dimension;
|
||||
result.height = dimension;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void AtlasAllocator::clear(size_t maxTextureSize) noexcept {
|
||||
std::fill(mQuadTree.begin(), mQuadTree.end(), Node{});
|
||||
mMaxTextureSizePot = (sizeof(maxTextureSize) * 8 - 1u) - utils::clz(maxTextureSize);
|
||||
}
|
||||
|
||||
AtlasAllocator::NodeId AtlasAllocator::allocateInLayer(size_t maxHeight) noexcept {
|
||||
using namespace QuadTreeUtils;
|
||||
|
||||
NodeId candidate{ -1, 0 };
|
||||
if (UTILS_UNLIKELY(maxHeight > QuadTree::height())) {
|
||||
return candidate;
|
||||
}
|
||||
|
||||
const int8_t n = int8_t(maxHeight);
|
||||
|
||||
QuadTree::traverse(0, 0, n,
|
||||
[this, n, &candidate](NodeId const& curr) -> QuadTree::TraversalResult {
|
||||
|
||||
// we should never reach a level higher than n
|
||||
assert_invariant(curr.l <= n);
|
||||
|
||||
// get the node being processed
|
||||
const size_t i = index(curr.l, curr.code);
|
||||
Node const& node = mQuadTree[i];
|
||||
|
||||
// if the node is allocated, the whole tree below it is unavailable
|
||||
if (node.isAllocated()) {
|
||||
// if a node is allocated it can't have children
|
||||
assert_invariant(!node.hasChildren());
|
||||
return QuadTree::TraversalResult::SKIP_CHILDREN;
|
||||
}
|
||||
|
||||
// we're looking for the `deepest` unallocated node that has no children,
|
||||
// up to the depth we're trying to allocate
|
||||
if (curr.l > candidate.l && !node.hasChildren()) {
|
||||
candidate = curr;
|
||||
// Special case where we found a fitting node, just exit.
|
||||
if (curr.l == n) {
|
||||
return QuadTree::TraversalResult::EXIT;
|
||||
}
|
||||
}
|
||||
|
||||
// We only want to find a fitting node that already has siblings, in order
|
||||
// to accomplish a "best fit" allocation. So if we're a parent of a 'fitting'
|
||||
// node and don't have children, we skip the children recursion.
|
||||
if (curr.l == n - 1 && !node.hasChildren()) {
|
||||
return QuadTree::TraversalResult::SKIP_CHILDREN;
|
||||
}
|
||||
|
||||
// continue going down the tree
|
||||
return QuadTree::TraversalResult::RECURSE;
|
||||
});
|
||||
|
||||
if (candidate.l >= 0) {
|
||||
const size_t i = index(candidate.l, candidate.code);
|
||||
Node& allocation = mQuadTree[i];
|
||||
|
||||
if (candidate.l == n) {
|
||||
allocation.allocated = true;
|
||||
if (UTILS_LIKELY(n > 0)) {
|
||||
// the root doesn't have a parent
|
||||
const size_t p = parent(candidate.l, candidate.code);
|
||||
Node& parent = mQuadTree[p];
|
||||
assert_invariant(!parent.isAllocated());
|
||||
assert_invariant(parent.hasChildren());
|
||||
assert_invariant(!parent.hasAllChildren());
|
||||
parent.children++;
|
||||
}
|
||||
} else if (candidate.l < int8_t(QuadTree::height())) {
|
||||
// we need to create the hierarchy down to the level we need
|
||||
assert_invariant(!allocation.isAllocated());
|
||||
assert_invariant(!allocation.hasChildren());
|
||||
|
||||
NodeId found{};
|
||||
QuadTree::traverse(candidate.l, candidate.code,
|
||||
[this, n, &found](NodeId const& curr) -> QuadTree::TraversalResult {
|
||||
size_t i = index(curr.l, curr.code);
|
||||
Node& node = mQuadTree[i];
|
||||
if (curr.l == n) {
|
||||
found = curr;
|
||||
node.allocated = true;
|
||||
return QuadTree::TraversalResult::EXIT;
|
||||
}
|
||||
node.children++;
|
||||
return QuadTree::TraversalResult::RECURSE;
|
||||
});
|
||||
|
||||
candidate = found;
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_ATLASALLOCATOR_H
|
||||
#define TNT_FILAMENT_ATLASALLOCATOR_H
|
||||
|
||||
#include <utils/QuadTree.h>
|
||||
|
||||
#include <filament/Viewport.h>
|
||||
|
||||
class AtlasAllocator_AllocateFirstLevel_Test;
|
||||
class AtlasAllocator_AllocateSecondLevel_Test;
|
||||
class AtlasAllocator_AllocateMixed0_Test;
|
||||
class AtlasAllocator_AllocateMixed1_Test;
|
||||
class AtlasAllocator_AllocateMixed2_Test;
|
||||
|
||||
namespace filament {
|
||||
|
||||
/*
|
||||
* A 2D allocator. Allocations must be square and have a power-of-two size.
|
||||
* AtlasAllocator hard codes a depth of 4, that is only 4 allocation sizes are permitted.
|
||||
* This doesn't actually allocate memory, just manages space within an abstract 2D image.
|
||||
*/
|
||||
class AtlasAllocator {
|
||||
|
||||
/*
|
||||
* A quadtree is used to track the allocated regions. Each node of the quadtree stores a
|
||||
* `Node` data structure below.
|
||||
* The `Node` tracks if it is allocated as well as the number of children it has. It doesn't
|
||||
* track which children though.
|
||||
*/
|
||||
struct Node {
|
||||
// whether this node is allocated. Implies no children.
|
||||
constexpr bool isAllocated() const noexcept { return allocated; }
|
||||
// whether this node has children. Implies it's not allocated.
|
||||
constexpr bool hasChildren() const noexcept { return children != 0; }
|
||||
// whether this node has all four children. Implies hasChildren().
|
||||
constexpr bool hasAllChildren() const noexcept { return children == 4; }
|
||||
bool allocated : 1; // true / false
|
||||
uint8_t children : 3; // 0, 1, 2, 3, 4
|
||||
};
|
||||
|
||||
static constexpr size_t QUAD_TREE_DEPTH = 4u;
|
||||
using QuadTree = utils::QuadTreeArray<Node, QUAD_TREE_DEPTH>;
|
||||
using NodeId = QuadTree::NodeId;
|
||||
|
||||
public:
|
||||
/*
|
||||
* Create allocator and specify the maximum texture size. Must be a power of two.
|
||||
* Allocations size allowed are the four power-of-two smaller or equal to this size.
|
||||
*/
|
||||
explicit AtlasAllocator(size_t maxTextureSize = 1024) noexcept;
|
||||
|
||||
/*
|
||||
* Allocates a square of size `textureSize`. Must be one of the power-of-two allowed
|
||||
* (see above).
|
||||
* Returns the location of the allocation within the maxTextureSize^2 square.
|
||||
*/
|
||||
Viewport allocate(size_t textureSize) noexcept;
|
||||
|
||||
/*
|
||||
* Frees all allocations and reset the maximum texture size.
|
||||
*/
|
||||
void clear(size_t maxTextureSize = 1024) noexcept;
|
||||
|
||||
private:
|
||||
friend AtlasAllocator_AllocateFirstLevel_Test;
|
||||
friend AtlasAllocator_AllocateSecondLevel_Test;
|
||||
friend AtlasAllocator_AllocateMixed0_Test;
|
||||
friend AtlasAllocator_AllocateMixed1_Test;
|
||||
friend AtlasAllocator_AllocateMixed2_Test;
|
||||
|
||||
QuadTree::NodeId allocateInLayer(size_t n) noexcept;
|
||||
|
||||
// quad-tree array to store the allocated list
|
||||
QuadTree mQuadTree{};
|
||||
uint8_t mMaxTextureSizePot = 0;
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_ATLASALLOCATOR_H
|
||||
@@ -292,4 +292,44 @@ MaterialInstance* MaterialInstance::duplicate(MaterialInstance const* other, con
|
||||
}
|
||||
|
||||
|
||||
float MaterialInstance::getMaskThreshold() const noexcept {
|
||||
return downcast(this)->getMaskThreshold();
|
||||
}
|
||||
|
||||
float MaterialInstance::getSpecularAntiAliasingVariance() const noexcept {
|
||||
return downcast(this)->getSpecularAntiAliasingVariance();
|
||||
}
|
||||
|
||||
float MaterialInstance::getSpecularAntiAliasingThreshold() const noexcept {
|
||||
return downcast(this)->getSpecularAntiAliasingThreshold();
|
||||
}
|
||||
|
||||
bool MaterialInstance::isDoubleSided() const noexcept {
|
||||
return downcast(this)->isDoubleSided();
|
||||
}
|
||||
|
||||
TransparencyMode MaterialInstance::getTransparencyMode() const noexcept {
|
||||
return downcast(this)->getTransparencyMode();
|
||||
}
|
||||
|
||||
CullingMode MaterialInstance::getCullingMode() const noexcept {
|
||||
return downcast(this)->getCullingMode();
|
||||
}
|
||||
|
||||
bool MaterialInstance::isColorWriteEnabled() const noexcept {
|
||||
return downcast(this)->isColorWriteEnabled();
|
||||
}
|
||||
|
||||
bool MaterialInstance::isDepthWriteEnabled() const noexcept {
|
||||
return downcast(this)->isDepthWriteEnabled();
|
||||
}
|
||||
|
||||
bool MaterialInstance::isStencilWriteEnabled() const noexcept {
|
||||
return downcast(this)->isStencilWriteEnabled();
|
||||
}
|
||||
|
||||
bool MaterialInstance::isDepthCullingEnabled() const noexcept {
|
||||
return downcast(this)->isDepthCullingEnabled();
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "PerShadowMapUniforms.h"
|
||||
|
||||
#include "ShadowMapManager.h"
|
||||
|
||||
#include "details/Camera.h"
|
||||
#include "details/Engine.h"
|
||||
|
||||
#include <private/filament/EngineEnums.h>
|
||||
|
||||
namespace filament {
|
||||
|
||||
using namespace backend;
|
||||
using namespace math;
|
||||
|
||||
PerShadowMapUniforms::PerShadowMapUniforms(FEngine& engine) noexcept {
|
||||
DriverApi& driver = engine.getDriverApi();
|
||||
mUniformBufferHandle = driver.createBufferObject(sizeof(PerViewUib),
|
||||
BufferObjectBinding::UNIFORM, BufferUsage::DYNAMIC);
|
||||
}
|
||||
|
||||
void PerShadowMapUniforms::terminate(DriverApi& driver) {
|
||||
driver.destroyBufferObject(mUniformBufferHandle);
|
||||
}
|
||||
|
||||
PerViewUib& PerShadowMapUniforms::edit(Transaction const& transaction) noexcept {
|
||||
assert_invariant(transaction.uniforms);
|
||||
return *transaction.uniforms;
|
||||
}
|
||||
|
||||
void PerShadowMapUniforms::prepareCamera(Transaction const& transaction,
|
||||
FEngine& engine, const CameraInfo& camera) noexcept {
|
||||
mat4f const& viewFromWorld = camera.view;
|
||||
mat4f const& worldFromView = camera.model;
|
||||
mat4f const& clipFromView = camera.projection;
|
||||
|
||||
const mat4f viewFromClip{ inverse((mat4)camera.projection) };
|
||||
const mat4f clipFromWorld{ highPrecisionMultiply(clipFromView, viewFromWorld) };
|
||||
const mat4f worldFromClip{ highPrecisionMultiply(worldFromView, viewFromClip) };
|
||||
|
||||
auto& s = edit(transaction);
|
||||
s.viewFromWorldMatrix = viewFromWorld; // view
|
||||
s.worldFromViewMatrix = worldFromView; // model
|
||||
s.clipFromViewMatrix = clipFromView; // projection
|
||||
s.viewFromClipMatrix = viewFromClip; // 1/projection
|
||||
s.clipFromWorldMatrix = clipFromWorld; // projection * view
|
||||
s.worldFromClipMatrix = worldFromClip; // 1/(projection * view)
|
||||
s.clipTransform = camera.clipTransfrom;
|
||||
s.cameraPosition = float3{ camera.getPosition() };
|
||||
s.worldOffset = camera.getWorldOffset();
|
||||
s.cameraFar = camera.zf;
|
||||
s.oneOverFarMinusNear = 1.0f / (camera.zf - camera.zn);
|
||||
s.nearOverFarMinusNear = camera.zn / (camera.zf - camera.zn);
|
||||
|
||||
// with a clip-space of [-w, w] ==> z' = -z
|
||||
// with a clip-space of [0, w] ==> z' = (w - z)/2
|
||||
s.clipControl = engine.getDriverApi().getClipSpaceParams();
|
||||
}
|
||||
|
||||
void PerShadowMapUniforms::prepareLodBias(Transaction const& transaction,
|
||||
float bias) noexcept {
|
||||
auto& s = edit(transaction);
|
||||
s.lodBias = bias;
|
||||
}
|
||||
|
||||
void PerShadowMapUniforms::prepareViewport(Transaction const& transaction,
|
||||
const filament::Viewport& viewport,
|
||||
uint32_t xoffset, uint32_t yoffset) noexcept {
|
||||
const float w = float(viewport.width);
|
||||
const float h = float(viewport.height);
|
||||
auto& s = edit(transaction);
|
||||
s.resolution = float4{ w, h, 1.0f / w, 1.0f / h };
|
||||
s.origin = float2{ viewport.left, viewport.bottom };
|
||||
s.offset = float2{ xoffset, yoffset };
|
||||
}
|
||||
|
||||
void PerShadowMapUniforms::prepareTime(Transaction const& transaction,
|
||||
FEngine& engine, math::float4 const& userTime) noexcept {
|
||||
auto& s = edit(transaction);
|
||||
const uint64_t oneSecondRemainder = engine.getEngineTime().count() % 1000000000;
|
||||
const float fraction = float(double(oneSecondRemainder) / 1000000000.0);
|
||||
s.time = fraction;
|
||||
s.userTime = userTime;
|
||||
}
|
||||
|
||||
void PerShadowMapUniforms::prepareShadowMapping(Transaction const& transaction,
|
||||
bool highPrecision) noexcept {
|
||||
auto& s = edit(transaction);
|
||||
constexpr float low = 5.54f; // ~ std::log(std::numeric_limits<math::half>::max()) * 0.5f;
|
||||
constexpr float high = 42.0f; // ~ std::log(std::numeric_limits<float>::max()) * 0.5f;
|
||||
s.vsmExponent = highPrecision ? high : low;
|
||||
}
|
||||
|
||||
|
||||
PerShadowMapUniforms::Transaction PerShadowMapUniforms::open(backend::DriverApi& driver) noexcept {
|
||||
Transaction transaction;
|
||||
// TODO: use out-of-line buffer if too large
|
||||
transaction.uniforms = (PerViewUib *)driver.allocate(sizeof(PerViewUib));
|
||||
assert_invariant(transaction.uniforms);
|
||||
return transaction;
|
||||
}
|
||||
|
||||
void PerShadowMapUniforms::commit(Transaction& transaction,
|
||||
backend::DriverApi& driver) noexcept {
|
||||
driver.updateBufferObject(mUniformBufferHandle, {
|
||||
transaction.uniforms, sizeof(PerViewUib) }, 0);
|
||||
transaction.uniforms = nullptr;
|
||||
}
|
||||
|
||||
void PerShadowMapUniforms::bind(backend::DriverApi& driver) noexcept {
|
||||
driver.bindUniformBuffer(+UniformBindingPoints::PER_VIEW, mUniformBufferHandle);
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_PERSHADOWMAPUNIFORMS_H
|
||||
#define TNT_FILAMENT_PERSHADOWMAPUNIFORMS_H
|
||||
|
||||
#include <filament/Viewport.h>
|
||||
|
||||
#include <private/filament/UibStructs.h>
|
||||
#include <private/backend/SamplerGroup.h>
|
||||
|
||||
#include "TypedUniformBuffer.h"
|
||||
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <utils/EntityInstance.h>
|
||||
|
||||
#include <random>
|
||||
|
||||
namespace filament {
|
||||
|
||||
struct CameraInfo;
|
||||
|
||||
class FEngine;
|
||||
class LightManager;
|
||||
|
||||
/*
|
||||
* PerShadowMapUniforms manages the UBO needed to generate our shadow maps. Internally it just
|
||||
* holds onto a `PerViewUniform` UBO handle, but doesn't keep any shadow copy of it, instead it
|
||||
* writes the data directly into the commandstream, for this reason partial update of the data
|
||||
* is not possible.
|
||||
*/
|
||||
class PerShadowMapUniforms {
|
||||
|
||||
using LightManagerInstance = utils::EntityInstance<LightManager>;
|
||||
|
||||
public:
|
||||
class Transaction {
|
||||
friend PerShadowMapUniforms;
|
||||
PerViewUib* uniforms = nullptr;
|
||||
Transaction() = default; // disallow creation by the caller
|
||||
};
|
||||
|
||||
explicit PerShadowMapUniforms(FEngine& engine) noexcept;
|
||||
|
||||
void terminate(backend::DriverApi& driver);
|
||||
|
||||
static void prepareCamera(Transaction const& transaction,
|
||||
FEngine& engine, const CameraInfo& camera) noexcept;
|
||||
|
||||
static void prepareLodBias(Transaction const& transaction,
|
||||
float bias) noexcept;
|
||||
|
||||
static void prepareViewport(Transaction const& transaction,
|
||||
const filament::Viewport& viewport, uint32_t xoffset, uint32_t yoffset) noexcept;
|
||||
|
||||
static void prepareTime(Transaction const& transaction,
|
||||
FEngine& engine, math::float4 const& userTime) noexcept;
|
||||
|
||||
static void prepareShadowMapping(Transaction const& transaction,
|
||||
bool highPrecision) noexcept;
|
||||
|
||||
static Transaction open(backend::DriverApi& driver) noexcept;
|
||||
|
||||
// update local data into GPU UBO
|
||||
void commit(Transaction& transaction, backend::DriverApi& driver) noexcept;
|
||||
|
||||
// bind this UBO
|
||||
void bind(backend::DriverApi& driver) noexcept;
|
||||
|
||||
private:
|
||||
static PerViewUib& edit(Transaction const& transaction) noexcept;
|
||||
backend::Handle<backend::HwBufferObject> mUniformBufferHandle;
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif //TNT_FILAMENT_PERSHADOWMAPUNIFORMS_H
|
||||
@@ -34,15 +34,13 @@
|
||||
|
||||
#include <math/mat4.h>
|
||||
|
||||
|
||||
namespace filament {
|
||||
|
||||
using namespace backend;
|
||||
using namespace math;
|
||||
|
||||
PerViewUniforms::PerViewUniforms(FEngine& engine) noexcept
|
||||
: mEngine(engine),
|
||||
mSamplers(PerViewSib::SAMPLER_COUNT) {
|
||||
: mSamplers(PerViewSib::SAMPLER_COUNT) {
|
||||
DriverApi& driver = engine.getDriverApi();
|
||||
|
||||
mSamplerGroupHandle = driver.createSamplerGroup(mSamplers.getSize());
|
||||
@@ -50,10 +48,6 @@ PerViewUniforms::PerViewUniforms(FEngine& engine) noexcept
|
||||
mUniformBufferHandle = driver.createBufferObject(mUniforms.getSize(),
|
||||
BufferObjectBinding::UNIFORM, BufferUsage::DYNAMIC);
|
||||
|
||||
// with a clip-space of [-w, w] ==> z' = -z
|
||||
// with a clip-space of [0, w] ==> z' = (w - z)/2
|
||||
mClipControl = driver.getClipSpaceParams();
|
||||
|
||||
if (engine.getDFG().isValid()) {
|
||||
TextureSampler sampler(TextureSampler::MagFilter::LINEAR);
|
||||
mSamplers.setSampler(PerViewSib::IBL_DFG_LUT,
|
||||
@@ -66,7 +60,7 @@ void PerViewUniforms::terminate(DriverApi& driver) {
|
||||
driver.destroySamplerGroup(mSamplerGroupHandle);
|
||||
}
|
||||
|
||||
void PerViewUniforms::prepareCamera(const CameraInfo& camera) noexcept {
|
||||
void PerViewUniforms::prepareCamera(FEngine& engine, const CameraInfo& camera) noexcept {
|
||||
mat4f const& viewFromWorld = camera.view;
|
||||
mat4f const& worldFromView = camera.model;
|
||||
mat4f const& clipFromView = camera.projection;
|
||||
@@ -88,17 +82,15 @@ void PerViewUniforms::prepareCamera(const CameraInfo& camera) noexcept {
|
||||
s.cameraFar = camera.zf;
|
||||
s.oneOverFarMinusNear = 1.0f / (camera.zf - camera.zn);
|
||||
s.nearOverFarMinusNear = camera.zn / (camera.zf - camera.zn);
|
||||
s.clipControl = mClipControl;
|
||||
|
||||
// with a clip-space of [-w, w] ==> z' = -z
|
||||
// with a clip-space of [0, w] ==> z' = (w - z)/2
|
||||
s.clipControl = engine.getDriverApi().getClipSpaceParams();
|
||||
}
|
||||
|
||||
void PerViewUniforms::prepareUpscaler(math::float2 scale,
|
||||
DynamicResolutionOptions const& options) noexcept {
|
||||
void PerViewUniforms::prepareLodBias(float bias) noexcept {
|
||||
auto& s = mUniforms.edit();
|
||||
if (options.quality >= QualityLevel::HIGH) {
|
||||
s.lodBias = std::log2(std::min(scale.x, scale.y));
|
||||
} else {
|
||||
s.lodBias = 0.0f;
|
||||
}
|
||||
s.lodBias = bias;
|
||||
}
|
||||
|
||||
void PerViewUniforms::prepareExposure(float ev100) noexcept {
|
||||
@@ -118,17 +110,19 @@ void PerViewUniforms::prepareViewport(const filament::Viewport& viewport,
|
||||
s.offset = float2{ xoffset, yoffset };
|
||||
}
|
||||
|
||||
void PerViewUniforms::prepareTime(math::float4 const& userTime) noexcept {
|
||||
void PerViewUniforms::prepareTime(FEngine& engine, math::float4 const& userTime) noexcept {
|
||||
auto& s = mUniforms.edit();
|
||||
const uint64_t oneSecondRemainder = mEngine.getEngineTime().count() % 1000000000;
|
||||
const uint64_t oneSecondRemainder = engine.getEngineTime().count() % 1000000000;
|
||||
const float fraction = float(double(oneSecondRemainder) / 1000000000.0);
|
||||
s.time = fraction;
|
||||
s.userTime = userTime;
|
||||
}
|
||||
|
||||
void PerViewUniforms::prepareTemporalNoise(TemporalAntiAliasingOptions const& options) noexcept {
|
||||
void PerViewUniforms::prepareTemporalNoise(FEngine& engine,
|
||||
TemporalAntiAliasingOptions const& options) noexcept {
|
||||
std::uniform_real_distribution<float> uniformDistribution{ 0.0f, 1.0f };
|
||||
auto& s = mUniforms.edit();
|
||||
const float temporalNoise = mUniformDistribution(mEngine.getRandomEngine());
|
||||
const float temporalNoise = uniformDistribution(engine.getRandomEngine());
|
||||
s.temporalNoise = options.enabled ? temporalNoise : 0.0f;
|
||||
}
|
||||
|
||||
@@ -217,11 +211,11 @@ void PerViewUniforms::prepareStructure(Handle<HwTexture> structure) noexcept {
|
||||
mSamplers.setSampler(PerViewSib::STRUCTURE, { structure, {}});
|
||||
}
|
||||
|
||||
void PerViewUniforms::prepareDirectionalLight(
|
||||
void PerViewUniforms::prepareDirectionalLight(FEngine& engine,
|
||||
float exposure,
|
||||
float3 const& sceneSpaceDirection,
|
||||
PerViewUniforms::LightManagerInstance directionalLight) noexcept {
|
||||
FLightManager& lcm = mEngine.getLightManager();
|
||||
FLightManager& lcm = engine.getLightManager();
|
||||
auto& s = mUniforms.edit();
|
||||
|
||||
const float3 l = -sceneSpaceDirection; // guaranteed normalized
|
||||
@@ -255,9 +249,8 @@ void PerViewUniforms::prepareDirectionalLight(
|
||||
}
|
||||
}
|
||||
|
||||
void PerViewUniforms::prepareAmbientLight(FIndirectLight const& ibl,
|
||||
void PerViewUniforms::prepareAmbientLight(FEngine& engine, FIndirectLight const& ibl,
|
||||
float intensity, float exposure) noexcept {
|
||||
auto& engine = mEngine;
|
||||
auto& s = mUniforms.edit();
|
||||
|
||||
// Set up uniforms and sampler for the IBL, guaranteed to be non-null at this point.
|
||||
@@ -297,14 +290,10 @@ void PerViewUniforms::prepareShadowMapping(bool highPrecision) noexcept {
|
||||
|
||||
void PerViewUniforms::prepareShadowSampling(PerViewUib& uniforms,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms) noexcept {
|
||||
uniforms.lightFromWorldMatrix = shadowMappingUniforms.lightFromWorldMatrix;
|
||||
uniforms.cascadeSplits = shadowMappingUniforms.cascadeSplits;
|
||||
uniforms.shadowBulbRadiusLs = shadowMappingUniforms.shadowBulbRadiusLs;
|
||||
uniforms.shadowBias = shadowMappingUniforms.shadowBias;
|
||||
uniforms.ssContactShadowDistance = shadowMappingUniforms.ssContactShadowDistance;
|
||||
uniforms.directionalShadows = shadowMappingUniforms.directionalShadows;
|
||||
uniforms.cascades = shadowMappingUniforms.cascades;
|
||||
uniforms.cascades |= uint32_t(shadowMappingUniforms.elvsm) << 31u;
|
||||
}
|
||||
|
||||
void PerViewUniforms::prepareShadowVSM(Handle<HwTexture> texture,
|
||||
|
||||
@@ -48,6 +48,11 @@ class FIndirectLight;
|
||||
class Froxelizer;
|
||||
class LightManager;
|
||||
|
||||
/*
|
||||
* PerViewUniforms manages the UBO and samplers needed to render the color passes. Internally it
|
||||
* holds onto handles for the PER_VIEW UBO and SamplerGroup. This class maintains a shadow copy
|
||||
* of the UBO/sampler data, so it is possible to partially update it between commits.
|
||||
*/
|
||||
class PerViewUniforms {
|
||||
|
||||
using LightManagerInstance = utils::EntityInstance<LightManager>;
|
||||
@@ -63,8 +68,8 @@ public:
|
||||
|
||||
void terminate(backend::DriverApi& driver);
|
||||
|
||||
void prepareCamera(const CameraInfo& camera) noexcept;
|
||||
void prepareUpscaler(math::float2 scale, DynamicResolutionOptions const& options) noexcept;
|
||||
void prepareCamera(FEngine& engine, const CameraInfo& camera) noexcept;
|
||||
void prepareLodBias(float bias) noexcept;
|
||||
|
||||
/*
|
||||
* @param viewport viewport (should be same as RenderPassParams::viewport)
|
||||
@@ -75,8 +80,8 @@ public:
|
||||
*/
|
||||
void prepareViewport(const filament::Viewport& viewport, uint32_t xoffset, uint32_t yoffset) noexcept;
|
||||
|
||||
void prepareTime(math::float4 const& userTime) noexcept;
|
||||
void prepareTemporalNoise(TemporalAntiAliasingOptions const& options) noexcept;
|
||||
void prepareTime(FEngine& engine, math::float4 const& userTime) noexcept;
|
||||
void prepareTemporalNoise(FEngine& engine, TemporalAntiAliasingOptions const& options) noexcept;
|
||||
void prepareExposure(float ev100) noexcept;
|
||||
void prepareFog(math::float3 const& cameraPosition, FogOptions const& options) noexcept;
|
||||
void prepareStructure(TextureHandle structure) noexcept;
|
||||
@@ -95,10 +100,11 @@ public:
|
||||
|
||||
void prepareShadowMapping(bool highPrecision) noexcept;
|
||||
|
||||
void prepareDirectionalLight(float exposure,
|
||||
void prepareDirectionalLight(FEngine& engine, float exposure,
|
||||
math::float3 const& sceneSpaceDirection, LightManagerInstance instance) noexcept;
|
||||
|
||||
void prepareAmbientLight(FIndirectLight const& ibl, float intensity, float exposure) noexcept;
|
||||
void prepareAmbientLight(FEngine& engine,
|
||||
FIndirectLight const& ibl, float intensity, float exposure) noexcept;
|
||||
|
||||
void prepareDynamicLights(Froxelizer& froxelizer) noexcept;
|
||||
|
||||
@@ -126,13 +132,10 @@ public:
|
||||
void unbindSamplers() noexcept;
|
||||
|
||||
private:
|
||||
FEngine& mEngine;
|
||||
math::float2 mClipControl{};
|
||||
TypedUniformBuffer<PerViewUib> mUniforms;
|
||||
backend::SamplerGroup mSamplers;
|
||||
backend::Handle<backend::HwBufferObject> mUniformBufferHandle;
|
||||
backend::Handle<backend::HwSamplerGroup> mSamplerGroupHandle;
|
||||
std::uniform_real_distribution<float> mUniformDistribution{ 0.0f, 1.0f };
|
||||
static void prepareShadowSampling(PerViewUib& uniforms,
|
||||
ShadowMappingUniforms const& shadowMappingUniforms) noexcept;
|
||||
};
|
||||
|
||||
@@ -2476,7 +2476,7 @@ void PostProcessManager::prepareTaa(FrameGraph& fg, filament::Viewport const& sv
|
||||
|
||||
fg.addTrivialSideEffectPass("Jitter Camera",
|
||||
[=, &uniforms] (DriverApi& driver) {
|
||||
uniforms.prepareCamera(*inoutCameraInfo);
|
||||
uniforms.prepareCamera(mEngine, *inoutCameraInfo);
|
||||
uniforms.commit(driver);
|
||||
});
|
||||
}
|
||||
|
||||
+56
-47
@@ -79,25 +79,12 @@ void RenderPass::setCamera(const CameraInfo& camera) noexcept {
|
||||
mCameraForwardVector = camera.getForwardVector();
|
||||
}
|
||||
|
||||
void RenderPass::overridePolygonOffset(backend::PolygonOffset const* polygonOffset) noexcept {
|
||||
if ((mPolygonOffsetOverride = (polygonOffset != nullptr))) {
|
||||
mPolygonOffset = *polygonOffset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RenderPass::setScissorViewport(backend::Viewport viewport) noexcept {
|
||||
assert_invariant(viewport.width <= std::numeric_limits<int32_t>::max());
|
||||
assert_invariant(viewport.height <= std::numeric_limits<int32_t>::max());
|
||||
mScissorViewport = viewport;
|
||||
}
|
||||
|
||||
void RenderPass::overrideScissor(backend::Viewport const* scissor) noexcept {
|
||||
if ((mScissorOverride = (scissor != nullptr))) {
|
||||
mScissor = *scissor;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPass::appendCommands(FEngine& engine, CommandTypeFlags const commandTypeFlags) noexcept {
|
||||
SYSTRACE_CONTEXT();
|
||||
|
||||
@@ -196,6 +183,22 @@ void RenderPass::sortCommands(FEngine& engine) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPass::execute(FEngine& engine, const char* name,
|
||||
backend::Handle<backend::HwRenderTarget> renderTarget,
|
||||
backend::RenderPassParams params) const noexcept {
|
||||
|
||||
DriverApi& driver = engine.getDriverApi();
|
||||
|
||||
// this is a good time to flush the CommandStream, because we're about to potentially
|
||||
// output a lot of commands. This guarantees here that we have at least
|
||||
// FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB bytes (1MiB by default).
|
||||
engine.flush();
|
||||
|
||||
driver.beginRenderPass(renderTarget, params);
|
||||
getExecutor().execute(engine, name);
|
||||
driver.endRenderPass();
|
||||
}
|
||||
|
||||
void RenderPass::instanceify(FEngine& engine) noexcept {
|
||||
SYSTRACE_NAME("instanceify");
|
||||
|
||||
@@ -355,8 +358,8 @@ void RenderPass::setupColorCommand(Command& cmdDraw, Variant variant,
|
||||
|
||||
cmdDraw.primitive.rasterState.inverseFrontFaces = inverseFrontFaces;
|
||||
cmdDraw.primitive.rasterState.culling = mi->getCullingMode();
|
||||
cmdDraw.primitive.rasterState.colorWrite = mi->getColorWrite();
|
||||
cmdDraw.primitive.rasterState.depthWrite = mi->getDepthWrite();
|
||||
cmdDraw.primitive.rasterState.colorWrite = mi->isColorWriteEnabled();
|
||||
cmdDraw.primitive.rasterState.depthWrite = mi->isDepthWriteEnabled();
|
||||
cmdDraw.primitive.rasterState.depthFunc = mi->getDepthFunc();
|
||||
cmdDraw.primitive.mi = mi;
|
||||
cmdDraw.primitive.materialVariant = variant;
|
||||
@@ -541,11 +544,6 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags,
|
||||
*/
|
||||
for (size_t pi = 0, c = primitives.size(); pi < c; ++pi) {
|
||||
auto const& primitive = primitives[pi];
|
||||
// handle the case where this primitive is empty / no-op
|
||||
if (primitive.getPrimitiveType() == PrimitiveType::NONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto const& morphTargets = morphing.targets[pi];
|
||||
FMaterialInstance const* const mi = primitive.getMaterialInstance();
|
||||
FMaterial const* const ma = mi->getMaterial();
|
||||
@@ -608,6 +606,9 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags,
|
||||
// cancel command if asked to filter translucent objects
|
||||
key |= select(filterTranslucentObjects);
|
||||
|
||||
// cancel command if both front and back faces are culled
|
||||
key |= select(mi->getCullingMode() == CullingMode::FRONT_AND_BACK);
|
||||
|
||||
*curr = cmdColor;
|
||||
curr->key = key;
|
||||
++curr;
|
||||
@@ -634,6 +635,10 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags,
|
||||
}
|
||||
|
||||
*curr = cmdColor;
|
||||
|
||||
// cancel command if both front and back faces are culled
|
||||
curr->key |= select(mi->getCullingMode() == CullingMode::FRONT_AND_BACK);
|
||||
|
||||
++curr;
|
||||
}
|
||||
|
||||
@@ -658,11 +663,16 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags,
|
||||
|
||||
// FIXME: should writeDepthForShadowCasters take precedence over mi->getDepthWrite()?
|
||||
cmdDepth.primitive.rasterState.depthWrite = (1 // only keep bit 0
|
||||
& (mi->getDepthWrite() | (mode == TransparencyMode::TWO_PASSES_ONE_SIDE))
|
||||
& (mi->isDepthWriteEnabled() | (mode == TransparencyMode::TWO_PASSES_ONE_SIDE))
|
||||
& !(filterTranslucentObjects & translucent)
|
||||
& !(depthFilterAlphaMaskedObjects & rs.alphaToCoverage))
|
||||
| writeDepthForShadowCasters;
|
||||
|
||||
*curr = cmdDepth;
|
||||
|
||||
// cancel command if both front and back faces are culled
|
||||
curr->key |= select(mi->getCullingMode() == CullingMode::FRONT_AND_BACK);
|
||||
|
||||
++curr;
|
||||
}
|
||||
}
|
||||
@@ -685,24 +695,25 @@ void RenderPass::updateSummedPrimitiveCounts(
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
void RenderPass::Executor::execute(FEngine& engine, const char* name,
|
||||
backend::Handle<backend::HwRenderTarget> renderTarget,
|
||||
backend::RenderPassParams const& params) const noexcept {
|
||||
DriverApi& driver = engine.getDriverApi();
|
||||
void RenderPass::Executor::overridePolygonOffset(backend::PolygonOffset const* polygonOffset) noexcept {
|
||||
if ((mPolygonOffsetOverride = (polygonOffset != nullptr))) {
|
||||
mPolygonOffset = *polygonOffset;
|
||||
}
|
||||
}
|
||||
|
||||
// this is a good time to flush the CommandStream, because we're about to potentially
|
||||
// output a lot of commands. This guarantees here that we have at least
|
||||
// FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB bytes (1MiB by default).
|
||||
engine.flush();
|
||||
void RenderPass::Executor::overrideScissor(backend::Viewport const* scissor) noexcept {
|
||||
if ((mScissorOverride = (scissor != nullptr))) {
|
||||
mScissor = *scissor;
|
||||
}
|
||||
}
|
||||
|
||||
driver.beginRenderPass(renderTarget, params);
|
||||
recordDriverCommands(engine, driver, mBegin, mEnd, params.readOnlyDepthStencil);
|
||||
driver.endRenderPass();
|
||||
void RenderPass::Executor::execute(FEngine& engine, const char* name) const noexcept {
|
||||
execute(engine.getDriverApi(), mCommands.begin(), mCommands.end());
|
||||
}
|
||||
|
||||
UTILS_NOINLINE // no need to be inlined
|
||||
void RenderPass::Executor::recordDriverCommands(FEngine& engine, backend::DriverApi& driver,
|
||||
const Command* first, const Command* last, uint16_t readOnlyDepthStencil) const noexcept {
|
||||
void RenderPass::Executor::execute(backend::DriverApi& driver,
|
||||
const Command* first, const Command* last) const noexcept {
|
||||
SYSTRACE_CALL();
|
||||
|
||||
if (first != last) {
|
||||
@@ -722,7 +733,7 @@ void RenderPass::Executor::recordDriverCommands(FEngine& engine, backend::Driver
|
||||
Handle<HwBufferObject> uboHandle = mUboHandle;
|
||||
FMaterialInstance const* UTILS_RESTRICT mi = nullptr;
|
||||
FMaterial const* UTILS_RESTRICT ma = nullptr;
|
||||
auto customCommands = mCustomCommands.data();
|
||||
auto const* UTILS_RESTRICT pCustomCommands = mCustomCommands.data();
|
||||
|
||||
first--;
|
||||
while (++first != last) {
|
||||
@@ -735,7 +746,12 @@ void RenderPass::Executor::recordDriverCommands(FEngine& engine, backend::Driver
|
||||
if (UTILS_UNLIKELY((first->key & CUSTOM_MASK) != uint64_t(CustomCommand::PASS))) {
|
||||
uint32_t index = (first->key & CUSTOM_INDEX_MASK) >> CUSTOM_INDEX_SHIFT;
|
||||
assert_invariant(index < mCustomCommands.size());
|
||||
customCommands[index]();
|
||||
pCustomCommands[index]();
|
||||
continue;
|
||||
}
|
||||
|
||||
// primitiveHandle may be invalid if no geometry was set on the renderable.
|
||||
if (UTILS_UNLIKELY(!first->primitive.primitiveHandle)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -743,11 +759,6 @@ void RenderPass::Executor::recordDriverCommands(FEngine& engine, backend::Driver
|
||||
const PrimitiveInfo info = first->primitive;
|
||||
pipeline.rasterState = info.rasterState;
|
||||
|
||||
#ifndef NDEBUG
|
||||
const bool readOnlyDepthGuaranteed = readOnlyDepthStencil & RenderPassParams::READONLY_DEPTH;
|
||||
assert_invariant(!readOnlyDepthGuaranteed || !pipeline.rasterState.depthWrite);
|
||||
#endif
|
||||
|
||||
if (UTILS_UNLIKELY(mi != info.mi)) {
|
||||
// this is always taken the first time
|
||||
mi = info.mi;
|
||||
@@ -829,15 +840,13 @@ void RenderPass::Executor::recordDriverCommands(FEngine& engine, backend::Driver
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
RenderPass::Executor::Executor(RenderPass const* pass, Command const* b, Command const* e) noexcept
|
||||
: mBegin(b), mEnd(e),
|
||||
mCustomCommands(pass->mCustomCommands),
|
||||
: mCommands(b, e),
|
||||
mCustomCommands(pass->mCustomCommands.data(), pass->mCustomCommands.size()),
|
||||
mUboHandle(pass->mUboHandle),
|
||||
mInstancedUboHandle(pass->mInstancedUboHandle),
|
||||
mPolygonOffset(pass->mPolygonOffset),
|
||||
mScissor(pass->mScissor),
|
||||
mScissorViewport(pass->mScissorViewport),
|
||||
mPolygonOffsetOverride(pass->mPolygonOffsetOverride),
|
||||
mScissorOverride(pass->mScissorOverride) {
|
||||
mPolygonOffsetOverride(false),
|
||||
mScissorOverride(false) {
|
||||
assert_invariant(b >= pass->begin());
|
||||
assert_invariant(e <= pass->end());
|
||||
}
|
||||
|
||||
+36
-40
@@ -276,15 +276,9 @@ public:
|
||||
// allocated commands ARE NOT freed, they're owned by the Arena
|
||||
~RenderPass() noexcept;
|
||||
|
||||
// if non-null, overrides the material's polygon offset
|
||||
void overridePolygonOffset(backend::PolygonOffset const* polygonOffset) noexcept;
|
||||
|
||||
// a box that both offsets the viewport and clips it
|
||||
void setScissorViewport(backend::Viewport viewport) noexcept;
|
||||
|
||||
// if non-null, overrides the material's scissor
|
||||
void overrideScissor(backend::Viewport const* scissor) noexcept;
|
||||
|
||||
// specifies the geometry to generate commands for
|
||||
void setGeometry(FScene::RenderableSoa const& soa, utils::Range<uint32_t> vr,
|
||||
backend::Handle<backend::HwBufferObject> uboHandle) noexcept;
|
||||
@@ -318,49 +312,61 @@ public:
|
||||
// Helper to execute all the commands generated by this RenderPass
|
||||
void execute(FEngine& engine, const char* name,
|
||||
backend::Handle<backend::HwRenderTarget> renderTarget,
|
||||
backend::RenderPassParams params) const noexcept {
|
||||
getExecutor().execute(engine, name, renderTarget, params);
|
||||
}
|
||||
backend::RenderPassParams params) const noexcept;
|
||||
|
||||
/*
|
||||
* Executor holds the range of commands to execute for a given pass
|
||||
*/
|
||||
class Executor {
|
||||
using CustomCommandFn = std::function<void()>;
|
||||
using CustomCommandVector = std::vector<CustomCommandFn,
|
||||
utils::STLAllocator<CustomCommandFn, LinearAllocatorArena>>;
|
||||
|
||||
friend class RenderPass;
|
||||
Command const* mBegin;
|
||||
Command const* mEnd;
|
||||
const CustomCommandVector mCustomCommands;
|
||||
const backend::Handle<backend::HwBufferObject> mUboHandle;
|
||||
const backend::Handle<backend::HwBufferObject> mInstancedUboHandle;
|
||||
const backend::PolygonOffset mPolygonOffset;
|
||||
const backend::Viewport mScissor;
|
||||
const backend::Viewport mScissorViewport;
|
||||
const bool mPolygonOffsetOverride : 1;
|
||||
const bool mScissorOverride : 1;
|
||||
|
||||
// these fields are constant after creation
|
||||
utils::Slice<Command> mCommands;
|
||||
utils::Slice<CustomCommandFn> mCustomCommands;
|
||||
backend::Handle<backend::HwBufferObject> mUboHandle;
|
||||
backend::Handle<backend::HwBufferObject> mInstancedUboHandle;
|
||||
backend::Viewport mScissorViewport;
|
||||
|
||||
backend::Viewport mScissor{}; // value of scissor override
|
||||
backend::PolygonOffset mPolygonOffset{}; // value of the override
|
||||
bool mPolygonOffsetOverride : 1; // whether to override the polygon offset setting
|
||||
bool mScissorOverride : 1; // whether to override the polygon offset setting
|
||||
|
||||
Executor(RenderPass const* pass, Command const* b, Command const* e) noexcept;
|
||||
|
||||
void recordDriverCommands(FEngine& engine, backend::DriverApi& driver,
|
||||
const Command* first, const Command* last, uint16_t readOnlyDepthStencil) const noexcept;
|
||||
void execute(backend::DriverApi& driver,
|
||||
const Command* first, const Command* last) const noexcept;
|
||||
|
||||
public:
|
||||
Executor() = default;
|
||||
Executor(Executor const& rhs);
|
||||
Executor& operator=(Executor const& rhs) = default;
|
||||
~Executor() noexcept;
|
||||
void execute(FEngine& engine, const char* name,
|
||||
backend::Handle<backend::HwRenderTarget> renderTarget,
|
||||
backend::RenderPassParams const& params) const noexcept;
|
||||
|
||||
// if non-null, overrides the material's polygon offset
|
||||
void overridePolygonOffset(backend::PolygonOffset const* polygonOffset) noexcept;
|
||||
|
||||
// if non-null, overrides the material's scissor
|
||||
void overrideScissor(backend::Viewport const* scissor) noexcept;
|
||||
|
||||
void execute(FEngine& engine, const char* name) const noexcept;
|
||||
};
|
||||
|
||||
// returns a new executor for this pass
|
||||
Executor getExecutor() {
|
||||
return { this, mCommandBegin, mCommandEnd };
|
||||
}
|
||||
|
||||
Executor getExecutor() const {
|
||||
return { this, mCommandBegin, mCommandEnd };
|
||||
}
|
||||
|
||||
// returns a new executor for this pass with a custom range
|
||||
Executor getExecutor(Command const* b, Command const* e) {
|
||||
return { this, b, e };
|
||||
}
|
||||
|
||||
Executor getExecutor(Command const* b, Command const* e) const {
|
||||
return { this, b, e };
|
||||
}
|
||||
@@ -438,24 +444,14 @@ private:
|
||||
// Additional visibility mask
|
||||
FScene::VisibleMaskType mVisibilityMask = std::numeric_limits<FScene::VisibleMaskType>::max();
|
||||
|
||||
// whether to override the polygon offset setting
|
||||
bool mPolygonOffsetOverride = false;
|
||||
|
||||
// whether to override the polygon offset setting
|
||||
bool mScissorOverride = false;
|
||||
|
||||
// value of the override
|
||||
backend::PolygonOffset mPolygonOffset{};
|
||||
|
||||
// value of scissor override
|
||||
backend::Viewport mScissor{};
|
||||
|
||||
backend::Viewport mScissorViewport{ 0, 0,
|
||||
std::numeric_limits<int32_t>::max(),
|
||||
std::numeric_limits<int32_t>::max() };
|
||||
|
||||
// a vector for our custom commands
|
||||
mutable Executor::CustomCommandVector mCustomCommands;
|
||||
using CustomCommandVector = std::vector<Executor::CustomCommandFn,
|
||||
utils::STLAllocator<Executor::CustomCommandFn, LinearAllocatorArena>>;
|
||||
mutable CustomCommandVector mCustomCommands;
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -71,7 +71,7 @@ private:
|
||||
AttributeBitset mEnabledAttributes = {};
|
||||
uint16_t mBlendOrder = 0;
|
||||
bool mGlobalBlendOrderEnabled = false;
|
||||
backend::PrimitiveType mPrimitiveType = backend::PrimitiveType::NONE;
|
||||
backend::PrimitiveType mPrimitiveType = backend::PrimitiveType::TRIANGLES;
|
||||
UTILS_UNUSED uint8_t reserved[4] = {};
|
||||
};
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ FrameGraphId<FrameGraphTexture> RendererUtils::colorPass(
|
||||
view.prepareSSAO(data.ssao ?
|
||||
resources.getTexture(data.ssao) : engine.getOneTextureArray());
|
||||
|
||||
view.prepareShadowMap(view.getVsmShadowOptions().highPrecision);
|
||||
view.prepareShadowMapping(view.getVsmShadowOptions().highPrecision);
|
||||
|
||||
// set shadow sampler
|
||||
view.prepareShadow(data.shadows ?
|
||||
@@ -200,6 +200,7 @@ FrameGraphId<FrameGraphTexture> RendererUtils::colorPass(
|
||||
|
||||
view.prepareViewport(static_cast<filament::Viewport&>(out.params.viewport),
|
||||
config.xoffset, config.yoffset);
|
||||
|
||||
view.commitUniforms(driver);
|
||||
|
||||
out.params.clearColor = data.clearColor;
|
||||
@@ -217,7 +218,14 @@ FrameGraphId<FrameGraphTexture> RendererUtils::colorPass(
|
||||
if (colorGradingConfig.asSubpass || colorGradingConfig.customResolve) {
|
||||
out.params.subpassMask = 1;
|
||||
}
|
||||
passExecutor.execute(engine, resources.getPassName(), out.target, out.params);
|
||||
|
||||
// this is a good time to flush the CommandStream, because we're about to potentially
|
||||
// output a lot of commands. This guarantees here that we have at least
|
||||
// FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB bytes (1MiB by default).
|
||||
engine.flush();
|
||||
driver.beginRenderPass(out.target, out.params);
|
||||
passExecutor.execute(engine, resources.getPassName());
|
||||
driver.endRenderPass();
|
||||
|
||||
// color pass is typically heavy, and we don't have much CPU work left after
|
||||
// this point, so flushing now allows us to start the GPU earlier and reduce
|
||||
|
||||
+107
-85
@@ -41,8 +41,10 @@ using namespace backend;
|
||||
static constexpr bool USE_DEPTH_CLAMP = false;
|
||||
|
||||
ShadowMap::ShadowMap(FEngine& engine) noexcept
|
||||
: mShadowType(ShadowType::DIRECTIONAL),
|
||||
mHasVisibleShadows(false) {
|
||||
: mPerShadowMapUniforms(engine),
|
||||
mShadowType(ShadowType::DIRECTIONAL),
|
||||
mHasVisibleShadows(false),
|
||||
mFace(0) {
|
||||
Entity entities[2];
|
||||
engine.getEntityManager().create(2, entities);
|
||||
mCamera = engine.createCamera(entities[0]);
|
||||
@@ -60,16 +62,19 @@ void ShadowMap::terminate(FEngine& engine) {
|
||||
engine.destroyCameraComponent(e);
|
||||
}
|
||||
engine.getEntityManager().destroy(sizeof(entities) / sizeof(Entity), entities);
|
||||
mPerShadowMapUniforms.terminate(engine.getDriverApi());
|
||||
}
|
||||
|
||||
ShadowMap::~ShadowMap() = default;
|
||||
|
||||
void ShadowMap::initialize(size_t lightIndex, ShadowType shadowType, uint16_t shadowIndex,
|
||||
void ShadowMap::initialize(size_t lightIndex, ShadowType shadowType,
|
||||
uint16_t shadowIndex, uint8_t face,
|
||||
LightManager::ShadowOptions const* options) {
|
||||
mLightIndex = lightIndex;
|
||||
mShadowIndex = shadowIndex;
|
||||
mOptions = options;
|
||||
mShadowType = shadowType;
|
||||
mFace = face;
|
||||
}
|
||||
|
||||
mat4f ShadowMap::getDirectionalLightViewMatrix(float3 direction, float3 position) noexcept {
|
||||
@@ -408,41 +413,10 @@ ShadowMap::ShaderParameters ShadowMap::updateDirectional(FEngine& engine,
|
||||
return shaderParameters;
|
||||
}
|
||||
|
||||
ShadowMap::ShaderParameters ShadowMap::updateSpot(FEngine& engine,
|
||||
const FScene::LightSoa& lightData, size_t index,
|
||||
filament::CameraInfo const& camera,
|
||||
const ShadowMapInfo& shadowMapInfo,
|
||||
FScene const& scene, SceneInfo sceneInfo) noexcept {
|
||||
|
||||
ShaderParameters shaderParameters;
|
||||
|
||||
auto& lcm = engine.getLightManager();
|
||||
auto li = lightData.elementAt<FScene::LIGHT_INSTANCE>(index);
|
||||
auto position = lightData.elementAt<FScene::POSITION_RADIUS>(index).xyz;
|
||||
auto direction = lightData.elementAt<FScene::DIRECTION>(index);
|
||||
auto radius = lightData.elementAt<FScene::POSITION_RADIUS>(index).w;
|
||||
auto outerConeAngle = lcm.getSpotLightOuterCone(li);
|
||||
const FLightManager::ShadowParams& params = lcm.getShadowParams(li);
|
||||
|
||||
/*
|
||||
* Compute the light model matrix.
|
||||
*/
|
||||
|
||||
// Choose a reasonable value for the near plane.
|
||||
const mat4f Mv = getDirectionalLightViewMatrix(direction, position);
|
||||
|
||||
// find decent near/far
|
||||
ShadowMap::updateSceneInfoSpot(Mv, scene, sceneInfo);
|
||||
|
||||
// if the scene was empty, near > far
|
||||
mHasVisibleShadows = -sceneInfo.lsNearFar[0] < -sceneInfo.lsNearFar[1];
|
||||
|
||||
// FIXME: we need a configuration for minimum near plane (for now hardcoded to 1cm)
|
||||
float nearPlane = std::max(0.01f, -sceneInfo.lsNearFar[0]);
|
||||
float farPlane = std::min(radius, -sceneInfo.lsNearFar[1]);
|
||||
|
||||
float outerConeAngleDegrees = outerConeAngle * f::RAD_TO_DEG;
|
||||
const mat4f Mp = mat4f::perspective(outerConeAngleDegrees * 2.0f, 1.0f, nearPlane, farPlane);
|
||||
ShadowMap::ShaderParameters ShadowMap::updateSpotOrPoint(
|
||||
mat4f const& Mv, float outerConeAngle, float nearPlane, float farPlane,
|
||||
const ShadowMapInfo& shadowMapInfo, const FLightManager::ShadowParams& params) noexcept {
|
||||
const mat4f Mp = mat4f::perspective(outerConeAngle * f::RAD_TO_DEG * 2.0f, 1.0f, nearPlane, farPlane);
|
||||
const mat4f MpMv(math::highPrecisionMultiply(Mp, Mv));
|
||||
|
||||
// Final shadow transform
|
||||
@@ -464,7 +438,9 @@ ShadowMap::ShaderParameters ShadowMap::updateSpot(FEngine& engine,
|
||||
// = zInLightSpace * texelSizeAtOneMeter
|
||||
// = zInLightSpace * (2*tan(halfConeAngle)/dimension)
|
||||
// Note: this would not work with LISPSM, which warps the texture space.
|
||||
shaderParameters.texelSizeAtOneMeterWs = (2.0f * std::tan(outerConeAngle) / float(shadowMapInfo.shadowDimension));
|
||||
ShaderParameters shaderParameters;
|
||||
shaderParameters.texelSizeAtOneMeterWs =
|
||||
(2.0f * std::tan(outerConeAngle) / float(shadowMapInfo.shadowDimension));
|
||||
shaderParameters.lightFromWorldZ = -transpose(Mv)[2]; // negate because camera looks in -Z
|
||||
|
||||
if (!shadowMapInfo.vsm) {
|
||||
@@ -473,9 +449,9 @@ ShadowMap::ShaderParameters ShadowMap::updateSpot(FEngine& engine,
|
||||
shaderParameters.lightSpace = computeVsmLightSpaceMatrix(St, Mv, nearPlane, farPlane);
|
||||
}
|
||||
|
||||
const float3 direction = -transpose(Mv)[2].xyz;
|
||||
const float constantBias = shadowMapInfo.vsm ? 0.0f : params.options.constantBias;
|
||||
const mat4f b = mat4f::translation(direction * constantBias);
|
||||
const mat4f Sb = S * b;
|
||||
|
||||
// It's important to set the light camera's model matrix separately from its projection, so that
|
||||
// the cameraPosition uniform gets set correctly.
|
||||
@@ -488,19 +464,44 @@ ShadowMap::ShaderParameters ShadowMap::updateSpot(FEngine& engine,
|
||||
mCamera->setModelMatrix(mat4{ FCamera::rigidTransformInverse(Mv * b) });
|
||||
mCamera->setCustomProjection(mat4(Mp), nearPlane, farPlane);
|
||||
|
||||
// for the debug camera, we need to undo the world origin
|
||||
mDebugCamera->setCustomProjection(mat4(Sb * camera.worldOrigin), nearPlane, radius);
|
||||
|
||||
return shaderParameters;
|
||||
}
|
||||
|
||||
ShadowMap::ShaderParameters ShadowMap::updateSpot(FEngine& engine,
|
||||
const FScene::LightSoa& lightData, size_t index,
|
||||
filament::CameraInfo const& camera,
|
||||
const ShadowMapInfo& shadowMapInfo,
|
||||
FScene const& scene, SceneInfo sceneInfo) noexcept {
|
||||
|
||||
auto& lcm = engine.getLightManager();
|
||||
auto position = lightData.elementAt<FScene::POSITION_RADIUS>(index).xyz;
|
||||
auto direction = lightData.elementAt<FScene::DIRECTION>(index);
|
||||
auto radius = lightData.elementAt<FScene::POSITION_RADIUS>(index).w;
|
||||
auto li = lightData.elementAt<FScene::LIGHT_INSTANCE>(index);
|
||||
const FLightManager::ShadowParams& params = lcm.getShadowParams(li);
|
||||
const mat4f Mv = getDirectionalLightViewMatrix(direction, position);
|
||||
|
||||
// find decent near/far
|
||||
ShadowMap::updateSceneInfoSpot(Mv, scene, sceneInfo);
|
||||
|
||||
// if the scene was empty, near > far
|
||||
mHasVisibleShadows = -sceneInfo.lsNearFar[0] < -sceneInfo.lsNearFar[1];
|
||||
if (!mHasVisibleShadows) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// FIXME: we need a configuration for minimum near plane (for now hardcoded to 1cm)
|
||||
float nearPlane = std::max(0.01f, -sceneInfo.lsNearFar[0]);
|
||||
float farPlane = std::min(radius, -sceneInfo.lsNearFar[1]);
|
||||
auto outerConeAngle = lcm.getSpotLightOuterCone(li);
|
||||
return updateSpotOrPoint(Mv, outerConeAngle, nearPlane, farPlane, shadowMapInfo, params);
|
||||
}
|
||||
|
||||
ShadowMap::ShaderParameters ShadowMap::updatePoint(FEngine& engine,
|
||||
const FScene::LightSoa& lightData, size_t index,
|
||||
filament::CameraInfo const& camera, const ShadowMapInfo& shadowMapInfo, FScene const& scene,
|
||||
SceneInfo, uint8_t face) noexcept {
|
||||
|
||||
ShaderParameters shaderParameters;
|
||||
|
||||
// check if this shadow map has anything to render
|
||||
mHasVisibleShadows = false;
|
||||
FScene::RenderableSoa const& UTILS_RESTRICT soa = scene.getRenderableData();
|
||||
@@ -513,53 +514,16 @@ ShadowMap::ShaderParameters ShadowMap::updatePoint(FEngine& engine,
|
||||
}
|
||||
}
|
||||
if (!mHasVisibleShadows) {
|
||||
return shaderParameters;
|
||||
return {};
|
||||
}
|
||||
|
||||
auto& lcm = engine.getLightManager();
|
||||
|
||||
auto li = lightData.elementAt<FScene::LIGHT_INSTANCE>(index);
|
||||
auto position = lightData.elementAt<FScene::POSITION_RADIUS>(index).xyz;
|
||||
auto radius = lightData.elementAt<FScene::POSITION_RADIUS>(index).w;
|
||||
auto li = lightData.elementAt<FScene::LIGHT_INSTANCE>(index);
|
||||
const FLightManager::ShadowParams& params = lcm.getShadowParams(li);
|
||||
|
||||
/*
|
||||
* Compute the light model matrix.
|
||||
*/
|
||||
|
||||
const mat4f Mv = getPointLightViewMatrix(TextureCubemapFace(face), position);
|
||||
const float3 direction = -transpose(Mv)[2].xyz;
|
||||
|
||||
// TODO: don't hardcode near plane
|
||||
// Choose a reasonable value for the near plane.
|
||||
float nearPlane = 0.01f;
|
||||
float farPlane = radius;
|
||||
const mat4f Mp = mat4f::perspective(90.0f, 1.0f, nearPlane, farPlane);
|
||||
|
||||
// For calculating the point light normal bias, we need the texel size in world space at the
|
||||
// sample location. Using Thales's theorem, we find:
|
||||
// texelSize(zInLightSpace) = zInLightSpace * texelSizeOnTheNearPlane / near
|
||||
// = zInLightSpace * texelSizeAtOneMeter
|
||||
// = zInLightSpace * (2*tan(halfConeAngle)/dimension)
|
||||
// Note: this would not work with LISPSM, which warps the texture space.
|
||||
shaderParameters.texelSizeAtOneMeterWs =
|
||||
(2.0f * std::tan(f::PI_4) / float(shadowMapInfo.shadowDimension));
|
||||
|
||||
const float constantBias = shadowMapInfo.vsm ? 0.0f : params.options.constantBias;
|
||||
const mat4f b = mat4f::translation(direction * constantBias);
|
||||
|
||||
// It's important to set the light camera's model matrix separately from its projection, so that
|
||||
// the cameraPosition uniform gets set correctly.
|
||||
// mLightSpace is used in the shader to access the shadow map texture, and has the model matrix
|
||||
// baked in.
|
||||
|
||||
// The model matrix below is in fact inverted to get the view matrix and passed to the
|
||||
// shader as 'viewFromWorldMatrix', and is used in the VSM case to compute the depth metric.
|
||||
// (see depth_main.fs). Note that in the case of VSM, 'b' below is identity.
|
||||
mCamera->setModelMatrix(mat4{ FCamera::rigidTransformInverse(Mv * b) });
|
||||
mCamera->setCustomProjection(mat4(Mp), nearPlane, farPlane);
|
||||
|
||||
return shaderParameters;
|
||||
return updateSpotOrPoint(Mv, 45.0f * f::DEG_TO_RAD, 0.01f, radius, shadowMapInfo, params);
|
||||
}
|
||||
|
||||
mat4f ShadowMap::applyLISPSM(mat4f& Wp,
|
||||
@@ -1179,6 +1143,8 @@ void ShadowMap::visitScene(const FScene& scene, uint32_t visibleLayers,
|
||||
|
||||
void ShadowMap::initSceneInfo(ShadowMap::SceneInfo& sceneInfo,
|
||||
uint8_t visibleLayers, FScene const& scene, mat4f const& viewMatrix) {
|
||||
sceneInfo.csNearFar = { -1.0f, 1.0f };
|
||||
sceneInfo.lsNearFar = {};
|
||||
sceneInfo.visibleLayers = visibleLayers;
|
||||
sceneInfo.vsNearFar = { std::numeric_limits<float>::lowest(), std::numeric_limits<float>::max() };
|
||||
|
||||
@@ -1238,4 +1204,60 @@ void ShadowMap::updateSceneInfoSpot(mat4f const& Mv, FScene const& scene,
|
||||
);
|
||||
}
|
||||
|
||||
filament::Viewport ShadowMap::getViewport() const noexcept {
|
||||
// We set a viewport with a 1-texel border for when we index outside the
|
||||
// texture.
|
||||
// DON'T CHANGE this unless ShadowMap::getTextureCoordsMapping() is updated too.
|
||||
// see: ShadowMap::getTextureCoordsMapping()
|
||||
//
|
||||
// For floating-point depth textures, the 1-texel border could be set to
|
||||
// FLOAT_MAX to avoid clamping in the shadow shader (see sampleDepth inside
|
||||
// shadowing.fs). Unfortunately, the APIs don't seem let us clear depth
|
||||
// attachments to anything greater than 1.0, so we'd need a way to do this other
|
||||
// than clearing.
|
||||
const uint32_t dim = mOptions->mapSize;
|
||||
if (isPointShadow()) {
|
||||
// for point-light we don't have a border
|
||||
return { 0, 0, dim, dim };
|
||||
} else {
|
||||
return { 1, 1, dim - 2, dim - 2 };
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
void ShadowMap::prepareCamera(Transaction const& transaction,
|
||||
FEngine& engine, const CameraInfo& cameraInfo) noexcept {
|
||||
PerShadowMapUniforms::prepareCamera(transaction, engine, cameraInfo);
|
||||
PerShadowMapUniforms::prepareLodBias(transaction, 0.0f);
|
||||
}
|
||||
|
||||
void ShadowMap::prepareViewport(Transaction const& transaction,
|
||||
const filament::Viewport& viewport) noexcept {
|
||||
PerShadowMapUniforms::prepareViewport(transaction, viewport, 0, 0);
|
||||
}
|
||||
|
||||
void ShadowMap::prepareTime(Transaction const& transaction,
|
||||
FEngine& engine, math::float4 const& userTime) noexcept {
|
||||
PerShadowMapUniforms::prepareTime(transaction, engine, userTime);
|
||||
}
|
||||
|
||||
void ShadowMap::prepareShadowMapping(Transaction const& transaction,
|
||||
bool highPrecision) noexcept {
|
||||
PerShadowMapUniforms::prepareShadowMapping(transaction, highPrecision);
|
||||
}
|
||||
|
||||
PerShadowMapUniforms::Transaction ShadowMap::open(DriverApi& driver) noexcept {
|
||||
return PerShadowMapUniforms::open(driver);
|
||||
}
|
||||
|
||||
void ShadowMap::commit(Transaction& transaction,
|
||||
backend::DriverApi& driver) const noexcept {
|
||||
mPerShadowMapUniforms.commit(transaction, driver);
|
||||
}
|
||||
|
||||
void ShadowMap::bind(backend::DriverApi& driver) const noexcept {
|
||||
mPerShadowMapUniforms.bind(driver);
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -19,12 +19,14 @@
|
||||
|
||||
#include "components/LightManager.h"
|
||||
|
||||
#include "PerShadowMapUniforms.h"
|
||||
|
||||
#include "details/Camera.h"
|
||||
#include "details/Scene.h"
|
||||
|
||||
#include "backend/DriverApiForward.h"
|
||||
#include "private/backend/SamplerGroup.h"
|
||||
#include "math/mat4.h"
|
||||
#include "private/backend/DriverApi.h"
|
||||
|
||||
#include <filament/Viewport.h>
|
||||
|
||||
#include <math/mat4.h>
|
||||
#include <math/vec4.h>
|
||||
@@ -122,7 +124,7 @@ public:
|
||||
static math::mat4f getPointLightViewMatrix(backend::TextureCubemapFace face,
|
||||
math::float3 position) noexcept;
|
||||
|
||||
void initialize(size_t lightIndex, ShadowType shadowType, uint16_t shadowIndex,
|
||||
void initialize(size_t lightIndex, ShadowType shadowType, uint16_t shadowIndex, uint8_t face,
|
||||
LightManager::ShadowOptions const* options);
|
||||
|
||||
struct ShaderParameters {
|
||||
@@ -172,6 +174,8 @@ public:
|
||||
static void updateSceneInfoSpot(const math::mat4f& Mv, FScene const& scene,
|
||||
SceneInfo& sceneInfo);
|
||||
|
||||
filament::Viewport getViewport() const noexcept;
|
||||
|
||||
LightManager::ShadowOptions const* getShadowOptions() const noexcept { return mOptions; }
|
||||
size_t getLightIndex() const { return mLightIndex; }
|
||||
uint16_t getShadowIndex() const { return mShadowIndex; }
|
||||
@@ -181,6 +185,22 @@ public:
|
||||
bool isSpotShadow() const noexcept { return mShadowType == ShadowType::SPOT; }
|
||||
bool isPointShadow() const noexcept { return mShadowType == ShadowType::POINT; }
|
||||
ShadowType getShadowType() const noexcept { return mShadowType; }
|
||||
uint8_t getFace() const noexcept { return mFace; }
|
||||
|
||||
using Transaction = PerShadowMapUniforms::Transaction;
|
||||
|
||||
static void prepareCamera(Transaction const& transaction,
|
||||
FEngine& engine, const CameraInfo& cameraInfo) noexcept;
|
||||
static void prepareViewport(Transaction const& transaction,
|
||||
const filament::Viewport& viewport) noexcept;
|
||||
static void prepareTime(Transaction const& transaction,
|
||||
FEngine& engine, math::float4 const& userTime) noexcept;
|
||||
static void prepareShadowMapping(Transaction const& transaction,
|
||||
bool highPrecision) noexcept;
|
||||
static PerShadowMapUniforms::Transaction open(backend::DriverApi& driver) noexcept;
|
||||
void commit(Transaction& transaction,
|
||||
backend::DriverApi& driver) const noexcept;
|
||||
void bind(backend::DriverApi& driver) const noexcept;
|
||||
|
||||
private:
|
||||
struct Segment {
|
||||
@@ -194,6 +214,11 @@ private:
|
||||
// 8 corners, 12 segments w/ 2 intersection max -- all of this twice (8 + 12 * 2) * 2 (768 bytes)
|
||||
using FrustumBoxIntersection = std::array<math::float3, 64>;
|
||||
|
||||
ShaderParameters updateSpotOrPoint(
|
||||
math::mat4f const& Mv, float outerConeAngle, float nearPlane, float farPlane,
|
||||
const ShadowMapInfo& shadowMapInfo,
|
||||
const FLightManager::ShadowParams& params) noexcept;
|
||||
|
||||
static math::mat4f applyLISPSM(math::mat4f& Wp,
|
||||
filament::CameraInfo const& camera, FLightManager::ShadowParams const& params,
|
||||
const math::mat4f& LMpMv,
|
||||
@@ -278,8 +303,10 @@ private:
|
||||
{ 2, 6, 7, 3 }, // top
|
||||
};
|
||||
|
||||
FCamera* mCamera = nullptr; // 8
|
||||
FCamera* mDebugCamera = nullptr; // 8
|
||||
mutable PerShadowMapUniforms mPerShadowMapUniforms; // 4
|
||||
|
||||
FCamera* mCamera = nullptr; // 8
|
||||
FCamera* mDebugCamera = nullptr; // 8
|
||||
|
||||
// The data below technically belongs to ShadowMapManager, but it simplifies allocations
|
||||
// to store it here. This data is always associated with this shadow map anyway.
|
||||
@@ -287,8 +314,9 @@ private:
|
||||
uint32_t mLightIndex = 0; // which light are we shadowing // 4
|
||||
uint16_t mShadowIndex = 0; // our index in the shadowMap vector // 2
|
||||
uint8_t mLayer = 0; // our layer in the shadowMap texture // 1
|
||||
ShadowType mShadowType : 2;
|
||||
bool mHasVisibleShadows : 2;
|
||||
ShadowType mShadowType : 2; // :2
|
||||
bool mHasVisibleShadows : 2; // :2
|
||||
uint8_t mFace : 3; // :3
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
+116
-124
@@ -97,23 +97,39 @@ void ShadowMapManager::setDirectionalShadowMap(size_t lightIndex,
|
||||
LightManager::ShadowOptions const* options) noexcept {
|
||||
assert_invariant(options->shadowCascades <= CONFIG_MAX_SHADOW_CASCADES);
|
||||
for (size_t c = 0; c < options->shadowCascades; c++) {
|
||||
auto* pShadowMap = getCascadeShadowMap(c);
|
||||
pShadowMap->initialize(lightIndex, ShadowType::DIRECTIONAL, c, options);
|
||||
const size_t i = c;
|
||||
assert_invariant(i < CONFIG_MAX_SHADOW_CASCADES);
|
||||
auto* pShadowMap = getCascadeShadowMap(i);
|
||||
pShadowMap->initialize(lightIndex, ShadowType::DIRECTIONAL, i, 0, options);
|
||||
mCascadeShadowMaps.push_back(pShadowMap);
|
||||
}
|
||||
}
|
||||
|
||||
void ShadowMapManager::addShadowMap(size_t lightIndex, bool spotlight,
|
||||
LightManager::ShadowOptions const* options) noexcept {
|
||||
const size_t c = mSpotShadowMaps.size();
|
||||
assert_invariant(c < CONFIG_MAX_SHADOWMAP_PUNCTUAL);
|
||||
auto* pShadowMap = getPointOrSpotShadowMap(c);
|
||||
pShadowMap->initialize(lightIndex, spotlight ? ShadowType::SPOT : ShadowType::POINT, c, options);
|
||||
mSpotShadowMaps.push_back(pShadowMap);
|
||||
if (spotlight) {
|
||||
const size_t c = mSpotShadowMaps.size();
|
||||
const size_t i = c + CONFIG_MAX_SHADOW_CASCADES;
|
||||
assert_invariant(i < CONFIG_MAX_SHADOWMAPS);
|
||||
auto* pShadowMap = getPointOrSpotShadowMap(i);
|
||||
pShadowMap->initialize(lightIndex, ShadowType::SPOT, i, 0, options);
|
||||
mSpotShadowMaps.push_back(pShadowMap);
|
||||
} else {
|
||||
// point-light, generate 6 independent shadowmaps
|
||||
for (size_t face = 0; face < 6; face++) {
|
||||
const size_t c = mSpotShadowMaps.size();
|
||||
const size_t i = c + CONFIG_MAX_SHADOW_CASCADES;
|
||||
assert_invariant(i < CONFIG_MAX_SHADOWMAPS);
|
||||
auto* pShadowMap = getPointOrSpotShadowMap(i);
|
||||
pShadowMap->initialize(lightIndex, ShadowType::POINT, i, face, options);
|
||||
mSpotShadowMaps.push_back(pShadowMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine& engine,
|
||||
RenderPass const& pass, FView& view, CameraInfo const& mainCameraInfo) noexcept {
|
||||
FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FEngine& engine, FrameGraph& fg,
|
||||
RenderPass const& pass, FView& view, CameraInfo const& mainCameraInfo,
|
||||
float4 const& userTime) noexcept {
|
||||
|
||||
const float moment2 = std::numeric_limits<half>::max();
|
||||
const float moment1 = std::sqrt(moment2);
|
||||
@@ -132,12 +148,10 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine
|
||||
|
||||
struct PrepareShadowPassData {
|
||||
struct ShadowPass {
|
||||
mutable RenderPass pass;
|
||||
mutable CameraInfo cameraInfo;
|
||||
mutable RenderPass::Executor executor;
|
||||
ShadowMap* shadowMap;
|
||||
utils::Range<uint32_t> range;
|
||||
FScene::VisibleMaskType visibilityMask;
|
||||
uint8_t face = 0;
|
||||
};
|
||||
// the actual shadow map atlas (currently a 2D texture array)
|
||||
FrameGraphId<FrameGraphTexture> shadows;
|
||||
@@ -147,7 +161,7 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine
|
||||
|
||||
auto& prepareShadowPass = fg.addPass<PrepareShadowPassData>("Prepare Shadow Pass",
|
||||
[&](FrameGraph::Builder& builder, auto& data) {
|
||||
data.passList.reserve(CONFIG_MAX_SHADOW_LAYERS);
|
||||
data.passList.reserve(CONFIG_MAX_SHADOWMAPS);
|
||||
data.shadows = builder.createTexture("Shadowmap", {
|
||||
.width = textureRequirements.size, .height = textureRequirements.size,
|
||||
.depth = textureRequirements.layers,
|
||||
@@ -166,7 +180,7 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine
|
||||
// for the directional light, we already know if it has visible shadows.
|
||||
if (pShadowMap->hasVisibleShadows()) {
|
||||
passList.push_back({
|
||||
pass, {}, pShadowMap, directionalShadowCastersRange,
|
||||
{}, pShadowMap, directionalShadowCastersRange,
|
||||
VISIBLE_DIR_SHADOW_RENDERABLE });
|
||||
}
|
||||
}
|
||||
@@ -178,16 +192,8 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine
|
||||
for (auto* pShadowMap : mSpotShadowMaps) {
|
||||
assert_invariant(!pShadowMap->isDirectionalShadow());
|
||||
passList.push_back({
|
||||
pass, {}, pShadowMap, spotShadowCastersRange,
|
||||
{}, pShadowMap, spotShadowCastersRange,
|
||||
VISIBLE_DYN_SHADOW_RENDERABLE });
|
||||
if (pShadowMap->isPointShadow()) {
|
||||
// add the 5 extra faces
|
||||
for (uint8_t face = 1; face < 6; face++) {
|
||||
passList.push_back({
|
||||
pass, {}, pShadowMap, spotShadowCastersRange,
|
||||
VISIBLE_DYN_SHADOW_RENDERABLE, face });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,10 +203,8 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine
|
||||
// "read" from one of its resource (only writes), so the FrameGraph culls it.
|
||||
builder.sideEffect();
|
||||
},
|
||||
[this, &engine, &view, scene, &mainCameraInfo](
|
||||
[this, &engine, &view, scene, mainCameraInfo, userTime, passTemplate = pass](
|
||||
FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
|
||||
// set uniforms needed to render this ShadowMap
|
||||
view.prepareShadowMap(view.getVsmShadowOptions().highPrecision);
|
||||
|
||||
// Note: we could almost parallel_for the loop below, the problem currently is
|
||||
// that updatePrimitivesLod() updates temporary global state.
|
||||
@@ -215,7 +219,6 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine
|
||||
// for spot shadow map, we need to do the culling
|
||||
switch (shadowMap.getShadowType()) {
|
||||
case ShadowType::DIRECTIONAL:
|
||||
// nothing to do, it's been done already
|
||||
break;
|
||||
case ShadowType::SPOT:
|
||||
prepareSpotShadowMap(shadowMap, engine, view, mainCameraInfo,
|
||||
@@ -225,51 +228,60 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine
|
||||
case ShadowType::POINT:
|
||||
preparePointShadowMap(shadowMap, engine, view, mainCameraInfo,
|
||||
scene->getRenderableData(), entry.range,
|
||||
scene->getLightData(), entry.face, mSceneInfo);
|
||||
scene->getLightData(), mSceneInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
if (shadowMap.hasVisibleShadows()) {
|
||||
// TODO: this loop can generate a lot of commands. investigate if
|
||||
// we could compact or reduce the number of commands.
|
||||
// - we could move this into the execute of each pass, but
|
||||
// then we would have to update the UBO each time.
|
||||
// - we could also always use the same commands for all
|
||||
// shadow maps, but then we'd generate a lot of
|
||||
// unneeded draw call.
|
||||
// Note: this loop can generate a lot of commands that come out of the
|
||||
// "per frame command arena". The allocation persists until the
|
||||
// end of the frame.
|
||||
// One way to possibly mitigate this, would be to always use the
|
||||
// same command buffer for all shadow map, but then we'd generate
|
||||
// a lot of unneeded draw calls.
|
||||
// To do this efficiently, we'd need a way to cull draw calls already
|
||||
// recorded in the command buffer, per shadow map.
|
||||
|
||||
// generate and sort the commands for rendering the shadow map
|
||||
|
||||
// cameraInfo only valid after calling update
|
||||
const CameraInfo cameraInfo{ shadowMap.getCamera() };
|
||||
|
||||
auto transaction = ShadowMap::open(driver);
|
||||
ShadowMap::prepareCamera(transaction, engine, cameraInfo);
|
||||
ShadowMap::prepareViewport(transaction, shadowMap.getViewport());
|
||||
ShadowMap::prepareTime(transaction, engine, userTime);
|
||||
ShadowMap::prepareShadowMapping(transaction,
|
||||
view.getVsmShadowOptions().highPrecision);
|
||||
shadowMap.commit(transaction, driver);
|
||||
|
||||
// updatePrimitivesLod must be run before RenderPass::appendCommands.
|
||||
view.updatePrimitivesLod(engine,
|
||||
cameraInfo, scene->getRenderableData(), entry.range);
|
||||
|
||||
// generate and sort the commands for rendering the shadow map
|
||||
RenderPass pass(passTemplate);
|
||||
pass.setCamera(cameraInfo);
|
||||
pass.setVisibilityMask(entry.visibilityMask);
|
||||
pass.setGeometry(scene->getRenderableData(),
|
||||
entry.range, scene->getRenderableUBO());
|
||||
pass.appendCommands(engine, RenderPass::SHADOW);
|
||||
pass.sortCommands(engine);
|
||||
|
||||
entry.executor = pass.getExecutor();
|
||||
|
||||
if (!view.hasVSM()) {
|
||||
auto li = scene->getLightData().elementAt<FScene::LIGHT_INSTANCE>(
|
||||
shadowMap.getLightIndex());
|
||||
auto const& params = engine.getLightManager().getShadowParams(li);
|
||||
auto const* options = shadowMap.getShadowOptions();
|
||||
const PolygonOffset polygonOffset = { // handle reversed Z
|
||||
.slope = -params.options.polygonOffsetSlope,
|
||||
.constant = -params.options.polygonOffsetConstant
|
||||
.slope = -options->polygonOffsetSlope,
|
||||
.constant = -options->polygonOffsetConstant
|
||||
};
|
||||
entry.pass.overridePolygonOffset(&polygonOffset);
|
||||
entry.executor.overridePolygonOffset(&polygonOffset);
|
||||
}
|
||||
|
||||
constexpr const backend::Viewport disabledScissor{ 0, 0,
|
||||
(uint32_t)std::numeric_limits<int32_t>::max(),
|
||||
(uint32_t)std::numeric_limits<int32_t>::max() };
|
||||
|
||||
entry.pass.setCamera(cameraInfo);
|
||||
entry.pass.setVisibilityMask(entry.visibilityMask);
|
||||
entry.pass.setGeometry(scene->getRenderableData(),
|
||||
entry.range, scene->getRenderableUBO());
|
||||
entry.pass.overrideScissor(&disabledScissor);
|
||||
entry.pass.appendCommands(engine, RenderPass::SHADOW);
|
||||
entry.pass.sortCommands(engine);
|
||||
entry.cameraInfo = cameraInfo;
|
||||
entry.executor.overrideScissor(&disabledScissor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,8 +299,7 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine
|
||||
struct ShadowPassData {
|
||||
FrameGraphId<FrameGraphTexture> tempBlurSrc{}; // temporary shadowmap when blurring
|
||||
FrameGraphId<FrameGraphTexture> output;
|
||||
uint32_t blurRt{};
|
||||
uint32_t shadowRt{};
|
||||
uint32_t rt{};
|
||||
};
|
||||
|
||||
auto const& passList = prepareShadowPass.getData().passList;
|
||||
@@ -297,7 +308,7 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint8_t layer = entry.shadowMap->getLayer() + entry.face;
|
||||
const uint8_t layer = entry.shadowMap->getLayer();
|
||||
const auto* options = entry.shadowMap->getShadowOptions();
|
||||
|
||||
auto& shadowPass = fg.addPass<ShadowPassData>("Shadow Pass",
|
||||
@@ -346,7 +357,7 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine
|
||||
data.tempBlurSrc = builder.write(data.tempBlurSrc,
|
||||
FrameGraphTexture::Usage::COLOR_ATTACHMENT);
|
||||
|
||||
data.blurRt = builder.declareRenderPass("Temp Shadow RT", {
|
||||
data.rt = builder.declareRenderPass("Temp Shadow RT", {
|
||||
.attachments = {
|
||||
.color = { data.tempBlurSrc },
|
||||
.depth = depth },
|
||||
@@ -365,53 +376,30 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FrameGraph& fg, FEngine
|
||||
}
|
||||
|
||||
// finally, create the shadowmap render target -- one per layer.
|
||||
data.shadowRt = builder.declareRenderPass("Shadow RT", renderTargetDesc);
|
||||
auto rt = builder.declareRenderPass("Shadow RT", renderTargetDesc);
|
||||
|
||||
// render either directly into the shadowmap, or to the temporary texture for
|
||||
// blurring.
|
||||
data.rt = blur ? data.rt : rt;
|
||||
},
|
||||
[=, &engine, &entry, &view](FrameGraphResources const& resources,
|
||||
[=, &engine, &entry](FrameGraphResources const& resources,
|
||||
auto const& data, DriverApi& driver) {
|
||||
|
||||
// Note: we capture entry by reference here. That's actually okay because
|
||||
// `entry` lives in `PrepareShadowPassData` which is guaranteed to still
|
||||
// be alive when we execute here (all passes stay alive until the FrameGraph
|
||||
// is destroyed).
|
||||
// It wouldn't work to capture by copy because entry.pass wouldn't be
|
||||
// It wouldn't work to capture by copy because entry.executor wouldn't be
|
||||
// initialized, as this happens in an `execute` block.
|
||||
|
||||
CameraInfo const& cameraInfo = entry.cameraInfo;
|
||||
auto rt = resources.getRenderPassInfo(data.rt);
|
||||
rt.params.viewport = entry.shadowMap->getViewport();
|
||||
|
||||
const auto& executor = entry.pass.getExecutor();
|
||||
const bool blur = view.hasVSM() && options->vsm.blurWidth > 0.0f;
|
||||
|
||||
// set uniforms relative to the camera
|
||||
view.prepareCamera(cameraInfo);
|
||||
|
||||
// We set a viewport with a 1-texel border for when we index outside the
|
||||
// texture.
|
||||
// DON'T CHANGE this unless ShadowMap::getTextureCoordsMapping() is updated too.
|
||||
// see: ShadowMap::getTextureCoordsMapping()
|
||||
//
|
||||
// For floating-point depth textures, the 1-texel border could be set to
|
||||
// FLOAT_MAX to avoid clamping in the shadow shader (see sampleDepth inside
|
||||
// shadowing.fs). Unfortunately, the APIs don't seem let us clear depth
|
||||
// attachments to anything greater than 1.0, so we'd need a way to do this other
|
||||
// than clearing.
|
||||
const uint32_t dim = options->mapSize;
|
||||
filament::Viewport viewport{ 1, 1, dim - 2, dim - 2 };
|
||||
if (entry.shadowMap->isPointShadow()) {
|
||||
// for point-light we don't have a border
|
||||
viewport = { 0, 0, dim, dim };
|
||||
}
|
||||
|
||||
view.prepareViewport(viewport, 0, 0);
|
||||
|
||||
view.commitUniforms(driver);
|
||||
|
||||
// render either directly into the shadowmap, or to the temporary texture for
|
||||
// blurring.
|
||||
auto rt = resources.getRenderPassInfo(blur ? data.blurRt : data.shadowRt);
|
||||
rt.params.viewport = viewport;
|
||||
|
||||
executor.execute(engine, "Shadow Pass", rt.target, rt.params);
|
||||
engine.flush();
|
||||
driver.beginRenderPass(rt.target, rt.params);
|
||||
entry.shadowMap->bind(driver);
|
||||
entry.executor.execute(engine, "Shadow Pass");
|
||||
driver.endRenderPass();
|
||||
});
|
||||
|
||||
|
||||
@@ -471,7 +459,7 @@ ShadowMapManager::ShadowTechnique ShadowMapManager::updateCascadeShadowMaps(FEng
|
||||
// entire camera frustum, as if we only had a single cascade.
|
||||
ShadowMap& shadowMap = *mCascadeShadowMaps[0];
|
||||
|
||||
auto shaderParameters = shadowMap.updateDirectional(mEngine,
|
||||
shadowMap.updateDirectional(mEngine,
|
||||
lightData, 0, cameraInfo, shadowMapInfo, *scene, sceneInfo);
|
||||
|
||||
hasVisibleShadows = shadowMap.hasVisibleShadows();
|
||||
@@ -480,18 +468,6 @@ ShadowMapManager::ShadowTechnique ShadowMapManager::updateCascadeShadowMaps(FEng
|
||||
Frustum const& frustum = shadowMap.getCamera().getCullingFrustum();
|
||||
FView::cullRenderables(engine.getJobSystem(), renderableData, frustum,
|
||||
VISIBLE_DIR_SHADOW_RENDERABLE_BIT);
|
||||
|
||||
// Set shadowBias, using the first directional cascade.
|
||||
// when computing the required bias we need a half-texel size, so we multiply by 0.5 here.
|
||||
// note: normalBias is set to zero for VSM
|
||||
const float normalBias = shadowMapInfo.vsm ? 0.0f : 0.5f * lcm.getShadowNormalBias(0);
|
||||
// Texel size is constant for directional light (although that's not true when LISPSM
|
||||
// is used, but in that case we're pretending it is).
|
||||
const float wsTexelSize = shaderParameters.texelSizeAtOneMeterWs;
|
||||
mShadowMappingUniforms.shadowBias = normalBias * wsTexelSize;
|
||||
mShadowMappingUniforms.shadowBulbRadiusLs =
|
||||
mSoftShadowOptions.penumbraScale * options.shadowBulbRadius / wsTexelSize;
|
||||
mShadowMappingUniforms.elvsm = options.vsm.elvsm;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,6 +520,10 @@ ShadowMapManager::ShadowTechnique ShadowMapManager::updateCascadeShadowMaps(FEng
|
||||
|
||||
mShadowMappingUniforms.cascadeSplits = wsSplitPositionUniform;
|
||||
|
||||
// when computing the required bias we need a half-texel size, so we multiply by 0.5 here.
|
||||
// note: normalBias is set to zero for VSM
|
||||
const float normalBias = shadowMapInfo.vsm ? 0.0f : 0.5f * lcm.getShadowNormalBias(0);
|
||||
|
||||
for (size_t i = 0, c = mCascadeShadowMaps.size(); i < c; i++) {
|
||||
assert_invariant(mCascadeShadowMaps[i]);
|
||||
|
||||
@@ -557,7 +537,22 @@ ShadowMapManager::ShadowTechnique ShadowMapManager::updateCascadeShadowMaps(FEng
|
||||
lightData, 0, cameraInfo, shadowMapInfo, *scene, sceneInfo);
|
||||
|
||||
if (shadowMap.hasVisibleShadows()) {
|
||||
mShadowMappingUniforms.lightFromWorldMatrix[i] = shaderParameters.lightSpace;
|
||||
const size_t shadowIndex = shadowMap.getShadowIndex();
|
||||
assert_invariant(shadowIndex == i);
|
||||
|
||||
// Texel size is constant for directional light (although that's not true when LISPSM
|
||||
// is used, but in that case we're pretending it is).
|
||||
const float wsTexelSize = shaderParameters.texelSizeAtOneMeterWs;
|
||||
|
||||
auto& s = mShadowUb.edit();
|
||||
s.shadows[shadowIndex].layer = shadowMap.getLayer();
|
||||
s.shadows[shadowIndex].lightFromWorldMatrix = shaderParameters.lightSpace;
|
||||
s.shadows[shadowIndex].normalBias = normalBias * wsTexelSize;
|
||||
s.shadows[shadowIndex].texelSizeAtOneMeter = wsTexelSize;
|
||||
s.shadows[shadowIndex].elvsm = options.vsm.elvsm;
|
||||
s.shadows[shadowIndex].bulbRadiusLs =
|
||||
mSoftShadowOptions.penumbraScale * options.shadowBulbRadius / wsTexelSize;
|
||||
|
||||
shadowTechnique |= ShadowTechnique::SHADOW_MAP;
|
||||
cascadeHasVisibleShadows |= 0x1u << i;
|
||||
}
|
||||
@@ -685,6 +680,7 @@ void ShadowMapManager::prepareSpotShadowMap(ShadowMap& shadowMap,
|
||||
auto& s = mShadowUb.edit();
|
||||
const double n = shadowMap.getCamera().getNear();
|
||||
const double f = shadowMap.getCamera().getCullingFar();
|
||||
s.shadows[shadowIndex].layer = shadowMap.getLayer();
|
||||
s.shadows[shadowIndex].lightFromWorldMatrix = shaderParameters.lightSpace;
|
||||
s.shadows[shadowIndex].direction = direction;
|
||||
s.shadows[shadowIndex].normalBias = normalBias * wsTexelSizeAtOneMeter;
|
||||
@@ -694,16 +690,18 @@ void ShadowMapManager::prepareSpotShadowMap(ShadowMap& shadowMap,
|
||||
s.shadows[shadowIndex].elvsm = options->vsm.elvsm;
|
||||
s.shadows[shadowIndex].bulbRadiusLs =
|
||||
mSoftShadowOptions.penumbraScale * options->shadowBulbRadius
|
||||
/ wsTexelSizeAtOneMeter;
|
||||
/ wsTexelSizeAtOneMeter;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ShadowMapManager::preparePointShadowMap(ShadowMap& shadowMap,
|
||||
FEngine& engine, FView& view, CameraInfo const& mainCameraInfo,
|
||||
FScene::RenderableSoa& renderableData, utils::Range<uint32_t> range,
|
||||
FScene::LightSoa& lightData, uint8_t face,
|
||||
FScene::LightSoa& lightData,
|
||||
ShadowMap::SceneInfo const& sceneInfo) noexcept {
|
||||
|
||||
const uint8_t face = shadowMap.getFace();
|
||||
const size_t lightIndex = shadowMap.getLightIndex();
|
||||
FLightManager::ShadowOptions const* const options = shadowMap.getShadowOptions();
|
||||
|
||||
@@ -755,7 +753,6 @@ void ShadowMapManager::preparePointShadowMap(ShadowMap& shadowMap,
|
||||
|
||||
|
||||
// and if we need to generate it, update all the UBO data
|
||||
// Note: this below is done for all six faces even if it sets identical values each time
|
||||
if (shadowMap.hasVisibleShadows()) {
|
||||
const size_t shadowIndex = shadowMap.getShadowIndex();
|
||||
const float wsTexelSizeAtOneMeter = shaderParameters.texelSizeAtOneMeterWs;
|
||||
@@ -765,16 +762,11 @@ void ShadowMapManager::preparePointShadowMap(ShadowMap& shadowMap,
|
||||
auto& s = mShadowUb.edit();
|
||||
const double n = shadowMap.getCamera().getNear();
|
||||
const double f = shadowMap.getCamera().getCullingFar();
|
||||
|
||||
s.shadows[shadowIndex].lightFromWorldMatrix = {}; // no texture matrix for point lights
|
||||
s.shadows[shadowIndex].layer = shadowMap.getLayer();
|
||||
s.shadows[shadowIndex].lightFromWorldMatrix = shaderParameters.lightSpace;
|
||||
s.shadows[shadowIndex].direction = {}; // no direction of point lights
|
||||
s.shadows[shadowIndex].normalBias = normalBias * wsTexelSizeAtOneMeter;
|
||||
s.shadows[shadowIndex].lightFromWorldZ = {
|
||||
-((n + f) / (f - n)) * 0.5f + 0.5f,
|
||||
(f * n) / (f - n),
|
||||
-n / (f - n),
|
||||
1.0f / (f - n),
|
||||
};
|
||||
s.shadows[shadowIndex].lightFromWorldZ = shaderParameters.lightFromWorldZ;
|
||||
s.shadows[shadowIndex].texelSizeAtOneMeter = wsTexelSizeAtOneMeter;
|
||||
s.shadows[shadowIndex].nearOverFarMinusNear = float(n / (f - n));
|
||||
s.shadows[shadowIndex].elvsm = options->vsm.elvsm;
|
||||
@@ -794,9 +786,13 @@ ShadowMapManager::ShadowTechnique ShadowMapManager::updateSpotShadowMaps(FEngine
|
||||
shadowTechnique |= ShadowTechnique::SHADOW_MAP;
|
||||
for (auto const* pShadowMap : mSpotShadowMaps) {
|
||||
const size_t lightIndex = pShadowMap->getLightIndex();
|
||||
shadowInfo[lightIndex].castsShadows = true; // FIXME: is that set correctly?
|
||||
shadowInfo[lightIndex].index = pShadowMap->getShadowIndex();
|
||||
shadowInfo[lightIndex].layer = pShadowMap->getLayer();
|
||||
// gather the per-light (not per shadow map) information. For point lights we will
|
||||
// "see" 6 shadowmaps (one per face), we must use the first face one, the shader
|
||||
// knows how to find the entry for other faces (they're guaranteed to be sequential).
|
||||
if (pShadowMap->getFace() == 0) {
|
||||
shadowInfo[lightIndex].castsShadows = true; // FIXME: is that set correctly?
|
||||
shadowInfo[lightIndex].index = pShadowMap->getShadowIndex();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,10 +833,6 @@ void ShadowMapManager::calculateTextureRequirements(FEngine& engine, FView& view
|
||||
maxDimension = std::max(maxDimension, options->mapSize);
|
||||
elvsm = elvsm || options->vsm.elvsm;
|
||||
pShadowMap->setLayer(layer++);
|
||||
if (pShadowMap->isPointShadow()) {
|
||||
// FIXME: we need to make sure we don't exceed 256
|
||||
layer += 5;
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t layersNeeded = layer;
|
||||
|
||||
@@ -45,14 +45,10 @@ class FrameGraph;
|
||||
class RenderPass;
|
||||
|
||||
struct ShadowMappingUniforms {
|
||||
std::array<math::mat4f, CONFIG_MAX_SHADOW_CASCADES> lightFromWorldMatrix;
|
||||
math::float4 cascadeSplits;
|
||||
float shadowBulbRadiusLs;
|
||||
float shadowBias;
|
||||
float ssContactShadowDistance;
|
||||
uint32_t directionalShadows;
|
||||
uint32_t cascades;
|
||||
bool elvsm;
|
||||
};
|
||||
|
||||
class ShadowMapManager {
|
||||
@@ -90,8 +86,8 @@ public:
|
||||
FScene::RenderableSoa& renderableData, FScene::LightSoa& lightData) noexcept;
|
||||
|
||||
// Renders all the shadow maps.
|
||||
FrameGraphId<FrameGraphTexture> render(FrameGraph& fg, FEngine& engine,
|
||||
RenderPass const& pass, FView& view, CameraInfo const& mainCameraInfo) noexcept;
|
||||
FrameGraphId<FrameGraphTexture> render(FEngine& engine, FrameGraph& fg, RenderPass const& pass,
|
||||
FView& view, CameraInfo const& mainCameraInfo, math::float4 const& userTime) noexcept;
|
||||
|
||||
ShadowMap* getCascadeShadowMap(size_t cascade) noexcept {
|
||||
assert_invariant(cascade < CONFIG_MAX_SHADOW_CASCADES);
|
||||
@@ -103,9 +99,9 @@ public:
|
||||
}
|
||||
|
||||
ShadowMap* getPointOrSpotShadowMap(size_t index) noexcept {
|
||||
assert_invariant(index < CONFIG_MAX_SHADOWMAP_PUNCTUAL);
|
||||
assert_invariant(index < CONFIG_MAX_SHADOWMAPS);
|
||||
return std::launder(reinterpret_cast<ShadowMap*>(
|
||||
&mShadowMapCache[CONFIG_MAX_SHADOW_CASCADES + index]));
|
||||
&mShadowMapCache[index]));
|
||||
}
|
||||
|
||||
ShadowMap const* getPointOrSpotShadowMap(size_t spot) const noexcept {
|
||||
@@ -140,7 +136,7 @@ private:
|
||||
void preparePointShadowMap(ShadowMap& map,
|
||||
FEngine& engine, FView& view, CameraInfo const& mainCameraInfo,
|
||||
FScene::RenderableSoa& renderableData, utils::Range<uint32_t> range,
|
||||
FScene::LightSoa& lightData, uint8_t face,
|
||||
FScene::LightSoa& lightData,
|
||||
ShadowMap::SceneInfo const& sceneInfo) noexcept;
|
||||
|
||||
static void updateSpotVisibilityMasks(
|
||||
@@ -205,7 +201,7 @@ private:
|
||||
mutable TypedUniformBuffer<ShadowUib> mShadowUb;
|
||||
backend::Handle<backend::HwBufferObject> mShadowUbh;
|
||||
|
||||
ShadowMappingUniforms mShadowMappingUniforms;
|
||||
ShadowMappingUniforms mShadowMappingUniforms = {};
|
||||
|
||||
ShadowMap::SceneInfo mSceneInfo;
|
||||
|
||||
@@ -215,13 +211,13 @@ private:
|
||||
|
||||
utils::FixedCapacityVector<ShadowMap*> mSpotShadowMaps{
|
||||
utils::FixedCapacityVector<ShadowMap*>::with_capacity(
|
||||
CONFIG_MAX_SHADOWMAP_PUNCTUAL) };
|
||||
CONFIG_MAX_SHADOWMAPS - CONFIG_MAX_SHADOW_CASCADES) };
|
||||
|
||||
// inline storage for all our ShadowMap objects, we can't easily use a std::array<> directly.
|
||||
// because ShadowMap doesn't have a default ctor, and we avoid out-of-line allocations.
|
||||
// Each ShadowMap is currently 32 bytes.
|
||||
// Each ShadowMap is currently 40 bytes (total of 2.5KB for 64 shadow maps)
|
||||
using ShadowMapStorage = std::aligned_storage<sizeof(ShadowMap), alignof(ShadowMap)>::type;
|
||||
std::array<ShadowMapStorage, CONFIG_MAX_SHADOW_LAYERS> mShadowMapCache;
|
||||
std::array<ShadowMapStorage, CONFIG_MAX_SHADOWMAPS> mShadowMapCache;
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
// return if any uniform has been changed
|
||||
bool isDirty() const noexcept { return mSomethingDirty; }
|
||||
|
||||
// mark the whole buffer as clean (no modified uniforms)
|
||||
// mark the whole buffer as "clean" (no modified uniforms)
|
||||
void clean() const noexcept { mSomethingDirty = false; }
|
||||
|
||||
// helper functions
|
||||
|
||||
@@ -747,4 +747,8 @@ bool FRenderableManager::getLightChannel(Instance ci, unsigned int channel) cons
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t FRenderableManager::getPrimitiveCount(Instance instance, uint8_t level) const noexcept {
|
||||
return getRenderPrimitives(instance, level).size();
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -160,7 +160,7 @@ public:
|
||||
}
|
||||
|
||||
inline size_t getLevelCount(Instance) const noexcept { return 1; }
|
||||
inline size_t getPrimitiveCount(Instance instance, uint8_t level) const noexcept;
|
||||
size_t getPrimitiveCount(Instance instance, uint8_t level) const noexcept;
|
||||
void setMaterialInstanceAt(Instance instance, uint8_t level,
|
||||
size_t primitiveIndex, FMaterialInstance const* materialInstance);
|
||||
MaterialInstance* getMaterialInstanceAt(Instance instance, uint8_t level, size_t primitiveIndex) const noexcept;
|
||||
@@ -411,10 +411,6 @@ utils::Slice<FRenderableManager::MorphTargets>& FRenderableManager::getMorphTarg
|
||||
return mManager[instance].morphTargets;
|
||||
}
|
||||
|
||||
size_t FRenderableManager::getPrimitiveCount(Instance instance, uint8_t level) const noexcept {
|
||||
return getRenderPrimitives(instance, level).size();
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_COMPONENTS_RENDERABLEMANAGER_H
|
||||
|
||||
@@ -258,12 +258,6 @@ uint32_t FEngine::getJobSystemThreadPoolSize() noexcept {
|
||||
void FEngine::init() {
|
||||
SYSTRACE_CALL();
|
||||
|
||||
#if FILAMENT_ENABLE_FGDBG
|
||||
if (!debug.fgdbg) {
|
||||
debug.fgdbg = std::make_unique<fgdbg::DebugServer>();
|
||||
}
|
||||
#endif
|
||||
|
||||
// this must be first.
|
||||
assert_invariant( intptr_t(&mDriverApiStorage) % alignof(DriverApi) == 0 );
|
||||
::new(&mDriverApiStorage) DriverApi(*mDriver, mCommandBufferQueue.getCircularBuffer());
|
||||
@@ -612,16 +606,16 @@ int FEngine::loop() {
|
||||
#endif
|
||||
if (portString != nullptr) {
|
||||
const int port = atoi(portString);
|
||||
debug.matdbg = std::make_unique<matdbg::DebugServer>(mBackend, port);
|
||||
debug.server = new matdbg::DebugServer(mBackend, port);
|
||||
|
||||
// Sometimes the server can fail to spin up (e.g. if the above port is already in use).
|
||||
// When this occurs, carry onward, developers can look at civetweb.txt for details.
|
||||
if (!debug.matdbg->isReady()) {
|
||||
delete debug.matdbg.get();
|
||||
debug.matdbg = nullptr;
|
||||
if (!debug.server->isReady()) {
|
||||
delete debug.server;
|
||||
debug.server = nullptr;
|
||||
} else {
|
||||
debug.matdbg->setEditCallback(FMaterial::onEditCallback);
|
||||
debug.matdbg->setQueryCallback(FMaterial::onQueryCallback);
|
||||
debug.server->setEditCallback(FMaterial::onEditCallback);
|
||||
debug.server->setQueryCallback(FMaterial::onQueryCallback);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -646,16 +640,6 @@ int FEngine::loop() {
|
||||
uint32_t id = std::thread::hardware_concurrency() - 1;
|
||||
|
||||
while (true) {
|
||||
#if FILAMENT_ENABLE_FGDBG
|
||||
// TODO (@feresr): Only for testing purposes, remove
|
||||
if (debug.fgdbg) {
|
||||
static int fgdbgMessage = 0;
|
||||
fgdbgMessage++;
|
||||
if (fgdbgMessage % 100 == 0) {
|
||||
debug.fgdbg->sendMessage(fgdbgMessage/100);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// looks like thread affinity needs to be reset regularly (on Android)
|
||||
JobSystem::setThreadAffinityById(id);
|
||||
if (!execute()) {
|
||||
|
||||
@@ -57,14 +57,6 @@
|
||||
#include <filament/Texture.h>
|
||||
#include <filament/VertexBuffer.h>
|
||||
|
||||
#if FILAMENT_ENABLE_FGDBG
|
||||
#include <fgdbg/DebugServer.h>
|
||||
#else
|
||||
namespace filament::fgdbg {
|
||||
class DebugServer;
|
||||
} // namespace filament::fgdbg
|
||||
#endif
|
||||
|
||||
#if FILAMENT_ENABLE_MATDBG
|
||||
#include <matdbg/DebugServer.h>
|
||||
#else
|
||||
@@ -527,8 +519,7 @@ public:
|
||||
// capture to file. At the moment, only supported by the Metal backend.
|
||||
bool doFrameCapture = false;
|
||||
} renderer;
|
||||
std::unique_ptr<matdbg::DebugServer> matdbg = nullptr;
|
||||
std::unique_ptr<fgdbg::DebugServer> fgdbg = nullptr;
|
||||
matdbg::DebugServer* server = nullptr;
|
||||
} debug;
|
||||
};
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder)
|
||||
|
||||
#if FILAMENT_ENABLE_MATDBG
|
||||
// Register the material with matdbg.
|
||||
matdbg::DebugServer* server = downcast(engine).debug.matdbg.get();
|
||||
matdbg::DebugServer* server = downcast(engine).debug.server;
|
||||
if (UTILS_UNLIKELY(server)) {
|
||||
auto details = builder.mImpl;
|
||||
mDebuggerId = server->addMaterial(mName, details->mPayload, details->mSize, this);
|
||||
@@ -319,7 +319,7 @@ void FMaterial::terminate(FEngine& engine) {
|
||||
|
||||
#if FILAMENT_ENABLE_MATDBG
|
||||
// Unregister the material with matdbg.
|
||||
matdbg::DebugServer* server = downcast(mEngine).debug.matdbg.get();
|
||||
matdbg::DebugServer* server = downcast(mEngine).debug.server;
|
||||
if (UTILS_UNLIKELY(server)) {
|
||||
server->removeMaterial(mDebuggerId);
|
||||
}
|
||||
@@ -442,9 +442,15 @@ Program FMaterial::getProgramBuilderWithVariants(
|
||||
}
|
||||
}
|
||||
|
||||
int platformId = 0;
|
||||
#if defined(IOS)
|
||||
platformId = 1;
|
||||
#endif
|
||||
|
||||
program.specializationConstants({
|
||||
{ 0, (int)mEngine.getSupportedFeatureLevel() },
|
||||
{ 1, (int)CONFIG_MAX_INSTANCES }
|
||||
{ 1, (int)CONFIG_MAX_INSTANCES },
|
||||
{ 2, platformId }
|
||||
});
|
||||
|
||||
return program;
|
||||
|
||||
@@ -35,17 +35,30 @@ namespace filament {
|
||||
|
||||
using namespace backend;
|
||||
|
||||
FMaterialInstance::FMaterialInstance() noexcept = default;
|
||||
FMaterialInstance::FMaterialInstance() noexcept
|
||||
: mCulling(CullingMode::BACK),
|
||||
mDepthFunc(RasterState::DepthFunc::LE),
|
||||
mColorWrite(false),
|
||||
mDepthWrite(false),
|
||||
mHasScissor(false),
|
||||
mIsDoubleSided(false),
|
||||
mTransparencyMode(TransparencyMode::DEFAULT) {
|
||||
}
|
||||
|
||||
FMaterialInstance::FMaterialInstance(FEngine& engine,
|
||||
FMaterialInstance const* other, const char* name)
|
||||
: mMaterial(other->mMaterial),
|
||||
mPolygonOffset(other->mPolygonOffset),
|
||||
mStencilState(other->mStencilState),
|
||||
mMaskThreshold(other->mMaskThreshold),
|
||||
mSpecularAntiAliasingVariance(other->mSpecularAntiAliasingVariance),
|
||||
mSpecularAntiAliasingThreshold(other->mSpecularAntiAliasingThreshold),
|
||||
mCulling(other->mCulling),
|
||||
mDepthFunc(other->mDepthFunc),
|
||||
mColorWrite(other->mColorWrite),
|
||||
mDepthWrite(other->mDepthWrite),
|
||||
mStencilState(other->mStencilState),
|
||||
mDepthFunc(other->mDepthFunc),
|
||||
mHasScissor(false),
|
||||
mIsDoubleSided(other->mIsDoubleSided),
|
||||
mScissorRect(other->mScissorRect),
|
||||
mName(name ? CString(name) : other->mName) {
|
||||
|
||||
@@ -63,10 +76,23 @@ FMaterialInstance::FMaterialInstance(FEngine& engine,
|
||||
mSbHandle = driver.createSamplerGroup(mSamplers.getSize());
|
||||
}
|
||||
|
||||
mMaterialSortingKey = RenderPass::makeMaterialSortingKey(
|
||||
material->getId(), material->generateMaterialInstanceId());
|
||||
if (material->hasDoubleSidedCapability()) {
|
||||
setDoubleSided(mIsDoubleSided);
|
||||
}
|
||||
|
||||
if (material->getBlendingMode() == BlendingMode::MASKED) {
|
||||
setMaskThreshold(mMaskThreshold);
|
||||
}
|
||||
|
||||
if (material->hasSpecularAntiAliasing()) {
|
||||
setSpecularAntiAliasingThreshold(mSpecularAntiAliasingThreshold);
|
||||
setSpecularAntiAliasingVariance(mSpecularAntiAliasingVariance);
|
||||
}
|
||||
|
||||
setTransparencyMode(material->getTransparencyMode());
|
||||
|
||||
mMaterialSortingKey = RenderPass::makeMaterialSortingKey(
|
||||
material->getId(), material->generateMaterialInstanceId());
|
||||
}
|
||||
|
||||
FMaterialInstance* FMaterialInstance::duplicate(
|
||||
@@ -183,14 +209,29 @@ void FMaterialInstance::setParameterImpl(std::string_view name,
|
||||
|
||||
void FMaterialInstance::setMaskThreshold(float threshold) noexcept {
|
||||
setParameter("_maskThreshold", math::saturate(threshold));
|
||||
mMaskThreshold = math::saturate(threshold);
|
||||
}
|
||||
|
||||
float FMaterialInstance::getMaskThreshold() const noexcept {
|
||||
return mMaskThreshold;
|
||||
}
|
||||
|
||||
void FMaterialInstance::setSpecularAntiAliasingVariance(float variance) noexcept {
|
||||
setParameter("_specularAntiAliasingVariance", math::saturate(variance));
|
||||
mSpecularAntiAliasingVariance = math::saturate(variance);
|
||||
}
|
||||
|
||||
float FMaterialInstance::getSpecularAntiAliasingVariance() const noexcept {
|
||||
return mSpecularAntiAliasingVariance;
|
||||
}
|
||||
|
||||
void FMaterialInstance::setSpecularAntiAliasingThreshold(float threshold) noexcept {
|
||||
setParameter("_specularAntiAliasingThreshold", math::saturate(threshold * threshold));
|
||||
mSpecularAntiAliasingThreshold = std::sqrt(math::saturate(threshold * threshold));
|
||||
}
|
||||
|
||||
float FMaterialInstance::getSpecularAntiAliasingThreshold() const noexcept {
|
||||
return mSpecularAntiAliasingThreshold;
|
||||
}
|
||||
|
||||
void FMaterialInstance::setDoubleSided(bool doubleSided) noexcept {
|
||||
@@ -202,6 +243,11 @@ void FMaterialInstance::setDoubleSided(bool doubleSided) noexcept {
|
||||
if (doubleSided) {
|
||||
setCullingMode(CullingMode::NONE);
|
||||
}
|
||||
mIsDoubleSided = doubleSided;
|
||||
}
|
||||
|
||||
bool FMaterialInstance::isDoubleSided() const noexcept {
|
||||
return mIsDoubleSided;
|
||||
}
|
||||
|
||||
void FMaterialInstance::setTransparencyMode(TransparencyMode mode) noexcept {
|
||||
@@ -212,6 +258,10 @@ void FMaterialInstance::setDepthCulling(bool enable) noexcept {
|
||||
mDepthFunc = enable ? RasterState::DepthFunc::GE : RasterState::DepthFunc::A;
|
||||
}
|
||||
|
||||
bool FMaterialInstance::isDepthCullingEnabled() const noexcept {
|
||||
return mDepthFunc != RasterState::DepthFunc::A;
|
||||
}
|
||||
|
||||
const char* FMaterialInstance::getName() const noexcept {
|
||||
// To decide whether to use the parent material name as a fallback, we check for the nullness of
|
||||
// the instance's CString rather than calling empty(). This allows instances to override the
|
||||
|
||||
@@ -89,9 +89,11 @@ public:
|
||||
|
||||
backend::CullingMode getCullingMode() const noexcept { return mCulling; }
|
||||
|
||||
bool getColorWrite() const noexcept { return mColorWrite; }
|
||||
bool isColorWriteEnabled() const noexcept { return mColorWrite; }
|
||||
|
||||
bool getDepthWrite() const noexcept { return mDepthWrite; }
|
||||
bool isDepthWriteEnabled() const noexcept { return mDepthWrite; }
|
||||
|
||||
bool isStencilWriteEnabled() const noexcept { return mStencilState.stencilWrite; }
|
||||
|
||||
backend::StencilState getStencilState() const noexcept { return mStencilState; }
|
||||
|
||||
@@ -108,12 +110,20 @@ public:
|
||||
|
||||
void setMaskThreshold(float threshold) noexcept;
|
||||
|
||||
float getMaskThreshold() const noexcept;
|
||||
|
||||
void setSpecularAntiAliasingVariance(float variance) noexcept;
|
||||
|
||||
float getSpecularAntiAliasingVariance() const noexcept;
|
||||
|
||||
void setSpecularAntiAliasingThreshold(float threshold) noexcept;
|
||||
|
||||
float getSpecularAntiAliasingThreshold() const noexcept;
|
||||
|
||||
void setDoubleSided(bool doubleSided) noexcept;
|
||||
|
||||
bool isDoubleSided() const noexcept;
|
||||
|
||||
void setTransparencyMode(TransparencyMode mode) noexcept;
|
||||
|
||||
void setCullingMode(CullingMode culling) noexcept { mCulling = culling; }
|
||||
@@ -126,6 +136,8 @@ public:
|
||||
|
||||
void setDepthCulling(bool enable) noexcept;
|
||||
|
||||
bool isDepthCullingEnabled() const noexcept;
|
||||
|
||||
void setStencilCompareFunction(StencilCompareFunc func, StencilFace face) noexcept {
|
||||
if (any(face & StencilFace::FRONT)) {
|
||||
mStencilState.front.stencilFunc = func;
|
||||
@@ -222,19 +234,26 @@ private:
|
||||
|
||||
// keep these grouped, they're accessed together in the render-loop
|
||||
FMaterial const* mMaterial = nullptr;
|
||||
|
||||
backend::Handle<backend::HwBufferObject> mUbHandle;
|
||||
backend::Handle<backend::HwSamplerGroup> mSbHandle;
|
||||
|
||||
UniformBuffer mUniforms;
|
||||
backend::SamplerGroup mSamplers;
|
||||
backend::PolygonOffset mPolygonOffset;
|
||||
backend::CullingMode mCulling;
|
||||
bool mColorWrite;
|
||||
bool mDepthWrite;
|
||||
bool mHasScissor = false;
|
||||
backend::StencilState mStencilState = {};
|
||||
backend::RasterState::DepthFunc mDepthFunc;
|
||||
TransparencyMode mTransparencyMode;
|
||||
|
||||
backend::PolygonOffset mPolygonOffset{};
|
||||
backend::StencilState mStencilState{};
|
||||
|
||||
float mMaskThreshold = 0.0f;
|
||||
float mSpecularAntiAliasingVariance = 0.0f;
|
||||
float mSpecularAntiAliasingThreshold = 0.0f;
|
||||
|
||||
backend::CullingMode mCulling : 2;
|
||||
backend::RasterState::DepthFunc mDepthFunc : 3;
|
||||
bool mColorWrite : 1;
|
||||
bool mDepthWrite : 1;
|
||||
bool mHasScissor : 1;
|
||||
bool mIsDoubleSided : 1;
|
||||
TransparencyMode mTransparencyMode : 2;
|
||||
|
||||
uint64_t mMaterialSortingKey = 0;
|
||||
|
||||
|
||||
@@ -656,7 +656,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
|
||||
|
||||
RenderPass shadowPass(pass);
|
||||
shadowPass.setVariant(shadowVariant);
|
||||
auto shadows = view.renderShadowMaps(fg, engine, cameraInfo, shadowPass);
|
||||
auto shadows = view.renderShadowMaps(engine, fg, cameraInfo, mShaderUserTime, shadowPass);
|
||||
blackboard["shadows"] = shadows;
|
||||
}
|
||||
|
||||
@@ -740,8 +740,8 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
|
||||
|
||||
// view set-ups that need to happen before rendering
|
||||
fg.addTrivialSideEffectPass("Prepare View Uniforms",
|
||||
[=, &uniforms = view.getPerViewUniforms()](DriverApi& driver) {
|
||||
uniforms.prepareCamera(cameraInfo);
|
||||
[=, &view, &engine](DriverApi& driver) {
|
||||
view.prepareCamera(engine, cameraInfo);
|
||||
|
||||
// The code here is a little fragile. In theory, we need to call prepareViewport()
|
||||
// for each render pass, because the viewport parameters depend on the resolution.
|
||||
@@ -761,11 +761,14 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
|
||||
// The reason why this bug is acceptable is that the viewport parameters are
|
||||
// currently only used for generating noise, so it's not too bad.
|
||||
|
||||
uniforms.prepareViewport(svp,
|
||||
view.prepareViewport(svp,
|
||||
xvp.left * aoOptions.resolution,
|
||||
xvp.bottom * aoOptions.resolution);
|
||||
|
||||
uniforms.commit(driver);
|
||||
view.commitUniforms(driver);
|
||||
|
||||
// set uniforms and samplers for the color passes
|
||||
view.bindPerViewUniformsAndSamplers(driver);
|
||||
});
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -343,9 +343,10 @@ void FScene::prepareDynamicLights(const CameraInfo& camera, ArenaScope& rootAren
|
||||
lp[gpuIndex].typeShadow = LightsUib::packTypeShadow(
|
||||
lcm.isPointLight(li) ? 0u : 1u,
|
||||
shadowInfo[i].contactShadows,
|
||||
shadowInfo[i].index,
|
||||
shadowInfo[i].layer);
|
||||
lp[gpuIndex].channels = LightsUib::packChannels(lcm.getLightChannels(li), shadowInfo[i].castsShadows);
|
||||
shadowInfo[i].index);
|
||||
lp[gpuIndex].channels = LightsUib::packChannels(
|
||||
lcm.getLightChannels(li),
|
||||
shadowInfo[i].castsShadows);
|
||||
}
|
||||
|
||||
driver.updateBufferObject(lightUbh, { lp, positionalLightCount * sizeof(LightsUib) }, 0);
|
||||
|
||||
@@ -155,7 +155,6 @@ public:
|
||||
bool castsShadows = false; // whether this light casts shadows
|
||||
bool contactShadows = false; // whether this light casts contact shadows
|
||||
uint8_t index = 0; // an index into the arrays in the Shadows uniform buffer
|
||||
uint8_t layer = 0; // which layer of the shadow texture array to sample from
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -179,7 +178,8 @@ public:
|
||||
LightSoa const& getLightData() const noexcept { return mLightData; }
|
||||
LightSoa& getLightData() noexcept { return mLightData; }
|
||||
|
||||
void updateUBOs(utils::Range<uint32_t> visibleRenderables, backend::Handle<backend::HwBufferObject> renderableUbh) noexcept;
|
||||
void updateUBOs(utils::Range<uint32_t> visibleRenderables,
|
||||
backend::Handle<backend::HwBufferObject> renderableUbh) noexcept;
|
||||
|
||||
bool hasContactShadows() const noexcept;
|
||||
|
||||
|
||||
@@ -294,10 +294,11 @@ void FView::prepareShadowing(FEngine& engine, DriverApi& driver,
|
||||
}
|
||||
|
||||
// Find all shadow-casting spotlights.
|
||||
size_t shadowLayerCount = 0;
|
||||
size_t shadowMapCount = 0;
|
||||
|
||||
// We allow a max of CONFIG_MAX_SHADOW_CASTING_SPOTS spotlight shadows. Any additional
|
||||
// We allow a max of CONFIG_MAX_SHADOWMAPS point/spotlight shadows. Any additional
|
||||
// shadow-casting spotlights are ignored.
|
||||
// Note that pointlight shadows cost 6 shadowmaps, reducing the total count.
|
||||
for (size_t l = FScene::DIRECTIONAL_LIGHTS_COUNT; l < lightData.size(); l++) {
|
||||
|
||||
// when we get here all the lights should be visible
|
||||
@@ -317,12 +318,12 @@ void FView::prepareShadowing(FEngine& engine, DriverApi& driver,
|
||||
mShadowMapManager.addShadowMap(l, lcm.isSpotLight(li), &shadowOptions);
|
||||
|
||||
if (lcm.isSpotLight(li)) {
|
||||
shadowLayerCount += 6;
|
||||
shadowMapCount += 6;
|
||||
} else {
|
||||
shadowLayerCount += 1;
|
||||
shadowMapCount += 1;
|
||||
}
|
||||
|
||||
if (shadowLayerCount > CONFIG_MAX_SHADOWMAP_PUNCTUAL - 1) {
|
||||
if (shadowMapCount > CONFIG_MAX_SHADOWMAPS - 1) {
|
||||
break; // we ran out of spotlight shadow casting
|
||||
}
|
||||
}
|
||||
@@ -383,7 +384,7 @@ void FView::prepareLighting(FEngine& engine, FEngine::DriverApi& driver, ArenaSc
|
||||
intensity = skybox ? skybox->getIntensity() : FIndirectLight::DEFAULT_INTENSITY;
|
||||
}
|
||||
|
||||
mPerViewUniforms.prepareAmbientLight(*ibl, intensity, exposure);
|
||||
mPerViewUniforms.prepareAmbientLight(engine, *ibl, intensity, exposure);
|
||||
|
||||
/*
|
||||
* Directional light (always at index 0)
|
||||
@@ -391,7 +392,7 @@ void FView::prepareLighting(FEngine& engine, FEngine::DriverApi& driver, ArenaSc
|
||||
|
||||
FLightManager::Instance directionalLight = lightData.elementAt<FScene::LIGHT_INSTANCE>(0);
|
||||
const float3 sceneSpaceDirection = lightData.elementAt<FScene::DIRECTION>(0); // guaranteed normalized
|
||||
mPerViewUniforms.prepareDirectionalLight(exposure, sceneSpaceDirection, directionalLight);
|
||||
mPerViewUniforms.prepareDirectionalLight(engine, exposure, sceneSpaceDirection, directionalLight);
|
||||
mHasDirectionalLight = directionalLight.isValid();
|
||||
}
|
||||
|
||||
@@ -602,13 +603,23 @@ void FView::prepare(FEngine& engine, DriverApi& driver, ArenaScope& arena,
|
||||
* Update driver state
|
||||
*/
|
||||
|
||||
mPerViewUniforms.prepareTime(userTime);
|
||||
mPerViewUniforms.prepareTime(engine, userTime);
|
||||
mPerViewUniforms.prepareFog(cameraInfo.getPosition(), mFogOptions);
|
||||
mPerViewUniforms.prepareTemporalNoise(mTemporalAntiAliasingOptions);
|
||||
mPerViewUniforms.prepareTemporalNoise(engine, mTemporalAntiAliasingOptions);
|
||||
mPerViewUniforms.prepareBlending(needsAlphaChannel);
|
||||
}
|
||||
|
||||
// set uniforms and samplers
|
||||
bindPerViewUniformsAndSamplers(driver);
|
||||
void FView::bindPerViewUniformsAndSamplers(FEngine::DriverApi& driver) const noexcept {
|
||||
mPerViewUniforms.bind(driver);
|
||||
|
||||
driver.bindUniformBuffer(+UniformBindingPoints::LIGHTS,
|
||||
mLightUbh);
|
||||
|
||||
driver.bindUniformBuffer(+UniformBindingPoints::SHADOW,
|
||||
mShadowMapManager.getShadowUniformsHandle());
|
||||
|
||||
driver.bindUniformBuffer(+UniformBindingPoints::FROXEL_RECORDS,
|
||||
mFroxelizer.getRecordBuffer());
|
||||
}
|
||||
|
||||
void FView::computeVisibilityMasks(
|
||||
@@ -656,12 +667,14 @@ UTILS_NOINLINE
|
||||
|
||||
void FView::prepareUpscaler(float2 scale) const noexcept {
|
||||
SYSTRACE_CALL();
|
||||
mPerViewUniforms.prepareUpscaler(scale, mDynamicResolution);
|
||||
const float bias = (mDynamicResolution.quality >= QualityLevel::HIGH) ?
|
||||
std::log2(std::min(scale.x, scale.y)) : 0.0f;
|
||||
mPerViewUniforms.prepareLodBias(bias);
|
||||
}
|
||||
|
||||
void FView::prepareCamera(const CameraInfo& cameraInfo) const noexcept {
|
||||
void FView::prepareCamera(FEngine& engine, const CameraInfo& cameraInfo) const noexcept {
|
||||
SYSTRACE_CALL();
|
||||
mPerViewUniforms.prepareCamera(cameraInfo);
|
||||
mPerViewUniforms.prepareCamera(engine, cameraInfo);
|
||||
}
|
||||
|
||||
void FView::prepareViewport(const filament::Viewport& viewport,
|
||||
@@ -681,13 +694,6 @@ void FView::prepareSSR(Handle<HwTexture> ssr, float refractionLodOffset,
|
||||
mPerViewUniforms.prepareSSR(ssr, refractionLodOffset, ssrOptions);
|
||||
}
|
||||
|
||||
void FView::prepareHistorySSR(Handle<HwTexture> ssr,
|
||||
mat4f const& historyProjection, mat4f const& uvFromViewMatrix,
|
||||
ScreenSpaceReflectionsOptions const& ssrOptions) const noexcept {
|
||||
mPerViewUniforms.prepareHistorySSR(ssr,
|
||||
historyProjection, uvFromViewMatrix, ssrOptions);
|
||||
}
|
||||
|
||||
void FView::prepareStructure(Handle<HwTexture> structure) const noexcept {
|
||||
// sampler must be NEAREST
|
||||
mPerViewUniforms.prepareStructure(structure);
|
||||
@@ -711,7 +717,7 @@ void FView::prepareShadow(Handle<HwTexture> texture) const noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
void FView::prepareShadowMap(bool highPrecision) const noexcept {
|
||||
void FView::prepareShadowMapping(bool highPrecision) const noexcept {
|
||||
mPerViewUniforms.prepareShadowMapping(highPrecision);
|
||||
}
|
||||
|
||||
@@ -894,9 +900,9 @@ void FView::updatePrimitivesLod(FEngine& engine, const CameraInfo&,
|
||||
}
|
||||
}
|
||||
|
||||
FrameGraphId<FrameGraphTexture> FView::renderShadowMaps(FrameGraph& fg, FEngine& engine,
|
||||
CameraInfo const& cameraInfo, RenderPass const& pass) noexcept {
|
||||
return mShadowMapManager.render(fg, engine, pass, *this, cameraInfo);
|
||||
FrameGraphId<FrameGraphTexture> FView::renderShadowMaps(FEngine& engine, FrameGraph& fg,
|
||||
CameraInfo const& cameraInfo, float4 const& userTime, RenderPass const& pass) noexcept {
|
||||
return mShadowMapManager.render(engine, fg, pass, *this, cameraInfo, userTime);
|
||||
}
|
||||
|
||||
void FView::commitFrameHistory(FEngine& engine) noexcept {
|
||||
|
||||
@@ -92,6 +92,8 @@ public:
|
||||
filament::Viewport const& viewport, CameraInfo const& cameraInfo,
|
||||
math::float4 const& userTime, bool needsAlphaChannel) noexcept;
|
||||
|
||||
void bindPerViewUniformsAndSamplers(FEngine::DriverApi& driver) const noexcept;
|
||||
|
||||
void setScene(FScene* scene) { mScene = scene; }
|
||||
FScene const* getScene() const noexcept { return mScene; }
|
||||
FScene* getScene() noexcept { return mScene; }
|
||||
@@ -132,7 +134,7 @@ public:
|
||||
}
|
||||
|
||||
void prepareUpscaler(math::float2 scale) const noexcept;
|
||||
void prepareCamera(const CameraInfo& cameraInfo) const noexcept;
|
||||
void prepareCamera(FEngine& engine, const CameraInfo& cameraInfo) const noexcept;
|
||||
void prepareViewport(const Viewport& viewport, uint32_t xoffset, uint32_t yoffset) const noexcept;
|
||||
void prepareShadowing(FEngine& engine, backend::DriverApi& driver,
|
||||
FScene::RenderableSoa& renderableData, FScene::LightSoa& lightData,
|
||||
@@ -143,12 +145,9 @@ public:
|
||||
void prepareSSAO(backend::Handle<backend::HwTexture> ssao) const noexcept;
|
||||
void prepareSSR(backend::Handle<backend::HwTexture> ssr, float refractionLodOffset,
|
||||
ScreenSpaceReflectionsOptions const& ssrOptions) const noexcept;
|
||||
void prepareHistorySSR(backend::Handle<backend::HwTexture> ssr,
|
||||
math::mat4f const& historyProjection, math::mat4f const& uvFromViewMatrix,
|
||||
ScreenSpaceReflectionsOptions const& ssrOptions) const noexcept;
|
||||
void prepareStructure(backend::Handle<backend::HwTexture> structure) const noexcept;
|
||||
void prepareShadow(backend::Handle<backend::HwTexture> structure) const noexcept;
|
||||
void prepareShadowMap(bool highPrecision) const noexcept;
|
||||
void prepareShadowMapping(bool highPrecision) const noexcept;
|
||||
|
||||
void cleanupRenderPasses() const noexcept;
|
||||
void froxelize(FEngine& engine, math::mat4f const& viewMatrix) const noexcept;
|
||||
@@ -165,8 +164,9 @@ public:
|
||||
bool hasPCSS() const noexcept { return mShadowType == ShadowType::PCSS; }
|
||||
bool hasPicking() const noexcept { return mActivePickingQueriesList != nullptr; }
|
||||
|
||||
FrameGraphId<FrameGraphTexture> renderShadowMaps(FrameGraph& fg, FEngine& engine,
|
||||
CameraInfo const& cameraInfo, RenderPass const& pass) noexcept;
|
||||
FrameGraphId<FrameGraphTexture> renderShadowMaps(FEngine& engine, FrameGraph& fg,
|
||||
CameraInfo const& cameraInfo, math::float4 const& userTime,
|
||||
RenderPass const& pass) noexcept;
|
||||
|
||||
void updatePrimitivesLod(
|
||||
FEngine& engine, const CameraInfo& camera,
|
||||
@@ -451,13 +451,6 @@ private:
|
||||
Culler::result_type* visibleMask,
|
||||
size_t count);
|
||||
|
||||
void bindPerViewUniformsAndSamplers(FEngine::DriverApi& driver) const noexcept {
|
||||
mPerViewUniforms.bind(driver);
|
||||
driver.bindUniformBuffer(+UniformBindingPoints::LIGHTS, mLightUbh);
|
||||
driver.bindUniformBuffer(+UniformBindingPoints::SHADOW, mShadowMapManager.getShadowUniformsHandle());
|
||||
driver.bindUniformBuffer(+UniformBindingPoints::FROXEL_RECORDS, mFroxelizer.getRecordBuffer());
|
||||
}
|
||||
|
||||
// Clean-up the whole history, free all resources. This is typically called when the View is
|
||||
// being terminated.
|
||||
void drainFrameHistory(FEngine& engine) noexcept;
|
||||
|
||||
@@ -42,6 +42,7 @@ list(APPEND RESGEN_SOURCE ${DUMMY_SRC})
|
||||
# away in Release builds
|
||||
if (TNT_DEV)
|
||||
add_executable(test_${TARGET}
|
||||
filament_AtlasAllocator_test.cpp
|
||||
filament_test_exposure.cpp
|
||||
filament_rendering_test.cpp
|
||||
filament_framegraph_test.cpp
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "AtlasAllocator.h"
|
||||
|
||||
using namespace filament;
|
||||
|
||||
TEST(AtlasAllocator, AllocateFirstLevel) {
|
||||
|
||||
AtlasAllocator allocator;
|
||||
|
||||
auto a = allocator.allocateInLayer(0);
|
||||
EXPECT_TRUE(a.l == 0 && a.code == 0);
|
||||
|
||||
auto b = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(b.l < 0);
|
||||
|
||||
auto c = allocator.allocateInLayer(2);
|
||||
EXPECT_TRUE(c.l < 0);
|
||||
|
||||
auto d = allocator.allocateInLayer(5);
|
||||
EXPECT_TRUE(d.l < 0);
|
||||
}
|
||||
|
||||
TEST(AtlasAllocator, AllocateSecondLevel) {
|
||||
|
||||
AtlasAllocator allocator;
|
||||
|
||||
auto d0 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(d0.l == 1 && d0.code == 0);
|
||||
|
||||
auto d1 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(d1.l == 1 && d1.code == 1);
|
||||
|
||||
auto d2 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(d2.l == 1 && d2.code == 2);
|
||||
|
||||
auto d3 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(d3.l == 1 && d3.code == 3);
|
||||
}
|
||||
|
||||
TEST(AtlasAllocator, AllocateMixed0) {
|
||||
AtlasAllocator allocator;
|
||||
|
||||
auto e0 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(e0.l == 1 && e0.code == 0);
|
||||
|
||||
auto e1 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(e1.l == 1 && e1.code == 1);
|
||||
|
||||
auto e2 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(e2.l == 1 && e2.code == 2);
|
||||
|
||||
auto e3 = allocator.allocateInLayer(2);
|
||||
EXPECT_TRUE(e3.l == 2 && e3.code == 12);
|
||||
|
||||
auto e4 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(e4.l < 0);
|
||||
}
|
||||
|
||||
TEST(AtlasAllocator, AllocateMixed1) {
|
||||
AtlasAllocator allocator;
|
||||
|
||||
auto e0 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(e0.l == 1 && e0.code == 0);
|
||||
|
||||
auto e1 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(e1.l == 1 && e1.code == 1);
|
||||
|
||||
auto e2 = allocator.allocateInLayer(2);
|
||||
EXPECT_TRUE(e2.l == 2 && e2.code == 8);
|
||||
|
||||
auto e3 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(e3.l == 1 && e3.code == 3);
|
||||
}
|
||||
|
||||
TEST(AtlasAllocator, AllocateMixed2) {
|
||||
AtlasAllocator allocator;
|
||||
|
||||
auto e0 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(e0.l == 1 && e0.code == 0);
|
||||
|
||||
auto e1 = allocator.allocateInLayer(1);
|
||||
EXPECT_TRUE(e1.l == 1 && e1.code == 1);
|
||||
|
||||
auto c0 = allocator.allocateInLayer(2);
|
||||
EXPECT_TRUE(c0.l == 2 && c0.code == 8);
|
||||
auto c1 = allocator.allocateInLayer(2);
|
||||
EXPECT_TRUE(c1.l == 2 && c1.code == 9);
|
||||
auto c2 = allocator.allocateInLayer(2);
|
||||
EXPECT_TRUE(c2.l == 2 && c2.code == 10);
|
||||
auto c3 = allocator.allocateInLayer(2);
|
||||
EXPECT_TRUE(c3.l == 2 && c3.code == 11);
|
||||
|
||||
auto c4 = allocator.allocateInLayer(2);
|
||||
EXPECT_TRUE(c4.l == 2 && c4.code == 12);
|
||||
auto c5 = allocator.allocateInLayer(2);
|
||||
EXPECT_TRUE(c5.l == 2 && c5.code == 13);
|
||||
auto c6 = allocator.allocateInLayer(2);
|
||||
EXPECT_TRUE(c6.l == 2 && c6.code == 14);
|
||||
auto c7 = allocator.allocateInLayer(2);
|
||||
EXPECT_TRUE(c7.l == 2 && c7.code == 15);
|
||||
}
|
||||
|
||||
TEST(AtlasAllocator, AllocateBySize) {
|
||||
AtlasAllocator allocator(256);
|
||||
|
||||
Viewport vp(0,0,256,256);
|
||||
auto vp0 = allocator.allocate(256);
|
||||
EXPECT_EQ(vp0, vp);
|
||||
|
||||
auto vp1 = allocator.allocate(128);
|
||||
EXPECT_TRUE(vp1.empty());
|
||||
}
|
||||
|
||||
TEST(AtlasAllocator, AllocateBySizeOneOfEach) {
|
||||
AtlasAllocator allocator(256);
|
||||
|
||||
Viewport r0(0,0,128,128);
|
||||
Viewport r1(128,0,64,64);
|
||||
Viewport r2(192,0,32,32);
|
||||
|
||||
auto vp0 = allocator.allocate(128);
|
||||
auto vp1 = allocator.allocate(64);
|
||||
auto vp2 = allocator.allocate(32);
|
||||
auto vp3 = allocator.allocate(16);
|
||||
|
||||
EXPECT_EQ(vp0, r0);
|
||||
EXPECT_EQ(vp1, r1);
|
||||
EXPECT_EQ(vp2, r2);
|
||||
EXPECT_TRUE(vp3.empty());
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = "Filament"
|
||||
spec.version = "1.28.0"
|
||||
spec.version = "1.29.0"
|
||||
spec.license = { :type => "Apache 2.0", :file => "LICENSE" }
|
||||
spec.homepage = "https://google.github.io/filament"
|
||||
spec.authors = "Google LLC."
|
||||
spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL."
|
||||
spec.platform = :ios, "11.0"
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.28.0/filament-v1.28.0-ios.tgz" }
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.29.0/filament-v1.29.0-ios.tgz" }
|
||||
|
||||
# Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon.
|
||||
spec.pod_target_xcconfig = {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
## Updating Vulkan headers
|
||||
|
||||
To update the Vulkan headers, perform the following steps.
|
||||
|
||||
First, find the latest version of the Vulkan headers here:
|
||||
https://github.com/KhronosGroup/Vulkan-Headers/tags
|
||||
|
||||
Replace `v1.3.232` with the latest version of the headers in the following commands.
|
||||
```
|
||||
cd libs/bluevk
|
||||
curl -OL https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/v1.3.232.zip
|
||||
unzip v1.3.232.zip
|
||||
rsync -r Vulkan-Headers-1.3.232/include/vulkan/ include/vulkan --delete
|
||||
rsync -r Vulkan-Headers-1.3.232/include/vk_video/ include/vk_video --delete
|
||||
rm include/vulkan/*.hpp
|
||||
rm -r Vulkan-Headers-1.3.232 v1.3.232.zip
|
||||
```
|
||||
@@ -37,6 +37,27 @@
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
#define VK_NO_PROTOTYPES
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#define VK_USE_PLATFORM_ANDROID_KHR 1
|
||||
#elif defined(IOS)
|
||||
#define VK_USE_PLATFORM_IOS_MVK 1
|
||||
#elif defined(__linux__)
|
||||
#if defined(FILAMENT_SUPPORTS_XCB)
|
||||
#define VK_USE_PLATFORM_XCB_KHR 1
|
||||
#endif
|
||||
#if defined(FILAMENT_SUPPORTS_XLIB)
|
||||
#define VK_USE_PLATFORM_XLIB_KHR 1
|
||||
#endif
|
||||
#if defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
#define VK_USE_PLATFORM_WAYLAND_KHR 1
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
#define VK_USE_PLATFORM_MACOS_MVK 1
|
||||
#elif defined(WIN32)
|
||||
#define VK_USE_PLATFORM_WIN32_KHR 1
|
||||
#endif
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -21,16 +21,13 @@ extern "C" {
|
||||
|
||||
#define vulkan_video_codec_h264std 1
|
||||
#include <stdint.h>
|
||||
// Vulkan 0.9 provisional Vulkan video H.264 encode and decode std specification version number
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H264_API_VERSION_0_9_5 VK_MAKE_VIDEO_STD_VERSION(0, 9, 5) // Patch version should always be set to 0
|
||||
|
||||
#define STD_VIDEO_H264_CPB_CNT_LIST_SIZE 32
|
||||
#define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS 6
|
||||
#define STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS 16
|
||||
#define STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS 2
|
||||
#define STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS 6
|
||||
#define STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS 64
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H264_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_API_VERSION_0_9_5
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H264_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264"
|
||||
#define STD_VIDEO_H264_MAX_NUM_LIST_REF 32
|
||||
#define STD_VIDEO_H264_MAX_CHROMA_PLANES 2
|
||||
|
||||
typedef enum StdVideoH264ChromaFormatIdc {
|
||||
STD_VIDEO_H264_CHROMA_FORMAT_IDC_MONOCHROME = 0,
|
||||
@@ -50,29 +47,29 @@ typedef enum StdVideoH264ProfileIdc {
|
||||
STD_VIDEO_H264_PROFILE_IDC_MAX_ENUM = 0x7FFFFFFF
|
||||
} StdVideoH264ProfileIdc;
|
||||
|
||||
typedef enum StdVideoH264Level {
|
||||
STD_VIDEO_H264_LEVEL_1_0 = 0,
|
||||
STD_VIDEO_H264_LEVEL_1_1 = 1,
|
||||
STD_VIDEO_H264_LEVEL_1_2 = 2,
|
||||
STD_VIDEO_H264_LEVEL_1_3 = 3,
|
||||
STD_VIDEO_H264_LEVEL_2_0 = 4,
|
||||
STD_VIDEO_H264_LEVEL_2_1 = 5,
|
||||
STD_VIDEO_H264_LEVEL_2_2 = 6,
|
||||
STD_VIDEO_H264_LEVEL_3_0 = 7,
|
||||
STD_VIDEO_H264_LEVEL_3_1 = 8,
|
||||
STD_VIDEO_H264_LEVEL_3_2 = 9,
|
||||
STD_VIDEO_H264_LEVEL_4_0 = 10,
|
||||
STD_VIDEO_H264_LEVEL_4_1 = 11,
|
||||
STD_VIDEO_H264_LEVEL_4_2 = 12,
|
||||
STD_VIDEO_H264_LEVEL_5_0 = 13,
|
||||
STD_VIDEO_H264_LEVEL_5_1 = 14,
|
||||
STD_VIDEO_H264_LEVEL_5_2 = 15,
|
||||
STD_VIDEO_H264_LEVEL_6_0 = 16,
|
||||
STD_VIDEO_H264_LEVEL_6_1 = 17,
|
||||
STD_VIDEO_H264_LEVEL_6_2 = 18,
|
||||
STD_VIDEO_H264_LEVEL_INVALID = 0x7FFFFFFF,
|
||||
STD_VIDEO_H264_LEVEL_MAX_ENUM = 0x7FFFFFFF
|
||||
} StdVideoH264Level;
|
||||
typedef enum StdVideoH264LevelIdc {
|
||||
STD_VIDEO_H264_LEVEL_IDC_1_0 = 0,
|
||||
STD_VIDEO_H264_LEVEL_IDC_1_1 = 1,
|
||||
STD_VIDEO_H264_LEVEL_IDC_1_2 = 2,
|
||||
STD_VIDEO_H264_LEVEL_IDC_1_3 = 3,
|
||||
STD_VIDEO_H264_LEVEL_IDC_2_0 = 4,
|
||||
STD_VIDEO_H264_LEVEL_IDC_2_1 = 5,
|
||||
STD_VIDEO_H264_LEVEL_IDC_2_2 = 6,
|
||||
STD_VIDEO_H264_LEVEL_IDC_3_0 = 7,
|
||||
STD_VIDEO_H264_LEVEL_IDC_3_1 = 8,
|
||||
STD_VIDEO_H264_LEVEL_IDC_3_2 = 9,
|
||||
STD_VIDEO_H264_LEVEL_IDC_4_0 = 10,
|
||||
STD_VIDEO_H264_LEVEL_IDC_4_1 = 11,
|
||||
STD_VIDEO_H264_LEVEL_IDC_4_2 = 12,
|
||||
STD_VIDEO_H264_LEVEL_IDC_5_0 = 13,
|
||||
STD_VIDEO_H264_LEVEL_IDC_5_1 = 14,
|
||||
STD_VIDEO_H264_LEVEL_IDC_5_2 = 15,
|
||||
STD_VIDEO_H264_LEVEL_IDC_6_0 = 16,
|
||||
STD_VIDEO_H264_LEVEL_IDC_6_1 = 17,
|
||||
STD_VIDEO_H264_LEVEL_IDC_6_2 = 18,
|
||||
STD_VIDEO_H264_LEVEL_IDC_INVALID = 0x7FFFFFFF,
|
||||
STD_VIDEO_H264_LEVEL_IDC_MAX_ENUM = 0x7FFFFFFF
|
||||
} StdVideoH264LevelIdc;
|
||||
|
||||
typedef enum StdVideoH264PocType {
|
||||
STD_VIDEO_H264_POC_TYPE_0 = 0,
|
||||
@@ -197,6 +194,7 @@ typedef struct StdVideoH264HrdParameters {
|
||||
uint8_t cpb_cnt_minus1;
|
||||
uint8_t bit_rate_scale;
|
||||
uint8_t cpb_size_scale;
|
||||
uint8_t reserved1;
|
||||
uint32_t bit_rate_value_minus1[STD_VIDEO_H264_CPB_CNT_LIST_SIZE];
|
||||
uint32_t cpb_size_value_minus1[STD_VIDEO_H264_CPB_CNT_LIST_SIZE];
|
||||
uint8_t cbr_flag[STD_VIDEO_H264_CPB_CNT_LIST_SIZE];
|
||||
@@ -207,19 +205,22 @@ typedef struct StdVideoH264HrdParameters {
|
||||
} StdVideoH264HrdParameters;
|
||||
|
||||
typedef struct StdVideoH264SequenceParameterSetVui {
|
||||
StdVideoH264AspectRatioIdc aspect_ratio_idc;
|
||||
uint16_t sar_width;
|
||||
uint16_t sar_height;
|
||||
uint8_t video_format;
|
||||
uint8_t color_primaries;
|
||||
uint8_t transfer_characteristics;
|
||||
uint8_t matrix_coefficients;
|
||||
uint32_t num_units_in_tick;
|
||||
uint32_t time_scale;
|
||||
StdVideoH264HrdParameters* pHrdParameters;
|
||||
uint8_t max_num_reorder_frames;
|
||||
uint8_t max_dec_frame_buffering;
|
||||
StdVideoH264SpsVuiFlags flags;
|
||||
StdVideoH264SpsVuiFlags flags;
|
||||
StdVideoH264AspectRatioIdc aspect_ratio_idc;
|
||||
uint16_t sar_width;
|
||||
uint16_t sar_height;
|
||||
uint8_t video_format;
|
||||
uint8_t colour_primaries;
|
||||
uint8_t transfer_characteristics;
|
||||
uint8_t matrix_coefficients;
|
||||
uint32_t num_units_in_tick;
|
||||
uint32_t time_scale;
|
||||
uint8_t max_num_reorder_frames;
|
||||
uint8_t max_dec_frame_buffering;
|
||||
uint8_t chroma_sample_loc_type_top_field;
|
||||
uint8_t chroma_sample_loc_type_bottom_field;
|
||||
uint32_t reserved1;
|
||||
const StdVideoH264HrdParameters* pHrdParameters;
|
||||
} StdVideoH264SequenceParameterSetVui;
|
||||
|
||||
typedef struct StdVideoH264SpsFlags {
|
||||
@@ -242,36 +243,38 @@ typedef struct StdVideoH264SpsFlags {
|
||||
} StdVideoH264SpsFlags;
|
||||
|
||||
typedef struct StdVideoH264ScalingLists {
|
||||
uint8_t scaling_list_present_mask;
|
||||
uint8_t use_default_scaling_matrix_mask;
|
||||
uint8_t ScalingList4x4[STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS][STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS];
|
||||
uint8_t ScalingList8x8[STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS][STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS];
|
||||
uint16_t scaling_list_present_mask;
|
||||
uint16_t use_default_scaling_matrix_mask;
|
||||
uint8_t ScalingList4x4[STD_VIDEO_H264_SCALING_LIST_4X4_NUM_LISTS][STD_VIDEO_H264_SCALING_LIST_4X4_NUM_ELEMENTS];
|
||||
uint8_t ScalingList8x8[STD_VIDEO_H264_SCALING_LIST_8X8_NUM_LISTS][STD_VIDEO_H264_SCALING_LIST_8X8_NUM_ELEMENTS];
|
||||
} StdVideoH264ScalingLists;
|
||||
|
||||
typedef struct StdVideoH264SequenceParameterSet {
|
||||
StdVideoH264ProfileIdc profile_idc;
|
||||
StdVideoH264Level level_idc;
|
||||
uint8_t seq_parameter_set_id;
|
||||
StdVideoH264ChromaFormatIdc chroma_format_idc;
|
||||
uint8_t bit_depth_luma_minus8;
|
||||
uint8_t bit_depth_chroma_minus8;
|
||||
uint8_t log2_max_frame_num_minus4;
|
||||
StdVideoH264PocType pic_order_cnt_type;
|
||||
uint8_t log2_max_pic_order_cnt_lsb_minus4;
|
||||
int32_t offset_for_non_ref_pic;
|
||||
int32_t offset_for_top_to_bottom_field;
|
||||
uint8_t num_ref_frames_in_pic_order_cnt_cycle;
|
||||
uint8_t max_num_ref_frames;
|
||||
uint32_t pic_width_in_mbs_minus1;
|
||||
uint32_t pic_height_in_map_units_minus1;
|
||||
uint32_t frame_crop_left_offset;
|
||||
uint32_t frame_crop_right_offset;
|
||||
uint32_t frame_crop_top_offset;
|
||||
uint32_t frame_crop_bottom_offset;
|
||||
StdVideoH264SpsFlags flags;
|
||||
int32_t* pOffsetForRefFrame;
|
||||
StdVideoH264ScalingLists* pScalingLists;
|
||||
StdVideoH264SequenceParameterSetVui* pSequenceParameterSetVui;
|
||||
StdVideoH264SpsFlags flags;
|
||||
StdVideoH264ProfileIdc profile_idc;
|
||||
StdVideoH264LevelIdc level_idc;
|
||||
StdVideoH264ChromaFormatIdc chroma_format_idc;
|
||||
uint8_t seq_parameter_set_id;
|
||||
uint8_t bit_depth_luma_minus8;
|
||||
uint8_t bit_depth_chroma_minus8;
|
||||
uint8_t log2_max_frame_num_minus4;
|
||||
StdVideoH264PocType pic_order_cnt_type;
|
||||
int32_t offset_for_non_ref_pic;
|
||||
int32_t offset_for_top_to_bottom_field;
|
||||
uint8_t log2_max_pic_order_cnt_lsb_minus4;
|
||||
uint8_t num_ref_frames_in_pic_order_cnt_cycle;
|
||||
uint8_t max_num_ref_frames;
|
||||
uint8_t reserved1;
|
||||
uint32_t pic_width_in_mbs_minus1;
|
||||
uint32_t pic_height_in_map_units_minus1;
|
||||
uint32_t frame_crop_left_offset;
|
||||
uint32_t frame_crop_right_offset;
|
||||
uint32_t frame_crop_top_offset;
|
||||
uint32_t frame_crop_bottom_offset;
|
||||
uint32_t reserved2;
|
||||
const int32_t* pOffsetForRefFrame;
|
||||
const StdVideoH264ScalingLists* pScalingLists;
|
||||
const StdVideoH264SequenceParameterSetVui* pSequenceParameterSetVui;
|
||||
} StdVideoH264SequenceParameterSet;
|
||||
|
||||
typedef struct StdVideoH264PpsFlags {
|
||||
@@ -279,25 +282,24 @@ typedef struct StdVideoH264PpsFlags {
|
||||
uint32_t redundant_pic_cnt_present_flag : 1;
|
||||
uint32_t constrained_intra_pred_flag : 1;
|
||||
uint32_t deblocking_filter_control_present_flag : 1;
|
||||
uint32_t weighted_bipred_idc_flag : 1;
|
||||
uint32_t weighted_pred_flag : 1;
|
||||
uint32_t pic_order_present_flag : 1;
|
||||
uint32_t bottom_field_pic_order_in_frame_present_flag : 1;
|
||||
uint32_t entropy_coding_mode_flag : 1;
|
||||
uint32_t pic_scaling_matrix_present_flag : 1;
|
||||
} StdVideoH264PpsFlags;
|
||||
|
||||
typedef struct StdVideoH264PictureParameterSet {
|
||||
uint8_t seq_parameter_set_id;
|
||||
uint8_t pic_parameter_set_id;
|
||||
uint8_t num_ref_idx_l0_default_active_minus1;
|
||||
uint8_t num_ref_idx_l1_default_active_minus1;
|
||||
StdVideoH264WeightedBipredIdc weighted_bipred_idc;
|
||||
int8_t pic_init_qp_minus26;
|
||||
int8_t pic_init_qs_minus26;
|
||||
int8_t chroma_qp_index_offset;
|
||||
int8_t second_chroma_qp_index_offset;
|
||||
StdVideoH264PpsFlags flags;
|
||||
StdVideoH264ScalingLists* pScalingLists;
|
||||
StdVideoH264PpsFlags flags;
|
||||
uint8_t seq_parameter_set_id;
|
||||
uint8_t pic_parameter_set_id;
|
||||
uint8_t num_ref_idx_l0_default_active_minus1;
|
||||
uint8_t num_ref_idx_l1_default_active_minus1;
|
||||
StdVideoH264WeightedBipredIdc weighted_bipred_idc;
|
||||
int8_t pic_init_qp_minus26;
|
||||
int8_t pic_init_qs_minus26;
|
||||
int8_t chroma_qp_index_offset;
|
||||
int8_t second_chroma_qp_index_offset;
|
||||
const StdVideoH264ScalingLists* pScalingLists;
|
||||
} StdVideoH264PictureParameterSet;
|
||||
|
||||
|
||||
|
||||
@@ -20,8 +20,12 @@ extern "C" {
|
||||
|
||||
|
||||
#define vulkan_video_codec_h264std_decode 1
|
||||
// Vulkan 0.9 provisional Vulkan video H.264 decode std specification version number
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_API_VERSION_0_9_8 VK_MAKE_VIDEO_STD_VERSION(0, 9, 8) // Patch version should always be set to 0
|
||||
|
||||
#define STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE 2
|
||||
#define STD_VIDEO_DECODE_H264_MVC_REF_LIST_SIZE 15
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_API_VERSION_0_9_8
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H264_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_decode"
|
||||
|
||||
typedef enum StdVideoDecodeH264FieldOrderCount {
|
||||
STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_TOP = 0,
|
||||
@@ -39,57 +43,30 @@ typedef struct StdVideoDecodeH264PictureInfoFlags {
|
||||
} StdVideoDecodeH264PictureInfoFlags;
|
||||
|
||||
typedef struct StdVideoDecodeH264PictureInfo {
|
||||
StdVideoDecodeH264PictureInfoFlags flags;
|
||||
uint8_t seq_parameter_set_id;
|
||||
uint8_t pic_parameter_set_id;
|
||||
uint16_t reserved;
|
||||
uint8_t reserved1;
|
||||
uint8_t reserved2;
|
||||
uint16_t frame_num;
|
||||
uint16_t idr_pic_id;
|
||||
int32_t PicOrderCnt[STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE];
|
||||
StdVideoDecodeH264PictureInfoFlags flags;
|
||||
} StdVideoDecodeH264PictureInfo;
|
||||
|
||||
typedef struct StdVideoDecodeH264ReferenceInfoFlags {
|
||||
uint32_t top_field_flag : 1;
|
||||
uint32_t bottom_field_flag : 1;
|
||||
uint32_t is_long_term : 1;
|
||||
uint32_t used_for_long_term_reference : 1;
|
||||
uint32_t is_non_existing : 1;
|
||||
} StdVideoDecodeH264ReferenceInfoFlags;
|
||||
|
||||
typedef struct StdVideoDecodeH264ReferenceInfo {
|
||||
StdVideoDecodeH264ReferenceInfoFlags flags;
|
||||
uint16_t FrameNum;
|
||||
uint16_t reserved;
|
||||
int32_t PicOrderCnt[2];
|
||||
StdVideoDecodeH264ReferenceInfoFlags flags;
|
||||
int32_t PicOrderCnt[STD_VIDEO_DECODE_H264_FIELD_ORDER_COUNT_LIST_SIZE];
|
||||
} StdVideoDecodeH264ReferenceInfo;
|
||||
|
||||
typedef struct StdVideoDecodeH264MvcElementFlags {
|
||||
uint32_t non_idr : 1;
|
||||
uint32_t anchor_pic : 1;
|
||||
uint32_t inter_view : 1;
|
||||
} StdVideoDecodeH264MvcElementFlags;
|
||||
|
||||
typedef struct StdVideoDecodeH264MvcElement {
|
||||
StdVideoDecodeH264MvcElementFlags flags;
|
||||
uint16_t viewOrderIndex;
|
||||
uint16_t viewId;
|
||||
uint16_t temporalId;
|
||||
uint16_t priorityId;
|
||||
uint16_t numOfAnchorRefsInL0;
|
||||
uint16_t viewIdOfAnchorRefsInL0[STD_VIDEO_DECODE_H264_MVC_REF_LIST_SIZE];
|
||||
uint16_t numOfAnchorRefsInL1;
|
||||
uint16_t viewIdOfAnchorRefsInL1[STD_VIDEO_DECODE_H264_MVC_REF_LIST_SIZE];
|
||||
uint16_t numOfNonAnchorRefsInL0;
|
||||
uint16_t viewIdOfNonAnchorRefsInL0[STD_VIDEO_DECODE_H264_MVC_REF_LIST_SIZE];
|
||||
uint16_t numOfNonAnchorRefsInL1;
|
||||
uint16_t viewIdOfNonAnchorRefsInL1[STD_VIDEO_DECODE_H264_MVC_REF_LIST_SIZE];
|
||||
} StdVideoDecodeH264MvcElement;
|
||||
|
||||
typedef struct StdVideoDecodeH264Mvc {
|
||||
uint32_t viewId0;
|
||||
uint32_t mvcElementCount;
|
||||
StdVideoDecodeH264MvcElement* pMvcElements;
|
||||
} StdVideoDecodeH264Mvc;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -20,6 +20,32 @@ extern "C" {
|
||||
|
||||
|
||||
#define vulkan_video_codec_h264std_encode 1
|
||||
// Vulkan 0.9 provisional Vulkan video H.264 encode std specification version number
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_8 VK_MAKE_VIDEO_STD_VERSION(0, 9, 8) // Patch version should always be set to 0
|
||||
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_API_VERSION_0_9_8
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H264_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h264_encode"
|
||||
typedef struct StdVideoEncodeH264WeightTableFlags {
|
||||
uint32_t luma_weight_l0_flag;
|
||||
uint32_t chroma_weight_l0_flag;
|
||||
uint32_t luma_weight_l1_flag;
|
||||
uint32_t chroma_weight_l1_flag;
|
||||
} StdVideoEncodeH264WeightTableFlags;
|
||||
|
||||
typedef struct StdVideoEncodeH264WeightTable {
|
||||
StdVideoEncodeH264WeightTableFlags flags;
|
||||
uint8_t luma_log2_weight_denom;
|
||||
uint8_t chroma_log2_weight_denom;
|
||||
int8_t luma_weight_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF];
|
||||
int8_t luma_offset_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF];
|
||||
int8_t chroma_weight_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES];
|
||||
int8_t chroma_offset_l0[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES];
|
||||
int8_t luma_weight_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF];
|
||||
int8_t luma_offset_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF];
|
||||
int8_t chroma_weight_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES];
|
||||
int8_t chroma_offset_l1[STD_VIDEO_H264_MAX_NUM_LIST_REF][STD_VIDEO_H264_MAX_CHROMA_PLANES];
|
||||
} StdVideoEncodeH264WeightTable;
|
||||
|
||||
typedef struct StdVideoEncodeH264SliceHeaderFlags {
|
||||
uint32_t direct_spatial_mv_pred_flag : 1;
|
||||
uint32_t num_ref_idx_active_override_flag : 1;
|
||||
@@ -31,11 +57,11 @@ typedef struct StdVideoEncodeH264SliceHeaderFlags {
|
||||
typedef struct StdVideoEncodeH264PictureInfoFlags {
|
||||
uint32_t idr_flag : 1;
|
||||
uint32_t is_reference_flag : 1;
|
||||
uint32_t long_term_reference_flag : 1;
|
||||
uint32_t used_for_long_term_reference : 1;
|
||||
} StdVideoEncodeH264PictureInfoFlags;
|
||||
|
||||
typedef struct StdVideoEncodeH264ReferenceInfoFlags {
|
||||
uint32_t is_long_term : 1;
|
||||
uint32_t used_for_long_term_reference : 1;
|
||||
} StdVideoEncodeH264ReferenceInfoFlags;
|
||||
|
||||
typedef struct StdVideoEncodeH264RefMgmtFlags {
|
||||
@@ -58,17 +84,19 @@ typedef struct StdVideoEncodeH264RefPicMarkingEntry {
|
||||
} StdVideoEncodeH264RefPicMarkingEntry;
|
||||
|
||||
typedef struct StdVideoEncodeH264RefMemMgmtCtrlOperations {
|
||||
StdVideoEncodeH264RefMgmtFlags flags;
|
||||
uint8_t refList0ModOpCount;
|
||||
StdVideoEncodeH264RefListModEntry* pRefList0ModOperations;
|
||||
uint8_t refList1ModOpCount;
|
||||
StdVideoEncodeH264RefListModEntry* pRefList1ModOperations;
|
||||
uint8_t refPicMarkingOpCount;
|
||||
StdVideoEncodeH264RefPicMarkingEntry* pRefPicMarkingOperations;
|
||||
StdVideoEncodeH264RefMgmtFlags flags;
|
||||
uint8_t refList0ModOpCount;
|
||||
const StdVideoEncodeH264RefListModEntry* pRefList0ModOperations;
|
||||
uint8_t refList1ModOpCount;
|
||||
const StdVideoEncodeH264RefListModEntry* pRefList1ModOperations;
|
||||
uint8_t refPicMarkingOpCount;
|
||||
const StdVideoEncodeH264RefPicMarkingEntry* pRefPicMarkingOperations;
|
||||
} StdVideoEncodeH264RefMemMgmtCtrlOperations;
|
||||
|
||||
typedef struct StdVideoEncodeH264PictureInfo {
|
||||
StdVideoEncodeH264PictureInfoFlags flags;
|
||||
uint8_t seq_parameter_set_id;
|
||||
uint8_t pic_parameter_set_id;
|
||||
StdVideoH264PictureType pictureType;
|
||||
uint32_t frame_num;
|
||||
int32_t PicOrderCnt;
|
||||
@@ -86,8 +114,6 @@ typedef struct StdVideoEncodeH264SliceHeader {
|
||||
StdVideoEncodeH264SliceHeaderFlags flags;
|
||||
uint32_t first_mb_in_slice;
|
||||
StdVideoH264SliceType slice_type;
|
||||
uint8_t seq_parameter_set_id;
|
||||
uint8_t pic_parameter_set_id;
|
||||
uint16_t idr_pic_id;
|
||||
uint8_t num_ref_idx_l0_active_minus1;
|
||||
uint8_t num_ref_idx_l1_active_minus1;
|
||||
@@ -95,6 +121,7 @@ typedef struct StdVideoEncodeH264SliceHeader {
|
||||
StdVideoH264DisableDeblockingFilterIdc disable_deblocking_filter_idc;
|
||||
int8_t slice_alpha_c0_offset_div2;
|
||||
int8_t slice_beta_offset_div2;
|
||||
const StdVideoEncodeH264WeightTable* pWeightTable;
|
||||
} StdVideoEncodeH264SliceHeader;
|
||||
|
||||
|
||||
|
||||
@@ -20,10 +20,7 @@ extern "C" {
|
||||
|
||||
|
||||
#define vulkan_video_codec_h265std 1
|
||||
// Vulkan 0.5 version number WIP
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H265_API_VERSION_0_9_5 VK_MAKE_VIDEO_STD_VERSION(0, 9, 5) // Patch version should always be set to 0
|
||||
|
||||
#define STD_VIDEO_H265_SUBLAYERS_MINUS1_LIST_SIZE 7
|
||||
#define STD_VIDEO_H265_SUBLAYERS_LIST_SIZE 7
|
||||
#define STD_VIDEO_H265_CPB_CNT_LIST_SIZE 32
|
||||
#define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_LISTS 6
|
||||
#define STD_VIDEO_H265_SCALING_LIST_4X4_NUM_ELEMENTS 16
|
||||
@@ -35,11 +32,16 @@ extern "C" {
|
||||
#define STD_VIDEO_H265_SCALING_LIST_32X32_NUM_ELEMENTS 64
|
||||
#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMPONENTS_LIST_SIZE 3
|
||||
#define STD_VIDEO_H265_PREDICTOR_PALETTE_COMP_ENTRIES_LIST_SIZE 128
|
||||
#define STD_VIDEO_H265_MAX_DPB_SIZE 16
|
||||
#define STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS 32
|
||||
#define STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE 6
|
||||
#define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_COLS_LIST_SIZE 19
|
||||
#define STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_ROWS_LIST_SIZE 21
|
||||
#define STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE 6
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H265_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_API_VERSION_0_9_5
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H265_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265"
|
||||
#define STD_VIDEO_H265_MAX_NUM_LIST_REF 15
|
||||
#define STD_VIDEO_H265_MAX_CHROMA_PLANES 2
|
||||
#define STD_VIDEO_H265_MAX_SHORT_TERM_REF_PIC_SETS 64
|
||||
#define STD_VIDEO_H265_MAX_LONG_TERM_PICS 16
|
||||
#define STD_VIDEO_H265_MAX_DELTA_POC 48
|
||||
|
||||
typedef enum StdVideoH265ChromaFormatIdc {
|
||||
STD_VIDEO_H265_CHROMA_FORMAT_IDC_MONOCHROME = 0,
|
||||
@@ -60,23 +62,23 @@ typedef enum StdVideoH265ProfileIdc {
|
||||
STD_VIDEO_H265_PROFILE_IDC_MAX_ENUM = 0x7FFFFFFF
|
||||
} StdVideoH265ProfileIdc;
|
||||
|
||||
typedef enum StdVideoH265Level {
|
||||
STD_VIDEO_H265_LEVEL_1_0 = 0,
|
||||
STD_VIDEO_H265_LEVEL_2_0 = 1,
|
||||
STD_VIDEO_H265_LEVEL_2_1 = 2,
|
||||
STD_VIDEO_H265_LEVEL_3_0 = 3,
|
||||
STD_VIDEO_H265_LEVEL_3_1 = 4,
|
||||
STD_VIDEO_H265_LEVEL_4_0 = 5,
|
||||
STD_VIDEO_H265_LEVEL_4_1 = 6,
|
||||
STD_VIDEO_H265_LEVEL_5_0 = 7,
|
||||
STD_VIDEO_H265_LEVEL_5_1 = 8,
|
||||
STD_VIDEO_H265_LEVEL_5_2 = 9,
|
||||
STD_VIDEO_H265_LEVEL_6_0 = 10,
|
||||
STD_VIDEO_H265_LEVEL_6_1 = 11,
|
||||
STD_VIDEO_H265_LEVEL_6_2 = 12,
|
||||
STD_VIDEO_H265_LEVEL_INVALID = 0x7FFFFFFF,
|
||||
STD_VIDEO_H265_LEVEL_MAX_ENUM = 0x7FFFFFFF
|
||||
} StdVideoH265Level;
|
||||
typedef enum StdVideoH265LevelIdc {
|
||||
STD_VIDEO_H265_LEVEL_IDC_1_0 = 0,
|
||||
STD_VIDEO_H265_LEVEL_IDC_2_0 = 1,
|
||||
STD_VIDEO_H265_LEVEL_IDC_2_1 = 2,
|
||||
STD_VIDEO_H265_LEVEL_IDC_3_0 = 3,
|
||||
STD_VIDEO_H265_LEVEL_IDC_3_1 = 4,
|
||||
STD_VIDEO_H265_LEVEL_IDC_4_0 = 5,
|
||||
STD_VIDEO_H265_LEVEL_IDC_4_1 = 6,
|
||||
STD_VIDEO_H265_LEVEL_IDC_5_0 = 7,
|
||||
STD_VIDEO_H265_LEVEL_IDC_5_1 = 8,
|
||||
STD_VIDEO_H265_LEVEL_IDC_5_2 = 9,
|
||||
STD_VIDEO_H265_LEVEL_IDC_6_0 = 10,
|
||||
STD_VIDEO_H265_LEVEL_IDC_6_1 = 11,
|
||||
STD_VIDEO_H265_LEVEL_IDC_6_2 = 12,
|
||||
STD_VIDEO_H265_LEVEL_IDC_INVALID = 0x7FFFFFFF,
|
||||
STD_VIDEO_H265_LEVEL_IDC_MAX_ENUM = 0x7FFFFFFF
|
||||
} StdVideoH265LevelIdc;
|
||||
|
||||
typedef enum StdVideoH265SliceType {
|
||||
STD_VIDEO_H265_SLICE_TYPE_B = 0,
|
||||
@@ -94,10 +96,33 @@ typedef enum StdVideoH265PictureType {
|
||||
STD_VIDEO_H265_PICTURE_TYPE_INVALID = 0x7FFFFFFF,
|
||||
STD_VIDEO_H265_PICTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
|
||||
} StdVideoH265PictureType;
|
||||
|
||||
typedef enum StdVideoH265AspectRatioIdc {
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_UNSPECIFIED = 0,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_SQUARE = 1,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_12_11 = 2,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_10_11 = 3,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_16_11 = 4,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_40_33 = 5,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_24_11 = 6,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_20_11 = 7,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_32_11 = 8,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_80_33 = 9,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_18_11 = 10,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_15_11 = 11,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_64_33 = 12,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_160_99 = 13,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_4_3 = 14,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_3_2 = 15,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_2_1 = 16,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_EXTENDED_SAR = 255,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_INVALID = 0x7FFFFFFF,
|
||||
STD_VIDEO_H265_ASPECT_RATIO_IDC_MAX_ENUM = 0x7FFFFFFF
|
||||
} StdVideoH265AspectRatioIdc;
|
||||
typedef struct StdVideoH265DecPicBufMgr {
|
||||
uint32_t max_latency_increase_plus1[STD_VIDEO_H265_SUBLAYERS_MINUS1_LIST_SIZE];
|
||||
uint8_t max_dec_pic_buffering_minus1[STD_VIDEO_H265_SUBLAYERS_MINUS1_LIST_SIZE];
|
||||
uint8_t max_num_reorder_pics[STD_VIDEO_H265_SUBLAYERS_MINUS1_LIST_SIZE];
|
||||
uint32_t max_latency_increase_plus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE];
|
||||
uint8_t max_dec_pic_buffering_minus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE];
|
||||
uint8_t max_num_reorder_pics[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE];
|
||||
} StdVideoH265DecPicBufMgr;
|
||||
|
||||
typedef struct StdVideoH265SubLayerHrdParameters {
|
||||
@@ -119,20 +144,21 @@ typedef struct StdVideoH265HrdFlags {
|
||||
} StdVideoH265HrdFlags;
|
||||
|
||||
typedef struct StdVideoH265HrdParameters {
|
||||
uint8_t tick_divisor_minus2;
|
||||
uint8_t du_cpb_removal_delay_increment_length_minus1;
|
||||
uint8_t dpb_output_delay_du_length_minus1;
|
||||
uint8_t bit_rate_scale;
|
||||
uint8_t cpb_size_scale;
|
||||
uint8_t cpb_size_du_scale;
|
||||
uint8_t initial_cpb_removal_delay_length_minus1;
|
||||
uint8_t au_cpb_removal_delay_length_minus1;
|
||||
uint8_t dpb_output_delay_length_minus1;
|
||||
uint8_t cpb_cnt_minus1[STD_VIDEO_H265_SUBLAYERS_MINUS1_LIST_SIZE];
|
||||
uint16_t elemental_duration_in_tc_minus1[STD_VIDEO_H265_SUBLAYERS_MINUS1_LIST_SIZE];
|
||||
StdVideoH265SubLayerHrdParameters* pSubLayerHrdParametersNal[STD_VIDEO_H265_SUBLAYERS_MINUS1_LIST_SIZE];
|
||||
StdVideoH265SubLayerHrdParameters* pSubLayerHrdParametersVcl[STD_VIDEO_H265_SUBLAYERS_MINUS1_LIST_SIZE];
|
||||
StdVideoH265HrdFlags flags;
|
||||
StdVideoH265HrdFlags flags;
|
||||
uint8_t tick_divisor_minus2;
|
||||
uint8_t du_cpb_removal_delay_increment_length_minus1;
|
||||
uint8_t dpb_output_delay_du_length_minus1;
|
||||
uint8_t bit_rate_scale;
|
||||
uint8_t cpb_size_scale;
|
||||
uint8_t cpb_size_du_scale;
|
||||
uint8_t initial_cpb_removal_delay_length_minus1;
|
||||
uint8_t au_cpb_removal_delay_length_minus1;
|
||||
uint8_t dpb_output_delay_length_minus1;
|
||||
uint8_t cpb_cnt_minus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE];
|
||||
uint16_t elemental_duration_in_tc_minus1[STD_VIDEO_H265_SUBLAYERS_LIST_SIZE];
|
||||
uint16_t reserved[3];
|
||||
const StdVideoH265SubLayerHrdParameters* pSubLayerHrdParametersNal;
|
||||
const StdVideoH265SubLayerHrdParameters* pSubLayerHrdParametersVcl;
|
||||
} StdVideoH265HrdParameters;
|
||||
|
||||
typedef struct StdVideoH265VpsFlags {
|
||||
@@ -142,15 +168,33 @@ typedef struct StdVideoH265VpsFlags {
|
||||
uint32_t vps_poc_proportional_to_timing_flag : 1;
|
||||
} StdVideoH265VpsFlags;
|
||||
|
||||
typedef struct StdVideoH265ProfileTierLevelFlags {
|
||||
uint32_t general_tier_flag : 1;
|
||||
uint32_t general_progressive_source_flag : 1;
|
||||
uint32_t general_interlaced_source_flag : 1;
|
||||
uint32_t general_non_packed_constraint_flag : 1;
|
||||
uint32_t general_frame_only_constraint_flag : 1;
|
||||
} StdVideoH265ProfileTierLevelFlags;
|
||||
|
||||
typedef struct StdVideoH265ProfileTierLevel {
|
||||
StdVideoH265ProfileTierLevelFlags flags;
|
||||
StdVideoH265ProfileIdc general_profile_idc;
|
||||
StdVideoH265LevelIdc general_level_idc;
|
||||
} StdVideoH265ProfileTierLevel;
|
||||
|
||||
typedef struct StdVideoH265VideoParameterSet {
|
||||
uint8_t vps_video_parameter_set_id;
|
||||
uint8_t vps_max_sub_layers_minus1;
|
||||
uint32_t vps_num_units_in_tick;
|
||||
uint32_t vps_time_scale;
|
||||
uint32_t vps_num_ticks_poc_diff_one_minus1;
|
||||
StdVideoH265DecPicBufMgr* pDecPicBufMgr;
|
||||
StdVideoH265HrdParameters* pHrdParameters;
|
||||
StdVideoH265VpsFlags flags;
|
||||
StdVideoH265VpsFlags flags;
|
||||
uint8_t vps_video_parameter_set_id;
|
||||
uint8_t vps_max_sub_layers_minus1;
|
||||
uint8_t reserved1;
|
||||
uint8_t reserved2;
|
||||
uint32_t vps_num_units_in_tick;
|
||||
uint32_t vps_time_scale;
|
||||
uint32_t vps_num_ticks_poc_diff_one_minus1;
|
||||
uint32_t reserved3;
|
||||
const StdVideoH265DecPicBufMgr* pDecPicBufMgr;
|
||||
const StdVideoH265HrdParameters* pHrdParameters;
|
||||
const StdVideoH265ProfileTierLevel* pProfileTierLevel;
|
||||
} StdVideoH265VideoParameterSet;
|
||||
|
||||
typedef struct StdVideoH265ScalingLists {
|
||||
@@ -184,29 +228,32 @@ typedef struct StdVideoH265SpsVuiFlags {
|
||||
} StdVideoH265SpsVuiFlags;
|
||||
|
||||
typedef struct StdVideoH265SequenceParameterSetVui {
|
||||
uint8_t aspect_ratio_idc;
|
||||
uint16_t sar_width;
|
||||
uint16_t sar_height;
|
||||
uint8_t video_format;
|
||||
uint8_t colour_primaries;
|
||||
uint8_t transfer_characteristics;
|
||||
uint8_t matrix_coeffs;
|
||||
uint8_t chroma_sample_loc_type_top_field;
|
||||
uint8_t chroma_sample_loc_type_bottom_field;
|
||||
uint16_t def_disp_win_left_offset;
|
||||
uint16_t def_disp_win_right_offset;
|
||||
uint16_t def_disp_win_top_offset;
|
||||
uint16_t def_disp_win_bottom_offset;
|
||||
uint32_t vui_num_units_in_tick;
|
||||
uint32_t vui_time_scale;
|
||||
uint32_t vui_num_ticks_poc_diff_one_minus1;
|
||||
StdVideoH265HrdParameters* pHrdParameters;
|
||||
uint16_t min_spatial_segmentation_idc;
|
||||
uint8_t max_bytes_per_pic_denom;
|
||||
uint8_t max_bits_per_min_cu_denom;
|
||||
uint8_t log2_max_mv_length_horizontal;
|
||||
uint8_t log2_max_mv_length_vertical;
|
||||
StdVideoH265SpsVuiFlags flags;
|
||||
StdVideoH265SpsVuiFlags flags;
|
||||
StdVideoH265AspectRatioIdc aspect_ratio_idc;
|
||||
uint16_t sar_width;
|
||||
uint16_t sar_height;
|
||||
uint8_t video_format;
|
||||
uint8_t colour_primaries;
|
||||
uint8_t transfer_characteristics;
|
||||
uint8_t matrix_coeffs;
|
||||
uint8_t chroma_sample_loc_type_top_field;
|
||||
uint8_t chroma_sample_loc_type_bottom_field;
|
||||
uint8_t reserved1;
|
||||
uint8_t reserved2;
|
||||
uint16_t def_disp_win_left_offset;
|
||||
uint16_t def_disp_win_right_offset;
|
||||
uint16_t def_disp_win_top_offset;
|
||||
uint16_t def_disp_win_bottom_offset;
|
||||
uint32_t vui_num_units_in_tick;
|
||||
uint32_t vui_time_scale;
|
||||
uint32_t vui_num_ticks_poc_diff_one_minus1;
|
||||
uint16_t min_spatial_segmentation_idc;
|
||||
uint16_t reserved3;
|
||||
uint8_t max_bytes_per_pic_denom;
|
||||
uint8_t max_bits_per_min_cu_denom;
|
||||
uint8_t log2_max_mv_length_horizontal;
|
||||
uint8_t log2_max_mv_length_vertical;
|
||||
const StdVideoH265HrdParameters* pHrdParameters;
|
||||
} StdVideoH265SequenceParameterSetVui;
|
||||
|
||||
typedef struct StdVideoH265PredictorPaletteEntries {
|
||||
@@ -216,6 +263,8 @@ typedef struct StdVideoH265PredictorPaletteEntries {
|
||||
typedef struct StdVideoH265SpsFlags {
|
||||
uint32_t sps_temporal_id_nesting_flag : 1;
|
||||
uint32_t separate_colour_plane_flag : 1;
|
||||
uint32_t conformance_window_flag : 1;
|
||||
uint32_t sps_sub_layer_ordering_info_present_flag : 1;
|
||||
uint32_t scaling_list_enabled_flag : 1;
|
||||
uint32_t sps_scaling_list_data_present_flag : 1;
|
||||
uint32_t amp_enabled_flag : 1;
|
||||
@@ -237,50 +286,80 @@ typedef struct StdVideoH265SpsFlags {
|
||||
uint32_t high_precision_offsets_enabled_flag : 1;
|
||||
uint32_t persistent_rice_adaptation_enabled_flag : 1;
|
||||
uint32_t cabac_bypass_alignment_enabled_flag : 1;
|
||||
uint32_t sps_scc_extension_flag : 1;
|
||||
uint32_t sps_curr_pic_ref_enabled_flag : 1;
|
||||
uint32_t palette_mode_enabled_flag : 1;
|
||||
uint32_t sps_palette_predictor_initializer_present_flag : 1;
|
||||
uint32_t sps_palette_predictor_initializers_present_flag : 1;
|
||||
uint32_t intra_boundary_filtering_disabled_flag : 1;
|
||||
} StdVideoH265SpsFlags;
|
||||
|
||||
typedef struct StdVideoH265ShortTermRefPicSetFlags {
|
||||
uint32_t inter_ref_pic_set_prediction_flag : 1;
|
||||
uint32_t delta_rps_sign : 1;
|
||||
} StdVideoH265ShortTermRefPicSetFlags;
|
||||
|
||||
typedef struct StdVideoH265ShortTermRefPicSet {
|
||||
StdVideoH265ShortTermRefPicSetFlags flags;
|
||||
uint32_t delta_idx_minus1;
|
||||
uint16_t use_delta_flag;
|
||||
uint16_t abs_delta_rps_minus1;
|
||||
uint16_t used_by_curr_pic_flag;
|
||||
uint16_t used_by_curr_pic_s0_flag;
|
||||
uint16_t used_by_curr_pic_s1_flag;
|
||||
uint16_t reserved1;
|
||||
uint8_t reserved2;
|
||||
uint8_t reserved3;
|
||||
uint8_t num_negative_pics;
|
||||
uint8_t num_positive_pics;
|
||||
uint16_t delta_poc_s0_minus1[STD_VIDEO_H265_MAX_DPB_SIZE];
|
||||
uint16_t delta_poc_s1_minus1[STD_VIDEO_H265_MAX_DPB_SIZE];
|
||||
} StdVideoH265ShortTermRefPicSet;
|
||||
|
||||
typedef struct StdVideoH265LongTermRefPicsSps {
|
||||
uint32_t used_by_curr_pic_lt_sps_flag;
|
||||
uint32_t lt_ref_pic_poc_lsb_sps[STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS];
|
||||
} StdVideoH265LongTermRefPicsSps;
|
||||
|
||||
typedef struct StdVideoH265SequenceParameterSet {
|
||||
StdVideoH265ProfileIdc profile_idc;
|
||||
StdVideoH265Level level_idc;
|
||||
uint32_t pic_width_in_luma_samples;
|
||||
uint32_t pic_height_in_luma_samples;
|
||||
uint8_t sps_video_parameter_set_id;
|
||||
uint8_t sps_max_sub_layers_minus1;
|
||||
uint8_t sps_seq_parameter_set_id;
|
||||
uint8_t chroma_format_idc;
|
||||
uint8_t bit_depth_luma_minus8;
|
||||
uint8_t bit_depth_chroma_minus8;
|
||||
uint8_t log2_max_pic_order_cnt_lsb_minus4;
|
||||
uint8_t sps_max_dec_pic_buffering_minus1;
|
||||
uint8_t log2_min_luma_coding_block_size_minus3;
|
||||
uint8_t log2_diff_max_min_luma_coding_block_size;
|
||||
uint8_t log2_min_luma_transform_block_size_minus2;
|
||||
uint8_t log2_diff_max_min_luma_transform_block_size;
|
||||
uint8_t max_transform_hierarchy_depth_inter;
|
||||
uint8_t max_transform_hierarchy_depth_intra;
|
||||
uint8_t num_short_term_ref_pic_sets;
|
||||
uint8_t num_long_term_ref_pics_sps;
|
||||
uint8_t pcm_sample_bit_depth_luma_minus1;
|
||||
uint8_t pcm_sample_bit_depth_chroma_minus1;
|
||||
uint8_t log2_min_pcm_luma_coding_block_size_minus3;
|
||||
uint8_t log2_diff_max_min_pcm_luma_coding_block_size;
|
||||
uint32_t conf_win_left_offset;
|
||||
uint32_t conf_win_right_offset;
|
||||
uint32_t conf_win_top_offset;
|
||||
uint32_t conf_win_bottom_offset;
|
||||
StdVideoH265DecPicBufMgr* pDecPicBufMgr;
|
||||
StdVideoH265SpsFlags flags;
|
||||
StdVideoH265ScalingLists* pScalingLists;
|
||||
StdVideoH265SequenceParameterSetVui* pSequenceParameterSetVui;
|
||||
uint8_t palette_max_size;
|
||||
uint8_t delta_palette_max_predictor_size;
|
||||
uint8_t motion_vector_resolution_control_idc;
|
||||
uint8_t sps_num_palette_predictor_initializer_minus1;
|
||||
StdVideoH265PredictorPaletteEntries* pPredictorPaletteEntries;
|
||||
StdVideoH265SpsFlags flags;
|
||||
StdVideoH265ChromaFormatIdc chroma_format_idc;
|
||||
uint32_t pic_width_in_luma_samples;
|
||||
uint32_t pic_height_in_luma_samples;
|
||||
uint8_t sps_video_parameter_set_id;
|
||||
uint8_t sps_max_sub_layers_minus1;
|
||||
uint8_t sps_seq_parameter_set_id;
|
||||
uint8_t bit_depth_luma_minus8;
|
||||
uint8_t bit_depth_chroma_minus8;
|
||||
uint8_t log2_max_pic_order_cnt_lsb_minus4;
|
||||
uint8_t log2_min_luma_coding_block_size_minus3;
|
||||
uint8_t log2_diff_max_min_luma_coding_block_size;
|
||||
uint8_t log2_min_luma_transform_block_size_minus2;
|
||||
uint8_t log2_diff_max_min_luma_transform_block_size;
|
||||
uint8_t max_transform_hierarchy_depth_inter;
|
||||
uint8_t max_transform_hierarchy_depth_intra;
|
||||
uint8_t num_short_term_ref_pic_sets;
|
||||
uint8_t num_long_term_ref_pics_sps;
|
||||
uint8_t pcm_sample_bit_depth_luma_minus1;
|
||||
uint8_t pcm_sample_bit_depth_chroma_minus1;
|
||||
uint8_t log2_min_pcm_luma_coding_block_size_minus3;
|
||||
uint8_t log2_diff_max_min_pcm_luma_coding_block_size;
|
||||
uint8_t reserved1;
|
||||
uint8_t reserved2;
|
||||
uint8_t palette_max_size;
|
||||
uint8_t delta_palette_max_predictor_size;
|
||||
uint8_t motion_vector_resolution_control_idc;
|
||||
uint8_t sps_num_palette_predictor_initializers_minus1;
|
||||
uint32_t conf_win_left_offset;
|
||||
uint32_t conf_win_right_offset;
|
||||
uint32_t conf_win_top_offset;
|
||||
uint32_t conf_win_bottom_offset;
|
||||
const StdVideoH265ProfileTierLevel* pProfileTierLevel;
|
||||
const StdVideoH265DecPicBufMgr* pDecPicBufMgr;
|
||||
const StdVideoH265ScalingLists* pScalingLists;
|
||||
const StdVideoH265ShortTermRefPicSet* pShortTermRefPicSet;
|
||||
const StdVideoH265LongTermRefPicsSps* pLongTermRefPicsSps;
|
||||
const StdVideoH265SequenceParameterSetVui* pSequenceParameterSetVui;
|
||||
const StdVideoH265PredictorPaletteEntries* pPredictorPaletteEntries;
|
||||
} StdVideoH265SequenceParameterSet;
|
||||
|
||||
typedef struct StdVideoH265PpsFlags {
|
||||
@@ -312,44 +391,48 @@ typedef struct StdVideoH265PpsFlags {
|
||||
uint32_t pps_curr_pic_ref_enabled_flag : 1;
|
||||
uint32_t residual_adaptive_colour_transform_enabled_flag : 1;
|
||||
uint32_t pps_slice_act_qp_offsets_present_flag : 1;
|
||||
uint32_t pps_palette_predictor_initializer_present_flag : 1;
|
||||
uint32_t pps_palette_predictor_initializers_present_flag : 1;
|
||||
uint32_t monochrome_palette_flag : 1;
|
||||
uint32_t pps_range_extension_flag : 1;
|
||||
} StdVideoH265PpsFlags;
|
||||
|
||||
typedef struct StdVideoH265PictureParameterSet {
|
||||
uint8_t pps_pic_parameter_set_id;
|
||||
uint8_t pps_seq_parameter_set_id;
|
||||
uint8_t num_extra_slice_header_bits;
|
||||
uint8_t num_ref_idx_l0_default_active_minus1;
|
||||
uint8_t num_ref_idx_l1_default_active_minus1;
|
||||
int8_t init_qp_minus26;
|
||||
uint8_t diff_cu_qp_delta_depth;
|
||||
int8_t pps_cb_qp_offset;
|
||||
int8_t pps_cr_qp_offset;
|
||||
uint8_t num_tile_columns_minus1;
|
||||
uint8_t num_tile_rows_minus1;
|
||||
uint16_t column_width_minus1[STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_COLS_LIST_SIZE];
|
||||
uint16_t row_height_minus1[STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_ROWS_LIST_SIZE];
|
||||
int8_t pps_beta_offset_div2;
|
||||
int8_t pps_tc_offset_div2;
|
||||
uint8_t log2_parallel_merge_level_minus2;
|
||||
StdVideoH265PpsFlags flags;
|
||||
StdVideoH265ScalingLists* pScalingLists;
|
||||
uint8_t log2_max_transform_skip_block_size_minus2;
|
||||
uint8_t diff_cu_chroma_qp_offset_depth;
|
||||
uint8_t chroma_qp_offset_list_len_minus1;
|
||||
int8_t cb_qp_offset_list[STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE];
|
||||
int8_t cr_qp_offset_list[STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE];
|
||||
uint8_t log2_sao_offset_scale_luma;
|
||||
uint8_t log2_sao_offset_scale_chroma;
|
||||
int8_t pps_act_y_qp_offset_plus5;
|
||||
int8_t pps_act_cb_qp_offset_plus5;
|
||||
int8_t pps_act_cr_qp_offset_plus5;
|
||||
uint8_t pps_num_palette_predictor_initializer;
|
||||
uint8_t luma_bit_depth_entry_minus8;
|
||||
uint8_t chroma_bit_depth_entry_minus8;
|
||||
StdVideoH265PredictorPaletteEntries* pPredictorPaletteEntries;
|
||||
StdVideoH265PpsFlags flags;
|
||||
uint8_t pps_pic_parameter_set_id;
|
||||
uint8_t pps_seq_parameter_set_id;
|
||||
uint8_t sps_video_parameter_set_id;
|
||||
uint8_t num_extra_slice_header_bits;
|
||||
uint8_t num_ref_idx_l0_default_active_minus1;
|
||||
uint8_t num_ref_idx_l1_default_active_minus1;
|
||||
int8_t init_qp_minus26;
|
||||
uint8_t diff_cu_qp_delta_depth;
|
||||
int8_t pps_cb_qp_offset;
|
||||
int8_t pps_cr_qp_offset;
|
||||
int8_t pps_beta_offset_div2;
|
||||
int8_t pps_tc_offset_div2;
|
||||
uint8_t log2_parallel_merge_level_minus2;
|
||||
uint8_t log2_max_transform_skip_block_size_minus2;
|
||||
uint8_t diff_cu_chroma_qp_offset_depth;
|
||||
uint8_t chroma_qp_offset_list_len_minus1;
|
||||
int8_t cb_qp_offset_list[STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE];
|
||||
int8_t cr_qp_offset_list[STD_VIDEO_H265_CHROMA_QP_OFFSET_LIST_SIZE];
|
||||
uint8_t log2_sao_offset_scale_luma;
|
||||
uint8_t log2_sao_offset_scale_chroma;
|
||||
int8_t pps_act_y_qp_offset_plus5;
|
||||
int8_t pps_act_cb_qp_offset_plus5;
|
||||
int8_t pps_act_cr_qp_offset_plus3;
|
||||
uint8_t pps_num_palette_predictor_initializers;
|
||||
uint8_t luma_bit_depth_entry_minus8;
|
||||
uint8_t chroma_bit_depth_entry_minus8;
|
||||
uint8_t num_tile_columns_minus1;
|
||||
uint8_t num_tile_rows_minus1;
|
||||
uint8_t reserved1;
|
||||
uint8_t reserved2;
|
||||
uint16_t column_width_minus1[STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_COLS_LIST_SIZE];
|
||||
uint16_t row_height_minus1[STD_VIDEO_H265_CHROMA_QP_OFFSET_TILE_ROWS_LIST_SIZE];
|
||||
uint32_t reserved3;
|
||||
const StdVideoH265ScalingLists* pScalingLists;
|
||||
const StdVideoH265PredictorPaletteEntries* pPredictorPaletteEntries;
|
||||
} StdVideoH265PictureParameterSet;
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,12 @@ extern "C" {
|
||||
|
||||
|
||||
#define vulkan_video_codec_h265std_decode 1
|
||||
// Vulkan 0.9 provisional Vulkan video H.265 decode std specification version number
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_API_VERSION_0_9_9 VK_MAKE_VIDEO_STD_VERSION(0, 9, 9) // Patch version should always be set to 0
|
||||
|
||||
#define STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE 8
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_API_VERSION_0_9_9
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H265_DECODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_decode"
|
||||
typedef struct StdVideoDecodeH265PictureInfoFlags {
|
||||
uint32_t IrapPicFlag : 1;
|
||||
uint32_t IdrPicFlag : 1;
|
||||
@@ -29,27 +34,27 @@ typedef struct StdVideoDecodeH265PictureInfoFlags {
|
||||
} StdVideoDecodeH265PictureInfoFlags;
|
||||
|
||||
typedef struct StdVideoDecodeH265PictureInfo {
|
||||
uint8_t vps_video_parameter_set_id;
|
||||
uint8_t sps_seq_parameter_set_id;
|
||||
StdVideoDecodeH265PictureInfoFlags flags;
|
||||
uint8_t sps_video_parameter_set_id;
|
||||
uint8_t pps_seq_parameter_set_id;
|
||||
uint8_t pps_pic_parameter_set_id;
|
||||
uint8_t num_short_term_ref_pic_sets;
|
||||
uint8_t NumDeltaPocsOfRefRpsIdx;
|
||||
int32_t PicOrderCntVal;
|
||||
uint16_t NumBitsForSTRefPicSetInSlice;
|
||||
uint8_t NumDeltaPocsOfRefRpsIdx;
|
||||
uint16_t reserved;
|
||||
uint8_t RefPicSetStCurrBefore[STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE];
|
||||
uint8_t RefPicSetStCurrAfter[STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE];
|
||||
uint8_t RefPicSetLtCurr[STD_VIDEO_DECODE_H265_REF_PIC_SET_LIST_SIZE];
|
||||
StdVideoDecodeH265PictureInfoFlags flags;
|
||||
} StdVideoDecodeH265PictureInfo;
|
||||
|
||||
typedef struct StdVideoDecodeH265ReferenceInfoFlags {
|
||||
uint32_t is_long_term : 1;
|
||||
uint32_t is_non_existing : 1;
|
||||
uint32_t used_for_long_term_reference : 1;
|
||||
uint32_t unused_for_reference : 1;
|
||||
} StdVideoDecodeH265ReferenceInfoFlags;
|
||||
|
||||
typedef struct StdVideoDecodeH265ReferenceInfo {
|
||||
int32_t PicOrderCntVal;
|
||||
StdVideoDecodeH265ReferenceInfoFlags flags;
|
||||
int32_t PicOrderCntVal;
|
||||
} StdVideoDecodeH265ReferenceInfo;
|
||||
|
||||
|
||||
|
||||
@@ -20,13 +20,37 @@ extern "C" {
|
||||
|
||||
|
||||
#define vulkan_video_codec_h265std_encode 1
|
||||
#define STD_VIDEO_ENCODE_H265_LUMA_LIST_SIZE 15
|
||||
#define STD_VIDEO_ENCODE_H265_CHROMA_LIST_SIZE 15
|
||||
#define STD_VIDEO_ENCODE_H265_CHROMA_LISTS_NUM 2
|
||||
// Vulkan 0.9 provisional Vulkan video H.265 encode std specification version number
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_9 VK_MAKE_VIDEO_STD_VERSION(0, 9, 9) // Patch version should always be set to 0
|
||||
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_SPEC_VERSION VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_API_VERSION_0_9_9
|
||||
#define VK_STD_VULKAN_VIDEO_CODEC_H265_ENCODE_EXTENSION_NAME "VK_STD_vulkan_video_codec_h265_encode"
|
||||
typedef struct StdVideoEncodeH265WeightTableFlags {
|
||||
uint16_t luma_weight_l0_flag;
|
||||
uint16_t chroma_weight_l0_flag;
|
||||
uint16_t luma_weight_l1_flag;
|
||||
uint16_t chroma_weight_l1_flag;
|
||||
} StdVideoEncodeH265WeightTableFlags;
|
||||
|
||||
typedef struct StdVideoEncodeH265WeightTable {
|
||||
StdVideoEncodeH265WeightTableFlags flags;
|
||||
uint8_t luma_log2_weight_denom;
|
||||
int8_t delta_chroma_log2_weight_denom;
|
||||
int8_t delta_luma_weight_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF];
|
||||
int8_t luma_offset_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF];
|
||||
int8_t delta_chroma_weight_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES];
|
||||
int8_t delta_chroma_offset_l0[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES];
|
||||
int8_t delta_luma_weight_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF];
|
||||
int8_t luma_offset_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF];
|
||||
int8_t delta_chroma_weight_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES];
|
||||
int8_t delta_chroma_offset_l1[STD_VIDEO_H265_MAX_NUM_LIST_REF][STD_VIDEO_H265_MAX_CHROMA_PLANES];
|
||||
} StdVideoEncodeH265WeightTable;
|
||||
|
||||
typedef struct StdVideoEncodeH265SliceSegmentHeaderFlags {
|
||||
uint32_t first_slice_segment_in_pic_flag : 1;
|
||||
uint32_t no_output_of_prior_pics_flag : 1;
|
||||
uint32_t dependent_slice_segment_flag : 1;
|
||||
uint32_t pic_output_flag : 1;
|
||||
uint32_t short_term_ref_pic_set_sps_flag : 1;
|
||||
uint32_t slice_temporal_mvp_enable_flag : 1;
|
||||
uint32_t slice_sao_luma_flag : 1;
|
||||
@@ -34,47 +58,42 @@ typedef struct StdVideoEncodeH265SliceSegmentHeaderFlags {
|
||||
uint32_t num_ref_idx_active_override_flag : 1;
|
||||
uint32_t mvd_l1_zero_flag : 1;
|
||||
uint32_t cabac_init_flag : 1;
|
||||
uint32_t slice_deblocking_filter_disable_flag : 1;
|
||||
uint32_t cu_chroma_qp_offset_enabled_flag : 1;
|
||||
uint32_t deblocking_filter_override_flag : 1;
|
||||
uint32_t slice_deblocking_filter_disabled_flag : 1;
|
||||
uint32_t collocated_from_l0_flag : 1;
|
||||
uint32_t slice_loop_filter_across_slices_enabled_flag : 1;
|
||||
uint32_t bLastSliceInPic : 1;
|
||||
uint32_t reservedBits : 18;
|
||||
uint16_t luma_weight_l0_flag;
|
||||
uint16_t chroma_weight_l0_flag;
|
||||
uint16_t luma_weight_l1_flag;
|
||||
uint16_t chroma_weight_l1_flag;
|
||||
} StdVideoEncodeH265SliceSegmentHeaderFlags;
|
||||
|
||||
typedef struct StdVideoEncodeH265SliceSegmentLongTermRefPics {
|
||||
uint8_t num_long_term_sps;
|
||||
uint8_t num_long_term_pics;
|
||||
uint8_t lt_idx_sps[STD_VIDEO_H265_MAX_LONG_TERM_REF_PICS_SPS];
|
||||
uint8_t poc_lsb_lt[STD_VIDEO_H265_MAX_LONG_TERM_PICS];
|
||||
uint16_t used_by_curr_pic_lt_flag;
|
||||
uint8_t delta_poc_msb_present_flag[STD_VIDEO_H265_MAX_DELTA_POC];
|
||||
uint8_t delta_poc_msb_cycle_lt[STD_VIDEO_H265_MAX_DELTA_POC];
|
||||
} StdVideoEncodeH265SliceSegmentLongTermRefPics;
|
||||
|
||||
typedef struct StdVideoEncodeH265SliceSegmentHeader {
|
||||
StdVideoH265SliceType slice_type;
|
||||
uint8_t slice_pic_parameter_set_id;
|
||||
uint8_t num_short_term_ref_pic_sets;
|
||||
uint32_t slice_segment_address;
|
||||
uint8_t short_term_ref_pic_set_idx;
|
||||
uint8_t num_long_term_sps;
|
||||
uint8_t num_long_term_pics;
|
||||
uint8_t collocated_ref_idx;
|
||||
uint8_t num_ref_idx_l0_active_minus1;
|
||||
uint8_t num_ref_idx_l1_active_minus1;
|
||||
uint8_t luma_log2_weight_denom;
|
||||
int8_t delta_chroma_log2_weight_denom;
|
||||
int8_t delta_luma_weight_l0[STD_VIDEO_ENCODE_H265_LUMA_LIST_SIZE];
|
||||
int8_t luma_offset_l0[STD_VIDEO_ENCODE_H265_LUMA_LIST_SIZE];
|
||||
int8_t delta_chroma_weight_l0[STD_VIDEO_ENCODE_H265_CHROMA_LIST_SIZE][STD_VIDEO_ENCODE_H265_CHROMA_LISTS_NUM];
|
||||
int8_t delta_chroma_offset_l0[STD_VIDEO_ENCODE_H265_CHROMA_LIST_SIZE][STD_VIDEO_ENCODE_H265_CHROMA_LISTS_NUM];
|
||||
int8_t delta_luma_weight_l1[STD_VIDEO_ENCODE_H265_LUMA_LIST_SIZE];
|
||||
int8_t luma_offset_l1[STD_VIDEO_ENCODE_H265_LUMA_LIST_SIZE];
|
||||
int8_t delta_chroma_weight_l1[STD_VIDEO_ENCODE_H265_CHROMA_LIST_SIZE][STD_VIDEO_ENCODE_H265_CHROMA_LISTS_NUM];
|
||||
int8_t delta_chroma_offset_l1[STD_VIDEO_ENCODE_H265_CHROMA_LIST_SIZE][STD_VIDEO_ENCODE_H265_CHROMA_LISTS_NUM];
|
||||
uint8_t MaxNumMergeCand;
|
||||
int8_t slice_cb_qp_offset;
|
||||
int8_t slice_cr_qp_offset;
|
||||
int8_t slice_beta_offset_div2;
|
||||
int8_t slice_tc_offset_div2;
|
||||
int8_t slice_act_y_qp_offset;
|
||||
int8_t slice_act_cb_qp_offset;
|
||||
int8_t slice_act_cr_qp_offset;
|
||||
StdVideoEncodeH265SliceSegmentHeaderFlags flags;
|
||||
StdVideoEncodeH265SliceSegmentHeaderFlags flags;
|
||||
StdVideoH265SliceType slice_type;
|
||||
uint32_t slice_segment_address;
|
||||
uint8_t short_term_ref_pic_set_idx;
|
||||
uint8_t collocated_ref_idx;
|
||||
uint8_t num_ref_idx_l0_active_minus1;
|
||||
uint8_t num_ref_idx_l1_active_minus1;
|
||||
uint8_t MaxNumMergeCand;
|
||||
int8_t slice_cb_qp_offset;
|
||||
int8_t slice_cr_qp_offset;
|
||||
int8_t slice_beta_offset_div2;
|
||||
int8_t slice_tc_offset_div2;
|
||||
int8_t slice_act_y_qp_offset;
|
||||
int8_t slice_act_cb_qp_offset;
|
||||
int8_t slice_act_cr_qp_offset;
|
||||
const StdVideoH265ShortTermRefPicSet* pShortTermRefPicSet;
|
||||
const StdVideoEncodeH265SliceSegmentLongTermRefPics* pLongTermRefPics;
|
||||
const StdVideoEncodeH265WeightTable* pWeightTable;
|
||||
} StdVideoEncodeH265SliceSegmentHeader;
|
||||
|
||||
typedef struct StdVideoEncodeH265ReferenceModificationFlags {
|
||||
@@ -85,35 +104,38 @@ typedef struct StdVideoEncodeH265ReferenceModificationFlags {
|
||||
typedef struct StdVideoEncodeH265ReferenceModifications {
|
||||
StdVideoEncodeH265ReferenceModificationFlags flags;
|
||||
uint8_t referenceList0ModificationsCount;
|
||||
uint8_t* pReferenceList0Modifications;
|
||||
const uint8_t* pReferenceList0Modifications;
|
||||
uint8_t referenceList1ModificationsCount;
|
||||
uint8_t* pReferenceList1Modifications;
|
||||
const uint8_t* pReferenceList1Modifications;
|
||||
} StdVideoEncodeH265ReferenceModifications;
|
||||
|
||||
typedef struct StdVideoEncodeH265PictureInfoFlags {
|
||||
uint32_t is_reference_flag : 1;
|
||||
uint32_t IrapPicFlag : 1;
|
||||
uint32_t long_term_flag : 1;
|
||||
uint32_t discardable_flag : 1;
|
||||
uint32_t cross_layer_bla_flag : 1;
|
||||
} StdVideoEncodeH265PictureInfoFlags;
|
||||
|
||||
typedef struct StdVideoEncodeH265PictureInfo {
|
||||
StdVideoEncodeH265PictureInfoFlags flags;
|
||||
StdVideoH265PictureType PictureType;
|
||||
uint8_t sps_video_parameter_set_id;
|
||||
uint8_t pps_seq_parameter_set_id;
|
||||
uint8_t pps_pic_parameter_set_id;
|
||||
int32_t PicOrderCntVal;
|
||||
uint8_t TemporalId;
|
||||
StdVideoEncodeH265PictureInfoFlags flags;
|
||||
} StdVideoEncodeH265PictureInfo;
|
||||
|
||||
typedef struct StdVideoEncodeH265ReferenceInfoFlags {
|
||||
uint32_t is_long_term : 1;
|
||||
uint32_t isUsedFlag : 1;
|
||||
uint32_t used_for_long_term_reference : 1;
|
||||
uint32_t unused_for_reference : 1;
|
||||
} StdVideoEncodeH265ReferenceInfoFlags;
|
||||
|
||||
typedef struct StdVideoEncodeH265ReferenceInfo {
|
||||
StdVideoEncodeH265ReferenceInfoFlags flags;
|
||||
int32_t PicOrderCntVal;
|
||||
uint8_t TemporalId;
|
||||
StdVideoEncodeH265ReferenceInfoFlags flags;
|
||||
} StdVideoEncodeH265ReferenceInfo;
|
||||
|
||||
|
||||
|
||||
@@ -2,45 +2,15 @@
|
||||
// File: vk_platform.h
|
||||
//
|
||||
/*
|
||||
** Copyright (c) 2014-2017 The Khronos Group Inc.
|
||||
** Copyright 2014-2022 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
** SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef VK_PLATFORM_H_
|
||||
#define VK_PLATFORM_H_
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#define VK_USE_PLATFORM_ANDROID_KHR 1
|
||||
#elif defined(IOS)
|
||||
#define VK_USE_PLATFORM_IOS_MVK 1
|
||||
#elif defined(__linux__)
|
||||
#if defined(FILAMENT_SUPPORTS_XCB)
|
||||
#define VK_USE_PLATFORM_XCB_KHR 1
|
||||
#endif
|
||||
#if defined(FILAMENT_SUPPORTS_XLIB)
|
||||
#define VK_USE_PLATFORM_XLIB_KHR 1
|
||||
#endif
|
||||
#if defined(FILAMENT_SUPPORTS_WAYLAND)
|
||||
#define VK_USE_PLATFORM_WAYLAND_KHR 1
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
#define VK_USE_PLATFORM_MACOS_MVK 1
|
||||
#elif defined(WIN32)
|
||||
#define VK_USE_PLATFORM_WIN32_KHR 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
@@ -72,7 +42,7 @@ extern "C"
|
||||
#define VKAPI_CALL __stdcall
|
||||
#define VKAPI_PTR VKAPI_CALL
|
||||
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
|
||||
#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
|
||||
#error "Vulkan is not supported for the 'armeabi' NDK ABI"
|
||||
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
|
||||
// On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
|
||||
// calling convention, i.e. float parameters are passed in registers. This
|
||||
@@ -88,7 +58,9 @@ extern "C"
|
||||
#define VKAPI_PTR
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#if !defined(VK_NO_STDDEF_H)
|
||||
#include <stddef.h>
|
||||
#endif // !defined(VK_NO_STDDEF_H)
|
||||
|
||||
#if !defined(VK_NO_STDINT_H)
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1600)
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
|
||||
|
||||
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
||||
#include <wayland-client.h>
|
||||
#include "vulkan_wayland.h"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ extern "C" {
|
||||
#define VK_KHR_video_queue 1
|
||||
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionKHR)
|
||||
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionParametersKHR)
|
||||
#define VK_KHR_VIDEO_QUEUE_SPEC_VERSION 3
|
||||
#define VK_KHR_VIDEO_QUEUE_SPEC_VERSION 7
|
||||
#define VK_KHR_VIDEO_QUEUE_EXTENSION_NAME "VK_KHR_video_queue"
|
||||
|
||||
typedef enum VkQueryResultStatusKHR {
|
||||
@@ -33,7 +33,7 @@ typedef enum VkQueryResultStatusKHR {
|
||||
} VkQueryResultStatusKHR;
|
||||
|
||||
typedef enum VkVideoCodecOperationFlagBitsKHR {
|
||||
VK_VIDEO_CODEC_OPERATION_INVALID_BIT_KHR = 0,
|
||||
VK_VIDEO_CODEC_OPERATION_NONE_KHR = 0,
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
VK_VIDEO_CODEC_OPERATION_ENCODE_H264_BIT_EXT = 0x00010000,
|
||||
#endif
|
||||
@@ -51,7 +51,7 @@ typedef enum VkVideoCodecOperationFlagBitsKHR {
|
||||
typedef VkFlags VkVideoCodecOperationFlagsKHR;
|
||||
|
||||
typedef enum VkVideoChromaSubsamplingFlagBitsKHR {
|
||||
VK_VIDEO_CHROMA_SUBSAMPLING_INVALID_BIT_KHR = 0,
|
||||
VK_VIDEO_CHROMA_SUBSAMPLING_INVALID_KHR = 0,
|
||||
VK_VIDEO_CHROMA_SUBSAMPLING_MONOCHROME_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR = 0x00000002,
|
||||
VK_VIDEO_CHROMA_SUBSAMPLING_422_BIT_KHR = 0x00000004,
|
||||
@@ -77,134 +77,136 @@ typedef enum VkVideoCapabilityFlagBitsKHR {
|
||||
typedef VkFlags VkVideoCapabilityFlagsKHR;
|
||||
|
||||
typedef enum VkVideoSessionCreateFlagBitsKHR {
|
||||
VK_VIDEO_SESSION_CREATE_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_SESSION_CREATE_PROTECTED_CONTENT_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_SESSION_CREATE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoSessionCreateFlagBitsKHR;
|
||||
typedef VkFlags VkVideoSessionCreateFlagsKHR;
|
||||
typedef VkFlags VkVideoSessionParametersCreateFlagsKHR;
|
||||
typedef VkFlags VkVideoBeginCodingFlagsKHR;
|
||||
typedef VkFlags VkVideoEndCodingFlagsKHR;
|
||||
|
||||
typedef enum VkVideoCodingControlFlagBitsKHR {
|
||||
VK_VIDEO_CODING_CONTROL_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_CODING_CONTROL_RESET_BIT_KHR = 0x00000001,
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
VK_VIDEO_CODING_CONTROL_ENCODE_RATE_CONTROL_BIT_KHR = 0x00000002,
|
||||
#endif
|
||||
#ifdef VK_ENABLE_BETA_EXTENSIONS
|
||||
VK_VIDEO_CODING_CONTROL_ENCODE_RATE_CONTROL_LAYER_BIT_KHR = 0x00000004,
|
||||
#endif
|
||||
VK_VIDEO_CODING_CONTROL_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoCodingControlFlagBitsKHR;
|
||||
typedef VkFlags VkVideoCodingControlFlagsKHR;
|
||||
|
||||
typedef enum VkVideoCodingQualityPresetFlagBitsKHR {
|
||||
VK_VIDEO_CODING_QUALITY_PRESET_NORMAL_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_CODING_QUALITY_PRESET_POWER_BIT_KHR = 0x00000002,
|
||||
VK_VIDEO_CODING_QUALITY_PRESET_QUALITY_BIT_KHR = 0x00000004,
|
||||
VK_VIDEO_CODING_QUALITY_PRESET_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoCodingQualityPresetFlagBitsKHR;
|
||||
typedef VkFlags VkVideoCodingQualityPresetFlagsKHR;
|
||||
typedef struct VkQueueFamilyQueryResultStatusProperties2KHR {
|
||||
typedef struct VkQueueFamilyQueryResultStatusPropertiesKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkBool32 supported;
|
||||
} VkQueueFamilyQueryResultStatusProperties2KHR;
|
||||
VkBool32 queryResultStatusSupport;
|
||||
} VkQueueFamilyQueryResultStatusPropertiesKHR;
|
||||
|
||||
typedef struct VkVideoQueueFamilyProperties2KHR {
|
||||
typedef struct VkQueueFamilyVideoPropertiesKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkVideoCodecOperationFlagsKHR videoCodecOperations;
|
||||
} VkVideoQueueFamilyProperties2KHR;
|
||||
} VkQueueFamilyVideoPropertiesKHR;
|
||||
|
||||
typedef struct VkVideoProfileKHR {
|
||||
typedef struct VkVideoProfileInfoKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
const void* pNext;
|
||||
VkVideoCodecOperationFlagBitsKHR videoCodecOperation;
|
||||
VkVideoChromaSubsamplingFlagsKHR chromaSubsampling;
|
||||
VkVideoComponentBitDepthFlagsKHR lumaBitDepth;
|
||||
VkVideoComponentBitDepthFlagsKHR chromaBitDepth;
|
||||
} VkVideoProfileKHR;
|
||||
} VkVideoProfileInfoKHR;
|
||||
|
||||
typedef struct VkVideoProfilesKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
uint32_t profileCount;
|
||||
const VkVideoProfileKHR* pProfiles;
|
||||
} VkVideoProfilesKHR;
|
||||
typedef struct VkVideoProfileListInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t profileCount;
|
||||
const VkVideoProfileInfoKHR* pProfiles;
|
||||
} VkVideoProfileListInfoKHR;
|
||||
|
||||
typedef struct VkVideoCapabilitiesKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkVideoCapabilityFlagsKHR capabilityFlags;
|
||||
VkVideoCapabilityFlagsKHR flags;
|
||||
VkDeviceSize minBitstreamBufferOffsetAlignment;
|
||||
VkDeviceSize minBitstreamBufferSizeAlignment;
|
||||
VkExtent2D videoPictureExtentGranularity;
|
||||
VkExtent2D minExtent;
|
||||
VkExtent2D maxExtent;
|
||||
uint32_t maxReferencePicturesSlotsCount;
|
||||
uint32_t maxReferencePicturesActiveCount;
|
||||
VkExtent2D pictureAccessGranularity;
|
||||
VkExtent2D minCodedExtent;
|
||||
VkExtent2D maxCodedExtent;
|
||||
uint32_t maxDpbSlots;
|
||||
uint32_t maxActiveReferencePictures;
|
||||
VkExtensionProperties stdHeaderVersion;
|
||||
} VkVideoCapabilitiesKHR;
|
||||
|
||||
typedef struct VkPhysicalDeviceVideoFormatInfoKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkImageUsageFlags imageUsage;
|
||||
const VkVideoProfilesKHR* pVideoProfiles;
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkImageUsageFlags imageUsage;
|
||||
} VkPhysicalDeviceVideoFormatInfoKHR;
|
||||
|
||||
typedef struct VkVideoFormatPropertiesKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkFormat format;
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkFormat format;
|
||||
VkComponentMapping componentMapping;
|
||||
VkImageCreateFlags imageCreateFlags;
|
||||
VkImageType imageType;
|
||||
VkImageTiling imageTiling;
|
||||
VkImageUsageFlags imageUsageFlags;
|
||||
} VkVideoFormatPropertiesKHR;
|
||||
|
||||
typedef struct VkVideoPictureResourceKHR {
|
||||
typedef struct VkVideoPictureResourceInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkOffset2D codedOffset;
|
||||
VkExtent2D codedExtent;
|
||||
uint32_t baseArrayLayer;
|
||||
VkImageView imageViewBinding;
|
||||
} VkVideoPictureResourceKHR;
|
||||
} VkVideoPictureResourceInfoKHR;
|
||||
|
||||
typedef struct VkVideoReferenceSlotKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
int8_t slotIndex;
|
||||
const VkVideoPictureResourceKHR* pPictureResource;
|
||||
} VkVideoReferenceSlotKHR;
|
||||
typedef struct VkVideoReferenceSlotInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
int32_t slotIndex;
|
||||
const VkVideoPictureResourceInfoKHR* pPictureResource;
|
||||
} VkVideoReferenceSlotInfoKHR;
|
||||
|
||||
typedef struct VkVideoGetMemoryPropertiesKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t memoryBindIndex;
|
||||
VkMemoryRequirements2* pMemoryRequirements;
|
||||
} VkVideoGetMemoryPropertiesKHR;
|
||||
typedef struct VkVideoSessionMemoryRequirementsKHR {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
uint32_t memoryBindIndex;
|
||||
VkMemoryRequirements memoryRequirements;
|
||||
} VkVideoSessionMemoryRequirementsKHR;
|
||||
|
||||
typedef struct VkVideoBindMemoryKHR {
|
||||
typedef struct VkBindVideoSessionMemoryInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t memoryBindIndex;
|
||||
VkDeviceMemory memory;
|
||||
VkDeviceSize memoryOffset;
|
||||
VkDeviceSize memorySize;
|
||||
} VkVideoBindMemoryKHR;
|
||||
} VkBindVideoSessionMemoryInfoKHR;
|
||||
|
||||
typedef struct VkVideoSessionCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t queueFamilyIndex;
|
||||
VkVideoSessionCreateFlagsKHR flags;
|
||||
const VkVideoProfileKHR* pVideoProfile;
|
||||
const VkVideoProfileInfoKHR* pVideoProfile;
|
||||
VkFormat pictureFormat;
|
||||
VkExtent2D maxCodedExtent;
|
||||
VkFormat referencePicturesFormat;
|
||||
uint32_t maxReferencePicturesSlotsCount;
|
||||
uint32_t maxReferencePicturesActiveCount;
|
||||
VkFormat referencePictureFormat;
|
||||
uint32_t maxDpbSlots;
|
||||
uint32_t maxActiveReferencePictures;
|
||||
const VkExtensionProperties* pStdHeaderVersion;
|
||||
} VkVideoSessionCreateInfoKHR;
|
||||
|
||||
typedef struct VkVideoSessionParametersCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoSessionParametersKHR videoSessionParametersTemplate;
|
||||
VkVideoSessionKHR videoSession;
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoSessionParametersCreateFlagsKHR flags;
|
||||
VkVideoSessionParametersKHR videoSessionParametersTemplate;
|
||||
VkVideoSessionKHR videoSession;
|
||||
} VkVideoSessionParametersCreateInfoKHR;
|
||||
|
||||
typedef struct VkVideoSessionParametersUpdateInfoKHR {
|
||||
@@ -217,11 +219,10 @@ typedef struct VkVideoBeginCodingInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoBeginCodingFlagsKHR flags;
|
||||
VkVideoCodingQualityPresetFlagsKHR codecQualityPreset;
|
||||
VkVideoSessionKHR videoSession;
|
||||
VkVideoSessionParametersKHR videoSessionParameters;
|
||||
uint32_t referenceSlotCount;
|
||||
const VkVideoReferenceSlotKHR* pReferenceSlots;
|
||||
const VkVideoReferenceSlotInfoKHR* pReferenceSlots;
|
||||
} VkVideoBeginCodingInfoKHR;
|
||||
|
||||
typedef struct VkVideoEndCodingInfoKHR {
|
||||
@@ -236,12 +237,12 @@ typedef struct VkVideoCodingControlInfoKHR {
|
||||
VkVideoCodingControlFlagsKHR flags;
|
||||
} VkVideoCodingControlInfoKHR;
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR)(VkPhysicalDevice physicalDevice, const VkVideoProfileKHR* pVideoProfile, VkVideoCapabilitiesKHR* pCapabilities);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceVideoCapabilitiesKHR)(VkPhysicalDevice physicalDevice, const VkVideoProfileInfoKHR* pVideoProfile, VkVideoCapabilitiesKHR* pCapabilities);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceVideoFormatPropertiesKHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceVideoFormatInfoKHR* pVideoFormatInfo, uint32_t* pVideoFormatPropertyCount, VkVideoFormatPropertiesKHR* pVideoFormatProperties);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateVideoSessionKHR)(VkDevice device, const VkVideoSessionCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkVideoSessionKHR* pVideoSession);
|
||||
typedef void (VKAPI_PTR *PFN_vkDestroyVideoSessionKHR)(VkDevice device, VkVideoSessionKHR videoSession, const VkAllocationCallbacks* pAllocator);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetVideoSessionMemoryRequirementsKHR)(VkDevice device, VkVideoSessionKHR videoSession, uint32_t* pVideoSessionMemoryRequirementsCount, VkVideoGetMemoryPropertiesKHR* pVideoSessionMemoryRequirements);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkBindVideoSessionMemoryKHR)(VkDevice device, VkVideoSessionKHR videoSession, uint32_t videoSessionBindMemoryCount, const VkVideoBindMemoryKHR* pVideoSessionBindMemories);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkGetVideoSessionMemoryRequirementsKHR)(VkDevice device, VkVideoSessionKHR videoSession, uint32_t* pMemoryRequirementsCount, VkVideoSessionMemoryRequirementsKHR* pMemoryRequirements);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkBindVideoSessionMemoryKHR)(VkDevice device, VkVideoSessionKHR videoSession, uint32_t bindSessionMemoryInfoCount, const VkBindVideoSessionMemoryInfoKHR* pBindSessionMemoryInfos);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateVideoSessionParametersKHR)(VkDevice device, const VkVideoSessionParametersCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkVideoSessionParametersKHR* pVideoSessionParameters);
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkUpdateVideoSessionParametersKHR)(VkDevice device, VkVideoSessionParametersKHR videoSessionParameters, const VkVideoSessionParametersUpdateInfoKHR* pUpdateInfo);
|
||||
typedef void (VKAPI_PTR *PFN_vkDestroyVideoSessionParametersKHR)(VkDevice device, VkVideoSessionParametersKHR videoSessionParameters, const VkAllocationCallbacks* pAllocator);
|
||||
@@ -252,7 +253,7 @@ typedef void (VKAPI_PTR *PFN_vkCmdControlVideoCodingKHR)(VkCommandBuffer command
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceVideoCapabilitiesKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
const VkVideoProfileKHR* pVideoProfile,
|
||||
const VkVideoProfileInfoKHR* pVideoProfile,
|
||||
VkVideoCapabilitiesKHR* pCapabilities);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceVideoFormatPropertiesKHR(
|
||||
@@ -275,14 +276,14 @@ VKAPI_ATTR void VKAPI_CALL vkDestroyVideoSessionKHR(
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetVideoSessionMemoryRequirementsKHR(
|
||||
VkDevice device,
|
||||
VkVideoSessionKHR videoSession,
|
||||
uint32_t* pVideoSessionMemoryRequirementsCount,
|
||||
VkVideoGetMemoryPropertiesKHR* pVideoSessionMemoryRequirements);
|
||||
uint32_t* pMemoryRequirementsCount,
|
||||
VkVideoSessionMemoryRequirementsKHR* pMemoryRequirements);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkBindVideoSessionMemoryKHR(
|
||||
VkDevice device,
|
||||
VkVideoSessionKHR videoSession,
|
||||
uint32_t videoSessionBindMemoryCount,
|
||||
const VkVideoBindMemoryKHR* pVideoSessionBindMemories);
|
||||
uint32_t bindSessionMemoryInfoCount,
|
||||
const VkBindVideoSessionMemoryInfoKHR* pBindSessionMemoryInfos);
|
||||
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateVideoSessionParametersKHR(
|
||||
VkDevice device,
|
||||
@@ -315,22 +316,24 @@ VKAPI_ATTR void VKAPI_CALL vkCmdControlVideoCodingKHR(
|
||||
|
||||
|
||||
#define VK_KHR_video_decode_queue 1
|
||||
#define VK_KHR_VIDEO_DECODE_QUEUE_SPEC_VERSION 4
|
||||
#define VK_KHR_VIDEO_DECODE_QUEUE_SPEC_VERSION 6
|
||||
#define VK_KHR_VIDEO_DECODE_QUEUE_EXTENSION_NAME "VK_KHR_video_decode_queue"
|
||||
|
||||
typedef enum VkVideoDecodeCapabilityFlagBitsKHR {
|
||||
VK_VIDEO_DECODE_CAPABILITY_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_COINCIDE_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_DECODE_CAPABILITY_DPB_AND_OUTPUT_DISTINCT_BIT_KHR = 0x00000002,
|
||||
VK_VIDEO_DECODE_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoDecodeCapabilityFlagBitsKHR;
|
||||
typedef VkFlags VkVideoDecodeCapabilityFlagsKHR;
|
||||
|
||||
typedef enum VkVideoDecodeFlagBitsKHR {
|
||||
VK_VIDEO_DECODE_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_DECODE_RESERVED_0_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_DECODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoDecodeFlagBitsKHR;
|
||||
typedef enum VkVideoDecodeUsageFlagBitsKHR {
|
||||
VK_VIDEO_DECODE_USAGE_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_DECODE_USAGE_TRANSCODING_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_DECODE_USAGE_OFFLINE_BIT_KHR = 0x00000002,
|
||||
VK_VIDEO_DECODE_USAGE_STREAMING_BIT_KHR = 0x00000004,
|
||||
VK_VIDEO_DECODE_USAGE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoDecodeUsageFlagBitsKHR;
|
||||
typedef VkFlags VkVideoDecodeUsageFlagsKHR;
|
||||
typedef VkFlags VkVideoDecodeFlagsKHR;
|
||||
typedef struct VkVideoDecodeCapabilitiesKHR {
|
||||
VkStructureType sType;
|
||||
@@ -338,25 +341,31 @@ typedef struct VkVideoDecodeCapabilitiesKHR {
|
||||
VkVideoDecodeCapabilityFlagsKHR flags;
|
||||
} VkVideoDecodeCapabilitiesKHR;
|
||||
|
||||
typedef struct VkVideoDecodeUsageInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoDecodeUsageFlagsKHR videoUsageHints;
|
||||
} VkVideoDecodeUsageInfoKHR;
|
||||
|
||||
typedef struct VkVideoDecodeInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoDecodeFlagsKHR flags;
|
||||
VkBuffer srcBuffer;
|
||||
VkDeviceSize srcBufferOffset;
|
||||
VkDeviceSize srcBufferRange;
|
||||
VkVideoPictureResourceKHR dstPictureResource;
|
||||
const VkVideoReferenceSlotKHR* pSetupReferenceSlot;
|
||||
uint32_t referenceSlotCount;
|
||||
const VkVideoReferenceSlotKHR* pReferenceSlots;
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoDecodeFlagsKHR flags;
|
||||
VkBuffer srcBuffer;
|
||||
VkDeviceSize srcBufferOffset;
|
||||
VkDeviceSize srcBufferRange;
|
||||
VkVideoPictureResourceInfoKHR dstPictureResource;
|
||||
const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot;
|
||||
uint32_t referenceSlotCount;
|
||||
const VkVideoReferenceSlotInfoKHR* pReferenceSlots;
|
||||
} VkVideoDecodeInfoKHR;
|
||||
|
||||
typedef void (VKAPI_PTR *PFN_vkCmdDecodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoDecodeInfoKHR* pFrameInfo);
|
||||
typedef void (VKAPI_PTR *PFN_vkCmdDecodeVideoKHR)(VkCommandBuffer commandBuffer, const VkVideoDecodeInfoKHR* pDecodeInfo);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR void VKAPI_CALL vkCmdDecodeVideoKHR(
|
||||
VkCommandBuffer commandBuffer,
|
||||
const VkVideoDecodeInfoKHR* pFrameInfo);
|
||||
const VkVideoDecodeInfoKHR* pDecodeInfo);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -392,18 +401,20 @@ typedef struct VkPhysicalDevicePortabilitySubsetPropertiesKHR {
|
||||
|
||||
|
||||
#define VK_KHR_video_encode_queue 1
|
||||
#define VK_KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION 5
|
||||
#define VK_KHR_VIDEO_ENCODE_QUEUE_SPEC_VERSION 7
|
||||
#define VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME "VK_KHR_video_encode_queue"
|
||||
|
||||
typedef enum VkVideoEncodeFlagBitsKHR {
|
||||
VK_VIDEO_ENCODE_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_ENCODE_RESERVED_0_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_ENCODE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeFlagBitsKHR;
|
||||
typedef enum VkVideoEncodeTuningModeKHR {
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_HIGH_QUALITY_KHR = 1,
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_LOW_LATENCY_KHR = 2,
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_ULTRA_LOW_LATENCY_KHR = 3,
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_LOSSLESS_KHR = 4,
|
||||
VK_VIDEO_ENCODE_TUNING_MODE_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeTuningModeKHR;
|
||||
typedef VkFlags VkVideoEncodeFlagsKHR;
|
||||
|
||||
typedef enum VkVideoEncodeCapabilityFlagBitsKHR {
|
||||
VK_VIDEO_ENCODE_CAPABILITY_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_ENCODE_CAPABILITY_PRECEDING_EXTERNALLY_ENCODED_BYTES_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_ENCODE_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeCapabilityFlagBitsKHR;
|
||||
@@ -417,25 +428,38 @@ typedef enum VkVideoEncodeRateControlModeFlagBitsKHR {
|
||||
} VkVideoEncodeRateControlModeFlagBitsKHR;
|
||||
typedef VkFlags VkVideoEncodeRateControlModeFlagsKHR;
|
||||
|
||||
typedef enum VkVideoEncodeRateControlFlagBitsKHR {
|
||||
VK_VIDEO_ENCODE_RATE_CONTROL_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_ENCODE_RATE_CONTROL_RESERVED_0_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_ENCODE_RATE_CONTROL_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeRateControlFlagBitsKHR;
|
||||
typedef enum VkVideoEncodeUsageFlagBitsKHR {
|
||||
VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_ENCODE_USAGE_TRANSCODING_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_ENCODE_USAGE_STREAMING_BIT_KHR = 0x00000002,
|
||||
VK_VIDEO_ENCODE_USAGE_RECORDING_BIT_KHR = 0x00000004,
|
||||
VK_VIDEO_ENCODE_USAGE_CONFERENCING_BIT_KHR = 0x00000008,
|
||||
VK_VIDEO_ENCODE_USAGE_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeUsageFlagBitsKHR;
|
||||
typedef VkFlags VkVideoEncodeUsageFlagsKHR;
|
||||
|
||||
typedef enum VkVideoEncodeContentFlagBitsKHR {
|
||||
VK_VIDEO_ENCODE_CONTENT_DEFAULT_KHR = 0,
|
||||
VK_VIDEO_ENCODE_CONTENT_CAMERA_BIT_KHR = 0x00000001,
|
||||
VK_VIDEO_ENCODE_CONTENT_DESKTOP_BIT_KHR = 0x00000002,
|
||||
VK_VIDEO_ENCODE_CONTENT_RENDERED_BIT_KHR = 0x00000004,
|
||||
VK_VIDEO_ENCODE_CONTENT_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
|
||||
} VkVideoEncodeContentFlagBitsKHR;
|
||||
typedef VkFlags VkVideoEncodeContentFlagsKHR;
|
||||
typedef VkFlags VkVideoEncodeRateControlFlagsKHR;
|
||||
typedef struct VkVideoEncodeInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoEncodeFlagsKHR flags;
|
||||
uint32_t qualityLevel;
|
||||
VkBuffer dstBitstreamBuffer;
|
||||
VkDeviceSize dstBitstreamBufferOffset;
|
||||
VkDeviceSize dstBitstreamBufferMaxRange;
|
||||
VkVideoPictureResourceKHR srcPictureResource;
|
||||
const VkVideoReferenceSlotKHR* pSetupReferenceSlot;
|
||||
uint32_t referenceSlotCount;
|
||||
const VkVideoReferenceSlotKHR* pReferenceSlots;
|
||||
uint32_t precedingExternallyEncodedBytes;
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoEncodeFlagsKHR flags;
|
||||
uint32_t qualityLevel;
|
||||
VkBuffer dstBitstreamBuffer;
|
||||
VkDeviceSize dstBitstreamBufferOffset;
|
||||
VkDeviceSize dstBitstreamBufferMaxRange;
|
||||
VkVideoPictureResourceInfoKHR srcPictureResource;
|
||||
const VkVideoReferenceSlotInfoKHR* pSetupReferenceSlot;
|
||||
uint32_t referenceSlotCount;
|
||||
const VkVideoReferenceSlotInfoKHR* pReferenceSlots;
|
||||
uint32_t precedingExternallyEncodedBytes;
|
||||
} VkVideoEncodeInfoKHR;
|
||||
|
||||
typedef struct VkVideoEncodeCapabilitiesKHR {
|
||||
@@ -448,6 +472,14 @@ typedef struct VkVideoEncodeCapabilitiesKHR {
|
||||
VkExtent2D inputImageDataFillAlignment;
|
||||
} VkVideoEncodeCapabilitiesKHR;
|
||||
|
||||
typedef struct VkVideoEncodeUsageInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkVideoEncodeUsageFlagsKHR videoUsageHints;
|
||||
VkVideoEncodeContentFlagsKHR videoContentHints;
|
||||
VkVideoEncodeTuningModeKHR tuningMode;
|
||||
} VkVideoEncodeUsageInfoKHR;
|
||||
|
||||
typedef struct VkVideoEncodeRateControlLayerInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -480,9 +512,16 @@ VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR(
|
||||
#define VK_EXT_video_encode_h264 1
|
||||
#include "vk_video/vulkan_video_codec_h264std.h"
|
||||
#include "vk_video/vulkan_video_codec_h264std_encode.h"
|
||||
#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 7
|
||||
#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 9
|
||||
#define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264"
|
||||
|
||||
typedef enum VkVideoEncodeH264RateControlStructureEXT {
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0,
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_FLAT_EXT = 1,
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_DYADIC_EXT = 2,
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH264RateControlStructureEXT;
|
||||
|
||||
typedef enum VkVideoEncodeH264CapabilityFlagBitsEXT {
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_DIRECT_8X8_INFERENCE_ENABLED_BIT_EXT = 0x00000001,
|
||||
VK_VIDEO_ENCODE_H264_CAPABILITY_DIRECT_8X8_INFERENCE_DISABLED_BIT_EXT = 0x00000002,
|
||||
@@ -528,14 +567,6 @@ typedef enum VkVideoEncodeH264OutputModeFlagBitsEXT {
|
||||
VK_VIDEO_ENCODE_H264_OUTPUT_MODE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH264OutputModeFlagBitsEXT;
|
||||
typedef VkFlags VkVideoEncodeH264OutputModeFlagsEXT;
|
||||
|
||||
typedef enum VkVideoEncodeH264RateControlStructureFlagBitsEXT {
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0,
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_FLAT_BIT_EXT = 0x00000001,
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_DYADIC_BIT_EXT = 0x00000002,
|
||||
VK_VIDEO_ENCODE_H264_RATE_CONTROL_STRUCTURE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH264RateControlStructureFlagBitsEXT;
|
||||
typedef VkFlags VkVideoEncodeH264RateControlStructureFlagsEXT;
|
||||
typedef struct VkVideoEncodeH264CapabilitiesEXT {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
@@ -555,17 +586,17 @@ typedef struct VkVideoEncodeH264CapabilitiesEXT {
|
||||
typedef struct VkVideoEncodeH264SessionParametersAddInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t spsStdCount;
|
||||
const StdVideoH264SequenceParameterSet* pSpsStd;
|
||||
uint32_t ppsStdCount;
|
||||
const StdVideoH264PictureParameterSet* pPpsStd;
|
||||
uint32_t stdSPSCount;
|
||||
const StdVideoH264SequenceParameterSet* pStdSPSs;
|
||||
uint32_t stdPPSCount;
|
||||
const StdVideoH264PictureParameterSet* pStdPPSs;
|
||||
} VkVideoEncodeH264SessionParametersAddInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264SessionParametersCreateInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t maxSpsStdCount;
|
||||
uint32_t maxPpsStdCount;
|
||||
uint32_t maxStdSPSCount;
|
||||
uint32_t maxStdPPSCount;
|
||||
const VkVideoEncodeH264SessionParametersAddInfoEXT* pParametersAddInfo;
|
||||
} VkVideoEncodeH264SessionParametersCreateInfoEXT;
|
||||
|
||||
@@ -576,7 +607,7 @@ typedef struct VkVideoEncodeH264DpbSlotInfoEXT {
|
||||
const StdVideoEncodeH264ReferenceInfo* pStdReferenceInfo;
|
||||
} VkVideoEncodeH264DpbSlotInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264ReferenceListsEXT {
|
||||
typedef struct VkVideoEncodeH264ReferenceListsInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint8_t referenceList0EntryCount;
|
||||
@@ -584,48 +615,48 @@ typedef struct VkVideoEncodeH264ReferenceListsEXT {
|
||||
uint8_t referenceList1EntryCount;
|
||||
const VkVideoEncodeH264DpbSlotInfoEXT* pReferenceList1Entries;
|
||||
const StdVideoEncodeH264RefMemMgmtCtrlOperations* pMemMgmtCtrlOperations;
|
||||
} VkVideoEncodeH264ReferenceListsEXT;
|
||||
} VkVideoEncodeH264ReferenceListsInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264NaluSliceEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t mbCount;
|
||||
const VkVideoEncodeH264ReferenceListsEXT* pReferenceFinalLists;
|
||||
const StdVideoEncodeH264SliceHeader* pSliceHeaderStd;
|
||||
} VkVideoEncodeH264NaluSliceEXT;
|
||||
typedef struct VkVideoEncodeH264NaluSliceInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t mbCount;
|
||||
const VkVideoEncodeH264ReferenceListsInfoEXT* pReferenceFinalLists;
|
||||
const StdVideoEncodeH264SliceHeader* pSliceHeaderStd;
|
||||
} VkVideoEncodeH264NaluSliceInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264VclFrameInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const VkVideoEncodeH264ReferenceListsEXT* pReferenceFinalLists;
|
||||
uint32_t naluSliceEntryCount;
|
||||
const VkVideoEncodeH264NaluSliceEXT* pNaluSliceEntries;
|
||||
const StdVideoEncodeH264PictureInfo* pCurrentPictureInfo;
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const VkVideoEncodeH264ReferenceListsInfoEXT* pReferenceFinalLists;
|
||||
uint32_t naluSliceEntryCount;
|
||||
const VkVideoEncodeH264NaluSliceInfoEXT* pNaluSliceEntries;
|
||||
const StdVideoEncodeH264PictureInfo* pCurrentPictureInfo;
|
||||
} VkVideoEncodeH264VclFrameInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264EmitPictureParametersEXT {
|
||||
typedef struct VkVideoEncodeH264EmitPictureParametersInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint8_t spsId;
|
||||
VkBool32 emitSpsEnable;
|
||||
uint32_t ppsIdEntryCount;
|
||||
const uint8_t* ppsIdEntries;
|
||||
} VkVideoEncodeH264EmitPictureParametersEXT;
|
||||
} VkVideoEncodeH264EmitPictureParametersInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264ProfileEXT {
|
||||
typedef struct VkVideoEncodeH264ProfileInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
StdVideoH264ProfileIdc stdProfileIdc;
|
||||
} VkVideoEncodeH264ProfileEXT;
|
||||
} VkVideoEncodeH264ProfileInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264RateControlInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t gopFrameCount;
|
||||
uint32_t idrPeriod;
|
||||
uint32_t consecutiveBFrameCount;
|
||||
VkVideoEncodeH264RateControlStructureFlagBitsEXT rateControlStructure;
|
||||
uint8_t temporalLayerCount;
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t gopFrameCount;
|
||||
uint32_t idrPeriod;
|
||||
uint32_t consecutiveBFrameCount;
|
||||
VkVideoEncodeH264RateControlStructureEXT rateControlStructure;
|
||||
uint8_t temporalLayerCount;
|
||||
} VkVideoEncodeH264RateControlInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH264QpEXT {
|
||||
@@ -659,9 +690,16 @@ typedef struct VkVideoEncodeH264RateControlLayerInfoEXT {
|
||||
#define VK_EXT_video_encode_h265 1
|
||||
#include "vk_video/vulkan_video_codec_h265std.h"
|
||||
#include "vk_video/vulkan_video_codec_h265std_encode.h"
|
||||
#define VK_EXT_VIDEO_ENCODE_H265_SPEC_VERSION 7
|
||||
#define VK_EXT_VIDEO_ENCODE_H265_SPEC_VERSION 9
|
||||
#define VK_EXT_VIDEO_ENCODE_H265_EXTENSION_NAME "VK_EXT_video_encode_h265"
|
||||
|
||||
typedef enum VkVideoEncodeH265RateControlStructureEXT {
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0,
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_FLAT_EXT = 1,
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_DYADIC_EXT = 2,
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH265RateControlStructureEXT;
|
||||
|
||||
typedef enum VkVideoEncodeH265CapabilityFlagBitsEXT {
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_SEPARATE_COLOUR_PLANE_BIT_EXT = 0x00000001,
|
||||
VK_VIDEO_ENCODE_H265_CAPABILITY_SCALING_LISTS_BIT_EXT = 0x00000002,
|
||||
@@ -725,14 +763,6 @@ typedef enum VkVideoEncodeH265TransformBlockSizeFlagBitsEXT {
|
||||
VK_VIDEO_ENCODE_H265_TRANSFORM_BLOCK_SIZE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH265TransformBlockSizeFlagBitsEXT;
|
||||
typedef VkFlags VkVideoEncodeH265TransformBlockSizeFlagsEXT;
|
||||
|
||||
typedef enum VkVideoEncodeH265RateControlStructureFlagBitsEXT {
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_UNKNOWN_EXT = 0,
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_FLAT_BIT_EXT = 0x00000001,
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_DYADIC_BIT_EXT = 0x00000002,
|
||||
VK_VIDEO_ENCODE_H265_RATE_CONTROL_STRUCTURE_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoEncodeH265RateControlStructureFlagBitsEXT;
|
||||
typedef VkFlags VkVideoEncodeH265RateControlStructureFlagsEXT;
|
||||
typedef struct VkVideoEncodeH265CapabilitiesEXT {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
@@ -761,20 +791,20 @@ typedef struct VkVideoEncodeH265CapabilitiesEXT {
|
||||
typedef struct VkVideoEncodeH265SessionParametersAddInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t vpsStdCount;
|
||||
const StdVideoH265VideoParameterSet* pVpsStd;
|
||||
uint32_t spsStdCount;
|
||||
const StdVideoH265SequenceParameterSet* pSpsStd;
|
||||
uint32_t ppsStdCount;
|
||||
const StdVideoH265PictureParameterSet* pPpsStd;
|
||||
uint32_t stdVPSCount;
|
||||
const StdVideoH265VideoParameterSet* pStdVPSs;
|
||||
uint32_t stdSPSCount;
|
||||
const StdVideoH265SequenceParameterSet* pStdSPSs;
|
||||
uint32_t stdPPSCount;
|
||||
const StdVideoH265PictureParameterSet* pStdPPSs;
|
||||
} VkVideoEncodeH265SessionParametersAddInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265SessionParametersCreateInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t maxVpsStdCount;
|
||||
uint32_t maxSpsStdCount;
|
||||
uint32_t maxPpsStdCount;
|
||||
uint32_t maxStdVPSCount;
|
||||
uint32_t maxStdSPSCount;
|
||||
uint32_t maxStdPPSCount;
|
||||
const VkVideoEncodeH265SessionParametersAddInfoEXT* pParametersAddInfo;
|
||||
} VkVideoEncodeH265SessionParametersCreateInfoEXT;
|
||||
|
||||
@@ -785,7 +815,7 @@ typedef struct VkVideoEncodeH265DpbSlotInfoEXT {
|
||||
const StdVideoEncodeH265ReferenceInfo* pStdReferenceInfo;
|
||||
} VkVideoEncodeH265DpbSlotInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265ReferenceListsEXT {
|
||||
typedef struct VkVideoEncodeH265ReferenceListsInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint8_t referenceList0EntryCount;
|
||||
@@ -793,26 +823,26 @@ typedef struct VkVideoEncodeH265ReferenceListsEXT {
|
||||
uint8_t referenceList1EntryCount;
|
||||
const VkVideoEncodeH265DpbSlotInfoEXT* pReferenceList1Entries;
|
||||
const StdVideoEncodeH265ReferenceModifications* pReferenceModifications;
|
||||
} VkVideoEncodeH265ReferenceListsEXT;
|
||||
} VkVideoEncodeH265ReferenceListsInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265NaluSliceSegmentEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t ctbCount;
|
||||
const VkVideoEncodeH265ReferenceListsEXT* pReferenceFinalLists;
|
||||
const StdVideoEncodeH265SliceSegmentHeader* pSliceSegmentHeaderStd;
|
||||
} VkVideoEncodeH265NaluSliceSegmentEXT;
|
||||
typedef struct VkVideoEncodeH265NaluSliceSegmentInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t ctbCount;
|
||||
const VkVideoEncodeH265ReferenceListsInfoEXT* pReferenceFinalLists;
|
||||
const StdVideoEncodeH265SliceSegmentHeader* pSliceSegmentHeaderStd;
|
||||
} VkVideoEncodeH265NaluSliceSegmentInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265VclFrameInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const VkVideoEncodeH265ReferenceListsEXT* pReferenceFinalLists;
|
||||
uint32_t naluSliceSegmentEntryCount;
|
||||
const VkVideoEncodeH265NaluSliceSegmentEXT* pNaluSliceSegmentEntries;
|
||||
const StdVideoEncodeH265PictureInfo* pCurrentPictureInfo;
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const VkVideoEncodeH265ReferenceListsInfoEXT* pReferenceFinalLists;
|
||||
uint32_t naluSliceSegmentEntryCount;
|
||||
const VkVideoEncodeH265NaluSliceSegmentInfoEXT* pNaluSliceSegmentEntries;
|
||||
const StdVideoEncodeH265PictureInfo* pCurrentPictureInfo;
|
||||
} VkVideoEncodeH265VclFrameInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265EmitPictureParametersEXT {
|
||||
typedef struct VkVideoEncodeH265EmitPictureParametersInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint8_t vpsId;
|
||||
@@ -821,22 +851,22 @@ typedef struct VkVideoEncodeH265EmitPictureParametersEXT {
|
||||
VkBool32 emitSpsEnable;
|
||||
uint32_t ppsIdEntryCount;
|
||||
const uint8_t* ppsIdEntries;
|
||||
} VkVideoEncodeH265EmitPictureParametersEXT;
|
||||
} VkVideoEncodeH265EmitPictureParametersInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265ProfileEXT {
|
||||
typedef struct VkVideoEncodeH265ProfileInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
StdVideoH265ProfileIdc stdProfileIdc;
|
||||
} VkVideoEncodeH265ProfileEXT;
|
||||
} VkVideoEncodeH265ProfileInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265RateControlInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t gopFrameCount;
|
||||
uint32_t idrPeriod;
|
||||
uint32_t consecutiveBFrameCount;
|
||||
VkVideoEncodeH265RateControlStructureFlagBitsEXT rateControlStructure;
|
||||
uint8_t subLayerCount;
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t gopFrameCount;
|
||||
uint32_t idrPeriod;
|
||||
uint32_t consecutiveBFrameCount;
|
||||
VkVideoEncodeH265RateControlStructureEXT rateControlStructure;
|
||||
uint8_t subLayerCount;
|
||||
} VkVideoEncodeH265RateControlInfoEXT;
|
||||
|
||||
typedef struct VkVideoEncodeH265QpEXT {
|
||||
@@ -869,7 +899,7 @@ typedef struct VkVideoEncodeH265RateControlLayerInfoEXT {
|
||||
|
||||
#define VK_EXT_video_decode_h264 1
|
||||
#include "vk_video/vulkan_video_codec_h264std_decode.h"
|
||||
#define VK_EXT_VIDEO_DECODE_H264_SPEC_VERSION 5
|
||||
#define VK_EXT_VIDEO_DECODE_H264_SPEC_VERSION 7
|
||||
#define VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME "VK_EXT_video_decode_h264"
|
||||
|
||||
typedef enum VkVideoDecodeH264PictureLayoutFlagBitsEXT {
|
||||
@@ -879,34 +909,34 @@ typedef enum VkVideoDecodeH264PictureLayoutFlagBitsEXT {
|
||||
VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||
} VkVideoDecodeH264PictureLayoutFlagBitsEXT;
|
||||
typedef VkFlags VkVideoDecodeH264PictureLayoutFlagsEXT;
|
||||
typedef struct VkVideoDecodeH264ProfileEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
StdVideoH264ProfileIdc stdProfileIdc;
|
||||
VkVideoDecodeH264PictureLayoutFlagsEXT pictureLayout;
|
||||
} VkVideoDecodeH264ProfileEXT;
|
||||
typedef struct VkVideoDecodeH264ProfileInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
StdVideoH264ProfileIdc stdProfileIdc;
|
||||
VkVideoDecodeH264PictureLayoutFlagBitsEXT pictureLayout;
|
||||
} VkVideoDecodeH264ProfileInfoEXT;
|
||||
|
||||
typedef struct VkVideoDecodeH264CapabilitiesEXT {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
StdVideoH264Level maxLevel;
|
||||
VkOffset2D fieldOffsetGranularity;
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
StdVideoH264LevelIdc maxLevelIdc;
|
||||
VkOffset2D fieldOffsetGranularity;
|
||||
} VkVideoDecodeH264CapabilitiesEXT;
|
||||
|
||||
typedef struct VkVideoDecodeH264SessionParametersAddInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t spsStdCount;
|
||||
const StdVideoH264SequenceParameterSet* pSpsStd;
|
||||
uint32_t ppsStdCount;
|
||||
const StdVideoH264PictureParameterSet* pPpsStd;
|
||||
uint32_t stdSPSCount;
|
||||
const StdVideoH264SequenceParameterSet* pStdSPSs;
|
||||
uint32_t stdPPSCount;
|
||||
const StdVideoH264PictureParameterSet* pStdPPSs;
|
||||
} VkVideoDecodeH264SessionParametersAddInfoEXT;
|
||||
|
||||
typedef struct VkVideoDecodeH264SessionParametersCreateInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t maxSpsStdCount;
|
||||
uint32_t maxPpsStdCount;
|
||||
uint32_t maxStdSPSCount;
|
||||
uint32_t maxStdPPSCount;
|
||||
const VkVideoDecodeH264SessionParametersAddInfoEXT* pParametersAddInfo;
|
||||
} VkVideoDecodeH264SessionParametersCreateInfoEXT;
|
||||
|
||||
@@ -914,16 +944,10 @@ typedef struct VkVideoDecodeH264PictureInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const StdVideoDecodeH264PictureInfo* pStdPictureInfo;
|
||||
uint32_t slicesCount;
|
||||
const uint32_t* pSlicesDataOffsets;
|
||||
uint32_t sliceCount;
|
||||
const uint32_t* pSliceOffsets;
|
||||
} VkVideoDecodeH264PictureInfoEXT;
|
||||
|
||||
typedef struct VkVideoDecodeH264MvcEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
const StdVideoDecodeH264Mvc* pStdMvc;
|
||||
} VkVideoDecodeH264MvcEXT;
|
||||
|
||||
typedef struct VkVideoDecodeH264DpbSlotInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
@@ -934,37 +958,37 @@ typedef struct VkVideoDecodeH264DpbSlotInfoEXT {
|
||||
|
||||
#define VK_EXT_video_decode_h265 1
|
||||
#include "vk_video/vulkan_video_codec_h265std_decode.h"
|
||||
#define VK_EXT_VIDEO_DECODE_H265_SPEC_VERSION 3
|
||||
#define VK_EXT_VIDEO_DECODE_H265_SPEC_VERSION 5
|
||||
#define VK_EXT_VIDEO_DECODE_H265_EXTENSION_NAME "VK_EXT_video_decode_h265"
|
||||
typedef struct VkVideoDecodeH265ProfileEXT {
|
||||
typedef struct VkVideoDecodeH265ProfileInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
StdVideoH265ProfileIdc stdProfileIdc;
|
||||
} VkVideoDecodeH265ProfileEXT;
|
||||
} VkVideoDecodeH265ProfileInfoEXT;
|
||||
|
||||
typedef struct VkVideoDecodeH265CapabilitiesEXT {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
StdVideoH265Level maxLevel;
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
StdVideoH265LevelIdc maxLevelIdc;
|
||||
} VkVideoDecodeH265CapabilitiesEXT;
|
||||
|
||||
typedef struct VkVideoDecodeH265SessionParametersAddInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t vpsStdCount;
|
||||
const StdVideoH265VideoParameterSet* pVpsStd;
|
||||
uint32_t spsStdCount;
|
||||
const StdVideoH265SequenceParameterSet* pSpsStd;
|
||||
uint32_t ppsStdCount;
|
||||
const StdVideoH265PictureParameterSet* pPpsStd;
|
||||
uint32_t stdVPSCount;
|
||||
const StdVideoH265VideoParameterSet* pStdVPSs;
|
||||
uint32_t stdSPSCount;
|
||||
const StdVideoH265SequenceParameterSet* pStdSPSs;
|
||||
uint32_t stdPPSCount;
|
||||
const StdVideoH265PictureParameterSet* pStdPPSs;
|
||||
} VkVideoDecodeH265SessionParametersAddInfoEXT;
|
||||
|
||||
typedef struct VkVideoDecodeH265SessionParametersCreateInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
uint32_t maxVpsStdCount;
|
||||
uint32_t maxSpsStdCount;
|
||||
uint32_t maxPpsStdCount;
|
||||
uint32_t maxStdVPSCount;
|
||||
uint32_t maxStdSPSCount;
|
||||
uint32_t maxStdPPSCount;
|
||||
const VkVideoDecodeH265SessionParametersAddInfoEXT* pParametersAddInfo;
|
||||
} VkVideoDecodeH265SessionParametersCreateInfoEXT;
|
||||
|
||||
@@ -972,8 +996,8 @@ typedef struct VkVideoDecodeH265PictureInfoEXT {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
StdVideoDecodeH265PictureInfo* pStdPictureInfo;
|
||||
uint32_t slicesCount;
|
||||
const uint32_t* pSlicesDataOffsets;
|
||||
uint32_t sliceCount;
|
||||
const uint32_t* pSliceOffsets;
|
||||
} VkVideoDecodeH265PictureInfoEXT;
|
||||
|
||||
typedef struct VkVideoDecodeH265DpbSlotInfoEXT {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,65 +0,0 @@
|
||||
#ifndef VULKAN_MIR_H_
|
||||
#define VULKAN_MIR_H_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||
** you may not use this file except in compliance with the License.
|
||||
** You may obtain a copy of the License at
|
||||
**
|
||||
** http://www.apache.org/licenses/LICENSE-2.0
|
||||
**
|
||||
** Unless required by applicable law or agreed to in writing, software
|
||||
** distributed under the License is distributed on an "AS IS" BASIS,
|
||||
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
** See the License for the specific language governing permissions and
|
||||
** limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
** This header is generated from the Khronos Vulkan XML API Registry.
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
#define VK_KHR_mir_surface 1
|
||||
#define VK_KHR_MIR_SURFACE_SPEC_VERSION 4
|
||||
#define VK_KHR_MIR_SURFACE_EXTENSION_NAME "VK_KHR_mir_surface"
|
||||
|
||||
typedef VkFlags VkMirSurfaceCreateFlagsKHR;
|
||||
|
||||
typedef struct VkMirSurfaceCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkMirSurfaceCreateFlagsKHR flags;
|
||||
MirConnection* connection;
|
||||
MirSurface* mirSurface;
|
||||
} VkMirSurfaceCreateInfoKHR;
|
||||
|
||||
|
||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateMirSurfaceKHR)(VkInstance instance, const VkMirSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
||||
typedef VkBool32 (VKAPI_PTR *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, MirConnection* connection);
|
||||
|
||||
#ifndef VK_NO_PROTOTYPES
|
||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateMirSurfaceKHR(
|
||||
VkInstance instance,
|
||||
const VkMirSurfaceCreateInfoKHR* pCreateInfo,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
VkSurfaceKHR* pSurface);
|
||||
|
||||
VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceMirPresentationSupportKHR(
|
||||
VkPhysicalDevice physicalDevice,
|
||||
uint32_t queueFamilyIndex,
|
||||
MirConnection* connection);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,22 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
project(fgdbg)
|
||||
|
||||
set(TARGET fgdbg)
|
||||
set(PUBLIC_HDR_DIR include)
|
||||
|
||||
# ==================================================================================================
|
||||
# Sources and headers
|
||||
# ==================================================================================================
|
||||
|
||||
set(PUBLIC_HDRS include/fgdbg/DebugServer.h include/fgdbg/Session.h)
|
||||
|
||||
set(SRCS src/DebugServer.cpp src/Session.cpp)
|
||||
|
||||
# ==================================================================================================
|
||||
# Include and target definitions
|
||||
# ==================================================================================================
|
||||
|
||||
add_library(${TARGET} STATIC ${PUBLIC_HDRS} ${SRCS})
|
||||
target_link_libraries(${TARGET} PUBLIC civetweb utils)
|
||||
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
|
||||
include_directories(${PUBLIC_HDR_DIR})
|
||||
@@ -1 +0,0 @@
|
||||
# FrameGraph Debugger (WIP)
|
||||
@@ -1,9 +0,0 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
/.idea/caches
|
||||
/.idea/gradle.xml
|
||||
.DS_Store
|
||||
/build
|
||||
@@ -1,46 +0,0 @@
|
||||
import org.jetbrains.compose.compose
|
||||
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.6.10"
|
||||
id("org.jetbrains.compose") version "1.1.1"
|
||||
}
|
||||
|
||||
group = "com.google.filament"
|
||||
version = "1.0"
|
||||
val ktorVersion: String by project
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
|
||||
maven {
|
||||
url = uri("https://maven.pkg.jetbrains.space/public/p/ktor/eap")
|
||||
name = "ktor-eap"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(compose.desktop.currentOs)
|
||||
dependencies {
|
||||
implementation("io.ktor:ktor-client-core:$ktorVersion")
|
||||
implementation("io.ktor:ktor-client-cio:$ktorVersion")
|
||||
implementation("io.ktor:ktor-client-websockets:$ktorVersion")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "11"
|
||||
}
|
||||
|
||||
compose.desktop {
|
||||
application {
|
||||
mainClass = "MainKt"
|
||||
nativeDistributions {
|
||||
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
||||
packageName = "fgdbg"
|
||||
packageVersion = "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
kotlin.code.style=official
|
||||
ktorVersion=2.1.2
|
||||
Binary file not shown.
@@ -1,5 +0,0 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
Vendored
-234
@@ -1,234 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
Vendored
-89
@@ -1,89 +0,0 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -1,9 +0,0 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
google()
|
||||
gradlePluginPortal()
|
||||
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
|
||||
}
|
||||
|
||||
}
|
||||
rootProject.name = "fgdbg"
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.plugins.websocket.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.websocket.Frame
|
||||
import io.ktor.websocket.readText
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
private enum class ConnectionState { UNKNOWN, CONNECTED, CONNECTING, ERROR }
|
||||
|
||||
private data class Connection(
|
||||
val host: String = "localhost",
|
||||
val port: Int = 8082,
|
||||
val path: String = "/",
|
||||
val state: MutableState<ConnectionState> = mutableStateOf(ConnectionState.UNKNOWN),
|
||||
val reconnectDelay: Int = 5,
|
||||
)
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
fun App() {
|
||||
val connection = remember { Connection() }
|
||||
val client = remember { HttpClient { install(WebSockets) } }
|
||||
var message by remember { mutableStateOf("") }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
while (true) {
|
||||
connection.state.value = ConnectionState.CONNECTING
|
||||
try {
|
||||
client.webSocket(HttpMethod.Get,
|
||||
connection.host,
|
||||
connection.port,
|
||||
connection.path) {
|
||||
message = "Connected!"
|
||||
connection.state.value = ConnectionState.CONNECTED
|
||||
while (true) {
|
||||
val frame = incoming.receive() as? Frame.Text ?: continue
|
||||
message = frame.readText()
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
connection.state.value = ConnectionState.ERROR
|
||||
repeat(connection.reconnectDelay) {
|
||||
val remaining = connection.reconnectDelay - it
|
||||
message = "Connection interrupted, will re-connect in $remaining seconds..."
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DisposableEffect(Unit) { onDispose { client.close() } }
|
||||
|
||||
MaterialTheme {
|
||||
when (connection.state.value) {
|
||||
ConnectionState.CONNECTED -> {
|
||||
Row(Modifier.height(40.dp)) {
|
||||
Text(modifier = Modifier.align(Alignment.CenterVertically),
|
||||
text = "Listening on ${connection.host}:${connection.port} ")
|
||||
Button(onClick = {}) { Text(message) }
|
||||
}
|
||||
}
|
||||
ConnectionState.ERROR -> Text(text = message, color = Color.Red)
|
||||
else -> Text(connection.state.value.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main() = application { Window(onCloseRequest = ::exitApplication) { App() } }
|
||||
@@ -1,2 +0,0 @@
|
||||
class NavRestore {
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FGDBG_DEBUGSERVER_H
|
||||
#define FGDBG_DEBUGSERVER_H
|
||||
|
||||
class CivetServer;
|
||||
|
||||
namespace filament::fgdbg {
|
||||
|
||||
class DebugServer {
|
||||
public:
|
||||
DebugServer();
|
||||
~DebugServer();
|
||||
|
||||
void sendMessage(int number);
|
||||
|
||||
private:
|
||||
CivetServer* mServer;
|
||||
|
||||
class RestRequestHandler *mRestRequestHandler = nullptr;
|
||||
class WebSocketHandler* mWebSocketHandler = nullptr;
|
||||
|
||||
friend class RestRequestHandler;
|
||||
friend class WebSocketHandler;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // FGDBG_DEBUGSERVER_H
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FGDBG_PASS_H
|
||||
#define FGDBG_PASS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace filament::fgdbg {
|
||||
using ResourceId = int;
|
||||
|
||||
struct Pass {
|
||||
std::string name;
|
||||
int id;
|
||||
std::vector<ResourceId> reads;
|
||||
std::vector<ResourceId> writes;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //FGDBG_PASS_H
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FGDBG_RESOURCE_H
|
||||
#define FGDBG_RESOURCE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace filament::fgdbg {
|
||||
struct Resource {
|
||||
std::string name;
|
||||
int id;
|
||||
int size;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //FGDBG_RESOURCE_H
|
||||
@@ -1,28 +0,0 @@
|
||||
//
|
||||
// Created by Fernando Raviola on 4/11/2022.
|
||||
//
|
||||
|
||||
#ifndef FGDBG_SESSION_H
|
||||
#define FGDBG_SESSION_H
|
||||
|
||||
#include "DebugServer.h"
|
||||
#include "Resource.h"
|
||||
#include "Pass.h"
|
||||
#include <memory>
|
||||
|
||||
namespace filament::fgdbg {
|
||||
class Session {
|
||||
|
||||
public:
|
||||
Session(std::shared_ptr<DebugServer> server) : server{ server } {}
|
||||
|
||||
void addPasses(std::vector<Pass> passes);
|
||||
void addResources(std::vector<Resource> resources);
|
||||
void update();
|
||||
|
||||
private:
|
||||
std::shared_ptr<DebugServer> server;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //FGDBG_SESSION_H
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "fgdbg/DebugServer.h"
|
||||
#include <CivetServer.h>
|
||||
#include <utils/Log.h>
|
||||
#include <tsl/robin_set.h>
|
||||
|
||||
namespace filament::fgdbg {
|
||||
|
||||
using namespace utils;
|
||||
|
||||
static const std::string_view kSuccessHeader =
|
||||
"HTTP/1.1 200 OK\r\nContent-Type: %s\r\n"
|
||||
"Connection: close\r\n\r\n";
|
||||
|
||||
class RestRequestHandler : public CivetHandler {
|
||||
|
||||
public:
|
||||
RestRequestHandler() = default;
|
||||
|
||||
bool handleGet(CivetServer *server, struct mg_connection *conn) override {
|
||||
mg_printf(conn, kSuccessHeader.data(), "application/json");
|
||||
mg_printf(conn, "{ RestRequestHandler is working! }");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class WebSocketHandler : public CivetWebSocketHandler {
|
||||
|
||||
public:
|
||||
WebSocketHandler() = default;
|
||||
|
||||
bool handleConnection(CivetServer *server, const struct mg_connection *conn) override {
|
||||
return true;
|
||||
}
|
||||
|
||||
void handleReadyState(CivetServer *server, struct mg_connection *conn) override {
|
||||
mConnections.insert(conn);
|
||||
}
|
||||
|
||||
void handleClose(CivetServer *server, const struct mg_connection *conn) override {
|
||||
auto *key = const_cast<struct mg_connection *>(conn);
|
||||
mConnections.erase(key);
|
||||
}
|
||||
|
||||
void send(int number) {
|
||||
auto string = std::to_string(number);
|
||||
for (auto connection : mConnections) {
|
||||
mg_websocket_write(connection,
|
||||
MG_WEBSOCKET_OPCODE_TEXT,
|
||||
string.c_str(),
|
||||
string.length());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
tsl::robin_set<struct mg_connection*> mConnections;
|
||||
};
|
||||
|
||||
DebugServer::DebugServer() {
|
||||
slog.d << "FrameGraph debug server created" << io::endl;
|
||||
|
||||
//TODO (@feresr): Make port param customizable
|
||||
const char* kServerOptions[] = {
|
||||
"listening_ports", "8082",
|
||||
"num_threads", "10",
|
||||
"error_log_file", "civetweb.txt",
|
||||
nullptr
|
||||
};
|
||||
|
||||
mServer = new CivetServer(kServerOptions);
|
||||
if (!mServer->getContext()) {
|
||||
delete mServer;
|
||||
mServer = nullptr;
|
||||
slog.e << "Unable to start fgdbg DebugServer, see civetweb.txt for details." << io::endl;
|
||||
return;
|
||||
}
|
||||
slog.i << "Server started successfully" << io::endl;
|
||||
|
||||
mRestRequestHandler = new RestRequestHandler();
|
||||
mWebSocketHandler = new WebSocketHandler();
|
||||
|
||||
mServer->addHandler("", mRestRequestHandler);
|
||||
mServer->addWebSocketHandler("", mWebSocketHandler);
|
||||
}
|
||||
|
||||
void DebugServer::sendMessage(int number) {
|
||||
mWebSocketHandler->send(number);
|
||||
}
|
||||
|
||||
DebugServer::~DebugServer() {
|
||||
slog.d << "FrameGraph debug server destroyed" << io::endl;
|
||||
delete mRestRequestHandler;
|
||||
delete mWebSocketHandler;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "Session.h"
|
||||
|
||||
namespace filament::fgdbg {
|
||||
|
||||
void Session::addPasses(std::vector <Pass> passes);
|
||||
void Session::addResources(std::vector <Resource> resources);
|
||||
void Session::update();
|
||||
|
||||
}
|
||||
@@ -27,7 +27,7 @@
|
||||
namespace filament {
|
||||
|
||||
// update this when a new version of filament wouldn't work with older materials
|
||||
static constexpr size_t MATERIAL_VERSION = 28;
|
||||
static constexpr size_t MATERIAL_VERSION = 29;
|
||||
|
||||
/**
|
||||
* Supported shading models
|
||||
|
||||
@@ -60,29 +60,23 @@ enum class SamplerBindingPoints : uint8_t {
|
||||
constexpr size_t CONFIG_MAX_LIGHT_COUNT = 256;
|
||||
constexpr size_t CONFIG_MAX_LIGHT_INDEX = CONFIG_MAX_LIGHT_COUNT - 1;
|
||||
|
||||
// The maximum number of shadowmaps.
|
||||
// There is currently a maximum limit of 128 shadowmaps.
|
||||
// Factors contributing to this limit:
|
||||
// - minspec for UBOs is 16KiB, which currently can hold a maximum of 128 entries
|
||||
constexpr size_t CONFIG_MAX_SHADOWMAPS = 64;
|
||||
|
||||
// The maximum number of shadow layers.
|
||||
// There is currently a limit to 146 layers.
|
||||
// There is currently a maximum limit of 255 layers.
|
||||
// Several factors are contributing to this limit:
|
||||
// - minspec for 2d texture arrays layer is 256
|
||||
// - we're using uint8_t to store the number of layers (255 max)
|
||||
// - minspec for UBOs is 16KiB, which currently can hold a maximum of 146 entries
|
||||
// - we need to reserve 4 entries for the cascaded shadow map
|
||||
//
|
||||
// CONFIG_MAX_SHADOW_LAYERS determines how many shadows can be used in the
|
||||
// scene. Currently, a spotlight uses 1 layer, a cascaded directional light uses up to 4
|
||||
// and a point light uses 6.
|
||||
//
|
||||
constexpr size_t CONFIG_MAX_SHADOW_LAYERS = 64;
|
||||
// - nonsensical to be larger than the number of shadowmaps
|
||||
constexpr size_t CONFIG_MAX_SHADOW_LAYERS = CONFIG_MAX_SHADOWMAPS;
|
||||
|
||||
// The maximum number of shadow cascades that can be used for directional lights.
|
||||
constexpr size_t CONFIG_MAX_SHADOW_CASCADES = 4;
|
||||
|
||||
// Maximum number of shadowmap for point and spotlights
|
||||
// spotlights use 1, point lights use 6
|
||||
constexpr size_t CONFIG_MAX_SHADOWMAP_PUNCTUAL =
|
||||
CONFIG_MAX_SHADOW_LAYERS - CONFIG_MAX_SHADOW_CASCADES;
|
||||
|
||||
|
||||
// The maximum UBO size, in bytes. This value is set to 16 KiB due to the ES3.0 spec.
|
||||
// Note that this value constrains the maximum number of skinning bones, morph targets,
|
||||
// instances, and shadow casting spotlights.
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
|
||||
struct SamplerInfo { // NOLINT(cppcoreguidelines-pro-type-member-init)
|
||||
utils::CString name; // name of this sampler
|
||||
utils::CString uniformName; // name of the uniform holding this sampler (needed for glsl)
|
||||
utils::CString uniformName; // name of the uniform holding this sampler (needed for glsl/MSL)
|
||||
uint8_t offset; // offset in "Sampler" of this sampler in the buffer
|
||||
Type type; // type of this sampler
|
||||
Format format; // format of this sampler
|
||||
|
||||
@@ -124,12 +124,10 @@ struct PerViewUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
|
||||
// bit 0-3: cascade count
|
||||
// bit 4: visualize cascades
|
||||
// bit 8-11: cascade has visible shadows
|
||||
// bit 31: elvsm
|
||||
uint32_t cascades;
|
||||
float shadowBulbRadiusLs; // light radius in light-space
|
||||
float shadowBias; // normal bias
|
||||
float reserved0;
|
||||
float reserved1; // normal bias
|
||||
float shadowPenumbraRatioScale; // For DPCF or PCSS, scale penumbra ratio for artistic use
|
||||
std::array<math::mat4f, CONFIG_MAX_SHADOW_CASCADES> lightFromWorldMatrix;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// VSM shadows [variant: VSM]
|
||||
@@ -164,7 +162,7 @@ struct PerViewUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
|
||||
float ssrStride; // ssr texel stride, >= 1.0
|
||||
|
||||
// bring PerViewUib to 2 KiB
|
||||
math::float4 reserved[47];
|
||||
math::float4 reserved[63];
|
||||
};
|
||||
|
||||
// 2 KiB == 128 float4s
|
||||
@@ -229,11 +227,11 @@ struct LightsUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
|
||||
math::float2 spotScaleOffset; // { scale, offset }
|
||||
float reserved3; // 0
|
||||
float intensity; // float
|
||||
uint32_t typeShadow; // 0x00.ll.ii.ct (t: 0=point, 1=spot, c:contact, ii: index, ll: layer)
|
||||
uint32_t typeShadow; // 0x00.00.ii.ct (t: 0=point, 1=spot, c:contact, ii: index)
|
||||
uint32_t channels; // 0x000c00ll (ll: light channels, c: caster)
|
||||
|
||||
static uint32_t packTypeShadow(uint8_t type, bool contactShadow, uint8_t index, uint8_t layer) noexcept {
|
||||
return (type & 0xF) | (contactShadow ? 0x10 : 0x00) | (index << 8) | (layer << 16);
|
||||
static uint32_t packTypeShadow(uint8_t type, bool contactShadow, uint8_t index) noexcept {
|
||||
return (type & 0xF) | (contactShadow ? 0x10 : 0x00) | (index << 8);
|
||||
}
|
||||
static uint32_t packChannels(uint8_t lightChannels, bool castShadows) noexcept {
|
||||
return lightChannels | (castShadows ? 0x10000 : 0);
|
||||
@@ -249,17 +247,22 @@ static_assert(sizeof(LightsUib) == 64,
|
||||
struct ShadowUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
|
||||
static constexpr std::string_view _name{ "ShadowUniforms" };
|
||||
struct alignas(16) ShadowData {
|
||||
math::mat4f lightFromWorldMatrix; // 64 - unused for point lights
|
||||
math::float3 direction; // 12 - unused for point lights
|
||||
float normalBias; // 4 - unused for point lights
|
||||
math::float4 lightFromWorldZ; // 16 - point lights { depth reconstruction values }
|
||||
math::mat4f lightFromWorldMatrix; // 64
|
||||
math::float3 direction; // 12
|
||||
float normalBias; // 4
|
||||
math::float4 lightFromWorldZ; // 16
|
||||
|
||||
float texelSizeAtOneMeter; // 4
|
||||
float bulbRadiusLs; // 4
|
||||
float nearOverFarMinusNear; // 4
|
||||
bool elvsm; // 4
|
||||
|
||||
uint32_t layer; // 4
|
||||
uint32_t reserved0; // 4
|
||||
uint32_t reserved1; // 4
|
||||
uint32_t reserved2; // 4
|
||||
};
|
||||
ShadowData shadows[CONFIG_MAX_SHADOWMAP_PUNCTUAL];
|
||||
ShadowData shadows[CONFIG_MAX_SHADOWMAPS];
|
||||
};
|
||||
static_assert(sizeof(ShadowUib) <= CONFIG_MINSPEC_UBO_SIZE,
|
||||
"ShadowUib exceeds max UBO size");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user