Compare commits
1 Commits
v1.70.2
...
pf/vk-add-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5462621eb |
2
.github/actions/get-mesa/action.yml
vendored
2
.github/actions/get-mesa/action.yml
vendored
@@ -9,7 +9,7 @@ runs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: mesa
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-mesa-deps-${{ env.GITHUB_MESA_VERSION }}
|
||||
key: ${{ runner.os }}-mesa-deps-${{ env.GITHUB_MESA_VERSION }}
|
||||
- name: Get Mesa
|
||||
run: |
|
||||
bash build/common/get-mesa.sh
|
||||
|
||||
3
.github/actions/get-vulkan-sdk/action.yml
vendored
3
.github/actions/get-vulkan-sdk/action.yml
vendored
@@ -9,7 +9,7 @@ runs:
|
||||
id: cache-vulkan-sdk
|
||||
with:
|
||||
path: ~/VulkanSDK
|
||||
key: vulkansdk-${{ env.GITHUB_VULKANSDK_VERSION }}-2-${{ runner.os }}-${{ runner.arch }}
|
||||
key: vulkansdk-${{ env.GITHUB_VULKANSDK_VERSION }}-2-${{ runner.os }}
|
||||
- name: Download Vulkan SDK
|
||||
if: steps.cache-vulkan-sdk.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
@@ -23,7 +23,6 @@ runs:
|
||||
unpack_vulkan_installer
|
||||
shell: bash
|
||||
- name: Run Vulkan SDK setup
|
||||
if: runner.os != 'Linux'
|
||||
run: |
|
||||
pushd .
|
||||
cd ~/VulkanSDK/${GITHUB_VULKANSDK_VERSION}
|
||||
|
||||
@@ -8,15 +8,9 @@ runs:
|
||||
- uses: ./.github/actions/get-mesa
|
||||
- uses: ./.github/actions/get-vulkan-sdk
|
||||
- name: Prerequisites
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
# Must have at least clang-16 for a webgpu/dawn build.
|
||||
sudo xcode-select -s /Applications/Xcode_16.2.app/Contents/Developer
|
||||
# this enforces the gltf_viewer build to use apple clang as oppose the brew clang used for get-mesa
|
||||
echo "CC=/usr/bin/clang" >> $GITHUB_ENV
|
||||
echo "CXX=/usr/bin/clang++" >> $GITHUB_ENV
|
||||
echo "/usr/local/bin" >> $GITHUB_PATH
|
||||
echo "/usr/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
- name: Generate images
|
||||
run: |
|
||||
|
||||
2
.github/actions/web-prereq/action.yml
vendored
2
.github/actions/web-prereq/action.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: 'Web Prerequisites'
|
||||
name: 'Web Preqrequisites'
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
|
||||
13
.github/workflows/presubmit.yml
vendored
13
.github/workflows/presubmit.yml
vendored
@@ -96,7 +96,7 @@ jobs:
|
||||
- name: Run build script
|
||||
run: |
|
||||
cd build/linux && printf "y" | ./build.sh presubmit
|
||||
- name: Test - material parser
|
||||
- name: Test material parser
|
||||
run: |
|
||||
out/cmake-release/filament/test/test_material_parser
|
||||
|
||||
@@ -266,10 +266,10 @@ jobs:
|
||||
echo "accept=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
shell: bash
|
||||
- name: Renderdiff generate
|
||||
- name: Renderdiff Generate
|
||||
if: steps.check_accept.outputs.accept != 'true'
|
||||
uses: ./.github/actions/renderdiff-generate
|
||||
- name: Compare rendered images
|
||||
- name: Render and compare
|
||||
if: steps.check_accept.outputs.accept != 'true'
|
||||
id: render_compare
|
||||
env:
|
||||
@@ -301,13 +301,12 @@ jobs:
|
||||
echo "$DELIMITER" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
shell: bash
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: steps.check_accept.outputs.accept != 'true'
|
||||
with:
|
||||
name: presubmit-renderdiff-result
|
||||
path: ./out/renderdiff
|
||||
- name: Check results
|
||||
- name: Compare result
|
||||
if: steps.check_accept.outputs.accept != 'true'
|
||||
run: |
|
||||
ERROR_STR="${{ steps.render_compare.outputs.err }}"
|
||||
@@ -316,7 +315,7 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
build-wgsl-webgpu:
|
||||
validate-wgsl-webgpu:
|
||||
name: validate-wgsl-webgpu
|
||||
runs-on: 'arm-ubuntu-24.04-16core'
|
||||
needs: [check-verification]
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.70.2'
|
||||
implementation 'com.google.android.filament:filament-android:1.70.0'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -50,7 +50,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```shell
|
||||
pod 'Filament', '~> 1.70.2'
|
||||
pod 'Filament', '~> 1.70.0'
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -7,9 +7,6 @@ A new header is inserted each time a *tag* is created.
|
||||
Instead, if you are authoring a PR for the main branch, add your release note to
|
||||
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
|
||||
|
||||
## v1.70.2
|
||||
|
||||
|
||||
## v1.70.1
|
||||
|
||||
|
||||
|
||||
@@ -61,7 +61,6 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size
|
||||
add_library(filament-utils-jni SHARED
|
||||
src/main/cpp/AutomationEngine.cpp
|
||||
src/main/cpp/Bookmark.cpp
|
||||
src/main/cpp/DeviceUtils.cpp
|
||||
src/main/cpp/HDRLoader.cpp
|
||||
src/main/cpp/IBLPrefilterContext.cpp
|
||||
src/main/cpp/Utils.cpp
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2026 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 <jni.h>
|
||||
|
||||
#include <filament/Engine.h>
|
||||
|
||||
#include <backend/Platform.h>
|
||||
|
||||
#include <utils/CString.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
using namespace filament;
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr std::array<backend::Platform::DeviceInfoType, 3> VULKAN_INFO = {
|
||||
backend::Platform::DeviceInfoType::VULKAN_DEVICE_NAME,
|
||||
backend::Platform::DeviceInfoType::VULKAN_DRIVER_NAME,
|
||||
backend::Platform::DeviceInfoType::VULKAN_DRIVER_INFO,
|
||||
};
|
||||
|
||||
constexpr std::array<backend::Platform::DeviceInfoType, 3> GL_INFO = {
|
||||
backend::Platform::DeviceInfoType::OPENGL_VENDOR,
|
||||
backend::Platform::DeviceInfoType::OPENGL_RENDERER,
|
||||
backend::Platform::DeviceInfoType::OPENGL_VERSION,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" JNIEXPORT jstring JNICALL
|
||||
Java_com_google_android_filament_utils_DeviceUtils_nGetGpuDriverInfo(JNIEnv* env, jclass,
|
||||
jlong nativeEngine) {
|
||||
auto emptyStr = [env]() { return env->NewStringUTF(""); };
|
||||
Engine* engine = (Engine*) nativeEngine;
|
||||
if (!engine) {
|
||||
return emptyStr();
|
||||
}
|
||||
|
||||
backend::Platform* platform = engine->getPlatform();
|
||||
if (!platform) {
|
||||
return emptyStr();
|
||||
}
|
||||
|
||||
std::array<backend::Platform::DeviceInfoType, 3> infoTypes;
|
||||
switch (engine->getBackend()) {
|
||||
case backend::Backend::VULKAN:
|
||||
infoTypes = VULKAN_INFO;
|
||||
break;
|
||||
case backend::Backend::OPENGL:
|
||||
infoTypes = GL_INFO;
|
||||
break;
|
||||
default:
|
||||
return emptyStr();
|
||||
}
|
||||
|
||||
backend::Driver* driver = const_cast<backend::Driver*>(engine->getDriver());
|
||||
utils::CString fullInfo;
|
||||
std::for_each(infoTypes.begin(), infoTypes.end(),
|
||||
[&](backend::Platform::DeviceInfoType infoType) {
|
||||
utils::CString const newInfo = platform->getDeviceInfo(infoType, driver);
|
||||
if (!newInfo.empty()) {
|
||||
if (!fullInfo.empty()) {
|
||||
fullInfo += " | ";
|
||||
}
|
||||
fullInfo += newInfo.c_str();
|
||||
}
|
||||
});
|
||||
return env->NewStringUTF(fullInfo.c_str());
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2026 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.android.filament.utils;
|
||||
|
||||
import com.google.android.filament.Engine;
|
||||
|
||||
public class DeviceUtils {
|
||||
public static String getGpuDriverInfo(Engine engine) {
|
||||
return nGetGpuDriverInfo(engine.getNativeObject());
|
||||
}
|
||||
private static native String nGetGpuDriverInfo(long nativeEngine);
|
||||
}
|
||||
@@ -266,35 +266,6 @@ class ModelViewer(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the model's transform, animation, and camera state to defaults.
|
||||
* Call this when reusing the same model across multiple tests.
|
||||
*/
|
||||
fun resetToDefaultState() {
|
||||
// 1. Reset Camera parameters
|
||||
cameraFocalLength = 28f
|
||||
cameraNear = kNearPlane
|
||||
cameraFar = kFarPlane
|
||||
updateCameraProjection()
|
||||
|
||||
// 2. Reset the manipulator's look-at vectors to initial state
|
||||
cameraManipulator?.let { cm ->
|
||||
cm.jumpToBookmark(cm.homeBookmark)
|
||||
}
|
||||
|
||||
// 3. Reset Animations
|
||||
animator?.let {
|
||||
if (it.animationCount > 0) {
|
||||
it.applyAnimation(0, 0.0f)
|
||||
}
|
||||
it.updateBoneMatrices()
|
||||
}
|
||||
|
||||
// 4. Re-apply the unit cube transform to clear custom scaling/translation
|
||||
clearRootTransform()
|
||||
transformToUnitCube()
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees all entities associated with the most recently-loaded model.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.70.2
|
||||
VERSION_NAME=1.70.0
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
@@ -30,11 +30,11 @@
|
||||
"view": {
|
||||
"postProcessingEnabled": true,
|
||||
"dithering": "NONE"
|
||||
},
|
||||
"tolerance": {
|
||||
"maxAbsDiff": 0.1,
|
||||
"maxFailingPixelsFraction": 0.0
|
||||
}
|
||||
},
|
||||
"tolerance": {
|
||||
"maxAbsDiff": 0.1,
|
||||
"maxFailingPixelsFraction": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -175,7 +175,7 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
|
||||
choreographer = Choreographer.getInstance()
|
||||
modelViewer = ModelViewer(surfaceView=surfaceView, manipulator=null)
|
||||
modelViewer = ModelViewer(surfaceView)
|
||||
inputManager = ValidationInputManager(this)
|
||||
|
||||
// Initialize IBL
|
||||
@@ -368,18 +368,6 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
}
|
||||
}
|
||||
|
||||
private fun createResultManager(outputDir: File): ValidationResultManager {
|
||||
val gpuDriverInfo = com.google.android.filament.utils.DeviceUtils.getGpuDriverInfo(modelViewer.engine)
|
||||
return ValidationResultManager(
|
||||
outputDir = outputDir,
|
||||
gpuDriverInfo = gpuDriverInfo,
|
||||
deviceName = android.os.Build.MODEL,
|
||||
deviceCodeName = android.os.Build.DEVICE,
|
||||
androidVersion = android.os.Build.VERSION.RELEASE,
|
||||
androidBuildNumber = android.os.Build.DISPLAY
|
||||
)
|
||||
}
|
||||
|
||||
private fun startValidation(input: ValidationInputManager.ValidationInput) {
|
||||
try {
|
||||
resultsContainer.removeAllViews()
|
||||
@@ -390,7 +378,7 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
|
||||
testResultsHeader.text = "${input.config.name}"
|
||||
|
||||
resultManager = createResultManager(input.outputDir)
|
||||
resultManager = ValidationResultManager(input.outputDir)
|
||||
|
||||
validationRunner = ValidationRunner(this, modelViewer, input.config, resultManager!!)
|
||||
validationRunner?.callback = this
|
||||
@@ -546,7 +534,7 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
private fun exportTestBundleAction() {
|
||||
currentInput?.let { input ->
|
||||
val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())
|
||||
val rm = resultManager ?: createResultManager(input.outputDir)
|
||||
val rm = resultManager ?: ValidationResultManager(input.outputDir)
|
||||
val zip = rm.exportTestBundle(input.config, timestamp)
|
||||
if (zip != null) {
|
||||
val msg = "Exported Bundle: ${zip.name}"
|
||||
@@ -562,7 +550,7 @@ class MainActivity : Activity(), ValidationRunner.Callback {
|
||||
private fun exportTestResultsAction() {
|
||||
currentInput?.let { input ->
|
||||
val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())
|
||||
val rm = resultManager ?: createResultManager(input.outputDir)
|
||||
val rm = resultManager ?: ValidationResultManager(input.outputDir)
|
||||
val zip = rm.exportTestResults(input.sourceZip, timestamp)
|
||||
if (zip != null) {
|
||||
val msg = "Exported Results: ${zip.name}"
|
||||
|
||||
@@ -31,14 +31,7 @@ data class ValidationResult(
|
||||
val diffMetric: Float = 0f
|
||||
)
|
||||
|
||||
class ValidationResultManager(
|
||||
private val outputDir: File,
|
||||
private val gpuDriverInfo: String,
|
||||
private val deviceName: String,
|
||||
private val deviceCodeName: String,
|
||||
private val androidVersion: String,
|
||||
private val androidBuildNumber: String
|
||||
) {
|
||||
class ValidationResultManager(private val outputDir: File) {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "ValidationResultManager"
|
||||
@@ -71,9 +64,9 @@ class ValidationResultManager(
|
||||
return outputDir
|
||||
}
|
||||
|
||||
fun finalizeResults(totalTimeMs: Long): File? {
|
||||
fun finalizeResults(): File? {
|
||||
// Write results JSON
|
||||
writeResultsJson(totalTimeMs)
|
||||
writeResultsJson()
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -110,10 +103,10 @@ class ValidationResultManager(
|
||||
zos.closeEntry()
|
||||
}
|
||||
|
||||
// 3. Add images (only rendered images, exclude diffs)
|
||||
outputDir.listFiles { _, name -> name.endsWith(".png") && !name.endsWith("_diff.png") }?.forEach { imgFile ->
|
||||
zos.putNextEntry(ZipEntry(imgFile.name))
|
||||
imgFile.inputStream().use { it.copyTo(zos) }
|
||||
// 3. Add diff images (any file ending in _diff.png in outputDir)
|
||||
outputDir.listFiles { _, name -> name.endsWith("_diff.png") }?.forEach { diffFile ->
|
||||
zos.putNextEntry(ZipEntry(diffFile.name))
|
||||
diffFile.inputStream().use { it.copyTo(zos) }
|
||||
zos.closeEntry()
|
||||
}
|
||||
}
|
||||
@@ -273,18 +266,7 @@ class ValidationResultManager(
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeResultsJson(totalTimeMs: Long) {
|
||||
val rootObject = JSONObject()
|
||||
|
||||
val metadataObject = JSONObject()
|
||||
metadataObject.put("gpu_driver_info", gpuDriverInfo ?: "")
|
||||
metadataObject.put("total_time_ms", totalTimeMs)
|
||||
metadataObject.put("device_name", deviceName ?: "")
|
||||
metadataObject.put("device_code_name", deviceCodeName ?: "")
|
||||
metadataObject.put("android_version", androidVersion ?: "")
|
||||
metadataObject.put("android_build_number", androidBuildNumber ?: "")
|
||||
rootObject.put("metadata", metadataObject)
|
||||
|
||||
private fun writeResultsJson() {
|
||||
val jsonArray = JSONArray()
|
||||
for (result in results) {
|
||||
val jsonObject = JSONObject()
|
||||
@@ -293,12 +275,11 @@ class ValidationResultManager(
|
||||
jsonObject.put("diff_metric", result.diffMetric)
|
||||
jsonArray.put(jsonObject)
|
||||
}
|
||||
rootObject.put("results", jsonArray)
|
||||
|
||||
val jsonFile = File(outputDir, "results.json")
|
||||
try {
|
||||
FileOutputStream(jsonFile).use { out ->
|
||||
out.write(rootObject.toString(4).toByteArray())
|
||||
out.write(jsonArray.toString(4).toByteArray())
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to write results.json", e)
|
||||
|
||||
@@ -42,7 +42,6 @@ class ValidationRunner(
|
||||
private var currentModelName: String? = null
|
||||
|
||||
private var frameCounter = 0
|
||||
private var suiteStartTime: Long = 0
|
||||
|
||||
enum class State {
|
||||
IDLE,
|
||||
@@ -66,7 +65,6 @@ class ValidationRunner(
|
||||
callback?.onAllTestsFinished()
|
||||
return
|
||||
}
|
||||
suiteStartTime = System.currentTimeMillis()
|
||||
currentTestIndex = 0
|
||||
currentModelIndex = 0
|
||||
startTest(config.tests[0])
|
||||
@@ -83,17 +81,6 @@ class ValidationRunner(
|
||||
}
|
||||
|
||||
private fun startModel(modelName: String) {
|
||||
if (currentModelName == modelName) {
|
||||
Log.i("ValidationRunner", "Reusing model $modelName")
|
||||
callback?.onStatusChanged("Reusing $modelName for ${currentTestConfig?.name}")
|
||||
|
||||
modelViewer.resetToDefaultState()
|
||||
|
||||
frameCounter = 0
|
||||
currentState = State.WARMUP
|
||||
return
|
||||
}
|
||||
|
||||
currentModelName = modelName
|
||||
val modelPath = config.models[modelName]
|
||||
if (modelPath == null) {
|
||||
@@ -358,10 +345,7 @@ class ValidationRunner(
|
||||
startTest(config.tests[currentTestIndex])
|
||||
} else {
|
||||
currentState = State.IDLE
|
||||
|
||||
val totalTimeMs = System.currentTimeMillis() - suiteStartTime
|
||||
|
||||
resultManager.finalizeResults(totalTimeMs)
|
||||
resultManager.finalizeResults()
|
||||
callback?.onAllTestsFinished()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,13 +54,8 @@ if [[ "$OS_NAME" == "Linux" ]]; then
|
||||
# is constantly being updated and sometimes not compatible with the current
|
||||
# linux platform.
|
||||
# Note that we assume this platform is compatible with ubuntu-22.04 x86_64
|
||||
DPKG_ARCH=$(dpkg --print-architecture)
|
||||
EXTRA_PACKAGES=""
|
||||
if [[ "$DPKG_ARCH" == "amd64" ]]; then
|
||||
EXTRA_PACKAGES="lib32gcc-s1 lib32stdc++6 libc6-i386"
|
||||
fi
|
||||
sudo apt-get -y install \
|
||||
autoconf automake autopoint autotools-dev bindgen bison build-essential bzip2 cpp cpp-11 debhelper debugedit dh-autoreconf dh-strip-nondeterminism diffstat directx-headers-dev dpkg-dev dwz flex g++ g++-11 gcc gcc-11 gcc-11-base:${DPKG_ARCH} gettext glslang-tools icu-devtools intltool-debian ${EXTRA_PACKAGES} libarchive-zip-perl libasan6:${DPKG_ARCH} libatomic1:${DPKG_ARCH} libc-dev-bin libc6-dbg:${DPKG_ARCH} libc6-dev:${DPKG_ARCH} libcc1-0:${DPKG_ARCH} libclang-${GITHUB_CLANG_VERSION}-dev libclang-common-${GITHUB_CLANG_VERSION}-dev libclang-cpp${GITHUB_CLANG_VERSION} libclang-cpp${GITHUB_CLANG_VERSION}-dev libclang1-14 libclang1-${GITHUB_CLANG_VERSION} libclc-${GITHUB_CLANG_VERSION} libclc-${GITHUB_CLANG_VERSION}-dev libcrypt-dev:${DPKG_ARCH} libdebhelper-perl libdpkg-perl libdrm-amdgpu1:${DPKG_ARCH} libdrm-dev:${DPKG_ARCH} libdrm-intel1:${DPKG_ARCH} libdrm-nouveau2:${DPKG_ARCH} libdrm-radeon1:${DPKG_ARCH} libelf-dev:${DPKG_ARCH} libexpat1-dev:${DPKG_ARCH} libffi-dev:${DPKG_ARCH} libfile-stripnondeterminism-perl libgc1:${DPKG_ARCH} libgcc-11-dev:${DPKG_ARCH} libgl1:${DPKG_ARCH} libgl1-mesa-dri:${DPKG_ARCH} libglapi-mesa:${DPKG_ARCH} libglvnd-core-dev:${DPKG_ARCH} libglvnd0:${DPKG_ARCH} libglx-mesa0:${DPKG_ARCH} libglx0:${DPKG_ARCH} libgomp1:${DPKG_ARCH} libicu-dev:${DPKG_ARCH} libisl23:${DPKG_ARCH} libitm1:${DPKG_ARCH} libllvm14:${DPKG_ARCH} libllvm${GITHUB_CLANG_VERSION}:${DPKG_ARCH} libllvmspirvlib-${GITHUB_CLANG_VERSION}-dev:${DPKG_ARCH} libllvmspirvlib${GITHUB_CLANG_VERSION}:${DPKG_ARCH} liblsan0:${DPKG_ARCH} libmpc3:${DPKG_ARCH} libncurses-dev:${DPKG_ARCH} libnsl-dev:${DPKG_ARCH} libobjc-11-dev:${DPKG_ARCH} libobjc4:${DPKG_ARCH} libpciaccess-dev:${DPKG_ARCH} libpciaccess0f:${DPKG_ARCH} libpfm4:${DPKG_ARCH} libpthread-stubs0-dev:${DPKG_ARCH} libquadmath0:${DPKG_ARCH} libsensors-config libsensors-dev:${DPKG_ARCH} libsensors5:${DPKG_ARCH} libset-scalar-perl libstd-rust-1.75:${DPKG_ARCH} libstd-rust-dev:${DPKG_ARCH} libstdc++-11-dev:${DPKG_ARCH} libsub-override-perl libtinfo-dev:${DPKG_ARCH} libtirpc-dev:${DPKG_ARCH} libtool libtsan0:${DPKG_ARCH} libubsan1:${DPKG_ARCH} libva-dev:${DPKG_ARCH} libva-drm2:${DPKG_ARCH} libva-glx2:${DPKG_ARCH} libva-wayland2:${DPKG_ARCH} libva-x11-2:${DPKG_ARCH} libva2:${DPKG_ARCH} libvdpau-dev:${DPKG_ARCH} libvdpau1:${DPKG_ARCH} libvulkan-dev:${DPKG_ARCH} libvulkan1:${DPKG_ARCH} libwayland-bin libwayland-client0:${DPKG_ARCH} libwayland-cursor0:${DPKG_ARCH} libwayland-dev:${DPKG_ARCH} libwayland-egl-backend-dev:${DPKG_ARCH} libwayland-egl1:${DPKG_ARCH} libwayland-server0:${DPKG_ARCH} libx11-dev:${DPKG_ARCH} libx11-xcb-dev:${DPKG_ARCH} libx11-xcb1:${DPKG_ARCH} libxau-dev:${DPKG_ARCH} libxcb-dri2-0:${DPKG_ARCH} libxcb-dri2-0-dev:${DPKG_ARCH} libxcb-dri3-0:${DPKG_ARCH} libxcb-dri3-dev:${DPKG_ARCH} libxcb-glx0:${DPKG_ARCH} libxcb-glx0-dev:${DPKG_ARCH} libxcb-present-dev:${DPKG_ARCH} libxcb-present0:${DPKG_ARCH} libxcb-randr0:${DPKG_ARCH} libxcb-randr0-dev:${DPKG_ARCH} libxcb-render0:${DPKG_ARCH} libxcb-render0-dev:${DPKG_ARCH} libxcb-shape0:${DPKG_ARCH} libxcb-shape0-dev:${DPKG_ARCH} libxcb-shm0:${DPKG_ARCH} libxcb-shm0-dev:${DPKG_ARCH} libxcb-sync-dev:${DPKG_ARCH} libxcb-sync1:${DPKG_ARCH} libxcb-xfixes0:${DPKG_ARCH} libxcb-xfixes0-dev:${DPKG_ARCH} libxcb1-dev:${DPKG_ARCH} libxdmcp-dev:${DPKG_ARCH} libxext-dev:${DPKG_ARCH} libxfixes-dev:${DPKG_ARCH} libxfixes3:${DPKG_ARCH} libxml2-dev:${DPKG_ARCH} libxrandr-dev:${DPKG_ARCH} libxrandr2:${DPKG_ARCH} libxrender-dev:${DPKG_ARCH} libxrender1:${DPKG_ARCH} libxshmfence-dev:${DPKG_ARCH} libxshmfence1:${DPKG_ARCH} libxxf86vm-dev:${DPKG_ARCH} libxxf86vm1:${DPKG_ARCH} libz3-4:${DPKG_ARCH} libz3-dev:${DPKG_ARCH} libzstd-dev:${DPKG_ARCH} linux-libc-dev:${DPKG_ARCH} llvm-${LLVM_VERSION} llvm-${LLVM_VERSION}-dev llvm-${LLVM_VERSION}-linker-tools llvm-${LLVM_VERSION}-runtime llvm-${LLVM_VERSION}-tools llvm-spirv-${LLVM_VERSION} lto-disabled-list m4 make meson ninja-build pkg-config po-debconf python3-mako python3-ply python3-pygments quilt rpcsvc-proto rustc spirv-tools valgrind wayland-protocols x11proto-dev xorg-sgml-doctools xtrans-dev zlib1g-dev:${DPKG_ARCH} \
|
||||
autoconf automake autopoint autotools-dev bindgen bison build-essential bzip2 cpp cpp-11 debhelper debugedit dh-autoreconf dh-strip-nondeterminism diffstat directx-headers-dev dpkg-dev dwz flex g++ g++-11 gcc gcc-11 gcc-11-base:amd64 gettext glslang-tools icu-devtools intltool-debian lib32gcc-s1 lib32stdc++6 libarchive-zip-perl libasan6:amd64 libatomic1:amd64 libc-dev-bin libc6-dbg:amd64 libc6-dev:amd64 libc6-i386 libcc1-0:amd64 libclang-${GITHUB_CLANG_VERSION}-dev libclang-common-${GITHUB_CLANG_VERSION}-dev libclang-cpp${GITHUB_CLANG_VERSION} libclang-cpp${GITHUB_CLANG_VERSION}-dev libclang1-14 libclang1-${GITHUB_CLANG_VERSION} libclc-${GITHUB_CLANG_VERSION} libclc-${GITHUB_CLANG_VERSION}-dev libcrypt-dev:amd64 libdebhelper-perl libdpkg-perl libdrm-amdgpu1:amd64 libdrm-dev:amd64 libdrm-intel1:amd64 libdrm-nouveau2:amd64 libdrm-radeon1:amd64 libelf-dev:amd64 libexpat1-dev:amd64 libffi-dev:amd64 libfile-stripnondeterminism-perl libgc1:amd64 libgcc-11-dev:amd64 libgl1:amd64 libgl1-mesa-dri:amd64 libglapi-mesa:amd64 libglvnd-core-dev:amd64 libglvnd0:amd64 libglx-mesa0:amd64 libglx0:amd64 libgomp1:amd64 libicu-dev:amd64 libisl23:amd64 libitm1:amd64 libllvm14:amd64 libllvm${GITHUB_CLANG_VERSION}:amd64 libllvmspirvlib-${GITHUB_CLANG_VERSION}-dev:amd64 libllvmspirvlib${GITHUB_CLANG_VERSION}:amd64 liblsan0:amd64 libmpc3:amd64 libncurses-dev:amd64 libnsl-dev:amd64 libobjc-11-dev:amd64 libobjc4:amd64 libpciaccess-dev:amd64 libpciaccess0f:amd64 libpfm4:amd64 libpthread-stubs0-dev:amd64 libquadmath0:amd64 libsensors-config libsensors-dev:amd64 libsensors5:amd64 libset-scalar-perl libstd-rust-1.75:amd64 libstd-rust-dev:amd64 libstdc++-11-dev:amd64 libsub-override-perl libtinfo-dev:amd64 libtirpc-dev:amd64 libtool libtsan0:amd64 libubsan1:amd64 libva-dev:amd64 libva-drm2:amd64 libva-glx2:amd64 libva-wayland2:amd64 libva-x11-2:amd64 libva2:amd64 libvdpau-dev:amd64 libvdpau1:amd64 libvulkan-dev:amd64 libvulkan1:amd64 libwayland-bin libwayland-client0:amd64 libwayland-cursor0:amd64 libwayland-dev:amd64 libwayland-egl-backend-dev:amd64 libwayland-egl1:amd64 libwayland-server0:amd64 libx11-dev:amd64 libx11-xcb-dev:amd64 libx11-xcb1:amd64 libxau-dev:amd64 libxcb-dri2-0:amd64 libxcb-dri2-0-dev:amd64 libxcb-dri3-0:amd64 libxcb-dri3-dev:amd64 libxcb-glx0:amd64 libxcb-glx0-dev:amd64 libxcb-present-dev:amd64 libxcb-present0:amd64 libxcb-randr0:amd64 libxcb-randr0-dev:amd64 libxcb-render0:amd64 libxcb-render0-dev:amd64 libxcb-shape0:amd64 libxcb-shape0-dev:amd64 libxcb-shm0:amd64 libxcb-shm0-dev:amd64 libxcb-sync-dev:amd64 libxcb-sync1:amd64 libxcb-xfixes0:amd64 libxcb-xfixes0-dev:amd64 libxcb1-dev:amd64 libxdmcp-dev:amd64 libxext-dev:amd64 libxfixes-dev:amd64 libxfixes3:amd64 libxml2-dev:amd64 libxrandr-dev:amd64 libxrandr2:amd64 libxrender-dev:amd64 libxrender1:amd64 libxshmfence-dev:amd64 libxshmfence1:amd64 libxxf86vm-dev:amd64 libxxf86vm1:amd64 libz3-4:amd64 libz3-dev:amd64 libzstd-dev:amd64 linux-libc-dev:amd64 llvm-${LLVM_VERSION} llvm-${LLVM_VERSION}-dev llvm-${LLVM_VERSION}-linker-tools llvm-${LLVM_VERSION}-runtime llvm-${LLVM_VERSION}-tools llvm-spirv-${LLVM_VERSION} lto-disabled-list m4 make meson ninja-build pkg-config po-debconf python3-mako python3-ply python3-pygments quilt rpcsvc-proto rustc spirv-tools valgrind wayland-protocols x11proto-dev xorg-sgml-doctools xtrans-dev zlib1g-dev:amd64 \
|
||||
clang-$GITHUB_CLANG_VERSION libc++-$GITHUB_CLANG_VERSION-dev libc++abi-$GITHUB_CLANG_VERSION-dev
|
||||
|
||||
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang-${GITHUB_CLANG_VERSION} 100
|
||||
@@ -85,7 +80,6 @@ elif [[ "$OS_NAME" == "Darwin" ]]; then
|
||||
if command -v brew > /dev/null 2>&1; then
|
||||
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=true brew install autoconf automake libx11 libxext libxrandr \
|
||||
llvm@${LLVM_VERSION} ninja meson pkg-config libxshmfence
|
||||
brew link --overwrite llvm@${LLVM_VERSION}
|
||||
# For reasons unknown, this is necessary for pkg-config to find homebrew's packages
|
||||
LOCAL_PKG_CONFIG_PATH="/opt/homebrew/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
elif command -v port > /dev/null 2>&1; then
|
||||
|
||||
@@ -63,10 +63,6 @@ function _preferred_os_filename() {
|
||||
|
||||
function download_vulkan_installer() {
|
||||
local os=$(_get_os)
|
||||
if [[ "$os" == "linux" ]]; then
|
||||
echo "Linux uses apt to install vulkan dependencies, skipping tarball download." >&2
|
||||
return 0
|
||||
fi
|
||||
local dl_filename=$(_os_filename ${VULKAN_SDK_VERSION})
|
||||
local filename=$(_preferred_os_filename)
|
||||
local url=https://sdk.lunarg.com/sdk/download/$VULKAN_SDK_VERSION/$os/$dl_filename?Human=true
|
||||
@@ -83,22 +79,15 @@ function download_vulkan_installer() {
|
||||
|
||||
function unpack_vulkan_installer() {
|
||||
local os=$(_get_os)
|
||||
if [[ "$os" == "linux" ]]; then
|
||||
install_${os}
|
||||
return 0
|
||||
fi
|
||||
local filename=$(_preferred_os_filename $os)
|
||||
test -f $filename
|
||||
install_${os}
|
||||
}
|
||||
|
||||
function install_linux() {
|
||||
echo "Installing Vulkan dependencies via apt for Linux..." >&2
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y libvulkan-dev vulkan-validationlayers glslang-tools spirv-tools
|
||||
|
||||
# Create a dummy SDK dir to satisfy scripts expecting a VulkanSDK folder structure
|
||||
mkdir -p ~/VulkanSDK/${VULKAN_SDK_VERSION}
|
||||
test -d $VULKAN_SDK_DIR && test -f vulkan_sdk.tar.gz
|
||||
echo "extract just the SDK's prebuilt binaries ($VULKAN_SDK_VERSION/x86_64) from vulkan_sdk.tar.gz into $VULKAN_SDK" >&2
|
||||
tar -C "$VULKAN_SDK_DIR" --strip-components 2 -xf vulkan_sdk.tar.gz $VULKAN_SDK_VERSION/x86_64
|
||||
}
|
||||
|
||||
function install_mac() {
|
||||
|
||||
@@ -185,7 +185,7 @@ private:
|
||||
};
|
||||
|
||||
int mOSVersion;
|
||||
ExternalStreamManagerAndroid* mExternalStreamManager = nullptr;
|
||||
ExternalStreamManagerAndroid& mExternalStreamManager;
|
||||
AndroidDetails& mAndroidDetails;
|
||||
utils::PerformanceHintManager mPerformanceHintManager;
|
||||
utils::PerformanceHintManager::Session mPerformanceHintSession;
|
||||
|
||||
@@ -176,12 +176,6 @@ public:
|
||||
* presentation. Default is true.
|
||||
*/
|
||||
bool transitionSwapChainImageLayoutForPresent = true;
|
||||
|
||||
/**
|
||||
* The number of frames before an unused framebuffer is evicted from the cache.
|
||||
* Default is 3.
|
||||
*/
|
||||
uint32_t timeBeforeEvictionFbo = 3;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -222,15 +222,6 @@ OpenGLContext::OpenGLContext(OpenGLPlatform& platform,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(BACKEND_OPENGL_VERSION_GL) || defined(GL_EXT_disjoint_timer_query)
|
||||
if (ext.EXT_disjoint_timer_query) {
|
||||
mGpuTimeSupported = true;
|
||||
} else
|
||||
#endif
|
||||
if (platform.canCreateFence()) {
|
||||
mGpuTimeSupported = true;
|
||||
}
|
||||
|
||||
// in practice KHR_Debug has never been useful, and actually is confusing. We keep this
|
||||
// only for our own debugging, in case we need it some day.
|
||||
#if false && !defined(NDEBUG) && defined(GL_KHR_debug)
|
||||
|
||||
@@ -158,10 +158,8 @@ public:
|
||||
constexpr static inline size_t getIndexForBufferTarget(GLenum target) noexcept;
|
||||
|
||||
ShaderModel getShaderModel() const noexcept { return mShaderModel; }
|
||||
|
||||
|
||||
void resetState() noexcept;
|
||||
|
||||
bool isGpuTimeSupported() const noexcept { return mGpuTimeSupported; }
|
||||
|
||||
inline void useProgram(GLuint program) noexcept;
|
||||
|
||||
@@ -544,8 +542,6 @@ private:
|
||||
|
||||
Platform::DriverConfig const mDriverConfig;
|
||||
|
||||
bool mGpuTimeSupported = false;
|
||||
|
||||
void bindFramebufferResolved(GLenum target, GLuint buffer) noexcept;
|
||||
|
||||
const std::array<std::tuple<bool const&, char const*, char const*>, sizeof(bugs)> mBugDatabase{{
|
||||
|
||||
@@ -467,8 +467,7 @@ void OpenGLDriver::bindTexture(GLuint const unit, GLTexture const* t) noexcept {
|
||||
bool OpenGLDriver::useProgram(OpenGLProgram* p) noexcept {
|
||||
bool success = true;
|
||||
if (mBoundProgram != p) {
|
||||
// compile/link the program if needed and call glUseProgram.
|
||||
// This call may block until the program linking process is complete.
|
||||
// compile/link the program if needed and call glUseProgram
|
||||
success = p->use(this, mContext);
|
||||
assert_invariant(success == p->isValid());
|
||||
if (success) {
|
||||
@@ -2860,7 +2859,7 @@ bool OpenGLDriver::isFrameBufferFetchMultiSampleSupported() {
|
||||
}
|
||||
|
||||
bool OpenGLDriver::isFrameTimeSupported() {
|
||||
return mContext.isGpuTimeSupported();
|
||||
return TimerQueryFactory::isGpuTimeSupported();
|
||||
}
|
||||
|
||||
bool OpenGLDriver::isAutoDepthResolveSupported() {
|
||||
|
||||
@@ -48,7 +48,7 @@ class OpenGLDriver;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
bool TimerQueryFactory::mGpuTimeSupported = false;
|
||||
|
||||
TimerQueryFactoryInterface* TimerQueryFactory::init(
|
||||
OpenGLPlatform& platform, OpenGLContext& context) {
|
||||
@@ -65,14 +65,17 @@ TimerQueryFactoryInterface* TimerQueryFactory::init(
|
||||
} else {
|
||||
impl = new(std::nothrow) TimerQueryNativeFactory(context);
|
||||
}
|
||||
mGpuTimeSupported = true;
|
||||
} else
|
||||
#endif
|
||||
if (platform.canCreateFence()) {
|
||||
// no timer queries, but we can use fences
|
||||
impl = new(std::nothrow) TimerQueryFenceFactory(platform);
|
||||
mGpuTimeSupported = true;
|
||||
} else {
|
||||
// no queries, no fences -- that's a problem
|
||||
impl = new(std::nothrow) TimerQueryFallbackFactory();
|
||||
mGpuTimeSupported = false;
|
||||
}
|
||||
assert_invariant(impl);
|
||||
return impl;
|
||||
|
||||
@@ -61,9 +61,14 @@ struct GLTimerQuery : public HwTimerQuery {
|
||||
*/
|
||||
|
||||
class TimerQueryFactory {
|
||||
static bool mGpuTimeSupported;
|
||||
public:
|
||||
static TimerQueryFactoryInterface* init(
|
||||
OpenGLPlatform& platform, OpenGLContext& context);
|
||||
|
||||
static bool isGpuTimeSupported() noexcept {
|
||||
return mGpuTimeSupported;
|
||||
}
|
||||
};
|
||||
|
||||
class TimerQueryFactoryInterface {
|
||||
|
||||
@@ -367,15 +367,14 @@ void ShaderCompilerService::compileProgram(
|
||||
<< " failed to link or compile";
|
||||
#endif
|
||||
}
|
||||
// The program blob is cached prior to signaling to ensure data integrity.
|
||||
// Since the receiving thread may immediately modify gl.program (e.g., via
|
||||
// glUniformBlockBinding) upon receipt of the signal, caching must be
|
||||
// finalized first.
|
||||
tryCachingProgram(mBlobCache, mDriver.mPlatform, token);
|
||||
// Now `token->gl.program` must be populated, so we signal the completion
|
||||
// of the linking. We don't need to check the result of the program here
|
||||
// because it'll be done in the engine thread.
|
||||
token->signal();
|
||||
// We try caching the program blob after sending the signal. This allows us
|
||||
// to unblock the engine thread as soon as the token is ready while
|
||||
// performing an expensive caching operation still in the pool.
|
||||
tryCachingProgram(mBlobCache, mDriver.mPlatform, token);
|
||||
// Updates the token's state. If the token is canceled while this function
|
||||
// executes, this update notifies `tick` that GL resource loading is
|
||||
// complete, allowing `tick` to proceed with resource destruction.
|
||||
|
||||
@@ -80,9 +80,6 @@ JNIEnv* ExternalStreamManagerAndroid::getEnvironmentSlow() noexcept {
|
||||
|
||||
Stream* ExternalStreamManagerAndroid::acquire(jobject surfaceTexture) noexcept {
|
||||
// note: This is called on the application thread (not the GL thread)
|
||||
// The application thread *MUST* be attached to the JVM to pass the java 'surfaceTexture' down
|
||||
// to filament natively, so we are guaranteed to get a valid JNIEnv from getThreadEnvironment()
|
||||
// without needing AttachCurrentThread.
|
||||
JNIEnv* env = VirtualMachineEnv::getThreadEnvironment();
|
||||
if (!env) {
|
||||
return nullptr; // this should not happen
|
||||
|
||||
@@ -120,7 +120,8 @@ struct PlatformEGLAndroid::AndroidDetails {
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
|
||||
PlatformEGLAndroid::PlatformEGLAndroid() noexcept
|
||||
: mAndroidDetails(*(new(std::nothrow) AndroidDetails{})) {
|
||||
: mExternalStreamManager(ExternalStreamManagerAndroid::create()),
|
||||
mAndroidDetails(*(new(std::nothrow) AndroidDetails{})) {
|
||||
mOSVersion = android_get_device_api_level();
|
||||
if (mOSVersion < 0) {
|
||||
mOSVersion = __ANDROID_API_FUTURE__;
|
||||
@@ -134,10 +135,7 @@ PlatformEGLAndroid::~PlatformEGLAndroid() noexcept {
|
||||
void PlatformEGLAndroid::terminate() noexcept {
|
||||
mPerformanceHintManager.terminate();
|
||||
mAndroidDetails.androidFrameCallback.terminate();
|
||||
if (mExternalStreamManager) {
|
||||
ExternalStreamManagerAndroid::destroy(mExternalStreamManager);
|
||||
mExternalStreamManager = nullptr;
|
||||
}
|
||||
ExternalStreamManagerAndroid::destroy(&mExternalStreamManager);
|
||||
PlatformEGL::terminate();
|
||||
}
|
||||
|
||||
@@ -227,10 +225,6 @@ Driver* PlatformEGLAndroid::createDriver(void* sharedContext,
|
||||
mPerformanceHintSession = PerformanceHintManager::Session{
|
||||
mPerformanceHintManager, &tid, 1, 16'666'667 };
|
||||
|
||||
mExternalStreamManager = &ExternalStreamManagerAndroid::create();
|
||||
FILAMENT_CHECK_POSTCONDITION(mExternalStreamManager)
|
||||
<< "Failed to create ExternalStreamManagerAndroid";
|
||||
|
||||
Driver* driver = PlatformEGL::createDriver(sharedContext, driverConfig);
|
||||
auto const extensions = GLUtils::split(eglQueryString(getEglDisplay(), EGL_EXTENSIONS));
|
||||
|
||||
@@ -617,13 +611,11 @@ void PlatformEGLAndroid::setPresentationTime(int64_t const presentationTimeInNan
|
||||
}
|
||||
|
||||
Platform::Stream* PlatformEGLAndroid::createStream(void* nativeStream) noexcept {
|
||||
assert_invariant(mExternalStreamManager);
|
||||
return mExternalStreamManager->acquire(static_cast<jobject>(nativeStream));
|
||||
return mExternalStreamManager.acquire(static_cast<jobject>(nativeStream));
|
||||
}
|
||||
|
||||
void PlatformEGLAndroid::destroyStream(Stream* stream) noexcept {
|
||||
assert_invariant(mExternalStreamManager);
|
||||
mExternalStreamManager->release(stream);
|
||||
mExternalStreamManager.release(stream);
|
||||
}
|
||||
|
||||
Platform::Sync* PlatformEGLAndroid::createSync() noexcept {
|
||||
@@ -675,23 +667,19 @@ void PlatformEGLAndroid::destroySync(Sync* sync) noexcept {
|
||||
}
|
||||
|
||||
void PlatformEGLAndroid::attach(Stream* stream, intptr_t const tname) noexcept {
|
||||
assert_invariant(mExternalStreamManager);
|
||||
mExternalStreamManager->attach(stream, tname);
|
||||
mExternalStreamManager.attach(stream, tname);
|
||||
}
|
||||
|
||||
void PlatformEGLAndroid::detach(Stream* stream) noexcept {
|
||||
assert_invariant(mExternalStreamManager);
|
||||
mExternalStreamManager->detach(stream);
|
||||
mExternalStreamManager.detach(stream);
|
||||
}
|
||||
|
||||
void PlatformEGLAndroid::updateTexImage(Stream* stream, int64_t* timestamp) noexcept {
|
||||
assert_invariant(mExternalStreamManager);
|
||||
mExternalStreamManager->updateTexImage(stream, timestamp);
|
||||
mExternalStreamManager.updateTexImage(stream, timestamp);
|
||||
}
|
||||
|
||||
math::mat3f PlatformEGLAndroid::getTransformMatrix(Stream* stream) noexcept {
|
||||
assert_invariant(mExternalStreamManager);
|
||||
return mExternalStreamManager->getTransformMatrix(stream);
|
||||
return mExternalStreamManager.getTransformMatrix(stream);
|
||||
}
|
||||
|
||||
int PlatformEGLAndroid::getOSVersion() const noexcept {
|
||||
|
||||
@@ -106,6 +106,12 @@ void VulkanBufferCache::gc() noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
size_t totalBuffers = 0;
|
||||
for (auto& bufferPool : mGpuBufferPools) {
|
||||
totalBuffers += bufferPool.size();
|
||||
}
|
||||
FVK_LOGD << "VulkanBufferCache sizes: buffers=" << totalBuffers;
|
||||
|
||||
FVK_SYSTRACE_END();
|
||||
}
|
||||
|
||||
@@ -157,6 +163,10 @@ VulkanGpuBuffer const* VulkanBufferCache::allocate(VulkanBufferBinding binding,
|
||||
UTILS_UNUSED_IN_RELEASE VkResult result = vmaCreateBuffer(mAllocator, &bufferInfo, &allocInfo,
|
||||
&gpuBuffer->vkbuffer, &gpuBuffer->vmaAllocation, &gpuBuffer->allocationInfo);
|
||||
|
||||
FVK_LOGD << "VulkanBufferCache - allocated a vkBuffer " << gpuBuffer->vkbuffer
|
||||
<< " of size " << numBytes << " and binding = " << static_cast<int>(binding)
|
||||
<< " result=" << (int)result;
|
||||
|
||||
#if FVK_ENABLED(FVK_DEBUG_VULKAN_BUFFER_CACHE)
|
||||
if (result != VK_SUCCESS) {
|
||||
FVK_LOGE << "VulkanBufferCache - failed to allocate a new vkBuffer of size " << numBytes
|
||||
@@ -173,6 +183,7 @@ VulkanGpuBuffer const* VulkanBufferCache::allocate(VulkanBufferBinding binding,
|
||||
}
|
||||
|
||||
void VulkanBufferCache::destroy(VulkanGpuBuffer const* gpuBuffer) noexcept {
|
||||
FVK_LOGD << "VulkanBufferCache - Destroying vkBuffer " << gpuBuffer->vkbuffer;
|
||||
vmaDestroyBuffer(mAllocator, gpuBuffer->vkbuffer, gpuBuffer->vmaAllocation);
|
||||
delete gpuBuffer;
|
||||
gpuBuffer = nullptr;
|
||||
|
||||
@@ -194,6 +194,7 @@ void VulkanCommandBuffer::begin() noexcept {
|
||||
}
|
||||
|
||||
fvkmemory::resource_ptr<VulkanSemaphore> VulkanCommandBuffer::submit() {
|
||||
FVK_LOGD << "Submitting VulkanCommandBuffer: " << mBuffer << " (age=" << age() << ")";
|
||||
while (mMarkerCount > 0) {
|
||||
popMarker();
|
||||
}
|
||||
|
||||
@@ -260,8 +260,7 @@ VulkanDriver::VulkanDriver(VulkanPlatform* platform, VulkanContext& context,
|
||||
mPipelineCache(*this, mPlatform->getDevice(), mContext),
|
||||
mStagePool(mAllocator, &mResourceManager, &mCommands, &mContext.getPhysicalDeviceLimits()),
|
||||
mBufferCache(mContext, mResourceManager, mAllocator),
|
||||
mFramebufferCache(mPlatform->getDevice(),
|
||||
mPlatform->getCustomization().timeBeforeEvictionFbo),
|
||||
mFramebufferCache(mPlatform->getDevice()),
|
||||
mYcbcrConversionCache(mPlatform->getDevice()),
|
||||
mSamplerCache(mPlatform->getDevice()),
|
||||
mBlitter(mPlatform->getPhysicalDevice(), &mCommands),
|
||||
|
||||
@@ -20,12 +20,11 @@
|
||||
#include "VulkanHandles.h"
|
||||
#include "vulkan/utils/Image.h"
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
// If any VkRenderPass or VkFramebuffer is unused for more than TIME_BEFORE_EVICTION frames, it
|
||||
// is evicted from the cache.
|
||||
static constexpr uint32_t TIME_BEFORE_EVICTION = FVK_MAX_COMMAND_BUFFERS;
|
||||
static constexpr uint32_t TIME_BEFORE_EVICTION = 3;
|
||||
|
||||
using namespace bluevk;
|
||||
|
||||
@@ -63,9 +62,8 @@ bool VulkanFboCache::FboKeyEqualFn::operator()(const FboKey& k1, const FboKey& k
|
||||
return true;
|
||||
}
|
||||
|
||||
VulkanFboCache::VulkanFboCache(VkDevice device, uint32_t timeBeforeEvictionFbo)
|
||||
: mDevice(device),
|
||||
mTimeBeforeEvictionFbo(timeBeforeEvictionFbo) {}
|
||||
VulkanFboCache::VulkanFboCache(VkDevice device)
|
||||
: mDevice(device) {}
|
||||
|
||||
VulkanFboCache::~VulkanFboCache() {
|
||||
FILAMENT_CHECK_POSTCONDITION(mFramebufferCache.empty() && mRenderPassCache.empty())
|
||||
@@ -122,6 +120,8 @@ fvkmemory::resource_ptr<VulkanFramebuffer> VulkanFboCache::getFramebuffer(FboKey
|
||||
VkResult error = vkCreateFramebuffer(mDevice, &info, VKALLOC, &framebuffer);
|
||||
FILAMENT_CHECK_POSTCONDITION(error == VK_SUCCESS) << "Unable to create framebuffer."
|
||||
<< " error=" << static_cast<int32_t>(error);
|
||||
FVK_LOGD << "VulkanFboCache - Created VkFramebuffer " << framebuffer << " for renderTarget " << renderTarget.get()
|
||||
<< " size=" << config.width << "x" << config.height;
|
||||
fvkmemory::resource_ptr<VulkanFramebuffer> fbh =
|
||||
fvkmemory::resource_ptr<VulkanFramebuffer>::construct(resManager, mDevice, framebuffer,
|
||||
renderTarget);
|
||||
@@ -378,39 +378,36 @@ void VulkanFboCache::gc() noexcept {
|
||||
FVK_SYSTRACE_START("fbocache::gc");
|
||||
|
||||
// If this is one of the first few frames, return early to avoid wrapping unsigned integers.
|
||||
++mCurrentTime;
|
||||
if (++mCurrentTime <= TIME_BEFORE_EVICTION) {
|
||||
return;
|
||||
}
|
||||
const uint32_t evictTime = mCurrentTime - TIME_BEFORE_EVICTION;
|
||||
|
||||
if (UTILS_UNLIKELY(mCurrentTime > mTimeBeforeEvictionFbo)) {
|
||||
const uint32_t evictTimeFbo = mCurrentTime - mTimeBeforeEvictionFbo;
|
||||
for (FboMap::iterator iter = mFramebufferCache.begin(); iter != mFramebufferCache.end();) {
|
||||
const FboVal fbo = iter->second;
|
||||
if (fbo.timestamp < evictTimeFbo && fbo.handle) {
|
||||
mRenderPassRefCount[iter->first.renderPass]--;
|
||||
for (FboMap::iterator iter = mFramebufferCache.begin(); iter != mFramebufferCache.end(); ) {
|
||||
const FboVal fbo = iter->second;
|
||||
if (fbo.timestamp < evictTime && fbo.handle) {
|
||||
mRenderPassRefCount[iter->first.renderPass]--;
|
||||
|
||||
// erase(iterator) returns the iterator to the next element.
|
||||
iter = mFramebufferCache.erase(iter);
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
// erase(iterator) returns the iterator to the next element.
|
||||
iter = mFramebufferCache.erase(iter);
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
if (UTILS_UNLIKELY(mCurrentTime > TIME_BEFORE_EVICTION)) {
|
||||
const uint32_t evictTimeRp = mCurrentTime - TIME_BEFORE_EVICTION;
|
||||
for (RenderPassMap::iterator iter = mRenderPassCache.begin();
|
||||
iter != mRenderPassCache.end();) {
|
||||
const VkRenderPass handle = iter->second.handle->getVkRenderPass();
|
||||
if (iter->second.timestamp < evictTimeRp && handle &&
|
||||
mRenderPassRefCount[handle] == 0) {
|
||||
// erase(iterator) returns the iterator to the next element.
|
||||
iter = mRenderPassCache.erase(iter);
|
||||
mRenderPassRefCount.erase(handle);
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
for (RenderPassMap::iterator iter = mRenderPassCache.begin(); iter != mRenderPassCache.end(); ) {
|
||||
const VkRenderPass handle = iter->second.handle->getVkRenderPass();
|
||||
if (iter->second.timestamp < evictTime && handle && mRenderPassRefCount[handle] == 0) {
|
||||
// erase(iterator) returns the iterator to the next element.
|
||||
iter = mRenderPassCache.erase(iter);
|
||||
mRenderPassRefCount.erase(handle);
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
FVK_LOGD << "VulkanFboCache sizes: framebuffers=" << mFramebufferCache.size() << " renderpasses=" << mRenderPassCache.size();
|
||||
|
||||
FVK_SYSTRACE_END();
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
bool operator()(const FboKey& k1, const FboKey& k2) const;
|
||||
};
|
||||
|
||||
explicit VulkanFboCache(VkDevice device, uint32_t timeBeforeEvictionFbo);
|
||||
explicit VulkanFboCache(VkDevice device);
|
||||
~VulkanFboCache();
|
||||
|
||||
// Retrieves or creates a VkFramebuffer handle.
|
||||
@@ -130,7 +130,6 @@ private:
|
||||
RenderPassMap mRenderPassCache;
|
||||
tsl::robin_map<VkRenderPass, uint32_t> mRenderPassRefCount;
|
||||
uint32_t mCurrentTime = 0;
|
||||
uint32_t mTimeBeforeEvictionFbo;
|
||||
};
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -403,10 +403,13 @@ VulkanRenderTarget::VulkanRenderTarget()
|
||||
mOffscreen(false),
|
||||
mProtected(false),
|
||||
mInfo(std::make_unique<Auxiliary>()) {
|
||||
FVK_LOGD << "Creating default VulkanRenderTarget: " << this;
|
||||
mInfo->rpkey.samples = mInfo->fbkey.samples = 1;
|
||||
}
|
||||
|
||||
VulkanRenderTarget::~VulkanRenderTarget() = default;
|
||||
VulkanRenderTarget::~VulkanRenderTarget() {
|
||||
FVK_LOGD << "Destroying VulkanRenderTarget: " << this << " (offscreen=" << mOffscreen << ")";
|
||||
}
|
||||
|
||||
void VulkanRenderTarget::bindSwapChain(fvkmemory::resource_ptr<VulkanSwapChain> swapchain) {
|
||||
assert_invariant(!mOffscreen);
|
||||
@@ -443,9 +446,12 @@ void VulkanRenderTarget::bindSwapChain(fvkmemory::resource_ptr<VulkanSwapChain>
|
||||
fbkey.depth = VK_NULL_HANDLE;
|
||||
}
|
||||
mInfo->colors.set(0);
|
||||
FVK_LOGD << "bindSwapChain: target=" << this << ", swapchain=" << swapchain.get()
|
||||
<< ", size=" << width << "x" << height;
|
||||
}
|
||||
|
||||
void VulkanRenderTarget::releaseSwapchain() {
|
||||
FVK_LOGD << "releaseSwapchain: target=" << this;
|
||||
mInfo->colors = {};
|
||||
mInfo->attachments.clear();
|
||||
}
|
||||
@@ -459,6 +465,7 @@ VulkanRenderTarget::VulkanRenderTarget(VkDevice device, VkPhysicalDevice physica
|
||||
mOffscreen(true),
|
||||
mProtected(false),
|
||||
mInfo(std::make_unique<Auxiliary>()) {
|
||||
FVK_LOGD << "Creating offscreen VulkanRenderTarget: " << this << ", size=" << width << "x" << height << ", samples=" << (int)samples;
|
||||
auto& depth = depthStencil[0];
|
||||
|
||||
// Constrain the sample count according to both kinds of sample count masks obtained from
|
||||
@@ -719,9 +726,13 @@ VulkanFramebuffer::VulkanFramebuffer(VkDevice device, VkFramebuffer framebuffer,
|
||||
fvkmemory::resource_ptr<VulkanRenderTarget> renderTarget)
|
||||
: mDevice(device),
|
||||
mFramebuffer(framebuffer),
|
||||
mRenderTarget(renderTarget) {}
|
||||
mRenderTarget(renderTarget) {
|
||||
FVK_LOGD << "Creating VulkanFramebuffer: " << framebuffer
|
||||
<< ", target=" << renderTarget.get();
|
||||
}
|
||||
|
||||
VulkanFramebuffer::~VulkanFramebuffer() {
|
||||
FVK_LOGD << "Destroying VulkanFramebuffer: " << mFramebuffer;
|
||||
vkDestroyFramebuffer(mDevice, mFramebuffer, VKALLOC);
|
||||
}
|
||||
|
||||
|
||||
@@ -534,6 +534,8 @@ void VulkanPipelineCache::gc() noexcept {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
FVK_LOGD << "VulkanPipelineCache sizes: pipelines=" << mPipelines.size();
|
||||
}
|
||||
|
||||
bool VulkanPipelineCache::PipelineEqual::operator()(const PipelineKey& k1,
|
||||
|
||||
@@ -271,6 +271,8 @@ void VulkanStagePool::gc() noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
FVK_LOGD << "VulkanStagePool sizes: stages=" << mStages.size() << " freeImages=" << mFreeImages.size();
|
||||
|
||||
FVK_SYSTRACE_END();
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ VulkanSwapChain::VulkanSwapChain(VulkanPlatform* platform, VulkanContext const&
|
||||
mCurrentSwapIndex(0),
|
||||
mAcquired(false),
|
||||
mIsFirstRenderPass(true) {
|
||||
FVK_LOGD << "Creating VulkanSwapChain: " << this << ", window=" << nativeWindow << ", size=" << extent.width << "x" << extent.height;
|
||||
swapChain = mPlatform->createSwapChain(nativeWindow, flags, extent);
|
||||
FILAMENT_CHECK_POSTCONDITION(swapChain) << "Unable to create swapchain";
|
||||
|
||||
@@ -53,6 +54,7 @@ VulkanSwapChain::VulkanSwapChain(VulkanPlatform* platform, VulkanContext const&
|
||||
}
|
||||
|
||||
VulkanSwapChain::~VulkanSwapChain() {
|
||||
FVK_LOGD << "Destroying VulkanSwapChain: " << this;
|
||||
// Must wait for the inflight command buffers to finish since they might contain the images
|
||||
// we're about to destroy.
|
||||
mCommands->flush();
|
||||
@@ -68,6 +70,7 @@ VulkanSwapChain::~VulkanSwapChain() {
|
||||
}
|
||||
|
||||
void VulkanSwapChain::update() {
|
||||
FVK_LOGD << "VulkanSwapChain::update: " << this;
|
||||
mColors.clear();
|
||||
|
||||
auto const bundle = mPlatform->getSwapChainBundle(swapChain);
|
||||
@@ -89,6 +92,7 @@ void VulkanSwapChain::update() {
|
||||
colorUsage |= TextureUsage::PROTECTED;
|
||||
}
|
||||
for (auto const color: bundle.colors) {
|
||||
FVK_LOGD << "VulkanSwapChain::update: Adding color image=" << color << " to swapchain " << this;
|
||||
auto colorTexture = fvkmemory::resource_ptr<VulkanTexture>::construct(mResourceManager,
|
||||
mContext, device, mAllocator, mResourceManager, mCommands, color, VK_NULL_HANDLE,
|
||||
bundle.colorFormat, VK_NULL_HANDLE /*ycrcb */, 1, bundle.extent.width,
|
||||
@@ -157,6 +161,7 @@ void VulkanSwapChain::acquire(bool& resized) {
|
||||
|
||||
// Check if the swapchain should be resized.
|
||||
if ((resized = mPlatform->hasResized(swapChain))) {
|
||||
FVK_LOGD << "VulkanSwapChain::acquire: Resizing " << this;
|
||||
if (mFlushAndWaitOnResize) {
|
||||
mCommands->flush();
|
||||
mCommands->wait();
|
||||
@@ -176,6 +181,7 @@ void VulkanSwapChain::acquire(bool& resized) {
|
||||
|
||||
mCurrentSwapIndex = imageSyncData.imageIndex;
|
||||
assert_invariant(mCurrentSwapIndex < mFinishedDrawing.size());
|
||||
FVK_LOGD << "VulkanSwapChain::acquire: " << this << ", index=" << mCurrentSwapIndex << ", image=" << mColors[mCurrentSwapIndex]->getVkImage();
|
||||
mFinishedDrawing[mCurrentSwapIndex] = {};
|
||||
FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR)
|
||||
<< "Cannot acquire in swapchain. error=" << static_cast<int32_t>(result);
|
||||
|
||||
@@ -294,9 +294,19 @@ VulkanTextureState::VulkanTextureState(VulkanStagePool& stagePool, VulkanCommand
|
||||
mYcbcr{ ycbcrConversion },
|
||||
mDefaultLayout(getDefaultLayoutImpl(usage)),
|
||||
mUsage(usage),
|
||||
mIsProtected(isProtected) {}
|
||||
mIsProtected(isProtected) {
|
||||
FVK_LOGD << "Creating VulkanTextureState: image=" << image
|
||||
<< ", memory=" << deviceMemory
|
||||
<< ", format=" << format
|
||||
<< ", viewType=" << viewType
|
||||
<< ", levels=" << (int)levels
|
||||
<< ", layers=" << (int)layerCount
|
||||
<< ", usage=" << usage;
|
||||
}
|
||||
|
||||
VulkanTextureState::~VulkanTextureState() {
|
||||
FVK_LOGD << "Destroying VulkanTextureState: image=" << mTextureImage
|
||||
<< ", memory=" << mTextureImageMemory;
|
||||
clearCachedImageViews();
|
||||
if (mTextureImageMemory != VK_NULL_HANDLE) {
|
||||
vkDestroyImage(mDevice, mTextureImage, VKALLOC);
|
||||
@@ -512,6 +522,12 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice,
|
||||
|
||||
void VulkanTexture::updateImage(const PixelBufferDescriptor& data, uint32_t width, uint32_t height,
|
||||
uint32_t depth, uint32_t xoffset, uint32_t yoffset, uint32_t zoffset, uint32_t miplevel) {
|
||||
FVK_LOGD << "updateImage: texture=" << mState->mTextureImage
|
||||
<< ", format=" << (int)data.format
|
||||
<< ", type=" << (int)data.type
|
||||
<< ", size=" << width << "x" << height << "x" << depth
|
||||
<< ", offset=" << xoffset << "," << yoffset << "," << zoffset
|
||||
<< ", mip=" << miplevel;
|
||||
assert_invariant(width <= this->width && height <= this->height);
|
||||
assert_invariant(depth <= this->depth * ((target == SamplerType::SAMPLER_CUBEMAP ||
|
||||
target == SamplerType::SAMPLER_CUBEMAP_ARRAY) ? 6 : 1));
|
||||
@@ -616,6 +632,11 @@ void VulkanTexture::updateImage(const PixelBufferDescriptor& data, uint32_t widt
|
||||
|
||||
void VulkanTexture::updateImageWithBlit(const PixelBufferDescriptor& data, uint32_t width,
|
||||
uint32_t height, uint32_t depth, uint32_t miplevel) {
|
||||
FVK_LOGD << "updateImageWithBlit: texture=" << mState->mTextureImage
|
||||
<< ", format=" << (int)data.format
|
||||
<< ", type=" << (int)data.type
|
||||
<< ", size=" << width << "x" << height << "x" << depth
|
||||
<< ", mip=" << miplevel;
|
||||
// Otherwise, use vkCmdCopyBufferToImage.
|
||||
size_t const bpp = PixelBufferDescriptor::computeDataSize(data.format, data.type, 1, 1, 1);
|
||||
// Note: if bpp = 0, we're dealing with a compressed format; we should fall
|
||||
@@ -755,10 +776,14 @@ bool VulkanTexture::transitionLayout(VkCommandBuffer cmdbuf, VkImageSubresourceR
|
||||
setLayout(range, newLayout);
|
||||
|
||||
if (hasTransitions) {
|
||||
FVK_LOGD << "transition texture=" << mState->mTextureImage << " (" << range.baseArrayLayer
|
||||
<< "," << range.baseMipLevel << ")" << " count=(" << range.layerCount << ","
|
||||
<< range.levelCount << ")" << " from=" << (int)oldLayout << " to=" << (int)newLayout
|
||||
<< " format=" << mState->mVkFormat;
|
||||
#if FVK_ENABLED(FVK_DEBUG_LAYOUT_TRANSITION)
|
||||
FVK_LOGD << "transition texture=" << mState->mTextureImage << " (" << range.baseArrayLayer
|
||||
<< "," << range.baseMipLevel << ")" << " count=(" << range.layerCount << ","
|
||||
<< range.levelCount << ")" << " from=" << oldLayout << " to=" << newLayout
|
||||
<< range.levelCount << ")" << " from=" << (int)oldLayout << " to=" << (int)newLayout
|
||||
<< " format=" << mState->mVkFormat << " depth="
|
||||
<< fvkutils::isVkDepthFormat(mState->mVkFormat)
|
||||
<< " slice-by-slice=" << transitionSliceBySlice;
|
||||
@@ -767,7 +792,7 @@ bool VulkanTexture::transitionLayout(VkCommandBuffer cmdbuf, VkImageSubresourceR
|
||||
#if FVK_ENABLED(FVK_DEBUG_LAYOUT_TRANSITION)
|
||||
FVK_LOGD << "transition texture=" << mState->mTextureImage << " (" << range.baseArrayLayer
|
||||
<< "," << range.baseMipLevel << ")" << " count=(" << range.layerCount << ","
|
||||
<< range.levelCount << ")" << " to=" << newLayout
|
||||
<< range.levelCount << ")" << " to=" << (int)newLayout
|
||||
<< " is skipped because of no change in layout";
|
||||
#endif
|
||||
}
|
||||
@@ -878,7 +903,7 @@ void VulkanTexture::print() const {
|
||||
level >= mPrimaryViewRange.baseMipLevel &&
|
||||
level < (mPrimaryViewRange.baseMipLevel + mPrimaryViewRange.levelCount);
|
||||
FVK_LOGD << "[" << mState->mTextureImage << "]: (" << layer << "," << level
|
||||
<< ")=" << getLayout(layer, level)
|
||||
<< ")=" << (int)getLayout(layer, level)
|
||||
<< " primary=" << primary;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,8 +318,6 @@ public:
|
||||
/**
|
||||
* Sets how many samples are to be used for MSAA in the post-process stage.
|
||||
* Default is 1 and disables MSAA.
|
||||
* Note that post-processing is disabled at FL0. If the feature level is
|
||||
* set to 0, values passed to this function are ignored.
|
||||
*
|
||||
* @param count number of samples to use for multi-sampled anti-aliasing.\n
|
||||
* 0: treated as 1
|
||||
@@ -410,9 +408,7 @@ public:
|
||||
|
||||
/**
|
||||
* Enables or disable multi-sample anti-aliasing (MSAA). Disabled by default.
|
||||
* Note that MSAA is a post-processing effect, and post-processing is disabled at FL0.
|
||||
* If the feature level is set to 0, values passed to this function are ignored.
|
||||
*
|
||||
*
|
||||
* @param options multi-sample anti-aliasing options
|
||||
*/
|
||||
void setMultiSampleAntiAliasingOptions(MultiSampleAntiAliasingOptions options) noexcept;
|
||||
|
||||
@@ -106,25 +106,19 @@ Handle<HwProgram> LocalProgramCache::prepareProgramSlow(DriverApi& driver, Varia
|
||||
assert_invariant(mMaterial != nullptr);
|
||||
|
||||
FEngine& engine = mMaterial->getEngine();
|
||||
|
||||
Handle<HwProgram> result;
|
||||
if (mMaterial->isSharedVariant(variant)) {
|
||||
FMaterial const* defaultMaterial = engine.getDefaultMaterial();
|
||||
assert_invariant(defaultMaterial);
|
||||
LocalProgramCache const& defaultPrograms = defaultMaterial->getPrograms();
|
||||
result = defaultPrograms.mCachedPrograms[variant.key];
|
||||
if (!result) {
|
||||
result = defaultPrograms.prepareProgram(driver, variant, priorityQueue);
|
||||
Handle<HwProgram> program = defaultPrograms.mCachedPrograms[variant.key];
|
||||
if (program) {
|
||||
return mCachedPrograms[variant.key] = program;
|
||||
}
|
||||
} else {
|
||||
result = mMaterial->getDefinition().prepareProgram(engine, driver,
|
||||
mMaterial->getMaterialParser(), getProgramSpecialization(variant), priorityQueue);
|
||||
return mCachedPrograms[variant.key] =
|
||||
defaultPrograms.prepareProgram(driver, variant, priorityQueue);
|
||||
}
|
||||
|
||||
FILAMENT_CHECK_POSTCONDITION(result) << "Requested variant " << (uint32_t)variant.key
|
||||
<< " does not exist for material " << mMaterial->getName();
|
||||
|
||||
return mCachedPrograms[variant.key] = result;
|
||||
return mCachedPrograms[variant.key] = mMaterial->getDefinition().prepareProgram(engine, driver,
|
||||
mMaterial->getMaterialParser(), getProgramSpecialization(variant), priorityQueue);
|
||||
}
|
||||
|
||||
ProgramSpecialization LocalProgramCache::getProgramSpecialization(Variant variant) const noexcept {
|
||||
|
||||
@@ -106,8 +106,6 @@ FView::FView(FEngine& engine)
|
||||
{
|
||||
DriverApi& driver = engine.getDriverApi();
|
||||
|
||||
mFeatureLevel = engine.getSupportedFeatureLevel();
|
||||
|
||||
auto const& layout = engine.getPerRenderableDescriptorSetLayout();
|
||||
|
||||
// initialize the common descriptor set with dummy descriptors
|
||||
@@ -1440,12 +1438,9 @@ void FView::setTemporalAntiAliasingOptions(TemporalAntiAliasingOptions options)
|
||||
}
|
||||
|
||||
void FView::setMultiSampleAntiAliasingOptions(MultiSampleAntiAliasingOptions options) noexcept {
|
||||
// MSAA is a post-process effect, and post-processing is disabled at FL0
|
||||
if (mFeatureLevel >= backend::FeatureLevel::FEATURE_LEVEL_1) {
|
||||
options.sampleCount = uint8_t(options.sampleCount < 1u ? 1u : options.sampleCount);
|
||||
mMultiSampleAntiAliasingOptions = options;
|
||||
assert_invariant(!options.enabled || !mRenderTarget || !mRenderTarget->hasSampleableDepth());
|
||||
}
|
||||
options.sampleCount = uint8_t(options.sampleCount < 1u ? 1u : options.sampleCount);
|
||||
mMultiSampleAntiAliasingOptions = options;
|
||||
assert_invariant(!options.enabled || !mRenderTarget || !mRenderTarget->hasSampleableDepth());
|
||||
}
|
||||
|
||||
void FView::setScreenSpaceReflectionsOptions(ScreenSpaceReflectionsOptions options) noexcept {
|
||||
|
||||
@@ -262,12 +262,9 @@ public:
|
||||
}
|
||||
|
||||
void setSampleCount(uint8_t count) noexcept {
|
||||
// MSAA is a post-process effect, and post-processing is disabled at FL0
|
||||
if (mFeatureLevel >= backend::FeatureLevel::FEATURE_LEVEL_1) {
|
||||
count = uint8_t(count < 1u ? 1u : count);
|
||||
mMultiSampleAntiAliasingOptions.sampleCount = count;
|
||||
mMultiSampleAntiAliasingOptions.enabled = count > 1u;
|
||||
}
|
||||
count = uint8_t(count < 1u ? 1u : count);
|
||||
mMultiSampleAntiAliasingOptions.sampleCount = count;
|
||||
mMultiSampleAntiAliasingOptions.enabled = count > 1u;
|
||||
}
|
||||
|
||||
uint8_t getSampleCount() const noexcept {
|
||||
@@ -632,8 +629,6 @@ private:
|
||||
|
||||
utils::CString mName;
|
||||
|
||||
backend::FeatureLevel mFeatureLevel = backend::FeatureLevel::FEATURE_LEVEL_1;
|
||||
|
||||
// the following values are set by prepare()
|
||||
Range mVisibleRenderables;
|
||||
Range mVisibleDirectionalShadowCasters;
|
||||
|
||||
@@ -40,10 +40,9 @@ fragment {
|
||||
sky = vec4(textureCube(materialParams_skybox, variable_eyeDirection.xyz).rgb, 1.0);
|
||||
#else
|
||||
sky = vec4(textureLod(materialParams_skybox, variable_eyeDirection.xyz, 0.0).rgb, 1.0);
|
||||
#endif
|
||||
sky.rgb *= frameUniforms.iblLuminance;
|
||||
#endif // MATERIAL_FEATURE_LEVEL == 0
|
||||
}
|
||||
#if MATERIAL_FEATURE_LEVEL > 0
|
||||
if (materialParams.showSun != 0 && frameUniforms.sun.w >= 0.0) {
|
||||
vec3 direction = normalize(variable_eyeDirection.xyz);
|
||||
// Assume the sun is a sphere
|
||||
@@ -54,7 +53,6 @@ fragment {
|
||||
float gradient = pow(1.0 - saturate(x), frameUniforms.sun.w);
|
||||
sky.rgb = sky.rgb + gradient * sun;
|
||||
}
|
||||
#endif // MATERIAL_FEATURE_LEVEL > 0
|
||||
material.baseColor = sky;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = "Filament"
|
||||
spec.version = "1.70.2"
|
||||
spec.version = "1.70.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.70.2/filament-v1.70.2-ios.tgz" }
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.70.0/filament-v1.70.0-ios.tgz" }
|
||||
|
||||
spec.libraries = 'c++'
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
namespace filament {
|
||||
|
||||
// update this when a new version of filament wouldn't work with older materials
|
||||
static constexpr size_t MATERIAL_VERSION = 70;
|
||||
static constexpr size_t MATERIAL_VERSION = 69;
|
||||
|
||||
// Those are the api levels that are used in the source material file (.mat)
|
||||
//
|
||||
|
||||
@@ -148,16 +148,16 @@ BufferInterfaceBlock const& UibGenerator::getPerViewUib() noexcept {
|
||||
{ "dynReserved2", 0, Type::INT },
|
||||
|
||||
{ "iblLuminance", 0, Type::FLOAT, Precision::DEFAULT, FeatureLevel::FEATURE_LEVEL_0 },
|
||||
{ "iblRoughnessOneLevel", 0, Type::FLOAT },
|
||||
{ "iblRoughnessOneLevel", 0, Type::FLOAT, Precision::DEFAULT, FeatureLevel::FEATURE_LEVEL_0 },
|
||||
{ "iblSH", 9, Type::FLOAT3 },
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// Directional Lighting [variant: DIR]
|
||||
// ------------------------------------------------------------------------------------
|
||||
{ "lightDirection", 0, Type::FLOAT3, Precision::HIGH },
|
||||
{ "lightDirection", 0, Type::FLOAT3, Precision::HIGH, FeatureLevel::FEATURE_LEVEL_0 },
|
||||
{ "padding0", 0, Type::FLOAT },
|
||||
{ "lightColorIntensity", 0, Type::FLOAT4, Precision::DEFAULT },
|
||||
{ "sun", 0, Type::FLOAT4, Precision::DEFAULT },
|
||||
{ "lightColorIntensity", 0, Type::FLOAT4, Precision::DEFAULT, FeatureLevel::FEATURE_LEVEL_0 },
|
||||
{ "sun", 0, Type::FLOAT4, Precision::DEFAULT, FeatureLevel::FEATURE_LEVEL_0 },
|
||||
{ "shadowFarAttenuationParams", 0, Type::FLOAT2, Precision::HIGH },
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
@@ -15,30 +15,38 @@
|
||||
// PCF Shadow Sampling
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
float sampleDepth(const mediump sampler2DArrayShadow map,
|
||||
const highp vec4 scissorNormalized,
|
||||
const uint layer, highp vec2 uv, highp float depth) {
|
||||
|
||||
// clamp needed for directional lights and/or large kernels
|
||||
uv = clamp(uv, scissorNormalized.xy, scissorNormalized.zw);
|
||||
|
||||
// depth must be clamped to support floating-point depth formats which are always in
|
||||
// the range [0, 1].
|
||||
return texture(map, vec4(uv, layer, saturate(depth)));
|
||||
}
|
||||
|
||||
// use hardware assisted PCF
|
||||
float ShadowSample_PCF_Hard(const mediump sampler2DArrayShadow map,
|
||||
const highp vec4 scissorNormalized,
|
||||
const uint layer, const highp vec4 shadowPosition) {
|
||||
// note: shadowPosition.z is in the [1, 0] range (reversed Z)
|
||||
highp vec3 position = shadowPosition.xyz * (1.0 / shadowPosition.w);
|
||||
position.xy = clamp(position.xy, scissorNormalized.xy, scissorNormalized.zw);
|
||||
position.z = saturate(position.z);
|
||||
return texture(map, vec4(position.xy, layer, position.z));
|
||||
// note: shadowPosition.z is in the [1, 0] range (reversed Z)
|
||||
return sampleDepth(map, scissorNormalized, layer, position.xy, position.z);
|
||||
}
|
||||
|
||||
// use hardware assisted PCF + 3x3 gaussian filter
|
||||
float ShadowSample_PCF_Low(const mediump sampler2DArrayShadow map,
|
||||
const highp vec4 scissorNormalized,
|
||||
const uint layer, const highp vec4 shadowPosition) {
|
||||
|
||||
highp vec2 size = vec2(frameUniforms.shadowAtlasResolution.x);
|
||||
highp vec2 texelSize = vec2(frameUniforms.shadowAtlasResolution.y);
|
||||
|
||||
// note: shadowPosition.z is in the [1, 0] range (reversed Z)
|
||||
highp vec3 position = shadowPosition.xyz * (1.0 / shadowPosition.w);
|
||||
position.z = saturate(position.z);
|
||||
// note: shadowPosition.z is in the [1, 0] range (reversed Z)
|
||||
highp vec2 size = vec2(textureSize(map, 0));
|
||||
highp vec2 texelSize = vec2(1.0) / size;
|
||||
|
||||
// Castaño, 2013, "Shadow Mapping Summary Part 1"
|
||||
highp float depth = position.z;
|
||||
|
||||
// clamp position to avoid overflows below, which cause some GPUs to abort
|
||||
position.xy = clamp(position.xy, vec2(-1.0), vec2(2.0));
|
||||
@@ -57,27 +65,12 @@ float ShadowSample_PCF_Low(const mediump sampler2DArrayShadow map,
|
||||
u *= texelSize.x;
|
||||
v *= texelSize.y;
|
||||
|
||||
float w0 = uw.x * vw.x;
|
||||
float w1 = uw.y * vw.x;
|
||||
float w2 = uw.x * vw.y;
|
||||
float w3 = uw.y * vw.y;
|
||||
|
||||
highp vec2 uv0 = base + vec2(u.x, v.x);
|
||||
highp vec2 uv1 = base + vec2(u.y, v.x);
|
||||
highp vec2 uv2 = base + vec2(u.x, v.y);
|
||||
highp vec2 uv3 = base + vec2(u.y, v.y);
|
||||
|
||||
uv0 = clamp(uv0, scissorNormalized.xy, scissorNormalized.zw);
|
||||
uv1 = clamp(uv1, scissorNormalized.xy, scissorNormalized.zw);
|
||||
uv2 = clamp(uv2, scissorNormalized.xy, scissorNormalized.zw);
|
||||
uv3 = clamp(uv3, scissorNormalized.xy, scissorNormalized.zw);
|
||||
|
||||
float sum = 0.0;
|
||||
sum += w0 * texture(map, vec4(uv0, layer, position.z));
|
||||
sum += w1 * texture(map, vec4(uv1, layer, position.z));
|
||||
sum += w2 * texture(map, vec4(uv2, layer, position.z));
|
||||
sum += w3 * texture(map, vec4(uv3, layer, position.z));
|
||||
return sum * 0.0625;
|
||||
sum += uw.x * vw.x * sampleDepth(map, scissorNormalized, layer, base + vec2(u.x, v.x), depth);
|
||||
sum += uw.y * vw.x * sampleDepth(map, scissorNormalized, layer, base + vec2(u.y, v.x), depth);
|
||||
sum += uw.x * vw.y * sampleDepth(map, scissorNormalized, layer, base + vec2(u.x, v.y), depth);
|
||||
sum += uw.y * vw.y * sampleDepth(map, scissorNormalized, layer, base + vec2(u.y, v.y), depth);
|
||||
return sum * (1.0 / 16.0);
|
||||
}
|
||||
|
||||
// use manual PCF
|
||||
@@ -86,10 +79,8 @@ float ShadowSample_PCF(const mediump sampler2DArray map,
|
||||
const uint layer, const highp vec4 shadowPosition) {
|
||||
highp vec3 position = shadowPosition.xyz * (1.0 / shadowPosition.w);
|
||||
// note: shadowPosition.z is in the [1, 0] range (reversed Z)
|
||||
position.xy = clamp(position.xy, scissorNormalized.xy, scissorNormalized.zw);
|
||||
position.z = saturate(position.z);
|
||||
highp float depth = textureLod(map, vec3(position.xy, layer), 0.0).r;
|
||||
return step(0.0, position.z - depth);
|
||||
highp vec2 tc = clamp(position.xy, scissorNormalized.xy, scissorNormalized.zw);
|
||||
return step(0.0, position.z - textureLod(map, vec3(tc, layer), 0.0).r);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -17,15 +17,9 @@ BACKEND_TEST_TARGET=''
|
||||
|
||||
# Set environment variables to use Mesa drivers.
|
||||
os_name=$(uname -s)
|
||||
arch_name=$(uname -m)
|
||||
if [[ "$os_name" == "Linux" ]]; then
|
||||
if [[ "$arch_name" == "aarch64" ]]; then
|
||||
export LD_LIBRARY_PATH="${PROJECT_ROOT_DIR}/mesa/out/lib/aarch64-linux-gnu"
|
||||
export VK_ICD_FILENAMES="${PROJECT_ROOT_DIR}/mesa/out/share/vulkan/icd.d/lvp_icd.aarch64.json"
|
||||
else
|
||||
export LD_LIBRARY_PATH="${PROJECT_ROOT_DIR}/mesa/out/lib/x86_64-linux-gnu"
|
||||
export VK_ICD_FILENAMES="${PROJECT_ROOT_DIR}/mesa/out/share/vulkan/icd.d/lvp_icd.x86_64.json"
|
||||
fi
|
||||
export LD_LIBRARY_PATH="${PROJECT_ROOT_DIR}/mesa/out/lib/x86_64-linux-gnu"
|
||||
export VK_ICD_FILENAMES="${PROJECT_ROOT_DIR}/mesa/out/share/vulkan/icd.d/lvp_icd.x86_64.json"
|
||||
BACKEND_TEST_TARGET=backend_test_linux
|
||||
elif [[ "$os_name" == "Darwin" ]]; then
|
||||
export DYLD_LIBRARY_PATH="${PROJECT_ROOT_DIR}/mesa/out/lib"
|
||||
|
||||
@@ -26,15 +26,9 @@ GLTF_DIR="$(pwd)/gltf/Models"
|
||||
BUILD_COMMON_DIR="$(pwd)/build/common"
|
||||
|
||||
os_name=$(uname -s)
|
||||
arch_name=$(uname -m)
|
||||
if [[ "$os_name" == "Linux" ]]; then
|
||||
if [[ "$arch_name" == "aarch64" ]]; then
|
||||
MESA_LIB_DIR="${MESA_DIR}lib/aarch64-linux-gnu"
|
||||
MESA_VK_ICD_PATH="${MESA_DIR}share/vulkan/icd.d/lvp_icd.aarch64.json"
|
||||
else
|
||||
MESA_LIB_DIR="${MESA_DIR}lib/x86_64-linux-gnu"
|
||||
MESA_VK_ICD_PATH="${MESA_DIR}share/vulkan/icd.d/lvp_icd.x86_64.json"
|
||||
fi
|
||||
MESA_LIB_DIR="${MESA_DIR}lib/x86_64-linux-gnu"
|
||||
MESA_VK_ICD_PATH="${MESA_DIR}share/vulkan/icd.d/lvp_icd.x86_64.json"
|
||||
elif [[ "$os_name" == "Darwin" ]]; then
|
||||
MESA_LIB_DIR="${MESA_DIR}lib"
|
||||
MESA_VK_ICD_PATH="${MESA_DIR}share/vulkan/icd.d/lvp_icd.aarch64.json"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "filament",
|
||||
"version": "1.70.2",
|
||||
"version": "1.70.0",
|
||||
"description": "Real-time physically based rendering engine",
|
||||
"main": "filament.js",
|
||||
"module": "filament.js",
|
||||
|
||||
Reference in New Issue
Block a user