Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f1035a92f |
@@ -17,17 +17,15 @@ runs:
|
||||
echo "Date: ${TSTAMP}" >> /tmp/commit_msg.txt
|
||||
echo "" >> /tmp/commit_msg.txt
|
||||
echo "${{ github.event.head_commit.message }}" >> /tmp/commit_msg.txt
|
||||
- name: Find commit message (PR)
|
||||
- name: Checkout code
|
||||
shell: bash
|
||||
id: checkout_code
|
||||
if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
echo "+++++ head commit message +++++"
|
||||
echo "$(git log -1 --no-merges)"
|
||||
echo "+++++++++++++++++++++++++++++++"
|
||||
echo "hash=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
|
||||
git checkout ${{ github.event.pull_request.head.sha }}
|
||||
echo "$(git log -1 --no-merges)" >> /tmp/commit_msg.txt
|
||||
git checkout ${{ github.event.pull_request.head.ref }}
|
||||
COMMIT_MESSAGE=$(git log -1)
|
||||
echo "$(git log -1)" >> /tmp/commit_msg.txt
|
||||
- shell: bash
|
||||
id: action_output
|
||||
run: |
|
||||
@@ -38,8 +36,8 @@ runs:
|
||||
echo "----- got commit message ---"
|
||||
cat /tmp/commit_msg.txt
|
||||
echo "----------------------------"
|
||||
- name: Cleanup Find commit message (PR)
|
||||
- name: Uncheckout code
|
||||
shell: bash
|
||||
if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
git checkout ${{ steps.checkout_code.outputs.hash }}
|
||||
git checkout ${{ steps.checkout_code.outputs.hash }}
|
||||
|
||||
@@ -122,6 +122,9 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- id: get_commit_msg
|
||||
uses: ./.github/actions/get-commit-msg
|
||||
- uses: actions/checkout@v4.1.6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: ./.github/actions/mac-prereq
|
||||
- name: Cache Mesa and deps
|
||||
uses: actions/cache@v4
|
||||
|
||||
@@ -49,8 +49,6 @@ option(FILAMENT_SUPPORTS_OSMESA "Enable OSMesa (headless GL context) for Filamen
|
||||
|
||||
option(FILAMENT_ENABLE_FGVIEWER "Enable the frame graph viewer" OFF)
|
||||
|
||||
option(FILAMENT_USE_ABSEIL_LOGGING "Use Abseil to log, may increase binary size" OFF)
|
||||
|
||||
# This is to disable GTAO for the short-term while we investigate a way to better manage size increases.
|
||||
# On the regular filament build (where size is of less concern), we enable GTAO by default.
|
||||
option(FILAMENT_DISABLE_GTAO "Disable GTAO" OFF)
|
||||
@@ -593,10 +591,6 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT FILAMENT_BACKEND_DEBUG_FLAG STREQU
|
||||
unset(FILAMENT_BACKEND_DEBUG_FLAG)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_USE_ABSEIL_LOGGING)
|
||||
add_definitions(-DFILAMENT_USE_ABSEIL_LOGGING)
|
||||
endif()
|
||||
|
||||
# ==================================================================================================
|
||||
# Material compilation flags
|
||||
# ==================================================================================================
|
||||
|
||||
@@ -6,4 +6,8 @@ We are chaning the way Vulkan buffers are handled. We need to switch over to a m
|
||||
**If you are cherry-picking a commit into an rc/ branch**: add the release note under the
|
||||
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
|
||||
|
||||
## Release notes for next branch cut
|
||||
## Release notes for next branch cut
|
||||
|
||||
- samples: samples now have a CLI to select backend api
|
||||
- materials: sampler now export their type in the material binary [⚠️ **New Material Version**]
|
||||
- materials: new mutable specialization constants feature. See the [materials documentation](https://google.github.io/filament/Materials.html) for details. [⚠️ **New Material Version**]
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.61.2'
|
||||
implementation 'com.google.android.filament:filament-android:1.61.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:
|
||||
|
||||
```shell
|
||||
pod 'Filament', '~> 1.61.2'
|
||||
pod 'Filament', '~> 1.61.0'
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -7,10 +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.61.2
|
||||
|
||||
- samples: samples now have a CLI to select backend api
|
||||
|
||||
## v1.61.1
|
||||
|
||||
|
||||
|
||||
@@ -59,10 +59,6 @@ add_library(smol-v STATIC IMPORTED)
|
||||
set_target_properties(smol-v PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libsmol-v.a)
|
||||
|
||||
add_library(abseil STATIC IMPORTED)
|
||||
set_target_properties(abseil PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libabseil.a)
|
||||
|
||||
if (FILAMENT_ENABLE_FGVIEWER)
|
||||
add_library(fgviewer STATIC IMPORTED)
|
||||
set_target_properties(fgviewer PROPERTIES IMPORTED_LOCATION
|
||||
@@ -132,7 +128,6 @@ target_link_libraries(filament-jni
|
||||
PRIVATE jnigraphics
|
||||
PRIVATE utils
|
||||
PRIVATE perfetto
|
||||
PRIVATE abseil
|
||||
|
||||
# libgeometry is PUBLIC because gltfio uses it.
|
||||
PUBLIC geometry
|
||||
|
||||
@@ -60,6 +60,14 @@ static void setParameter(JNIEnv* env, jlong nativeMaterialInstance, jstring name
|
||||
env->ReleaseStringUTFChars(name_, name);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void setConstant(JNIEnv* env, jlong nativeMaterialInstance, jstring name_, T v) {
|
||||
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
|
||||
const char *name = env->GetStringUTFChars(name_, 0);
|
||||
instance->setConstant(name, v);
|
||||
env->ReleaseStringUTFChars(name_, name);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nSetParameterBool(JNIEnv *env, jclass,
|
||||
@@ -264,6 +272,13 @@ Java_com_google_android_filament_MaterialInstance_nSetParameterTexture(
|
||||
env->ReleaseStringUTFChars(name_, name);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nSetConstantBool(JNIEnv *env, jclass,
|
||||
jlong nativeMaterialInstance, jstring name_, jboolean x) {
|
||||
setConstant(env, nativeMaterialInstance, name_, bool(x));
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_MaterialInstance_nSetScissor(
|
||||
|
||||
+13
@@ -402,6 +402,16 @@ public class MaterialInstance {
|
||||
nSetParameterFloat4(getNativeObject(), name, color[0], color[1], color[2], color[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a bool constant.
|
||||
*
|
||||
* @param name the name of the material constant
|
||||
* @param x the value of the material constant
|
||||
*/
|
||||
public void setConstant(@NonNull String name, boolean x) {
|
||||
nSetConstantBool(getNativeObject(), name, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set-up a custom scissor rectangle; by default it is disabled.
|
||||
*
|
||||
@@ -921,6 +931,9 @@ public class MaterialInstance {
|
||||
@NonNull String name, int element, @NonNull @Size(min = 1) float[] v,
|
||||
@IntRange(from = 0) int offset, @IntRange(from = 1) int count);
|
||||
|
||||
private static native void nSetConstantBool(long nativeMaterialInstance,
|
||||
@NonNull String name, boolean x);
|
||||
|
||||
private static native void nSetParameterTexture(long nativeMaterialInstance,
|
||||
@NonNull String name, long nativeTexture, long sampler);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.61.2
|
||||
VERSION_NAME=1.61.0
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ when using textures.
|
||||
This property can dramatically change the appearance of a surface. Non-metallic surfaces have
|
||||
chromatic diffuse reflection and achromatic specular reflection (reflected light does not change
|
||||
color). Metallic surfaces do not have any diffuse reflection and chromatic specular reflection
|
||||
(reflected light takes on the color of the surfaced as defined by `baseColor`).
|
||||
(reflected light takes on the color of the surfaced as defined by `baseColor`).
|
||||
|
||||
The effect of `metallic` is shown in figure [metallicProperty] (click on the image to see a
|
||||
larger version).
|
||||
@@ -247,7 +247,7 @@ The effect of `roughness` on metallic surfaces is shown in figure [roughnessCond
|
||||
When refraction through an object is enabled (using a `refractonType` of `thin` or `solid`), the
|
||||
`roughness` property will also affect the refractions, as shown in figure
|
||||
[roughnessRefractionProperty] (click on the image to see a larger version).
|
||||
|
||||
|
||||
![Figure [roughnessRefractionProperty]: Refractive sphere with `roughness` varying from 0.0
|
||||
(left) to 1.0 (right)](images/materials/refraction_roughness.png)
|
||||
|
||||
@@ -306,7 +306,7 @@ The sheen color controls the color appearance and strength of an optional sheen
|
||||
base layer described by the properties above. The sheen layer always sits below the clear coat layer
|
||||
if such a layer is present.
|
||||
|
||||
The sheen layer can be used to represent cloth and fabric materials. Please refer to
|
||||
The sheen layer can be used to represent cloth and fabric materials. Please refer to
|
||||
section [Cloth model] for more information about cloth and fabric materials.
|
||||
|
||||
The effect of `sheenColor` is shown in figure [materialSheenColor]
|
||||
@@ -519,14 +519,14 @@ light to bend further away from the initial path.
|
||||
|
||||
Table [commonMatIOR] describes acceptable refractive indices for various types of materials.
|
||||
|
||||
Material | IOR
|
||||
Material | IOR
|
||||
--------------------------:|:-----------------
|
||||
Air | 1.0
|
||||
Water | 1.33
|
||||
Common liquids | 1.33 to 1.5
|
||||
Common gemstones | 1.58 to 2.33
|
||||
Plastics, glass | 1.5 to 1.58
|
||||
Other dielectric materials | 1.33 to 1.58
|
||||
Water | 1.33
|
||||
Common liquids | 1.33 to 1.5
|
||||
Common gemstones | 1.58 to 2.33
|
||||
Plastics, glass | 1.5 to 1.58
|
||||
Other dielectric materials | 1.33 to 1.58
|
||||
[Table [commonMatIOR]: Index of refraction of common materials]
|
||||
|
||||
The appearance of a refractive material will greatly depend on the `refractionType` and
|
||||
@@ -1091,30 +1091,37 @@ Value
|
||||
`bool` or `number`, depending on the `type` of the constant. The type must be one of the types
|
||||
described in table [materialConstantsTypes].
|
||||
|
||||
Type | Description | Default
|
||||
:----------------------|:-----------------------------------------|:------------------
|
||||
int | A signed, 32 bit GLSL int | 0
|
||||
float | A single-precision GLSL float | 0.0
|
||||
bool | A GLSL bool | false
|
||||
Constants may also be specified as mutable by setting the `mutable` property to `true`. Only
|
||||
`bool` spec constants may be specified as mutable.
|
||||
|
||||
| Type | Description | Default | May be mutable? |
|
||||
|:------|:------------------------------|:--------|-----------------|
|
||||
| int | A signed, 32 bit GLSL int | | no |
|
||||
| float | A single-precision GLSL float | 0.0 | no |
|
||||
| bool | A GLSL bool | false | yes |
|
||||
[Table [materialConstantsTypes]: Material constants types]
|
||||
|
||||
Description
|
||||
: Lists the constant parameters accepted by your material. These constants can be set, or
|
||||
"specialized", at runtime when loading a material package. Multiple materials can be loaded from
|
||||
the same material package with differing constant parameter specializations. Once a material is
|
||||
loaded from a material package, its constant parameters cannot be changed. Compared to regular
|
||||
parameters, constant parameters allow the compiler to generate more efficient code. Access
|
||||
constant parameters from the shader by prefixing the name with `materialConstant_`. For example,
|
||||
a constant parameter named `myConstant` is accessed in the shader as
|
||||
`materialConstant_myConstant`. If a constant parameter is not set at runtime, the default is
|
||||
used.
|
||||
the same material package with differing constant parameter specializations. If a constant
|
||||
parameter is specialized as mutable, it may be changed at any time on a per-instance basis via
|
||||
`MaterialInstance::setConstant(name, value)`. Otherwise, once a material is loaded from a
|
||||
material package, its constant parameters cannot be changed.
|
||||
|
||||
Compared to regular parameters, constant parameters allow the compiler to generate more
|
||||
efficient code. Access constant parameters from the shader by prefixing the name with
|
||||
`materialConstant_`. For example, a constant parameter named `myConstant` is accessed in the
|
||||
shader as `materialConstant_myConstant`. If a constant parameter is not set at runtime, the
|
||||
default is used.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
constants : [
|
||||
{
|
||||
name : overrideAlpha,
|
||||
type : bool
|
||||
type : bool,
|
||||
mutable : true,
|
||||
},
|
||||
{
|
||||
name : customAlpha,
|
||||
@@ -2553,7 +2560,7 @@ standard skybox material. It produces a list of 2 parameters, named `showSun` an
|
||||
respectively a boolean and a cubemap texture.
|
||||
|
||||
```text
|
||||
$ matc --reflect parameters filament/src/materials/skybox.mat
|
||||
$ matc --reflect parameters filament/src/materials/skybox.mat
|
||||
{
|
||||
"parameters": [
|
||||
{
|
||||
@@ -2569,7 +2576,7 @@ $ matc --reflect parameters filament/src/materials/skybox.mat
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
### --variant-filter
|
||||
|
||||
|
||||
@@ -601,10 +601,6 @@ target_link_libraries(${TARGET} PUBLIC filaflat)
|
||||
target_link_libraries(${TARGET} PUBLIC filabridge)
|
||||
target_link_libraries(${TARGET} PUBLIC ibl-lite)
|
||||
|
||||
if (FILAMENT_USE_ABSEIL_LOGGING)
|
||||
target_link_libraries(${TARGET} PUBLIC absl::log)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_ENABLE_FGVIEWER)
|
||||
target_link_libraries(${TARGET} PUBLIC fgviewer)
|
||||
add_definitions(-DFILAMENT_ENABLE_FGVIEWER=1)
|
||||
|
||||
+4
-5
@@ -92,7 +92,7 @@ Copy your platform's Makefile below into a `Makefile` inside the same directory.
|
||||
### Linux
|
||||
|
||||
```make
|
||||
FILAMENT_LIBS=-lfilament -lbackend -lbluegl -lbluevk -lfilabridge -lfilaflat -lutils -lgeometry -lsmol-v -lvkshaders -libl -labseil
|
||||
FILAMENT_LIBS=-lfilament -lbackend -lbluegl -lbluevk -lfilabridge -lfilaflat -lutils -lgeometry -lsmol-v -lvkshaders -libl
|
||||
CC=clang++
|
||||
|
||||
main: main.o
|
||||
@@ -110,13 +110,12 @@ clean:
|
||||
### macOS
|
||||
|
||||
```make
|
||||
FILAMENT_LIBS=-lfilament -lbackend -lbluegl -lbluevk -lfilabridge -lfilaflat -lutils -lgeometry -lsmol-v -lvkshaders -libl -labseil
|
||||
FILAMENT_LIBS=-lfilament -lbackend -lbluegl -lbluevk -lfilabridge -lfilaflat -lutils -lgeometry -lsmol-v -lvkshaders -libl
|
||||
FRAMEWORKS=-framework Cocoa -framework Metal -framework CoreVideo
|
||||
CC=clang++
|
||||
ARCH ?= $(shell uname -m)
|
||||
|
||||
main: main.o
|
||||
$(CC) -Llib/$(ARCH)/ main.o $(FILAMENT_LIBS) $(FRAMEWORKS) -o main
|
||||
$(CC) -Llib/x86_64/ main.o $(FILAMENT_LIBS) $(FRAMEWORKS) -o main
|
||||
|
||||
main.o: main.cpp
|
||||
$(CC) -Iinclude/ -std=c++17 -c main.cpp
|
||||
@@ -140,7 +139,7 @@ used to change the run-time library version.
|
||||
|
||||
```make
|
||||
FILAMENT_LIBS=filament.lib backend.lib bluegl.lib bluevk.lib filabridge.lib filaflat.lib \
|
||||
utils.lib geometry.lib smol-v.lib ibl.lib vkshaders.lib abseil.lib
|
||||
utils.lib geometry.lib smol-v.lib ibl.lib vkshaders.lib
|
||||
CC=cl.exe
|
||||
|
||||
main.exe: main.obj
|
||||
|
||||
@@ -403,10 +403,6 @@ endif()
|
||||
target_link_libraries(${TARGET} PUBLIC math)
|
||||
target_link_libraries(${TARGET} PUBLIC utils)
|
||||
|
||||
if (FILAMENT_USE_ABSEIL_LOGGING)
|
||||
target_link_libraries(${TARGET} PRIVATE absl::log)
|
||||
endif()
|
||||
|
||||
# Android, iOS, and WebGL do not use bluegl.
|
||||
if(FILAMENT_SUPPORTS_OPENGL AND NOT IOS AND NOT ANDROID AND NOT WEBGL)
|
||||
target_link_libraries(${TARGET} PRIVATE bluegl)
|
||||
|
||||
@@ -149,13 +149,6 @@ public:
|
||||
* - PlatformEGLAndroid
|
||||
*/
|
||||
bool assertNativeWindowIsValid = false;
|
||||
|
||||
/**
|
||||
* The action to take if a Drawable cannot be acquired. If true, the
|
||||
* frame is aborted instead of panic. This is only supported for:
|
||||
* - PlatformMetal
|
||||
*/
|
||||
bool metalDisablePanicOnDrawableFailure = false;
|
||||
};
|
||||
|
||||
Platform() noexcept;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <utils/CString.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/Invocable.h>
|
||||
#include <utils/bitset.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
@@ -66,6 +67,7 @@ public:
|
||||
using DescriptorBindingsInfo = utils::FixedCapacityVector<Descriptor>;
|
||||
using DescriptorSetInfo = std::array<DescriptorBindingsInfo, MAX_DESCRIPTOR_SET_COUNT>;
|
||||
using SpecializationConstantsInfo = utils::FixedCapacityVector<SpecializationConstant>;
|
||||
using MutableSpecConstantsInfo = utils::bitset8;
|
||||
using ShaderBlob = utils::FixedCapacityVector<uint8_t>;
|
||||
using ShaderSource = std::array<ShaderBlob, SHADER_TYPE_COUNT>;
|
||||
|
||||
@@ -102,7 +104,8 @@ public:
|
||||
Program& descriptorBindings(backend::descriptor_set_t set,
|
||||
DescriptorBindingsInfo descriptorBindings) noexcept;
|
||||
|
||||
Program& specializationConstants(SpecializationConstantsInfo specConstants) noexcept;
|
||||
Program& specializationConstants(SpecializationConstantsInfo specConstants,
|
||||
uint32_t firstMutableId, MutableSpecConstantsInfo mutableSpecConstants) noexcept;
|
||||
|
||||
struct PushConstant {
|
||||
utils::CString name;
|
||||
|
||||
@@ -128,7 +128,7 @@ protected:
|
||||
bool setExternalImage(ExternalImageHandleRef externalImage, ExternalTexture* texture) noexcept override;
|
||||
|
||||
/**
|
||||
* Logs glGetError() to LOG(ERROR)
|
||||
* Logs glGetError() to slog.e
|
||||
* @param name a string giving some context on the error. Typically __func__.
|
||||
*/
|
||||
static void logEglError(const char* name) noexcept;
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#define FILAMENT_DEBUG_COMMANDS_NONE 0x0
|
||||
// Command debugging enabled. No logging by default.
|
||||
#define FILAMENT_DEBUG_COMMANDS_ENABLE 0x1
|
||||
// Command debugging enabled. Every command logged to DLOG(INFO)
|
||||
// Command debugging enabled. Every command logged to slog.d
|
||||
#define FILAMENT_DEBUG_COMMANDS_LOG 0x2
|
||||
// Command debugging enabled. Every command logged to systrace
|
||||
#define FILAMENT_DEBUG_COMMANDS_SYSTRACE 0x4
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "private/backend/CircularBuffer.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/architecture.h>
|
||||
#include <utils/ashmem.h>
|
||||
@@ -127,7 +127,7 @@ void* CircularBuffer::alloc(size_t size) {
|
||||
"couldn't allocate " << (size * 2 / 1024) <<
|
||||
" KiB of virtual address space for the command buffer";
|
||||
|
||||
LOG(WARNING) << "Using 'soft' CircularBuffer (" << (size * 2 / 1024) << " KiB)";
|
||||
slog.w << "Using 'soft' CircularBuffer (" << (size * 2 / 1024) << " KiB)" << io::endl;
|
||||
|
||||
// guard page at the end
|
||||
void* guard = (void*)(uintptr_t(data) + size * 2);
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Mutex.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Mutex.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
@@ -121,10 +121,11 @@ void CommandBufferQueue::flush() {
|
||||
|
||||
#ifndef NDEBUG
|
||||
size_t const totalUsed = circularBuffer.size() - mFreeSpace;
|
||||
DLOG(INFO) << "CommandStream used too much space (will block): "
|
||||
<< "needed space " << requiredSize << " out of " << mFreeSpace
|
||||
<< ", totalUsed=" << totalUsed << ", current=" << used
|
||||
<< ", queue size=" << mCommandBuffersToExecute.size() << " buffers";
|
||||
slog.d << "CommandStream used too much space (will block): "
|
||||
<< "needed space " << requiredSize << " out of " << mFreeSpace
|
||||
<< ", totalUsed=" << totalUsed << ", current=" << used
|
||||
<< ", queue size=" << mCommandBuffersToExecute.size() << " buffers"
|
||||
<< io::endl;
|
||||
|
||||
mHighWatermark = std::max(mHighWatermark, totalUsed);
|
||||
#endif
|
||||
|
||||
@@ -22,13 +22,10 @@
|
||||
#include <utils/CallStack.h>
|
||||
#endif
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Profiler.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/sstream.h>
|
||||
#include <utils/Profiler.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
@@ -132,10 +129,9 @@ void CommandType<void (Driver::*)(ARGS...)>::Command<METHOD>::log(std::index_seq
|
||||
#if DEBUG_COMMAND_STREAM
|
||||
static_assert(UTILS_HAS_RTTI, "DEBUG_COMMAND_STREAM can only be used with RTTI");
|
||||
std::string command = utils::CallStack::demangleTypeName(typeid(Command).name()).c_str();
|
||||
DLOG(INFO) << extractMethodName(command) << " : size=" << sizeof(Command);
|
||||
utils::io::sstream parameterPack;
|
||||
printParameterPack(parameterPack, std::get<I>(mArgs)...);
|
||||
DLOG(INFO) << "\t" << parameterPack.c_str();
|
||||
slog.d << extractMethodName(command) << " : size=" << sizeof(Command) << "\n\t";
|
||||
printParameterPack(slog.d, std::get<I>(mArgs)...);
|
||||
slog.d << io::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <math/half.h>
|
||||
@@ -149,7 +149,7 @@ void DriverBase::scheduleRelease(AcquiredImage const& image) noexcept {
|
||||
void DriverBase::debugCommandBegin(CommandStream* cmds, bool synchronous, const char* methodName) noexcept {
|
||||
if constexpr (bool(FILAMENT_DEBUG_COMMANDS > FILAMENT_DEBUG_COMMANDS_NONE)) {
|
||||
if constexpr (bool(FILAMENT_DEBUG_COMMANDS & FILAMENT_DEBUG_COMMANDS_LOG)) {
|
||||
DLOG(INFO) << methodName;
|
||||
utils::slog.d << methodName << utils::io::endl;
|
||||
}
|
||||
if constexpr (bool(FILAMENT_DEBUG_COMMANDS & FILAMENT_DEBUG_COMMANDS_SYSTRACE)) {
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <utils/Allocator.h>
|
||||
#include <utils/CString.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
@@ -57,8 +57,8 @@ HandleAllocator<P0, P1, P2>::Allocator::Allocator(AreaPolicy::HeapArea const& ar
|
||||
size_t const maxHeapSize = std::min(area.size(), HANDLE_INDEX_MASK * getAlignment());
|
||||
|
||||
if (UTILS_UNLIKELY(maxHeapSize != area.size())) {
|
||||
LOG(WARNING) << "HandleAllocator heap size reduced to " << maxHeapSize << " from "
|
||||
<< area.size();
|
||||
slog.w << "HandleAllocator heap size reduced to "
|
||||
<< maxHeapSize << " from " << area.size() << io::endl;
|
||||
}
|
||||
|
||||
// make sure we start with a clean arena. This is needed to ensure that all blocks start
|
||||
|
||||
@@ -80,8 +80,18 @@ Program& Program::attributes(AttributesInfo attributes) noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
Program& Program::specializationConstants(SpecializationConstantsInfo specConstants) noexcept {
|
||||
Program& Program::specializationConstants(SpecializationConstantsInfo specConstants,
|
||||
uint32_t firstMutableId, MutableSpecConstantsInfo mutableSpecConstants) noexcept {
|
||||
// String the two lists together.
|
||||
mSpecializationConstants = std::move(specConstants);
|
||||
uint32_t firstMutableIndex = specConstants.size();
|
||||
mSpecializationConstants.reserve(specConstants.size() + mutableSpecConstants.size());
|
||||
for (uint32_t i = 0; i < mutableSpecConstants.size(); i++) {
|
||||
mSpecializationConstants[i + firstMutableIndex] = SpecializationConstant {
|
||||
.id = i + firstMutableId,
|
||||
.value = mutableSpecConstants[i],
|
||||
};
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
#include "MetalContext.h"
|
||||
#include "MetalUtils.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
@@ -323,7 +323,7 @@ id<MTLFunction> MetalBlitter::compileFragmentFunction(BlitFunctionKey key) const
|
||||
if (!library || !function) {
|
||||
if (error) {
|
||||
auto description = [error.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
LOG(ERROR) << description;
|
||||
utils::slog.e << description << utils::io::endl;
|
||||
}
|
||||
}
|
||||
FILAMENT_CHECK_POSTCONDITION(library && function)
|
||||
@@ -349,7 +349,7 @@ id<MTLFunction> MetalBlitter::getBlitVertexFunction() {
|
||||
if (!library || !function) {
|
||||
if (error) {
|
||||
auto description = [error.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
LOG(ERROR) << description;
|
||||
utils::slog.e << description << utils::io::endl;
|
||||
}
|
||||
}
|
||||
FILAMENT_CHECK_POSTCONDITION(library && function)
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
#include "MetalContext.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/trap.h>
|
||||
|
||||
#include <thread>
|
||||
@@ -77,7 +77,8 @@ void MetalBufferPool::releaseBuffer(MetalBufferPoolEntry const *stage) noexcept
|
||||
|
||||
auto iter = mUsedStages.find(stage);
|
||||
if (iter == mUsedStages.end()) {
|
||||
LOG(ERROR) << "Unknown Metal buffer: " << stage->capacity << " bytes";
|
||||
utils::slog.e << "Unknown Metal buffer: " << stage->capacity << " bytes"
|
||||
<< utils::io::endl;
|
||||
return;
|
||||
}
|
||||
stage->lastAccessed = mCurrentFrame;
|
||||
|
||||
@@ -18,9 +18,8 @@
|
||||
|
||||
#include "MetalHandles.h"
|
||||
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
@@ -113,8 +112,8 @@ id<MTLCommandBuffer> getPendingCommandBuffer(MetalContext* context) {
|
||||
auto errorCode = (MTLCommandBufferError)buffer.error.code;
|
||||
if (@available(macOS 11.0, *)) {
|
||||
if (errorCode == MTLCommandBufferErrorMemoryless) {
|
||||
LOG(WARNING) << "Metal: memoryless geometry limit reached. Continuing with private "
|
||||
"storage mode.";
|
||||
utils::slog.w << "Metal: memoryless geometry limit reached. "
|
||||
"Continuing with private storage mode." << utils::io::endl;
|
||||
context->memorylessLimitsReached = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,10 +38,10 @@
|
||||
#include <Metal/Metal.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
#include <utils/Invocable.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/sstream.h>
|
||||
#include <utils/Invocable.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -78,18 +78,20 @@ Driver* MetalDriverFactory::create(PlatformMetal* const platform, const Platform
|
||||
// MetalVertexBufferInfo : 552 moderate
|
||||
// -- less than or equal to 552 bytes
|
||||
|
||||
DLOG(INFO) << "MetalSwapChain: " << sizeof(MetalSwapChain);
|
||||
DLOG(INFO) << "MetalBufferObject: " << sizeof(MetalBufferObject);
|
||||
DLOG(INFO) << "MetalVertexBuffer: " << sizeof(MetalVertexBuffer);
|
||||
DLOG(INFO) << "MetalVertexBufferInfo: " << sizeof(MetalVertexBufferInfo);
|
||||
DLOG(INFO) << "MetalIndexBuffer: " << sizeof(MetalIndexBuffer);
|
||||
DLOG(INFO) << "MetalRenderPrimitive: " << sizeof(MetalRenderPrimitive);
|
||||
DLOG(INFO) << "MetalTexture: " << sizeof(MetalTexture);
|
||||
DLOG(INFO) << "MetalTimerQuery: " << sizeof(MetalTimerQuery);
|
||||
DLOG(INFO) << "HwStream: " << sizeof(HwStream);
|
||||
DLOG(INFO) << "MetalRenderTarget: " << sizeof(MetalRenderTarget);
|
||||
DLOG(INFO) << "MetalFence: " << sizeof(MetalFence);
|
||||
DLOG(INFO) << "MetalProgram: " << sizeof(MetalProgram);
|
||||
utils::slog.d
|
||||
<< "\nMetalSwapChain: " << sizeof(MetalSwapChain)
|
||||
<< "\nMetalBufferObject: " << sizeof(MetalBufferObject)
|
||||
<< "\nMetalVertexBuffer: " << sizeof(MetalVertexBuffer)
|
||||
<< "\nMetalVertexBufferInfo: " << sizeof(MetalVertexBufferInfo)
|
||||
<< "\nMetalIndexBuffer: " << sizeof(MetalIndexBuffer)
|
||||
<< "\nMetalRenderPrimitive: " << sizeof(MetalRenderPrimitive)
|
||||
<< "\nMetalTexture: " << sizeof(MetalTexture)
|
||||
<< "\nMetalTimerQuery: " << sizeof(MetalTimerQuery)
|
||||
<< "\nHwStream: " << sizeof(HwStream)
|
||||
<< "\nMetalRenderTarget: " << sizeof(MetalRenderTarget)
|
||||
<< "\nMetalFence: " << sizeof(MetalFence)
|
||||
<< "\nMetalProgram: " << sizeof(MetalProgram)
|
||||
<< utils::io::endl;
|
||||
#endif
|
||||
return MetalDriver::create(platform, driverConfig);
|
||||
}
|
||||
@@ -133,18 +135,19 @@ MetalDriver::MetalDriver(
|
||||
|
||||
initializeSupportedGpuFamilies(mContext);
|
||||
|
||||
LOG(INFO) << "Supported GPU families: ";
|
||||
utils::slog.v << "Supported GPU families: " << utils::io::endl;
|
||||
if (mContext->highestSupportedGpuFamily.common > 0) {
|
||||
LOG(INFO) << " MTLGPUFamilyCommon" << (int) mContext->highestSupportedGpuFamily.common;
|
||||
utils::slog.v << " MTLGPUFamilyCommon" << (int) mContext->highestSupportedGpuFamily.common << utils::io::endl;
|
||||
}
|
||||
if (mContext->highestSupportedGpuFamily.apple > 0) {
|
||||
LOG(INFO) << " MTLGPUFamilyApple" << (int) mContext->highestSupportedGpuFamily.apple;
|
||||
utils::slog.v << " MTLGPUFamilyApple" << (int) mContext->highestSupportedGpuFamily.apple << utils::io::endl;
|
||||
}
|
||||
if (mContext->highestSupportedGpuFamily.mac > 0) {
|
||||
LOG(INFO) << " MTLGPUFamilyMac" << (int) mContext->highestSupportedGpuFamily.mac;
|
||||
utils::slog.v << " MTLGPUFamilyMac" << (int) mContext->highestSupportedGpuFamily.mac << utils::io::endl;
|
||||
}
|
||||
LOG(INFO) << "Features:";
|
||||
LOG(INFO) << " readWriteTextureSupport: " << (bool) mContext->device.readWriteTextureSupport;
|
||||
utils::slog.v << "Features:" << utils::io::endl;
|
||||
utils::slog.v << " readWriteTextureSupport: " <<
|
||||
(bool) mContext->device.readWriteTextureSupport << utils::io::endl;
|
||||
|
||||
// In order to support texture swizzling, the GPU needs to support it and the system be running
|
||||
// iOS 13+.
|
||||
@@ -585,7 +588,7 @@ void MetalDriver::createProgramR(Handle<HwProgram> rph, Program&& program) {
|
||||
#if FILAMENT_METAL_DEBUG_LOG
|
||||
auto handleId = rph.getId();
|
||||
DEBUG_LOG("createProgramR(rph = %d, program = ", handleId);
|
||||
DLOG(INFO) << program;
|
||||
utils::slog.d << program << utils::io::endl;
|
||||
#endif
|
||||
construct_handle<MetalProgram>(rph, *mContext, std::move(program));
|
||||
}
|
||||
@@ -2074,7 +2077,7 @@ void MetalDriver::dispatchCompute(Handle<HwProgram> program, math::uint3 workGro
|
||||
error:&error];
|
||||
if (error) {
|
||||
auto description = [error.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
LOG(ERROR) << description;
|
||||
utils::slog.e << description << utils::io::endl;
|
||||
}
|
||||
assert_invariant(!error);
|
||||
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
#include "MetalEnums.h"
|
||||
#include "MetalUtils.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/trap.h>
|
||||
|
||||
#define NSERROR_CHECK(message) \
|
||||
if (error) { \
|
||||
auto description = [error.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding]; \
|
||||
LOG(ERROR) << description; \
|
||||
utils::slog.e << description << utils::io::endl; \
|
||||
} \
|
||||
FILAMENT_CHECK_POSTCONDITION(error == nil) << message;
|
||||
|
||||
|
||||
@@ -27,11 +27,10 @@
|
||||
|
||||
#include "private/backend/BackendUtils.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/trap.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <math/scalar.h>
|
||||
|
||||
@@ -116,14 +115,14 @@ MetalSwapChain::MetalSwapChain(
|
||||
type(SwapChainType::CAMETALLAYER) {
|
||||
|
||||
if (!(flags & SwapChain::CONFIG_TRANSPARENT) && !nativeWindow.opaque) {
|
||||
LOG(WARNING) << "Warning: Filament SwapChain has no CONFIG_TRANSPARENT flag, but the "
|
||||
"CAMetaLayer("
|
||||
<< (__bridge void*) nativeWindow << ") has .opaque set to NO.";
|
||||
utils::slog.w << "Warning: Filament SwapChain has no CONFIG_TRANSPARENT flag, "
|
||||
"but the CAMetaLayer(" << (__bridge void*) nativeWindow << ")"
|
||||
" has .opaque set to NO." << utils::io::endl;
|
||||
}
|
||||
if ((flags & SwapChain::CONFIG_TRANSPARENT) && nativeWindow.opaque) {
|
||||
LOG(WARNING) << "Warning: Filament SwapChain has the CONFIG_TRANSPARENT flag, but the "
|
||||
"CAMetaLayer("
|
||||
<< (__bridge void*) nativeWindow << ") has .opaque set to YES.";
|
||||
utils::slog.w << "Warning: Filament SwapChain has the CONFIG_TRANSPARENT flag, "
|
||||
"but the CAMetaLayer(" << (__bridge void*) nativeWindow << ")"
|
||||
" has .opaque set to YES." << utils::io::endl;
|
||||
}
|
||||
|
||||
// Needed so we can use the SwapChain as a blit source.
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <backend/Program.h>
|
||||
|
||||
#include <utils/JobSystem.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Mutex.h>
|
||||
|
||||
#include <chrono>
|
||||
@@ -148,7 +147,7 @@ bool MetalShaderCompiler::isParallelShaderCompileSupported() const noexcept {
|
||||
if (error) {
|
||||
auto description =
|
||||
[error.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
LOG(WARNING) << description;
|
||||
utils::slog.w << description << utils::io::endl;
|
||||
errorMessage = error.localizedDescription;
|
||||
}
|
||||
PANIC_LOG("Failed to compile Metal program.");
|
||||
@@ -179,7 +178,7 @@ bool MetalShaderCompiler::isParallelShaderCompileSupported() const noexcept {
|
||||
if (error) {
|
||||
auto description =
|
||||
[error.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
LOG(WARNING) << description;
|
||||
utils::slog.w << description << utils::io::endl;
|
||||
errorMessage = error.localizedDescription;
|
||||
}
|
||||
PANIC_LOG("Failed to load main0 in Metal program.");
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "MetalEnums.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
@@ -95,7 +95,7 @@ id<MTLRenderPipelineState> PipelineStateCreator::operator()(id<MTLDevice> device
|
||||
[NSString stringWithFormat:@"Could not create Metal pipeline state: %@",
|
||||
error ? error.localizedDescription : @"unknown error"];
|
||||
auto description = [errorMessage cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
LOG(ERROR) << description;
|
||||
utils::slog.e << description << utils::io::endl;
|
||||
[[NSException exceptionWithName:@"MetalRenderPipelineFailure"
|
||||
reason:errorMessage
|
||||
userInfo:nil] raise];
|
||||
@@ -155,7 +155,7 @@ id<MTLSamplerState> SamplerStateCreator::operator()(id<MTLDevice> device,
|
||||
// MTLSamplerDescriptor.
|
||||
// In practice, this means shadows are not supported when running in the simulator.
|
||||
if (![device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v1]) {
|
||||
LOG(WARNING) << "Warning: sample comparison not supported by this GPU";
|
||||
utils::slog.w << "Warning: sample comparison not supported by this GPU" << utils::io::endl;
|
||||
samplerDescriptor.compareFunction = MTLCompareFunctionNever;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "MetalDriverFactory.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@@ -53,9 +53,6 @@ PlatformMetal::~PlatformMetal() noexcept {
|
||||
}
|
||||
|
||||
Driver* PlatformMetal::createDriver(void* /*sharedContext*/, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
pImpl->mDrawableFailureBehavior = driverConfig.metalDisablePanicOnDrawableFailure
|
||||
? DrawableFailureBehavior::ABORT_FRAME
|
||||
: DrawableFailureBehavior::PANIC;
|
||||
return MetalDriverFactory::create(this, driverConfig);
|
||||
}
|
||||
|
||||
@@ -132,8 +129,9 @@ void PlatformMetalImpl::createDeviceImpl(MetalDevice& outDevice) {
|
||||
result = MTLCreateSystemDefaultDevice();
|
||||
}
|
||||
|
||||
LOG(INFO) << "Selected physical device '"
|
||||
<< [result.name cStringUsingEncoding:NSUTF8StringEncoding] << "'";
|
||||
utils::slog.i << "Selected physical device '"
|
||||
<< [result.name cStringUsingEncoding:NSUTF8StringEncoding] << "'"
|
||||
<< utils::io::endl;
|
||||
|
||||
outDevice.device = result;
|
||||
mDevice = result;
|
||||
|
||||
@@ -360,7 +360,7 @@ void GLDescriptorSet::bind(
|
||||
}
|
||||
}, entry.desc);
|
||||
});
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void GLDescriptorSet::validate(HandleAllocatorGL& allocator,
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
#include "private/backend/Driver.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/trap.h>
|
||||
@@ -26,7 +25,6 @@
|
||||
#include <string_view>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <cstdio>
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
@@ -57,21 +55,19 @@ std::string_view getGLErrorString(GLenum error) noexcept {
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
GLenum checkGLError(const char* function, size_t line) noexcept {
|
||||
GLenum checkGLError(io::ostream& out, const char* function, size_t line) noexcept {
|
||||
GLenum const error = glGetError();
|
||||
if (UTILS_VERY_UNLIKELY(error != GL_NO_ERROR)) {
|
||||
auto const string = getGLErrorString(error);
|
||||
char hexError[16];
|
||||
snprintf(hexError, sizeof(hexError), "%#x", error);
|
||||
LOG(ERROR) << "OpenGL error " << hexError << " (" << string << ") in \"" << function
|
||||
<< "\" at line " << line;
|
||||
out << "OpenGL error " << io::hex << error << " (" << string << ") in \""
|
||||
<< function << "\" at line " << io::dec << line << io::endl;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
void assertGLError(const char* function, size_t line) noexcept {
|
||||
GLenum const err = checkGLError(function, line);
|
||||
void assertGLError(io::ostream& out, const char* function, size_t line) noexcept {
|
||||
GLenum const err = checkGLError(out, function, line);
|
||||
if (UTILS_VERY_UNLIKELY(err != GL_NO_ERROR)) {
|
||||
debug_trap();
|
||||
}
|
||||
@@ -101,21 +97,19 @@ std::string_view getFramebufferStatusString(GLenum status) noexcept {
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
GLenum checkFramebufferStatus(GLenum target, const char* function, size_t line) noexcept {
|
||||
GLenum checkFramebufferStatus(io::ostream& out, GLenum target, const char* function, size_t line) noexcept {
|
||||
GLenum const status = glCheckFramebufferStatus(target);
|
||||
if (UTILS_VERY_UNLIKELY(status != GL_FRAMEBUFFER_COMPLETE)) {
|
||||
auto const string = getFramebufferStatusString(status);
|
||||
char hexStatus[16];
|
||||
snprintf(hexStatus, sizeof(hexStatus), "%#x", status);
|
||||
LOG(ERROR) << "OpenGL framebuffer error " << hexStatus << " (" << string << ") in \""
|
||||
<< function << "\" at line " << line;
|
||||
out << "OpenGL framebuffer error " << io::hex << status << " (" << string << ") in \""
|
||||
<< function << "\" at line " << io::dec << line << io::endl;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
void assertFramebufferStatus(GLenum target, const char* function, size_t line) noexcept {
|
||||
GLenum const status = checkFramebufferStatus(target, function, line);
|
||||
void assertFramebufferStatus(io::ostream& out, GLenum target, const char* function, size_t line) noexcept {
|
||||
GLenum const status = checkFramebufferStatus(out, target, function, line);
|
||||
if (UTILS_VERY_UNLIKELY(status != GL_FRAMEBUFFER_COMPLETE)) {
|
||||
debug_trap();
|
||||
}
|
||||
|
||||
@@ -33,21 +33,21 @@
|
||||
namespace filament::backend::GLUtils {
|
||||
|
||||
std::string_view getGLErrorString(GLenum error) noexcept;
|
||||
GLenum checkGLError(const char* function, size_t line) noexcept;
|
||||
void assertGLError(const char* function, size_t line) noexcept;
|
||||
GLenum checkGLError(utils::io::ostream& out, const char* function, size_t line) noexcept;
|
||||
void assertGLError(utils::io::ostream& out, const char* function, size_t line) noexcept;
|
||||
|
||||
std::string_view getFramebufferStatusString(GLenum err) noexcept;
|
||||
GLenum checkFramebufferStatus(GLenum target, const char* function, size_t line) noexcept;
|
||||
void assertFramebufferStatus(GLenum target, const char* function, size_t line) noexcept;
|
||||
GLenum checkFramebufferStatus(utils::io::ostream& out, GLenum target, const char* function, size_t line) noexcept;
|
||||
void assertFramebufferStatus(utils::io::ostream& out, GLenum target, const char* function, size_t line) noexcept;
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define CHECK_GL_ERROR()
|
||||
# define CHECK_GL_ERROR_NON_FATAL()
|
||||
# define CHECK_GL_FRAMEBUFFER_STATUS(target)
|
||||
# define CHECK_GL_ERROR(out)
|
||||
# define CHECK_GL_ERROR_NON_FATAL(out)
|
||||
# define CHECK_GL_FRAMEBUFFER_STATUS(out, target)
|
||||
#else
|
||||
# define CHECK_GL_ERROR() { GLUtils::assertGLError(__func__, __LINE__); }
|
||||
# define CHECK_GL_ERROR_NON_FATAL() { GLUtils::checkGLError(__func__, __LINE__); }
|
||||
# define CHECK_GL_FRAMEBUFFER_STATUS(target) { GLUtils::checkFramebufferStatus( target, __func__, __LINE__); }
|
||||
# define CHECK_GL_ERROR(out) { GLUtils::assertGLError(out, __func__, __LINE__); }
|
||||
# define CHECK_GL_ERROR_NON_FATAL(out) { GLUtils::checkGLError(out, __func__, __LINE__); }
|
||||
# define CHECK_GL_FRAMEBUFFER_STATUS(out, target) { GLUtils::checkFramebufferStatus(out, target, __func__, __LINE__); }
|
||||
#endif
|
||||
|
||||
constexpr GLuint getComponentCount(ElementType const type) noexcept {
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
#include <backend/platforms/OpenGLPlatform.h>
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <functional>
|
||||
@@ -77,8 +77,8 @@ OpenGLContext::OpenGLContext(OpenGLPlatform& platform,
|
||||
state.version = (char const*)glGetString(GL_VERSION);
|
||||
state.shader = (char const*)glGetString(GL_SHADING_LANGUAGE_VERSION);
|
||||
|
||||
LOG(INFO) << "[" << state.vendor << "], [" << state.renderer << "], "
|
||||
"[" << state.version << "], [" << state.shader << "]";
|
||||
slog.v << "[" << state.vendor << "], [" << state.renderer << "], "
|
||||
"[" << state.version << "], [" << state.shader << "]" << io::endl;
|
||||
|
||||
/*
|
||||
* Figure out GL / GLES version, extensions and capabilities we need to
|
||||
@@ -164,33 +164,51 @@ OpenGLContext::OpenGLContext(OpenGLPlatform& platform,
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG(INFO) << "Feature level: " << +mFeatureLevel;
|
||||
LOG(INFO) << "Active workarounds: ";
|
||||
slog.v << "Feature level: " << +mFeatureLevel << '\n';
|
||||
slog.v << "Active workarounds: " << '\n';
|
||||
UTILS_NOUNROLL
|
||||
for (auto [enabled, name, _] : mBugDatabase) {
|
||||
if (enabled) {
|
||||
LOG(INFO) << name;
|
||||
slog.v << name << '\n';
|
||||
}
|
||||
}
|
||||
flush(slog.v);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// this is useful for development
|
||||
LOG(INFO) << "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = " << gets.max_anisotropy;
|
||||
LOG(INFO) << "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = " << gets.max_combined_texture_image_units;
|
||||
LOG(INFO) << "GL_MAX_TEXTURE_SIZE = " << gets.max_texture_size;
|
||||
LOG(INFO) << "GL_MAX_CUBE_MAP_TEXTURE_SIZE = " << gets.max_cubemap_texture_size;
|
||||
LOG(INFO) << "GL_MAX_3D_TEXTURE_SIZE = " << gets.max_3d_texture_size;
|
||||
LOG(INFO) << "GL_MAX_ARRAY_TEXTURE_LAYERS = " << gets.max_array_texture_layers;
|
||||
LOG(INFO) << "GL_MAX_DRAW_BUFFERS = " << gets.max_draw_buffers;
|
||||
LOG(INFO) << "GL_MAX_RENDERBUFFER_SIZE = " << gets.max_renderbuffer_size;
|
||||
LOG(INFO) << "GL_MAX_SAMPLES = " << gets.max_samples;
|
||||
LOG(INFO) << "GL_MAX_TEXTURE_IMAGE_UNITS = " << gets.max_texture_image_units;
|
||||
LOG(INFO) << "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = "
|
||||
<< gets.max_transform_feedback_separate_attribs;
|
||||
LOG(INFO) << "GL_MAX_UNIFORM_BLOCK_SIZE = " << gets.max_uniform_block_size;
|
||||
LOG(INFO) << "GL_MAX_UNIFORM_BUFFER_BINDINGS = " << gets.max_uniform_buffer_bindings;
|
||||
LOG(INFO) << "GL_NUM_PROGRAM_BINARY_FORMATS = " << gets.num_program_binary_formats;
|
||||
LOG(INFO) << "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = " << gets.uniform_buffer_offset_alignment;
|
||||
slog.v
|
||||
<< "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = "
|
||||
<< gets.max_anisotropy << '\n'
|
||||
<< "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = "
|
||||
<< gets.max_combined_texture_image_units << '\n'
|
||||
<< "GL_MAX_TEXTURE_SIZE = "
|
||||
<< gets.max_texture_size << '\n'
|
||||
<< "GL_MAX_CUBE_MAP_TEXTURE_SIZE = "
|
||||
<< gets.max_cubemap_texture_size << '\n'
|
||||
<< "GL_MAX_3D_TEXTURE_SIZE = "
|
||||
<< gets.max_3d_texture_size << '\n'
|
||||
<< "GL_MAX_ARRAY_TEXTURE_LAYERS = "
|
||||
<< gets.max_array_texture_layers << '\n'
|
||||
<< "GL_MAX_DRAW_BUFFERS = "
|
||||
<< gets.max_draw_buffers << '\n'
|
||||
<< "GL_MAX_RENDERBUFFER_SIZE = "
|
||||
<< gets.max_renderbuffer_size << '\n'
|
||||
<< "GL_MAX_SAMPLES = "
|
||||
<< gets.max_samples << '\n'
|
||||
<< "GL_MAX_TEXTURE_IMAGE_UNITS = "
|
||||
<< gets.max_texture_image_units << '\n'
|
||||
<< "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = "
|
||||
<< gets.max_transform_feedback_separate_attribs << '\n'
|
||||
<< "GL_MAX_UNIFORM_BLOCK_SIZE = "
|
||||
<< gets.max_uniform_block_size << '\n'
|
||||
<< "GL_MAX_UNIFORM_BUFFER_BINDINGS = "
|
||||
<< gets.max_uniform_buffer_bindings << '\n'
|
||||
<< "GL_NUM_PROGRAM_BINARY_FORMATS = "
|
||||
<< gets.num_program_binary_formats << '\n'
|
||||
<< "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT = "
|
||||
<< gets.uniform_buffer_offset_alignment << '\n'
|
||||
;
|
||||
flush(slog.v);
|
||||
#endif
|
||||
|
||||
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
|
||||
@@ -224,14 +242,15 @@ OpenGLContext::OpenGLContext(OpenGLPlatform& platform,
|
||||
if (ext.KHR_debug) {
|
||||
auto cb = +[](GLenum, GLenum type, GLuint, GLenum severity, GLsizei length,
|
||||
const GLchar* message, const void *) {
|
||||
auto logSeverity = utils::LogSeverity::kInfo;
|
||||
io::ostream* stream = &slog.i;
|
||||
switch (severity) {
|
||||
case GL_DEBUG_SEVERITY_HIGH: logSeverity = utils::LogSeverity::kError; break;
|
||||
case GL_DEBUG_SEVERITY_MEDIUM: logSeverity = utils::LogSeverity::kWarning; break;
|
||||
case GL_DEBUG_SEVERITY_LOW: logSeverity = utils::LogSeverity::kInfo; break;
|
||||
case GL_DEBUG_SEVERITY_HIGH: stream = &slog.e; break;
|
||||
case GL_DEBUG_SEVERITY_MEDIUM: stream = &slog.w; break;
|
||||
case GL_DEBUG_SEVERITY_LOW: stream = &slog.d; break;
|
||||
case GL_DEBUG_SEVERITY_NOTIFICATION:
|
||||
default: break;
|
||||
}
|
||||
io::ostream& out = *stream;
|
||||
const char* level = ": ";
|
||||
switch (type) {
|
||||
case GL_DEBUG_TYPE_ERROR: level = "ERROR: "; break;
|
||||
@@ -243,7 +262,7 @@ OpenGLContext::OpenGLContext(OpenGLPlatform& platform,
|
||||
case GL_DEBUG_TYPE_MARKER: level = "MARKER: "; break;
|
||||
default: break;
|
||||
}
|
||||
LOG(LEVEL(logSeverity)) << "KHR_debug " << level << std::string_view{ message, size_t(length) };
|
||||
out << "KHR_debug " << level << std::string_view{ message, size_t(length) } << io::endl;
|
||||
};
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
@@ -688,8 +707,9 @@ void OpenGLContext::initExtensionsGLES(Extensions* ext, GLint major, GLint minor
|
||||
GLUtils::unordered_string_set const exts = GLUtils::split(extensions);
|
||||
if constexpr (DEBUG_PRINT_EXTENSIONS) {
|
||||
for (auto extension: exts) {
|
||||
DLOG(INFO) << "\"" << std::string_view(extension) << "\"";
|
||||
slog.d << "\"" << std::string_view(extension) << "\"\n";
|
||||
}
|
||||
flush(slog.d);
|
||||
}
|
||||
|
||||
// figure out and initialize the extensions we need
|
||||
@@ -763,8 +783,9 @@ void OpenGLContext::initExtensionsGL(Extensions* ext, GLint major, GLint minor)
|
||||
}
|
||||
if constexpr (DEBUG_PRINT_EXTENSIONS) {
|
||||
for (auto extension: exts) {
|
||||
DLOG(INFO) << "\"" << std::string_view(extension) << "\"";
|
||||
slog.d << "\"" << std::string_view(extension) << "\"\n";
|
||||
}
|
||||
flush(slog.d);
|
||||
}
|
||||
|
||||
using namespace std::literals;
|
||||
@@ -1024,7 +1045,7 @@ GLuint OpenGLContext::getSamplerSlow(SamplerParams params) const noexcept {
|
||||
std::min(gets.max_anisotropy, anisotropy));
|
||||
}
|
||||
#endif
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
mSamplerMap[params] = s;
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -48,13 +48,12 @@
|
||||
|
||||
#include <type_traits>
|
||||
#include <utils/BitmaskEnum.h>
|
||||
#include <utils/CString.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/CString.h>
|
||||
#include <utils/Invocable.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Slice.h>
|
||||
#include <utils/Systrace.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/ostream.h>
|
||||
@@ -185,18 +184,20 @@ OpenGLDriver* OpenGLDriver::create(OpenGLPlatform* platform,
|
||||
// GLVertexBufferInfo : 132 moderate
|
||||
// -- less than or equal to 136 bytes
|
||||
|
||||
DLOG(INFO) << "GLSwapChain: " << sizeof(GLSwapChain);
|
||||
DLOG(INFO) << "GLBufferObject: " << sizeof(GLBufferObject);
|
||||
DLOG(INFO) << "GLVertexBuffer: " << sizeof(GLVertexBuffer);
|
||||
DLOG(INFO) << "GLVertexBufferInfo: " << sizeof(GLVertexBufferInfo);
|
||||
DLOG(INFO) << "GLIndexBuffer: " << sizeof(GLIndexBuffer);
|
||||
DLOG(INFO) << "GLRenderPrimitive: " << sizeof(GLRenderPrimitive);
|
||||
DLOG(INFO) << "GLTexture: " << sizeof(GLTexture);
|
||||
DLOG(INFO) << "GLTimerQuery: " << sizeof(GLTimerQuery);
|
||||
DLOG(INFO) << "GLStream: " << sizeof(GLStream);
|
||||
DLOG(INFO) << "GLRenderTarget: " << sizeof(GLRenderTarget);
|
||||
DLOG(INFO) << "GLFence: " << sizeof(GLFence);
|
||||
DLOG(INFO) << "OpenGLProgram: " << sizeof(OpenGLProgram);
|
||||
slog.d
|
||||
<< "\nGLSwapChain: " << sizeof(GLSwapChain)
|
||||
<< "\nGLBufferObject: " << sizeof(GLBufferObject)
|
||||
<< "\nGLVertexBuffer: " << sizeof(GLVertexBuffer)
|
||||
<< "\nGLVertexBufferInfo: " << sizeof(GLVertexBufferInfo)
|
||||
<< "\nGLIndexBuffer: " << sizeof(GLIndexBuffer)
|
||||
<< "\nGLRenderPrimitive: " << sizeof(GLRenderPrimitive)
|
||||
<< "\nGLTexture: " << sizeof(GLTexture)
|
||||
<< "\nGLTimerQuery: " << sizeof(GLTimerQuery)
|
||||
<< "\nGLStream: " << sizeof(GLStream)
|
||||
<< "\nGLRenderTarget: " << sizeof(GLRenderTarget)
|
||||
<< "\nGLFence: " << sizeof(GLFence)
|
||||
<< "\nOpenGLProgram: " << sizeof(OpenGLProgram)
|
||||
<< io::endl;
|
||||
#endif
|
||||
|
||||
// here we check we're on a supported version of GL before initializing the driver
|
||||
@@ -288,7 +289,7 @@ OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfi
|
||||
mStreamsWithPendingAcquiredImage.reserve(8);
|
||||
|
||||
#ifndef NDEBUG
|
||||
LOG(INFO) << "OS version: " << mPlatform.getOSVersion();
|
||||
slog.i << "OS version: " << mPlatform.getOSVersion() << io::endl;
|
||||
#endif
|
||||
|
||||
// Timer queries are core in GL 3.3, otherwise we need EXT_disjoint_timer_query
|
||||
@@ -667,7 +668,7 @@ void OpenGLDriver::createIndexBufferR(
|
||||
gl.bindVertexArray(nullptr);
|
||||
gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib->gl.buffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, nullptr, getBufferUsage(usage));
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::createBufferObjectR(Handle<HwBufferObject> boh,
|
||||
@@ -692,7 +693,7 @@ void OpenGLDriver::createBufferObjectR(Handle<HwBufferObject> boh,
|
||||
glBufferData(bo->gl.binding, byteCount, nullptr, getBufferUsage(usage));
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::createRenderPrimitiveR(Handle<HwRenderPrimitive> rph,
|
||||
@@ -729,7 +730,7 @@ void OpenGLDriver::createRenderPrimitiveR(Handle<HwRenderPrimitive> rph,
|
||||
// this records the index buffer into the currently bound VAO
|
||||
gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib->gl.buffer);
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::createProgramR(Handle<HwProgram> ph, Program&& program) {
|
||||
@@ -759,7 +760,7 @@ void OpenGLDriver::createProgramR(Handle<HwProgram> ph, Program&& program) {
|
||||
}
|
||||
|
||||
construct<OpenGLProgram>(ph, *this, std::move(program));
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
@@ -952,7 +953,7 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
|
||||
renderBufferStorage(t->gl.id, internalFormat, w, h, samples);
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::createTextureViewR(Handle<HwTexture> th,
|
||||
@@ -998,7 +999,7 @@ void OpenGLDriver::createTextureViewR(Handle<HwTexture> th,
|
||||
assert_invariant(ref);
|
||||
ref->count++;
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::createTextureViewSwizzleR(Handle<HwTexture> th, Handle<HwTexture> srch,
|
||||
@@ -1061,7 +1062,7 @@ void OpenGLDriver::createTextureViewSwizzleR(Handle<HwTexture> th, Handle<HwText
|
||||
assert_invariant(ref);
|
||||
ref->count++;
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::createTextureExternalImage2R(Handle<HwTexture> th, SamplerType target,
|
||||
@@ -1224,7 +1225,7 @@ void OpenGLDriver::importTextureR(Handle<HwTexture> th, intptr_t id,
|
||||
#endif
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::updateVertexArrayObject(GLRenderPrimitive* rp, GLVertexBuffer const* vb) {
|
||||
@@ -1484,7 +1485,7 @@ void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
|
||||
// we shouldn't be here
|
||||
break;
|
||||
}
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
} else
|
||||
#ifndef __EMSCRIPTEN__
|
||||
#ifdef GL_EXT_multisampled_render_to_texture
|
||||
@@ -1505,7 +1506,7 @@ void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment,
|
||||
GL_RENDERBUFFER, t->gl.id);
|
||||
}
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
} else
|
||||
#endif // GL_EXT_multisampled_render_to_texture
|
||||
#endif // __EMSCRIPTEN__
|
||||
@@ -1587,13 +1588,13 @@ void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
|
||||
break;
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
rt->gl.resolve |= resolveFlags;
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(GL_FRAMEBUFFER)
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_FRAMEBUFFER)
|
||||
}
|
||||
|
||||
void OpenGLDriver::renderBufferStorage(GLuint rbo, GLenum internalformat, uint32_t width, // NOLINT(readability-convert-member-functions-to-static)
|
||||
@@ -1622,7 +1623,7 @@ void OpenGLDriver::renderBufferStorage(GLuint rbo, GLenum internalformat, uint32
|
||||
// unbind the renderbuffer, to avoid any later confusion
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::createDefaultRenderTargetR(
|
||||
@@ -1719,7 +1720,7 @@ void OpenGLDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
|
||||
if (UTILS_LIKELY(!getContext().isES2())) {
|
||||
glDrawBuffers((GLsizei)maxDrawBuffers, bufs);
|
||||
}
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1759,7 +1760,7 @@ void OpenGLDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
|
||||
assert_invariant(any(targets & TargetBufferFlags::ALL));
|
||||
assert_invariant(tmin == tmax);
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::createFenceR(Handle<HwFence> fh, int) {
|
||||
@@ -2110,7 +2111,7 @@ void OpenGLDriver::setAcquiredImage(Handle<HwStream> sh, void* hwbuffer, const m
|
||||
|
||||
if (UTILS_UNLIKELY(glstream->user_thread.pending.image)) {
|
||||
scheduleRelease(glstream->user_thread.pending);
|
||||
LOG(WARNING) << "Acquired image is set more than once per frame.";
|
||||
slog.w << "Acquired image is set more than once per frame." << io::endl;
|
||||
}
|
||||
|
||||
glstream->user_thread.pending = mPlatform.transformAcquiredImage({
|
||||
@@ -2559,7 +2560,7 @@ void OpenGLDriver::makeCurrent(Handle<HwSwapChain> schDraw, Handle<HwSwapChain>
|
||||
|
||||
// OpenGL context has changed, resynchronize the state with the cache
|
||||
mContext.synchronizeStateAndCache(index);
|
||||
DLOG(INFO) << "*** OpenGL context change : " << (index ? "protected" : "default");
|
||||
slog.d << "*** OpenGL context change : " << (index ? "protected" : "default") << io::endl;
|
||||
});
|
||||
|
||||
mCurrentDrawSwapChain = scDraw;
|
||||
@@ -2600,7 +2601,7 @@ void OpenGLDriver::setVertexBufferObject(Handle<HwVertexBuffer> vbh,
|
||||
vb->bufferObjectsVersion = (version + 1) % kMaxVersion;
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::updateIndexBuffer(
|
||||
@@ -2617,7 +2618,7 @@ void OpenGLDriver::updateIndexBuffer(
|
||||
|
||||
scheduleDestroy(std::move(p));
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::registerBufferObjectStreams(Handle<HwBufferObject> boh, BufferObjectStreamDescriptor&& streams) {
|
||||
@@ -2697,7 +2698,7 @@ void OpenGLDriver::updateBufferObject(
|
||||
|
||||
scheduleDestroy(std::move(bd));
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::updateBufferObjectUnsynchronized(
|
||||
@@ -2744,7 +2745,7 @@ retry:
|
||||
scheduleDestroy(std::move(bd));
|
||||
}
|
||||
}
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2794,7 +2795,7 @@ void OpenGLDriver::generateMipmaps(Handle<HwTexture> th) {
|
||||
|
||||
glGenerateMipmap(t->gl.target);
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::setTextureData(GLTexture const* t, uint32_t level,
|
||||
@@ -2903,7 +2904,7 @@ void OpenGLDriver::setTextureData(GLTexture const* t, uint32_t level,
|
||||
|
||||
scheduleDestroy(std::move(p));
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::setCompressedTextureData(GLTexture const* t, uint32_t level,
|
||||
@@ -2989,7 +2990,7 @@ void OpenGLDriver::setCompressedTextureData(GLTexture const* t, uint32_t level,
|
||||
|
||||
scheduleDestroy(std::move(p));
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::setupExternalImage2(Platform::ExternalImageHandleRef image) {
|
||||
@@ -3152,7 +3153,7 @@ void OpenGLDriver::beginRenderPass(Handle<HwRenderTarget> rth,
|
||||
TargetBufferFlags discardFlags = params.flags.discardStart & rt->targets;
|
||||
|
||||
GLuint const fbo = gl.bindFramebuffer(GL_FRAMEBUFFER, rt->gl.fbo);
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(GL_FRAMEBUFFER)
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_FRAMEBUFFER)
|
||||
|
||||
// each render-pass starts with a disabled scissor
|
||||
gl.disable(GL_SCISSOR_TEST);
|
||||
@@ -3164,7 +3165,7 @@ void OpenGLDriver::beginRenderPass(Handle<HwRenderTarget> rth,
|
||||
if (attachmentCount) {
|
||||
gl.procs.invalidateFramebuffer(GL_FRAMEBUFFER, attachmentCount, attachments.data());
|
||||
}
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
} else {
|
||||
// It's important to clear the framebuffer before drawing, as it resets
|
||||
// the fb to a known state (resets fb compression and possibly other things).
|
||||
@@ -3251,7 +3252,7 @@ void OpenGLDriver::endRenderPass(int) {
|
||||
if (attachmentCount) {
|
||||
gl.procs.invalidateFramebuffer(GL_FRAMEBUFFER, attachmentCount, attachments.data());
|
||||
}
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3297,13 +3298,13 @@ void OpenGLDriver::resolvePass(ResolveAction action, GLRenderTarget const* rt,
|
||||
gl.bindFramebuffer(GL_READ_FRAMEBUFFER, read);
|
||||
gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, draw);
|
||||
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(GL_READ_FRAMEBUFFER)
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(GL_DRAW_FRAMEBUFFER)
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_READ_FRAMEBUFFER)
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_DRAW_FRAMEBUFFER)
|
||||
|
||||
gl.disable(GL_SCISSOR_TEST);
|
||||
glBlitFramebuffer(0, 0, (GLint)rt->width, (GLint)rt->height,
|
||||
0, 0, (GLint)rt->width, (GLint)rt->height, mask, GL_NEAREST);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -3482,7 +3483,7 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
if (buffer) {
|
||||
gl.bindFramebuffer(GL_FRAMEBUFFER, s->gl.fbo_read ? s->gl.fbo_read : s->gl.fbo);
|
||||
glReadPixels(GLint(x), GLint(y), GLint(width), GLint(height), glFormat, glType, buffer);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
// now we need to flip the buffer vertically to match our API
|
||||
size_t const stride = p.stride ? p.stride : width;
|
||||
@@ -3514,7 +3515,7 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER, pboSize, nullptr, GL_STATIC_DRAW);
|
||||
glReadPixels(GLint(x), GLint(y), GLint(width), GLint(height), glFormat, glType, nullptr);
|
||||
gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
// we're forced to make a copy on the heap because otherwise it deletes std::function<> copy
|
||||
// constructor.
|
||||
@@ -3554,7 +3555,7 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
|
||||
glDeleteBuffers(1, &pbo);
|
||||
scheduleDestroy(std::move(p));
|
||||
delete pUserBuffer;
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
});
|
||||
#endif
|
||||
}
|
||||
@@ -3579,7 +3580,7 @@ void OpenGLDriver::readBufferSubData(BufferObjectHandle boh,
|
||||
glCopyBufferSubData(bo->gl.binding, GL_PIXEL_PACK_BUFFER, offset, 0, size);
|
||||
gl.bindBuffer(bo->gl.binding, 0);
|
||||
gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
// then, we schedule a mapBuffer of the PBO later, once the fence has signaled
|
||||
auto* pUserBuffer = new BufferDescriptor(std::move(p));
|
||||
@@ -3596,7 +3597,7 @@ void OpenGLDriver::readBufferSubData(BufferObjectHandle boh,
|
||||
glDeleteBuffers(1, &pbo);
|
||||
scheduleDestroy(std::move(p));
|
||||
delete pUserBuffer;
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
});
|
||||
} else {
|
||||
gl.bindBuffer(bo->gl.binding, bo->gl.id);
|
||||
@@ -3609,7 +3610,7 @@ void OpenGLDriver::readBufferSubData(BufferObjectHandle boh,
|
||||
}
|
||||
gl.bindBuffer(bo->gl.binding, 0);
|
||||
scheduleDestroy(std::move(p));
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -3639,7 +3640,7 @@ void OpenGLDriver::whenFrameComplete(const std::function<void()>& fn) noexcept {
|
||||
void OpenGLDriver::whenGpuCommandsComplete(const std::function<void()>& fn) noexcept {
|
||||
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
mGpuCommandCompleteOps.emplace_back(sync, fn);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::executeGpuCommandsCompleteOps() noexcept {
|
||||
@@ -3857,7 +3858,7 @@ void OpenGLDriver::clearWithRasterPipe(TargetBufferFlags clearFlags,
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void OpenGLDriver::resolve(
|
||||
@@ -3968,7 +3969,7 @@ void OpenGLDriver::blit(
|
||||
case SamplerType::SAMPLER_EXTERNAL:
|
||||
break;
|
||||
}
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(GL_DRAW_FRAMEBUFFER)
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_DRAW_FRAMEBUFFER)
|
||||
|
||||
gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]);
|
||||
switch (s->target) {
|
||||
@@ -3994,14 +3995,14 @@ void OpenGLDriver::blit(
|
||||
case SamplerType::SAMPLER_EXTERNAL:
|
||||
break;
|
||||
}
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(GL_READ_FRAMEBUFFER)
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_READ_FRAMEBUFFER)
|
||||
|
||||
gl.disable(GL_SCISSOR_TEST);
|
||||
glBlitFramebuffer(
|
||||
srcOrigin.x, srcOrigin.y, srcOrigin.x + size.x, srcOrigin.y + size.y,
|
||||
dstOrigin.x, dstOrigin.y, dstOrigin.x + size.x, dstOrigin.y + size.y,
|
||||
mask, GL_NEAREST);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
gl.unbindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||
gl.unbindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||
@@ -4064,15 +4065,15 @@ void OpenGLDriver::blitDEPRECATED(TargetBufferFlags buffers,
|
||||
gl.bindFramebuffer(GL_READ_FRAMEBUFFER, s->gl.fbo);
|
||||
gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, d->gl.fbo);
|
||||
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(GL_READ_FRAMEBUFFER)
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(GL_DRAW_FRAMEBUFFER)
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_READ_FRAMEBUFFER)
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_DRAW_FRAMEBUFFER)
|
||||
|
||||
gl.disable(GL_SCISSOR_TEST);
|
||||
glBlitFramebuffer(
|
||||
srcRect.left, srcRect.bottom, srcRect.right(), srcRect.top(),
|
||||
dstRect.left, dstRect.bottom, dstRect.right(), dstRect.top(),
|
||||
GL_COLOR_BUFFER_BIT, glFilterMode);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4199,9 +4200,9 @@ void OpenGLDriver::draw2(uint32_t indexOffset, uint32_t indexCount, uint32_t ins
|
||||
#endif
|
||||
|
||||
#if FILAMENT_ENABLE_MATDBG
|
||||
CHECK_GL_ERROR_NON_FATAL()
|
||||
CHECK_GL_ERROR_NON_FATAL(utils::slog.e)
|
||||
#else
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4231,9 +4232,9 @@ void OpenGLDriver::draw2GLES2(uint32_t indexOffset, uint32_t indexCount, uint32_
|
||||
reinterpret_cast<const void*>(indexOffset << rp->gl.indicesShift));
|
||||
|
||||
#if FILAMENT_ENABLE_MATDBG
|
||||
CHECK_GL_ERROR_NON_FATAL()
|
||||
CHECK_GL_ERROR_NON_FATAL(utils::slog.e)
|
||||
#else
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4283,9 +4284,9 @@ void OpenGLDriver::dispatchCompute(Handle<HwProgram> program, uint3 workGroupCou
|
||||
#endif // BACKEND_OPENGL_LEVEL_GLES31
|
||||
|
||||
#if FILAMENT_ENABLE_MATDBG
|
||||
CHECK_GL_ERROR_NON_FATAL()
|
||||
CHECK_GL_ERROR_NON_FATAL(utils::slog.e)
|
||||
#else
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ void OpenGLProgram::initializeProgramState(OpenGLContext& context, GLuint progra
|
||||
case DescriptorType::INPUT_ATTACHMENT:
|
||||
break;
|
||||
}
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,14 +114,14 @@ void TimerQueryNativeFactory::createTimerQuery(GLTimerQuery* tq) {
|
||||
|
||||
tq->state = std::make_shared<GLTimerQuery::State>();
|
||||
mContext.procs.genQueries(1u, &tq->state->gl.query);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void TimerQueryNativeFactory::destroyTimerQuery(GLTimerQuery* tq) {
|
||||
assert_invariant(tq->state);
|
||||
|
||||
mContext.procs.deleteQueries(1u, &tq->state->gl.query);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
tq->state.reset();
|
||||
}
|
||||
@@ -131,14 +131,14 @@ void TimerQueryNativeFactory::beginTimeElapsedQuery(GLTimerQuery* tq) {
|
||||
|
||||
tq->state->elapsed.store(int64_t(TimerQueryResult::NOT_READY), std::memory_order_relaxed);
|
||||
mContext.procs.beginQuery(GL_TIME_ELAPSED, tq->state->gl.query);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
void TimerQueryNativeFactory::endTimeElapsedQuery(OpenGLDriver& driver, GLTimerQuery* tq) {
|
||||
assert_invariant(tq->state);
|
||||
|
||||
mContext.procs.endQuery(GL_TIME_ELAPSED);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
std::weak_ptr<GLTimerQuery::State> const weak = tq->state;
|
||||
|
||||
@@ -153,7 +153,7 @@ void TimerQueryNativeFactory::endTimeElapsedQuery(OpenGLDriver& driver, GLTimerQ
|
||||
|
||||
GLuint available = 0;
|
||||
context.procs.getQueryObjectuiv(state->gl.query, GL_QUERY_RESULT_AVAILABLE, &available);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
if (!available) {
|
||||
// we need to try this one again later
|
||||
return false;
|
||||
|
||||
@@ -31,14 +31,14 @@
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/CString.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/JobSystem.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
@@ -65,9 +65,9 @@ static std::string to_string(bool const b) { return b ? "true" : "false"; }
|
||||
static std::string to_string(int const i) { return std::to_string(i); }
|
||||
static std::string to_string(float const f) { return "float(" + std::to_string(f) + ")"; }
|
||||
|
||||
static void logCompilationError(ShaderStage shaderType, const char* name, GLuint shaderId,
|
||||
CString const& sourceCode) noexcept;
|
||||
static void logProgramLinkError(char const* name, GLuint program) noexcept;
|
||||
static void logCompilationError(io::ostream& out, ShaderStage shaderType, const char* name,
|
||||
GLuint shaderId, CString const& sourceCode) noexcept;
|
||||
static void logProgramLinkError(io::ostream& out, char const* name, GLuint program) noexcept;
|
||||
|
||||
static void process_GOOGLE_cpp_style_line_directive(OpenGLContext const& context, char* source,
|
||||
size_t len) noexcept;
|
||||
@@ -122,18 +122,12 @@ struct ShaderCompilerService::OpenGLProgramToken : ProgramToken {
|
||||
}
|
||||
|
||||
std::optional<CallbackManager::Handle> handle{};
|
||||
|
||||
// Only valid when the blob functions are provided by users. The validity of this variable
|
||||
// doesn't guarantee that the program was created from the cache blob.
|
||||
BlobCacheKey key;
|
||||
|
||||
// Used for the `THREAD_POOL` mode.
|
||||
mutable Mutex lock;
|
||||
mutable Condition cond;
|
||||
bool signaled = false;
|
||||
|
||||
// Indicate this program was created from the cache blob.
|
||||
bool retrievedFromBlobCache = false;
|
||||
};
|
||||
|
||||
ShaderCompilerService::OpenGLProgramToken::~OpenGLProgramToken() {
|
||||
@@ -265,7 +259,6 @@ ShaderCompilerService::program_token_t ShaderCompilerService::createProgram(
|
||||
// Try retrieving the cached program blob if available.
|
||||
token->gl.program = mBlobCache.retrieve(&token->key, mDriver.mPlatform, program);
|
||||
if (token->gl.program) {
|
||||
token->retrievedFromBlobCache = true;
|
||||
return token;
|
||||
}
|
||||
|
||||
@@ -344,15 +337,12 @@ GLuint ShaderCompilerService::getProgram(program_token_t& token) {
|
||||
|
||||
assert_invariant(token);// This function should be called when the token is still alive.
|
||||
|
||||
// Finalize any pending shader compilation tasks only when the token was created without cache.
|
||||
if (!token->retrievedFromBlobCache) {
|
||||
if (token->compiler.mMode == Mode::THREAD_POOL) {
|
||||
auto const job = token->compiler.mCompilerThreadPool.dequeue(token);
|
||||
if (!job) {
|
||||
// It's likely that the job was already completed. But it may be still being
|
||||
// executed at this moment. Just try waiting for it to avoid a race.
|
||||
token->wait();
|
||||
}
|
||||
if (token->compiler.mMode == Mode::THREAD_POOL) {
|
||||
auto const job = token->compiler.mCompilerThreadPool.dequeue(token);
|
||||
if (!job) {
|
||||
// It's likely that the job was already completed. But it may be still being
|
||||
// executed at this moment. Just try waiting for it to avoid a race.
|
||||
token->wait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,9 +433,8 @@ void ShaderCompilerService::ensureTokenIsReady(program_token_t const& token) {
|
||||
// just log warnings here instead of repeatedly checking compile status. If this turns
|
||||
// out to be a real issue later, we would need to consider doing the canonical way.
|
||||
if (!isCompileCompleted(token)) {
|
||||
LOG(WARNING)
|
||||
<< "Shader compilation for OpenGL program " << token->name.c_str_safe()
|
||||
<< " is not completed yet. The following program link may not succeed.";
|
||||
slog.w << "Shader compilation for OpenGL program " << token->name.c_str_safe()
|
||||
<< " is not completed yet. The following program link may not succeed.";
|
||||
}
|
||||
|
||||
linkProgram(mDriver.getContext(), token);
|
||||
@@ -655,7 +644,8 @@ void ShaderCompilerService::executeTickOps() noexcept {
|
||||
}
|
||||
// Something went wrong. Log the error message.
|
||||
const ShaderStage type = static_cast<ShaderStage>(i);
|
||||
logCompilationError(type, token->name.c_str_safe(), shader, token->shaderSourceCode[i]);
|
||||
logCompilationError(slog.e, type, token->name.c_str_safe(), shader,
|
||||
token->shaderSourceCode[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -707,7 +697,7 @@ void ShaderCompilerService::executeTickOps() noexcept {
|
||||
glGetProgramiv(token->gl.program, GL_LINK_STATUS, &status);
|
||||
if (UTILS_UNLIKELY(status != GL_TRUE)) {
|
||||
// Something went wrong. Log the error message.
|
||||
logProgramLinkError(token->name.c_str_safe(), token->gl.program);
|
||||
logProgramLinkError(slog.e, token->name.c_str_safe(), token->gl.program);
|
||||
linked = false;
|
||||
}
|
||||
// No need to keep the shaders around regardless of the result of the program linking.
|
||||
@@ -757,7 +747,7 @@ void ShaderCompilerService::executeTickOps() noexcept {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
UTILS_NOINLINE
|
||||
/* static */ void logCompilationError(ShaderStage shaderType, const char* name,
|
||||
/* static */ void logCompilationError(io::ostream& out, ShaderStage shaderType, const char* name,
|
||||
GLuint const shaderId, UTILS_UNUSED_IN_RELEASE CString const& sourceCode) noexcept {
|
||||
|
||||
{ // scope for the temporary string storage
|
||||
@@ -779,9 +769,8 @@ UTILS_NOINLINE
|
||||
CString infoLog(length);
|
||||
glGetShaderInfoLog(shaderId, length, nullptr, infoLog.data());
|
||||
|
||||
LOG(ERROR) << "Compilation error in " << to_string(shaderType) << " shader \"" << name
|
||||
<< "\":";
|
||||
LOG(ERROR) << "\"" << infoLog.c_str() << "\"";
|
||||
out << "Compilation error in " << to_string(shaderType) << " shader \"" << name << "\":\n"
|
||||
<< "\"" << infoLog.c_str() << "\"" << io::endl;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
@@ -796,25 +785,26 @@ UTILS_NOINLINE
|
||||
} else {
|
||||
line = shader.substr(start, end - start);
|
||||
}
|
||||
LOG(ERROR) << lc++ << ": " << line.c_str();
|
||||
out << lc++ << ": " << line.c_str() << '\n';
|
||||
if (end == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
start = end + 1;
|
||||
}
|
||||
LOG(ERROR) << "";
|
||||
out << io::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
UTILS_NOINLINE
|
||||
/* static */ void logProgramLinkError(char const* name, GLuint program) noexcept {
|
||||
/* static */ void logProgramLinkError(io::ostream& out, char const* name, GLuint program) noexcept {
|
||||
GLint length = 0;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
|
||||
|
||||
CString infoLog(length);
|
||||
glGetProgramInfoLog(program, length, nullptr, infoLog.data());
|
||||
|
||||
LOG(ERROR) << "Link error in \"" << name << "\":\n" << "\"" << infoLog.c_str() << "\"";
|
||||
out << "Link error in \"" << name << "\":\n"
|
||||
<< "\"" << infoLog.c_str() << "\"" << io::endl;
|
||||
}
|
||||
|
||||
// If usages of the Google-style line directive are present, remove them, as some
|
||||
|
||||
@@ -96,7 +96,7 @@ CocoaExternalImage::SharedGl::~SharedGl() noexcept {
|
||||
CocoaExternalImage::CocoaExternalImage(const CVOpenGLTextureCacheRef textureCache,
|
||||
const SharedGl &sharedGl) noexcept : mSharedGl(sharedGl), mTextureCache(textureCache) {
|
||||
glGenFramebuffers(1, &mFBO);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
CocoaExternalImage::~CocoaExternalImage() noexcept {
|
||||
@@ -125,7 +125,7 @@ bool CocoaExternalImage::set(CVPixelBufferRef image) noexcept {
|
||||
mTexture = createTextureFromImage(image);
|
||||
mRgbaTexture = encodeCopyRectangleToTexture2D(CVOpenGLTextureGetName(mTexture),
|
||||
CVPixelBufferGetWidth(image), CVPixelBufferGetHeight(image));
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -182,33 +182,33 @@ GLuint CocoaExternalImage::encodeCopyRectangleToTexture2D(GLuint rectangle,
|
||||
// Create a texture to hold the result of the blit image.
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
// source textures
|
||||
glBindSampler(0, mSharedGl.sampler);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE, rectangle);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
// destination texture
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(GL_FRAMEBUFFER)
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_FRAMEBUFFER)
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
// draw
|
||||
glViewport(0, 0, width, height);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
glUseProgram(mSharedGl.program);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
glDisableVertexAttribArray(0);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
mState.restore();
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ CocoaTouchExternalImage::CocoaTouchExternalImage(const CVOpenGLESTextureCacheRef
|
||||
|
||||
glGenFramebuffers(1, &mFBO);
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
}
|
||||
|
||||
CocoaTouchExternalImage::~CocoaTouchExternalImage() noexcept {
|
||||
@@ -247,7 +247,7 @@ GLuint CocoaTouchExternalImage::encodeColorConversionPass(GLuint yPlaneTexture,
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
// source textures
|
||||
glBindSampler(0, mSharedGl.sampler);
|
||||
@@ -261,8 +261,8 @@ GLuint CocoaTouchExternalImage::encodeColorConversionPass(GLuint yPlaneTexture,
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(GL_FRAMEBUFFER)
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
CHECK_GL_FRAMEBUFFER_STATUS(utils::slog.e, GL_FRAMEBUFFER)
|
||||
|
||||
// geometry
|
||||
glBindVertexArray(0);
|
||||
@@ -275,7 +275,7 @@ GLuint CocoaTouchExternalImage::encodeColorConversionPass(GLuint yPlaneTexture,
|
||||
glUseProgram(mSharedGl.program);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
|
||||
CHECK_GL_ERROR()
|
||||
CHECK_GL_ERROR(utils::slog.e)
|
||||
|
||||
mState.restore();
|
||||
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
|
||||
#include <backend/Platform.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#if __has_include(<android/surface_texture.h>)
|
||||
@@ -59,7 +59,7 @@ void ExternalStreamManagerAndroid::destroy(ExternalStreamManagerAndroid* pExtern
|
||||
ExternalStreamManagerAndroid::ExternalStreamManagerAndroid() noexcept
|
||||
: mVm(VirtualMachineEnv::get()) {
|
||||
if (__builtin_available(android 28, *)) {
|
||||
DLOG(INFO) << "Using ASurfaceTexture";
|
||||
slog.d << "Using ASurfaceTexture" << io::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
#endif
|
||||
#include <utils/compiler.h>
|
||||
|
||||
#include <utils/Invocable.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Invocable.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -74,7 +74,7 @@ void PlatformEGL::logEglError(const char* name) noexcept {
|
||||
}
|
||||
|
||||
void PlatformEGL::logEglError(const char* name, EGLint error) noexcept {
|
||||
LOG(ERROR) << name << " failed with " << getEglErrorName(error);
|
||||
slog.e << name << " failed with " << getEglErrorName(error) << io::endl;
|
||||
}
|
||||
|
||||
const char* PlatformEGL::getEglErrorName(EGLint error) noexcept {
|
||||
@@ -101,7 +101,7 @@ void PlatformEGL::clearGlError() noexcept {
|
||||
// clear GL error that may have been set by previous calls
|
||||
GLenum const error = glGetError();
|
||||
if (error != GL_NO_ERROR) {
|
||||
LOG(WARNING) << "Ignoring pending GL error " << io::hex << error;
|
||||
slog.w << "Ignoring pending GL error " << io::hex << error << io::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& drive
|
||||
}
|
||||
|
||||
if (UTILS_UNLIKELY(!initialized)) {
|
||||
LOG(ERROR) << "eglInitialize failed";
|
||||
slog.e << "eglInitialize failed" << io::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,12 +29,13 @@
|
||||
#include <android/native_window.h>
|
||||
#include <android/hardware_buffer.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/android/PerformanceHintManager.h>
|
||||
#include <utils/compiler.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
@@ -326,7 +327,7 @@ bool PlatformEGLAndroid::setImage(ExternalImageEGLAndroid const* eglExternalImag
|
||||
EGL_NATIVE_BUFFER_ANDROID, clientBuffer, imageAttrs);
|
||||
if (eglImage == EGL_NO_IMAGE_KHR) {
|
||||
// Handle error
|
||||
LOG(ERROR) << "Failed to create EGL image";
|
||||
slog.e << "Failed to create EGL image" << io::endl;
|
||||
glDeleteTextures(1, &texture->id);
|
||||
return false;
|
||||
}
|
||||
@@ -339,7 +340,7 @@ bool PlatformEGLAndroid::setImage(ExternalImageEGLAndroid const* eglExternalImag
|
||||
glBindTexture(texture->target, texture->id);
|
||||
GLenum error = glGetError();
|
||||
if (UTILS_UNLIKELY(error != GL_NO_ERROR)) {
|
||||
LOG(ERROR) << "Error after glBindTexture: " << error;
|
||||
slog.e << "Error after glBindTexture: " << error << io::endl;
|
||||
glDeleteTextures(1, &texture->id);
|
||||
eglDestroyImageKHR(eglGetCurrentDisplay(), eglImage);
|
||||
glActiveTexture(prevActiveTexture);
|
||||
@@ -349,7 +350,7 @@ bool PlatformEGLAndroid::setImage(ExternalImageEGLAndroid const* eglExternalImag
|
||||
glEGLImageTargetTexture2DOES(texture->target, static_cast<GLeglImageOES>(eglImage));
|
||||
error = glGetError();
|
||||
if (UTILS_UNLIKELY(error != GL_NO_ERROR)) {
|
||||
LOG(ERROR) << "Error after glEGLImageTargetTexture2DOES: " << error;
|
||||
slog.e << "Error after glEGLImageTargetTexture2DOES: " << error << io::endl;
|
||||
glDeleteTextures(1, &texture->id);
|
||||
eglDestroyImageKHR(eglGetCurrentDisplay(), eglImage);
|
||||
glActiveTexture(prevActiveTexture);
|
||||
@@ -407,7 +408,7 @@ AcquiredImage PlatformEGLAndroid::transformAcquiredImage(AcquiredImage source) n
|
||||
|
||||
EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(pHardwareBuffer);
|
||||
if (!clientBuffer) {
|
||||
LOG(ERROR) << "Unable to get EGLClientBuffer from AHardwareBuffer.";
|
||||
slog.e << "Unable to get EGLClientBuffer from AHardwareBuffer." << io::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -426,7 +427,7 @@ AcquiredImage PlatformEGLAndroid::transformAcquiredImage(AcquiredImage source) n
|
||||
EGLImageKHR eglImage = eglCreateImageKHR(mEGLDisplay,
|
||||
EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attributes.data());
|
||||
if (eglImage == EGL_NO_IMAGE_KHR) {
|
||||
LOG(ERROR) << "eglCreateImageKHR returned no image.";
|
||||
slog.e << "eglCreateImageKHR returned no image." << io::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -441,7 +442,7 @@ AcquiredImage PlatformEGLAndroid::transformAcquiredImage(AcquiredImage source) n
|
||||
auto patchedCallback = [](void* image, void* userdata) {
|
||||
Closure* closure = (Closure*)userdata;
|
||||
if (eglDestroyImageKHR(closure->display, (EGLImageKHR) image) == EGL_FALSE) {
|
||||
LOG(ERROR) << "eglDestroyImageKHR failed.";
|
||||
slog.e << "eglDestroyImageKHR failed." << io::endl;
|
||||
}
|
||||
closure->acquiredImage.callback(closure->acquiredImage.image, closure->acquiredImage.userData);
|
||||
delete closure;
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
using namespace utils;
|
||||
|
||||
@@ -42,12 +42,12 @@ backend::Driver* PlatformEGLHeadless::createDriver(void* sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept {
|
||||
EGLBoolean bindAPI = eglBindAPI(EGL_OPENGL_API);
|
||||
if (UTILS_UNLIKELY(!bindAPI)) {
|
||||
LOG(ERROR) << "eglBindAPI EGL_OPENGL_API failed";
|
||||
slog.e << "eglBindAPI EGL_OPENGL_API failed" << io::endl;
|
||||
return nullptr;
|
||||
}
|
||||
int bindBlueGL = bluegl::bind();
|
||||
if (UTILS_UNLIKELY(bindBlueGL != 0)) {
|
||||
LOG(ERROR) << "bluegl bind failed";
|
||||
slog.e << "bluegl bind failed" << io::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include <backend/platforms/PlatformGLX.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
@@ -84,7 +84,7 @@ static PFNGLXGETPROCADDRESSPROC getProcAddress;
|
||||
static bool loadLibraries() {
|
||||
g_glx.library = dlopen(LIBRARY_GLX, RTLD_LOCAL | RTLD_NOW);
|
||||
if (!g_glx.library) {
|
||||
LOG(ERROR) << "Could not find library " << LIBRARY_GLX;
|
||||
utils::slog.e << "Could not find library " << LIBRARY_GLX << utils::io::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ static bool loadLibraries() {
|
||||
|
||||
g_x11.library = dlopen(LIBRARY_X11, RTLD_LOCAL | RTLD_NOW);
|
||||
if (!g_x11.library) {
|
||||
LOG(ERROR) << "Could not find library " << LIBRARY_X11;
|
||||
utils::slog.e << "Could not find library " << LIBRARY_X11 << utils::io::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ Driver* PlatformGLX::createDriver(void* sharedGLContext,
|
||||
// Get the display device
|
||||
mGLXDisplay = g_x11.openDisplay(NULL);
|
||||
if (mGLXDisplay == nullptr) {
|
||||
LOG(ERROR) << "Failed to open X display. (exiting).";
|
||||
utils::slog.e << "Failed to open X display. (exiting)." << utils::io::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -145,7 +145,8 @@ Driver* PlatformGLX::createDriver(void* sharedGLContext,
|
||||
|
||||
r = g_glx.queryContext(mGLXDisplay, sharedCtx, GLX_FBCONFIG_ID, &usedFbId);
|
||||
if (r != 0) {
|
||||
LOG(ERROR) << "Failed to get GLX_FBCONFIG_ID from shared GL context.";
|
||||
utils::slog.e << "Failed to get GLX_FBCONFIG_ID from shared GL context."
|
||||
<< utils::io::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -153,7 +154,7 @@ Driver* PlatformGLX::createDriver(void* sharedGLContext,
|
||||
GLXFBConfig* fbConfigs = g_glx.getFbConfigs(mGLXDisplay, 0, &numConfigs);
|
||||
|
||||
if (fbConfigs == nullptr) {
|
||||
LOG(ERROR) << "Failed to get the available GLXFBConfigs.";
|
||||
utils::slog.e << "Failed to get the available GLXFBConfigs." << utils::io::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -163,7 +164,8 @@ Driver* PlatformGLX::createDriver(void* sharedGLContext,
|
||||
for (int i = 0; i < numConfigs; ++i) {
|
||||
r = g_glx.getFbConfigAttrib(mGLXDisplay, fbConfigs[i], GLX_FBCONFIG_ID, &fbId);
|
||||
if (r != 0) {
|
||||
LOG(ERROR) << "Failed to get GLX_FBCONFIG_ID for entry " << i << ".";
|
||||
utils::slog.e << "Failed to get GLX_FBCONFIG_ID for entry " << i << "."
|
||||
<< utils::io::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -174,7 +176,8 @@ Driver* PlatformGLX::createDriver(void* sharedGLContext,
|
||||
}
|
||||
|
||||
if (fbIndex < 0) {
|
||||
LOG(ERROR) << "Failed to find an `GLXFBConfig` with the requested ID.";
|
||||
utils::slog.e << "Failed to find an `GLXFBConfig` with the requested ID."
|
||||
<< utils::io::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -199,7 +202,8 @@ Driver* PlatformGLX::createDriver(void* sharedGLContext,
|
||||
getProcAddress((GLubyte*)"glXCreateContextAttribsARB");
|
||||
|
||||
if (glXCreateContextAttribs == nullptr) {
|
||||
LOG(INFO) << "Unable to retrieve function pointer for `glXCreateContextAttribs()`.";
|
||||
utils::slog.i << "Unable to retrieve function pointer for `glXCreateContextAttribs()`."
|
||||
<< utils::io::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "GL/glext.h"
|
||||
#include "GL/wglext.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
namespace {
|
||||
@@ -55,7 +55,8 @@ void reportWindowsError(DWORD dwError) {
|
||||
0, nullptr
|
||||
);
|
||||
|
||||
LOG(ERROR) << "Windows error code: " << dwError << ". " << lpMessageBuffer;
|
||||
utils::slog.e << "Windows error code: " << dwError << ". " << lpMessageBuffer
|
||||
<< utils::io::endl;
|
||||
|
||||
LocalFree(lpMessageBuffer);
|
||||
}
|
||||
@@ -105,7 +106,7 @@ Driver* PlatformWGL::createDriver(void* sharedGLContext,
|
||||
HDC whdc = mWhdc = GetDC(mHWnd);
|
||||
if (whdc == NULL) {
|
||||
dwError = GetLastError();
|
||||
LOG(ERROR) << "CreateWindowA() failed";
|
||||
utils::slog.e << "CreateWindowA() failed" << utils::io::endl;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -116,7 +117,8 @@ Driver* PlatformWGL::createDriver(void* sharedGLContext,
|
||||
tempContext = wglCreateContext(whdc);
|
||||
if (!wglMakeCurrent(whdc, tempContext)) {
|
||||
dwError = GetLastError();
|
||||
LOG(ERROR) << "wglMakeCurrent() failed, whdc=" << whdc << ", tempContext=" << tempContext;
|
||||
utils::slog.e << "wglMakeCurrent() failed, whdc=" << whdc << ", tempContext=" <<
|
||||
tempContext << utils::io::endl;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -140,7 +142,7 @@ Driver* PlatformWGL::createDriver(void* sharedGLContext,
|
||||
}
|
||||
|
||||
if (!mContext) {
|
||||
LOG(ERROR) << "wglCreateContextAttribs() failed, whdc=" << whdc;
|
||||
utils::slog.e << "wglCreateContextAttribs() failed, whdc=" << whdc << utils::io::endl;
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -150,7 +152,8 @@ Driver* PlatformWGL::createDriver(void* sharedGLContext,
|
||||
|
||||
if (!wglMakeCurrent(whdc, mContext)) {
|
||||
dwError = GetLastError();
|
||||
LOG(ERROR) << "wglMakeCurrent() failed, whdc=" << whdc << ", mContext=" << mContext;
|
||||
utils::slog.e << "wglMakeCurrent() failed, whdc=" << whdc << ", mContext=" <<
|
||||
mContext << utils::io::endl;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ inline void blitFast(VulkanCommandBuffer* commands, VkImageAspectFlags aspect, V
|
||||
FVK_LOGD << "Fast blit from=" << src.texture->getVkImage() << ",level=" << (int) src.level
|
||||
<< " layout=" << src.getLayout()
|
||||
<< " to=" << dst.texture->getVkImage() << ",level=" << (int) dst.level
|
||||
<< " layout=" << dst.getLayout();
|
||||
<< " layout=" << dst.getLayout() << utils::io::endl;
|
||||
}
|
||||
|
||||
VkImageSubresourceRange const srcRange = src.getSubresourceRange();
|
||||
@@ -80,7 +80,7 @@ inline void resolveFast(VulkanCommandBuffer* commands, VkImageAspectFlags aspect
|
||||
FVK_LOGD << "Fast blit from=" << src.texture->getVkImage() << ",level=" << (int) src.level
|
||||
<< " layout=" << src.getLayout()
|
||||
<< " to=" << dst.texture->getVkImage() << ",level=" << (int) dst.level
|
||||
<< " layout=" << dst.getLayout();
|
||||
<< " layout=" << dst.getLayout() << utils::io::endl;
|
||||
}
|
||||
|
||||
VkImageSubresourceRange const srcRange = src.getSubresourceRange();
|
||||
|
||||
@@ -215,7 +215,7 @@ VkSemaphore VulkanCommandBuffer::submit() {
|
||||
}
|
||||
FVK_LOGI << ") "
|
||||
<< " signal=" << mSubmission
|
||||
<< " fence=" << mFence;
|
||||
<< " fence=" << mFence << utils::io::endl;
|
||||
#endif
|
||||
|
||||
mFenceStatus->setStatus(VK_NOT_READY);
|
||||
@@ -224,7 +224,7 @@ VkSemaphore VulkanCommandBuffer::submit() {
|
||||
|
||||
#if FVK_ENABLED(FVK_DEBUG_COMMAND_BUFFER)
|
||||
if (result != VK_SUCCESS) {
|
||||
FVK_LOGD << "Failed command buffer submission result: " << result;
|
||||
FVK_LOGD << "Failed command buffer submission result: " << result << utils::io::endl;
|
||||
}
|
||||
#endif
|
||||
assert_invariant(result == VK_SUCCESS);
|
||||
@@ -490,7 +490,7 @@ void VulkanCommands::pushGroupMarker(char const* str, VulkanGroupMarkers::Timest
|
||||
mProtectedPool->pushMarker(str, timestamp);
|
||||
}
|
||||
#if FVK_ENABLED(FVK_DEBUG_PRINT_GROUP_MARKERS)
|
||||
FVK_LOGD << "----> " << str;
|
||||
FVK_LOGD << "----> " << str << utils::io::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -502,7 +502,8 @@ void VulkanCommands::popGroupMarker() {
|
||||
auto const& startTime = ret.second;
|
||||
auto const endTime = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double> diff = endTime - startTime;
|
||||
FVK_LOGD << "<---- " << marker << " elapsed: " << (diff.count() * 1000) << " ms";
|
||||
FVK_LOGD << "<---- " << marker << " elapsed: " << (diff.count() * 1000) << " ms"
|
||||
<< utils::io::endl;
|
||||
#else
|
||||
mPool->popMarker();
|
||||
#endif // FVK_DEBUG_PRINT_GROUP_MARKERS
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#ifndef TNT_FILAMENT_BACKEND_VULKANCONSTANTS_H
|
||||
#define TNT_FILAMENT_BACKEND_VULKANCONSTANTS_H
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -73,8 +73,8 @@
|
||||
#define FVK_DEBUG_RESOURCE_LEAK 0x00010000
|
||||
|
||||
// Set this to enable logging "only" to one output stream. This is useful in the case where we want
|
||||
// to debug with print statements and want ordered logging (e.g LOG(INFO) and LOG(ERROR) will not
|
||||
// appear in order of calls).
|
||||
// to debug with print statements and want ordered logging (e.g slog.i and slog.e will not appear in
|
||||
// order of calls).
|
||||
#define FVK_DEBUG_FORCE_LOG_TO_I 0x00020000
|
||||
|
||||
// Enable a minimal set of traces to assess the performance of the backend.
|
||||
@@ -174,15 +174,15 @@ static_assert(FVK_ENABLED(FVK_DEBUG_VALIDATION));
|
||||
#endif
|
||||
|
||||
#if FVK_ENABLED(FVK_DEBUG_FORCE_LOG_TO_I)
|
||||
#define FVK_LOGI LOG(INFO)
|
||||
#define FVK_LOGI (utils::slog.i)
|
||||
#define FVK_LOGD FVK_LOGI
|
||||
#define FVK_LOGE FVK_LOGI
|
||||
#define FVK_LOGW FVK_LOGI
|
||||
#else
|
||||
#define FVK_LOGE LOG(ERROR)
|
||||
#define FVK_LOGW LOG(WARNING)
|
||||
#define FVK_LOGD DLOG(INFO)
|
||||
#define FVK_LOGI LOG(INFO)
|
||||
#define FVK_LOGE (utils::slog.e)
|
||||
#define FVK_LOGW (utils::slog.w)
|
||||
#define FVK_LOGD (utils::slog.d)
|
||||
#define FVK_LOGI (utils::slog.i)
|
||||
#endif
|
||||
|
||||
// All vkCreate* functions take an optional allocator. For now we select the default allocator by
|
||||
|
||||
@@ -104,15 +104,15 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debugReportCallback(VkDebugReportFlagsEXT flags,
|
||||
VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location,
|
||||
int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) {
|
||||
if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
|
||||
FVK_LOGE << "VULKAN ERROR: (" << pLayerPrefix << ") " << pMessage;
|
||||
FVK_LOGE << "VULKAN ERROR: (" << pLayerPrefix << ") " << pMessage << utils::io::endl;
|
||||
} else {
|
||||
// TODO: emit best practices warnings about aggressive pipeline barriers.
|
||||
if (strstr(pMessage, "ALL_GRAPHICS_BIT") || strstr(pMessage, "ALL_COMMANDS_BIT")) {
|
||||
return VK_FALSE;
|
||||
}
|
||||
FVK_LOGW << "VULKAN WARNING: (" << pLayerPrefix << ") " << pMessage;
|
||||
FVK_LOGW << "VULKAN WARNING: (" << pLayerPrefix << ") " << pMessage << utils::io::endl;
|
||||
}
|
||||
FVK_LOGE;
|
||||
FVK_LOGE << utils::io::endl;
|
||||
return VK_FALSE;
|
||||
}
|
||||
#endif // FVK_ENABLED(FVK_DEBUG_VALIDATION)
|
||||
@@ -122,16 +122,18 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debugUtilsCallback(VkDebugUtilsMessageSeverityFla
|
||||
VkDebugUtilsMessageTypeFlagsEXT types, const VkDebugUtilsMessengerCallbackDataEXT* cbdata,
|
||||
void* pUserData) {
|
||||
if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
|
||||
FVK_LOGE << "VULKAN ERROR: (" << cbdata->pMessageIdName << ") " << cbdata->pMessage;
|
||||
FVK_LOGE << "VULKAN ERROR: (" << cbdata->pMessageIdName << ") " << cbdata->pMessage
|
||||
<< utils::io::endl;
|
||||
} else {
|
||||
// TODO: emit best practices warnings about aggressive pipeline barriers.
|
||||
if (strstr(cbdata->pMessage, "ALL_GRAPHICS_BIT")
|
||||
|| strstr(cbdata->pMessage, "ALL_COMMANDS_BIT")) {
|
||||
return VK_FALSE;
|
||||
}
|
||||
FVK_LOGW << "VULKAN WARNING: (" << cbdata->pMessageIdName << ") " << cbdata->pMessage;
|
||||
FVK_LOGW << "VULKAN WARNING: (" << cbdata->pMessageIdName << ") " << cbdata->pMessage
|
||||
<< utils::io::endl;
|
||||
}
|
||||
FVK_LOGE << "";
|
||||
FVK_LOGE << utils::io::endl;
|
||||
return VK_FALSE;
|
||||
}
|
||||
#endif // FVK_ENABLED(FVK_DEBUG_DEBUG_UTILS)
|
||||
@@ -274,18 +276,20 @@ Driver* VulkanDriver::create(VulkanPlatform* platform, VulkanContext const& cont
|
||||
// VulkanRenderTarget : 312 few
|
||||
// -- less than or equal to 312 bytes
|
||||
|
||||
FVK_LOGD << "VulkanSwapChain: " << sizeof(VulkanSwapChain);
|
||||
FVK_LOGD << "VulkanBufferObject: " << sizeof(VulkanBufferObject);
|
||||
FVK_LOGD << "VulkanVertexBuffer: " << sizeof(VulkanVertexBuffer);
|
||||
FVK_LOGD << "VulkanVertexBufferInfo: " << sizeof(VulkanVertexBufferInfo);
|
||||
FVK_LOGD << "VulkanIndexBuffer: " << sizeof(VulkanIndexBuffer);
|
||||
FVK_LOGD << "VulkanRenderPrimitive: " << sizeof(VulkanRenderPrimitive);
|
||||
FVK_LOGD << "VulkanTexture: " << sizeof(VulkanTexture);
|
||||
FVK_LOGD << "VulkanTimerQuery: " << sizeof(VulkanTimerQuery);
|
||||
FVK_LOGD << "HwStream: " << sizeof(HwStream);
|
||||
FVK_LOGD << "VulkanRenderTarget: " << sizeof(VulkanRenderTarget);
|
||||
FVK_LOGD << "VulkanFence: " << sizeof(VulkanFence);
|
||||
FVK_LOGD << "VulkanProgram: " << sizeof(VulkanProgram);
|
||||
FVK_LOGD
|
||||
<< "\nVulkanSwapChain: " << sizeof(VulkanSwapChain)
|
||||
<< "\nVulkanBufferObject: " << sizeof(VulkanBufferObject)
|
||||
<< "\nVulkanVertexBuffer: " << sizeof(VulkanVertexBuffer)
|
||||
<< "\nVulkanVertexBufferInfo: " << sizeof(VulkanVertexBufferInfo)
|
||||
<< "\nVulkanIndexBuffer: " << sizeof(VulkanIndexBuffer)
|
||||
<< "\nVulkanRenderPrimitive: " << sizeof(VulkanRenderPrimitive)
|
||||
<< "\nVulkanTexture: " << sizeof(VulkanTexture)
|
||||
<< "\nVulkanTimerQuery: " << sizeof(VulkanTimerQuery)
|
||||
<< "\nHwStream: " << sizeof(HwStream)
|
||||
<< "\nVulkanRenderTarget: " << sizeof(VulkanRenderTarget)
|
||||
<< "\nVulkanFence: " << sizeof(VulkanFence)
|
||||
<< "\nVulkanProgram: " << sizeof(VulkanProgram)
|
||||
<< utils::io::endl;
|
||||
#endif
|
||||
|
||||
assert_invariant(platform);
|
||||
@@ -795,12 +799,14 @@ void VulkanDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow,
|
||||
mResourceManager.gc();
|
||||
|
||||
if ((flags & backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE) != 0 && !isSRGBSwapChainSupported()) {
|
||||
FVK_LOGW << "sRGB swapchain requested, but Platform does not support it";
|
||||
FVK_LOGW << "sRGB swapchain requested, but Platform does not support it"
|
||||
<< utils::io::endl;
|
||||
flags = flags | ~(backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE);
|
||||
}
|
||||
if (flags & backend::SWAP_CHAIN_CONFIG_PROTECTED_CONTENT) {
|
||||
if (!isProtectedContentSupported()) {
|
||||
FVK_LOGW << "protected swapchain requested, but Platform does not support it";
|
||||
FVK_LOGW << "protected swapchain requested, but Platform does not support it"
|
||||
<< utils::io::endl;
|
||||
}
|
||||
}
|
||||
auto swapChain = resource_ptr<VulkanSwapChain>::make(&mResourceManager, sch, mPlatform,
|
||||
@@ -811,7 +817,8 @@ void VulkanDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow,
|
||||
void VulkanDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch, uint32_t width,
|
||||
uint32_t height, uint64_t flags) {
|
||||
if ((flags & backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE) != 0 && !isSRGBSwapChainSupported()) {
|
||||
FVK_LOGW << "sRGB swapchain requested, but Platform does not support it";
|
||||
FVK_LOGW << "sRGB swapchain requested, but Platform does not support it"
|
||||
<< utils::io::endl;
|
||||
flags = flags | ~(backend::SWAP_CHAIN_CONFIG_SRGB_COLORSPACE);
|
||||
}
|
||||
assert_invariant(width > 0 && height > 0 && "Vulkan requires non-zero swap chain dimensions.");
|
||||
@@ -1299,7 +1306,7 @@ TimerQueryResult VulkanDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint
|
||||
uint64_t const end = results.endTime;
|
||||
if (begin >= end) {
|
||||
// TODO: queries might have ran on different command buffers.
|
||||
FVK_LOGW << "Timestamps are not monotonically increasing. ";
|
||||
FVK_LOGW << "Timestamps are not monotonically increasing. " << utils::io::endl;
|
||||
*elapsedTime = 0;
|
||||
return TimerQueryResult::ERROR;
|
||||
}
|
||||
@@ -2037,7 +2044,7 @@ void VulkanDriver::debugCommandBegin(CommandStream* cmds, bool synchronous, cons
|
||||
assert_invariant(inRenderPass);
|
||||
inRenderPass = false;
|
||||
} else if (inRenderPass && OUTSIDE_COMMANDS.find(command) != OUTSIDE_COMMANDS.end()) {
|
||||
FVK_LOGE << command.data() << " issued inside a render pass.";
|
||||
FVK_LOGE << command.data() << " issued inside a render pass." << utils::io::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -100,7 +100,8 @@ VkFramebuffer VulkanFboCache::getFramebuffer(FboKey const& config) noexcept {
|
||||
<< "for render pass " << config.renderPass << ", "
|
||||
<< "samples = " << int(config.samples) << ", "
|
||||
<< "depth = " << (config.depth ? 1 : 0) << ", "
|
||||
<< "attachmentCount = " << attachmentCount;
|
||||
<< "attachmentCount = " << attachmentCount
|
||||
<< utils::io::endl;
|
||||
#endif
|
||||
|
||||
VkFramebufferCreateInfo info {
|
||||
@@ -340,7 +341,8 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey const& config) noexcept
|
||||
<< "needsResolveMask = " << int(config.needsResolveMask) << ", "
|
||||
<< "usesLazilyAllocatedMemory = " << int(config.usesLazilyAllocatedMemory) << ", "
|
||||
<< "viewCount = " << int(config.viewCount) << ", "
|
||||
<< "colorAttachmentCount[0] = " << subpasses[0].colorAttachmentCount;
|
||||
<< "colorAttachmentCount[0] = " << subpasses[0].colorAttachmentCount
|
||||
<< utils::io::endl;
|
||||
#endif
|
||||
|
||||
return renderPass;
|
||||
|
||||
@@ -287,7 +287,7 @@ VulkanProgram::VulkanProgram(VkDevice device, Program const& builder) noexcept
|
||||
|
||||
#if FVK_ENABLED(FVK_DEBUG_SHADER_MODULE)
|
||||
FVK_LOGD << "Created VulkanProgram " << builder << ", shaders = (" << modules[0]
|
||||
<< ", " << modules[1] << ")";
|
||||
<< ", " << modules[1] << ")" << utils::io::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -218,7 +218,8 @@ VulkanPipelineCache::PipelineCacheEntry* VulkanPipelineCache::createPipeline() n
|
||||
|
||||
#if FVK_ENABLED(FVK_DEBUG_SHADER_MODULE)
|
||||
FVK_LOGD << "vkCreateGraphicsPipelines with shaders = ("
|
||||
<< shaderStages[0].module << ", " << shaderStages[1].module << ")";
|
||||
<< shaderStages[0].module << ", " << shaderStages[1].module << ")"
|
||||
<< utils::io::endl;
|
||||
#endif
|
||||
PipelineCacheEntry cacheEntry = {
|
||||
.lastUsed = mCurrentTime,
|
||||
@@ -227,7 +228,7 @@ VulkanPipelineCache::PipelineCacheEntry* VulkanPipelineCache::createPipeline() n
|
||||
VKALLOC, &cacheEntry.handle);
|
||||
assert_invariant(error == VK_SUCCESS);
|
||||
if (error != VK_SUCCESS) {
|
||||
FVK_LOGE << "vkCreateGraphicsPipelines error " << error;
|
||||
FVK_LOGE << "vkCreateGraphicsPipelines error " << error << utils::io::endl;
|
||||
return nullptr;
|
||||
}
|
||||
return &mPipelines.emplace(mPipelineRequirements, cacheEntry).first.value();
|
||||
@@ -241,7 +242,7 @@ void VulkanPipelineCache::bindProgram(fvkmemory::resource_ptr<VulkanProgram> pro
|
||||
#if FVK_ENABLED(FVK_DEBUG_SHADER_MODULE)
|
||||
if (mPipelineRequirements.shaders[0] == VK_NULL_HANDLE ||
|
||||
mPipelineRequirements.shaders[1] == VK_NULL_HANDLE) {
|
||||
FVK_LOGE << "Binding missing shader: " << program->name.c_str();
|
||||
FVK_LOGE << "Binding missing shader: " << program->name.c_str() << utils::io::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ fvkmemory::resource_ptr<VulkanTimerQuery> VulkanQueryManager::getNextQuery(
|
||||
fvkmemory::ResourceManager* resourceManager) {
|
||||
auto unused = ~mUsed;
|
||||
if (unused.empty()) {
|
||||
FVK_LOGE << "More than " << mUsed.size() << " timers are not supported.";
|
||||
FVK_LOGE << "More than " << mUsed.size() << " timers are not supported." << utils::io::endl;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ void VulkanReadPixels::run(fvkmemory::resource_ptr<VulkanRenderTarget> srcTarget
|
||||
#if FVK_ENABLED(FVK_DEBUG_READ_PIXELS)
|
||||
FVK_LOGD << "readPixels created image=" << stagingImage
|
||||
<< " to copy from image=" << srcTexture->getVkImage()
|
||||
<< " src-layout=" << srcTexture->getLayout(0, 0);
|
||||
<< " src-layout=" << srcTexture->getLayout(0, 0) << utils::io::endl;
|
||||
#endif
|
||||
|
||||
VkMemoryRequirements memReqs;
|
||||
@@ -188,7 +188,8 @@ void VulkanReadPixels::run(fvkmemory::resource_ptr<VulkanRenderTarget> srcTarget
|
||||
memoryTypeIndex = selectMemoryFunc(memReqs.memoryTypeBits,
|
||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
FVK_LOGW
|
||||
<< "readPixels is slow because VK_MEMORY_PROPERTY_HOST_CACHED_BIT is not available";
|
||||
<< "readPixels is slow because VK_MEMORY_PROPERTY_HOST_CACHED_BIT is not available"
|
||||
<< utils::io::endl;
|
||||
}
|
||||
|
||||
FILAMENT_CHECK_POSTCONDITION(memoryTypeIndex < VK_MAX_MEMORY_TYPES)
|
||||
@@ -304,7 +305,7 @@ void VulkanReadPixels::run(fvkmemory::resource_ptr<VulkanRenderTarget> srcTarget
|
||||
fence = readCompleteFence]() mutable {
|
||||
VkResult status = vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX);
|
||||
if (status != VK_SUCCESS) {
|
||||
FVK_LOGE << "Failed to wait for readPixels fence";
|
||||
FVK_LOGE << "Failed to wait for readPixels fence" << utils::io::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -322,7 +323,7 @@ void VulkanReadPixels::run(fvkmemory::resource_ptr<VulkanRenderTarget> srcTarget
|
||||
fvkutils::getComponentCount(srcFormat), srcPixels,
|
||||
static_cast<int>(subResourceLayout.rowPitch), static_cast<int>(width),
|
||||
static_cast<int>(height), swizzle)) {
|
||||
FVK_LOGE << "Unsupported PixelDataFormat or PixelDataType";
|
||||
FVK_LOGE << "Unsupported PixelDataFormat or PixelDataType" << utils::io::endl;
|
||||
}
|
||||
|
||||
vkUnmapMemory(device, stagingMemory);
|
||||
|
||||
@@ -108,9 +108,9 @@ VulkanStage* VulkanStagePool::allocateNewStage(uint32_t capacity) {
|
||||
|
||||
#if FVK_ENABLED(FVK_DEBUG_STAGING_ALLOCATION)
|
||||
if (result != VK_SUCCESS) {
|
||||
FVK_LOGE << "Allocation error: " << result;
|
||||
FVK_LOGE << "Allocation error: " << result << utils::io::endl;
|
||||
} else {
|
||||
FVK_LOGD << "Allocated stage with hndl " << buffer;
|
||||
FVK_LOGD << "Allocated stage with hndl " << buffer << utils::io::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -188,8 +188,8 @@ VkImageUsageFlags getUsage(VulkanContext const& context, uint8_t samples,
|
||||
VkFormatProperties props;
|
||||
vkGetPhysicalDeviceFormatProperties(physicalDevice, vkFormat, &props);
|
||||
if (!(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
|
||||
FVK_LOGW << "Texture usage is SAMPLEABLE but format " << vkFormat
|
||||
<< " is not sampleable with optimal tiling.";
|
||||
FVK_LOGW << "Texture usage is SAMPLEABLE but format " << vkFormat << " is not "
|
||||
"sampleable with optimal tiling." << utils::io::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -361,7 +361,7 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice,
|
||||
imageInfo.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
|
||||
} else {
|
||||
FVK_LOGW << "Note: creating 2D views on 3D image is not available on this platform. "
|
||||
<< "i.e. we cannot render to slices of a 3D image";
|
||||
<< "i.e. we cannot render to slices of a 3D image" << utils::io::endl;
|
||||
}
|
||||
} else if (target == SamplerType::SAMPLER_CUBEMAP) {
|
||||
imageInfo.arrayLayers = 6;
|
||||
@@ -420,7 +420,7 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice,
|
||||
<< "type = " << imageInfo.imageType << ", "
|
||||
<< "flags = " << imageInfo.flags << ", "
|
||||
<< "target = " << static_cast<int>(target) <<", "
|
||||
<< "format = " << vkFormat;
|
||||
<< "format = " << vkFormat << utils::io::endl;
|
||||
}
|
||||
FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "Unable to create image."
|
||||
<< " error=" << static_cast<int32_t>(result);
|
||||
@@ -731,14 +731,14 @@ bool VulkanTexture::transitionLayout(VkCommandBuffer cmdbuf, VkImageSubresourceR
|
||||
<< range.levelCount << ")" << " from=" << oldLayout << " to=" << newLayout
|
||||
<< " format=" << mState->mVkFormat << " depth="
|
||||
<< fvkutils::isVkDepthFormat(mState->mVkFormat)
|
||||
<< " slice-by-slice=" << transitionSliceBySlice;
|
||||
<< " slice-by-slice=" << transitionSliceBySlice << utils::io::endl;
|
||||
#endif
|
||||
} else {
|
||||
#if FVK_ENABLED(FVK_DEBUG_LAYOUT_TRANSITION)
|
||||
FVK_LOGD << "transition texture=" << mState->mTextureImage << " (" << range.baseArrayLayer
|
||||
<< "," << range.baseMipLevel << ")" << " count=(" << range.layerCount << ","
|
||||
<< range.levelCount << ")" << " to=" << newLayout
|
||||
<< " is skipped because of no change in layout";
|
||||
<< " is skipped because of no change in layout" << utils::io::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -849,7 +849,8 @@ void VulkanTexture::print() const {
|
||||
level < (mPrimaryViewRange.baseMipLevel + mPrimaryViewRange.levelCount);
|
||||
FVK_LOGD << "[" << mState->mTextureImage << "]: (" << layer << "," << level
|
||||
<< ")=" << getLayout(layer, level)
|
||||
<< " primary=" << primary;
|
||||
<< " primary=" << primary
|
||||
<< utils::io::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -858,7 +859,8 @@ void VulkanTexture::print() const {
|
||||
FVK_LOGD << "[" << mState->mTextureImage << ", imageView=" << view.second << "]=>"
|
||||
<< " (" << range.baseArrayLayer << "," << range.baseMipLevel << ")"
|
||||
<< " count=(" << range.layerCount << "," << range.levelCount << ")"
|
||||
<< " aspect=" << range.aspectMask << " viewType=" << view.first.type;
|
||||
<< " aspect=" << range.aspectMask << " viewType=" << view.first.type
|
||||
<< utils::io::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "vulkan/memory/ResourceManager.h"
|
||||
#include "vulkan/VulkanHandles.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
namespace filament::backend::fvkmemory {
|
||||
@@ -128,11 +127,11 @@ void ResourceManager::traceConstruction(ResourceType type, HandleId id) {
|
||||
|
||||
void ResourceManager::print() const noexcept {
|
||||
#if FVK_ENABLED(FVK_DEBUG_RESOURCE_LEAK)
|
||||
LOG(ERROR) << "-------------------";
|
||||
utils::slog.e << "-------------------" << utils::io::endl;
|
||||
for (size_t i = 0; i < (size_t) ResourceType::UNDEFINED_TYPE; ++i) {
|
||||
LOG(ERROR) << " " << getTypeStr((ResourceType) i) << "=" << COUNTER[i];
|
||||
utils::slog.e <<" " << getTypeStr((ResourceType) i) << "=" << COUNTER[i] << utils::io::endl;
|
||||
}
|
||||
LOG(ERROR) << "+++++++++++++++++++";
|
||||
utils::slog.e << "+++++++++++++++++++" << utils::io::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,8 @@
|
||||
#include "vulkan/utils/Helper.h"
|
||||
|
||||
#include <bluevk/BlueVK.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/PrivateImplementation-impl.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
#define SWAPCHAIN_RET_FUNC(func, handle, ...) \
|
||||
if (mImpl->mSurfaceSwapChains.find(handle) != mImpl->mSurfaceSwapChains.end()) { \
|
||||
@@ -115,7 +114,7 @@ void printDeviceInfo(VkInstance instance, VkPhysicalDevice device) {
|
||||
chainStruct(&physicalDeviceProperties2, &driverProperties);
|
||||
vkGetPhysicalDeviceProperties2(device, &physicalDeviceProperties2);
|
||||
FVK_LOGI << "Vulkan device driver: " << driverProperties.driverName << " "
|
||||
<< driverProperties.driverInfo;
|
||||
<< driverProperties.driverInfo << utils::io::endl;
|
||||
}
|
||||
|
||||
VkPhysicalDeviceProperties deviceProperties;
|
||||
@@ -152,7 +151,7 @@ void printDeviceInfo(VkInstance instance, VkPhysicalDevice device) {
|
||||
<< "(vendor " << utils::io::hex << vendorID << ", "
|
||||
<< "device " << deviceID << ", "
|
||||
<< "driver " << driverVersion << ", " << utils::io::dec << "api " << major << "."
|
||||
<< minor << ")";
|
||||
<< minor << ")" << utils::io::endl;
|
||||
}
|
||||
|
||||
#if FVK_ENABLED(FVK_DEBUG_VALIDATION)
|
||||
@@ -175,7 +174,7 @@ void printDepthFormats(VkPhysicalDevice device) {
|
||||
FVK_LOGI << format << " ";
|
||||
}
|
||||
}
|
||||
FVK_LOGI << "";
|
||||
FVK_LOGI << utils::io::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -295,10 +294,10 @@ VkInstance createInstance(ExtensionSet const& requiredExts) {
|
||||
} else {
|
||||
#if defined(__ANDROID__)
|
||||
FVK_LOGD << "Validation layers are not available; did you set jniLibs in your "
|
||||
<< "gradle file?";
|
||||
<< "gradle file?" << utils::io::endl;
|
||||
#else
|
||||
FVK_LOGD << "Validation layer not available; did you install the Vulkan SDK?\n"
|
||||
<< "Please ensure that VK_LAYER_PATH is set correctly.";
|
||||
<< "Please ensure that VK_LAYER_PATH is set correctly." << utils::io::endl;
|
||||
#endif // __ANDROID__
|
||||
|
||||
}
|
||||
@@ -923,7 +922,7 @@ Driver* VulkanPlatform::createDriver(void* sharedContext,
|
||||
// Keep a copy of context for swapchains.
|
||||
mImpl->mContext = context;
|
||||
|
||||
return VulkanDriver::create(this, mImpl->mContext, driverConfig);
|
||||
return VulkanDriver::create(this, context, driverConfig);
|
||||
}
|
||||
|
||||
// This needs to be explictly written for
|
||||
@@ -985,7 +984,8 @@ SwapChainPtr VulkanPlatform::createSwapChain(void* nativeWindow, uint64_t flags,
|
||||
|
||||
if (flags & backend::SWAP_CHAIN_CONFIG_PROTECTED_CONTENT) {
|
||||
if (!mImpl->mContext.mProtectedMemorySupported) {
|
||||
LOG(WARNING) << "protected swapchain requested, but VulkanPlatform does not support it";
|
||||
utils::slog.w << "protected swapchain requested, but VulkanPlatform does not support it"
|
||||
<< utils::io::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -163,7 +163,8 @@ VkResult VulkanPlatformSurfaceSwapChain::create() {
|
||||
// the number of images, though there may be limits related to the total amount of memory used
|
||||
// by presentable images."
|
||||
if (maxImageCount != 0 && desiredImageCount > maxImageCount) {
|
||||
FVK_LOGE << "Swap chain does not support " << desiredImageCount << " images.";
|
||||
FVK_LOGE << "Swap chain does not support " << desiredImageCount << " images."
|
||||
<< utils::io::endl;
|
||||
desiredImageCount = caps.minImageCount;
|
||||
}
|
||||
|
||||
@@ -265,7 +266,8 @@ VkResult VulkanPlatformSurfaceSwapChain::create() {
|
||||
<< "swapchain-size=" << mSwapChainBundle.colors.size() << ", "
|
||||
<< "identity-transform=" << (caps.currentTransform == 1) << ", "
|
||||
<< "depth=" << mSwapChainBundle.depthFormat << ", "
|
||||
<< "protected=" << mSwapChainBundle.isProtected;
|
||||
<< "protected=" << mSwapChainBundle.isProtected
|
||||
<< io::endl;
|
||||
|
||||
VkSemaphoreCreateInfo const semaphoreCreateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||
@@ -291,7 +293,7 @@ VkResult VulkanPlatformSurfaceSwapChain::acquire(VulkanPlatform::ImageSyncData*
|
||||
// Users should be notified of a suboptimal surface, but it should not cause a cascade of
|
||||
// log messages or a loop of re-creations.
|
||||
if (result == VK_SUBOPTIMAL_KHR && !mSuboptimal) {
|
||||
FVK_LOGW << "Vulkan Driver: Suboptimal swap chain.";
|
||||
FVK_LOGW << "Vulkan Driver: Suboptimal swap chain." << io::endl;
|
||||
mSuboptimal = true;
|
||||
}
|
||||
return result;
|
||||
@@ -313,7 +315,7 @@ VkResult VulkanPlatformSurfaceSwapChain::present(uint32_t index, VkSemaphore fin
|
||||
// On Android Q and above, a suboptimal surface is always reported after screen rotation:
|
||||
// https://android-developers.googleblog.com/2020/02/handling-device-orientation-efficiently.html
|
||||
if (result == VK_SUBOPTIMAL_KHR && !mSuboptimal) {
|
||||
FVK_LOGW << "Vulkan Driver: Suboptimal swap chain.";
|
||||
FVK_LOGW << "Vulkan Driver: Suboptimal swap chain." << utils::io::endl;
|
||||
mSuboptimal = true;
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#ifndef TNT_FILAMENT_BACKEND_WEBGPUCONSTANTS_H
|
||||
#define TNT_FILAMENT_BACKEND_WEBGPUCONSTANTS_H
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
@@ -32,8 +32,8 @@ constexpr size_t WEBGPU_BUFFER_SIZE_MODULUS = 4;
|
||||
#define FWGPU_PRINT_SYSTEM 0x00000002
|
||||
|
||||
// Set this to enable logging "only" to one output stream. This is useful in the case where we want
|
||||
// to debug with print statements and want ordered logging (e.g LOG(INFO) and LOG(ERROR) will not
|
||||
// appear in order of calls).
|
||||
// to debug with print statements and want ordered logging (e.g slog.i and slog.e will not appear in
|
||||
// order of calls).
|
||||
#define FWGPU_DEBUG_FORCE_LOG_TO_I 0x00000004
|
||||
|
||||
// Useful default combinations
|
||||
@@ -54,15 +54,15 @@ constexpr size_t WEBGPU_BUFFER_SIZE_MODULUS = 4;
|
||||
#define FWGPU_ENABLED(flags) (((FWGPU_DEBUG_FLAGS) & (flags)) == (flags))
|
||||
|
||||
#if FWGPU_ENABLED(FWGPU_DEBUG_FORCE_LOG_TO_I)
|
||||
#define FWGPU_LOGI LOG(INFO)
|
||||
#define FWGPU_LOGI (utils::slog.i)
|
||||
#define FWGPU_LOGD FWGPU_LOGI
|
||||
#define FWGPU_LOGE FWGPU_LOGI
|
||||
#define FWGPU_LOGW FWGPU_LOGI
|
||||
#else
|
||||
#define FWGPU_LOGE LOG(ERROR)
|
||||
#define FWGPU_LOGW LOG(WARNING)
|
||||
#define FWGPU_LOGD DLOG(INFO)
|
||||
#define FWGPU_LOGI LOG(INFO)
|
||||
#define FWGPU_LOGE (utils::slog.e)
|
||||
#define FWGPU_LOGW (utils::slog.w)
|
||||
#define FWGPU_LOGD (utils::slog.d)
|
||||
#define FWGPU_LOGI (utils::slog.i)
|
||||
#endif
|
||||
|
||||
constexpr uint64_t REQUEST_ADAPTER_TIMEOUT_NANOSECONDS =
|
||||
|
||||
@@ -336,15 +336,15 @@ void WebGPUDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow,
|
||||
|
||||
FWGPU_LOGW << "WebGPU support is highly experimental, in development, and tested for only a "
|
||||
"small set of simple samples (e.g. hellotriangle and texturedquad), thus issues "
|
||||
"are likely to be encountered at this stage.";
|
||||
"are likely to be encountered at this stage."
|
||||
<< utils::io::endl;
|
||||
#if !FWGPU_ENABLED(FWGPU_PRINT_SYSTEM) && !defined(NDEBUG)
|
||||
char printSystemHex[16];
|
||||
snprintf(printSystemHex, sizeof(printSystemHex), "%#x", FWGPU_PRINT_SYSTEM);
|
||||
FWGPU_LOGI << "If the FILAMENT_BACKEND_DEBUG_FLAG variable were set with the " << printSystemHex
|
||||
FWGPU_LOGI << "If the FILAMENT_BACKEND_DEBUG_FLAG variable were set with the " << utils::io::hex
|
||||
<< FWGPU_PRINT_SYSTEM << utils::io::dec
|
||||
<< " bit flag on during build time the application would print system details "
|
||||
"about the selected graphics device, surface, etc. To see this try "
|
||||
"rebuilding Filament with that flag, e.g. ./build.sh -x "
|
||||
<< FWGPU_PRINT_SYSTEM << " ...";
|
||||
<< FWGPU_PRINT_SYSTEM << " ..." << utils::io::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -807,7 +807,6 @@ void WebGPUDriver::beginRenderPass(Handle<HwRenderTarget> renderTargetHandle,
|
||||
|
||||
wgpu::TextureView defaultColorView = nullptr;
|
||||
wgpu::TextureView defaultDepthStencilView = nullptr;
|
||||
wgpu::TextureFormat defaultDepthStencilFormat = wgpu::TextureFormat::Undefined;
|
||||
|
||||
std::array<wgpu::TextureView, MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT> customColorViews{};
|
||||
uint32_t customColorViewCount = 0;
|
||||
@@ -821,7 +820,6 @@ void WebGPUDriver::beginRenderPass(Handle<HwRenderTarget> renderTargetHandle,
|
||||
assert_invariant(mSwapChain && mTextureView);
|
||||
defaultColorView = mTextureView;
|
||||
defaultDepthStencilView = mSwapChain->getDepthTextureView();
|
||||
defaultDepthStencilFormat = mSwapChain->getDepthFormat();
|
||||
} else {
|
||||
// Resolve views for custom render target
|
||||
const auto& colorInfos = renderTarget->getColorAttachmentInfos();
|
||||
@@ -879,7 +877,6 @@ void WebGPUDriver::beginRenderPass(Handle<HwRenderTarget> renderTargetHandle,
|
||||
params,
|
||||
defaultColorView,
|
||||
defaultDepthStencilView,
|
||||
defaultDepthStencilFormat,
|
||||
customColorViews.data(),
|
||||
customColorViewCount,
|
||||
customDepthView,
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <webgpu/webgpu_cpp.h>
|
||||
#include <dawn/webgpu_cpp_print.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
@@ -188,7 +187,7 @@ namespace {
|
||||
switch (status) {
|
||||
case wgpu::CompilationInfoRequestStatus::CallbackCancelled:
|
||||
FWGPU_LOGW << "Shader compilation info callback cancelled for "
|
||||
<< descriptor.label << "?";
|
||||
<< descriptor.label << "?" << utils::io::endl;
|
||||
return;
|
||||
case wgpu::CompilationInfoRequestStatus::Success:
|
||||
break;
|
||||
@@ -204,7 +203,8 @@ namespace {
|
||||
<< " line#:" << message.lineNum
|
||||
<< " linePos:" << message.linePos
|
||||
<< " offset:" << message.offset
|
||||
<< " length:" << message.length;
|
||||
<< " length:" << message.length
|
||||
<< utils::io::endl;
|
||||
break;
|
||||
case wgpu::CompilationMessageType::Warning:
|
||||
FWGPU_LOGW
|
||||
@@ -212,7 +212,7 @@ namespace {
|
||||
<< message.message << " line#:" << message.lineNum
|
||||
<< " linePos:" << message.linePos
|
||||
<< " offset:" << message.offset
|
||||
<< " length:" << message.length;
|
||||
<< " length:" << message.length << utils::io::endl;
|
||||
break;
|
||||
case wgpu::CompilationMessageType::Error:
|
||||
errorCount++;
|
||||
@@ -231,7 +231,8 @@ namespace {
|
||||
<< errorStream.str();
|
||||
}
|
||||
#if FWGPU_ENABLED(FWGPU_DEBUG_VALIDATION)
|
||||
FWGPU_LOGD << descriptor.label << " compiled successfully";
|
||||
FWGPU_LOGD << descriptor.label << " compiled successfully"
|
||||
<< utils::io::endl;
|
||||
#endif
|
||||
}),
|
||||
SHADER_COMPILATION_TIMEOUT_NANOSECONDS);
|
||||
|
||||
@@ -73,7 +73,6 @@ wgpu::StoreOp WebGPURenderTarget::getStoreOperation(RenderPassParams const& para
|
||||
void WebGPURenderTarget::setUpRenderPassAttachments(wgpu::RenderPassDescriptor& outDescriptor,
|
||||
RenderPassParams const& params, wgpu::TextureView const& defaultColorTextureView,
|
||||
wgpu::TextureView const& defaultDepthStencilTextureView,
|
||||
wgpu::TextureFormat const& defaultDepthStencilFormat,
|
||||
wgpu::TextureView const* customColorTextureViews, uint32_t customColorTextureViewCount,
|
||||
wgpu::TextureView const& customDepthTextureView,
|
||||
wgpu::TextureView const& customStencilTextureView,
|
||||
@@ -94,39 +93,30 @@ void WebGPURenderTarget::setUpRenderPassAttachments(wgpu::RenderPassDescriptor&
|
||||
if (defaultDepthStencilTextureView) {
|
||||
mDepthStencilAttachmentDescriptor = {
|
||||
.view = defaultDepthStencilTextureView,
|
||||
.depthLoadOp =
|
||||
WebGPURenderTarget::getLoadOperation(params, TargetBufferFlags::DEPTH),
|
||||
.depthLoadOp = WebGPURenderTarget::getLoadOperation(params, TargetBufferFlags::DEPTH),
|
||||
.depthStoreOp =
|
||||
WebGPURenderTarget::getStoreOperation(params, TargetBufferFlags::DEPTH),
|
||||
.depthClearValue = static_cast<float>(params.clearDepth),
|
||||
.depthReadOnly =
|
||||
(params.readOnlyDepthStencil & RenderPassParams::READONLY_DEPTH) > 0,
|
||||
.stencilLoadOp = wgpu::LoadOp::Undefined,
|
||||
.stencilStoreOp = wgpu::StoreOp::Undefined,
|
||||
.stencilLoadOp =
|
||||
WebGPURenderTarget::getLoadOperation(params, TargetBufferFlags::STENCIL),
|
||||
.stencilStoreOp =
|
||||
WebGPURenderTarget::getStoreOperation(params, TargetBufferFlags::STENCIL),
|
||||
.stencilClearValue = params.clearStencil,
|
||||
.stencilReadOnly =
|
||||
(params.readOnlyDepthStencil & RenderPassParams::READONLY_STENCIL) > 0,
|
||||
};
|
||||
|
||||
if (defaultDepthStencilFormat == wgpu::TextureFormat::Depth24PlusStencil8 ||
|
||||
defaultDepthStencilFormat == wgpu::TextureFormat::Depth32FloatStencil8 ||
|
||||
defaultDepthStencilFormat == wgpu::TextureFormat::Stencil8) {
|
||||
mDepthStencilAttachmentDescriptor.stencilLoadOp =
|
||||
WebGPURenderTarget::getLoadOperation(params, TargetBufferFlags::STENCIL);
|
||||
mDepthStencilAttachmentDescriptor.stencilStoreOp =
|
||||
WebGPURenderTarget::getStoreOperation(params, TargetBufferFlags::STENCIL);
|
||||
}
|
||||
mHasDepthStencilAttachment = true;
|
||||
}
|
||||
} else { // Custom Render Target
|
||||
} else {// Custom Render Target
|
||||
for (uint32_t i = 0; i < customColorTextureViewCount; ++i) {
|
||||
if (customColorTextureViews[i]) {
|
||||
mColorAttachmentDescriptors.push_back({ .view = customColorTextureViews[i],
|
||||
// .resolveTarget = nullptr; // TODO: MSAA resolve for custom RT
|
||||
.loadOp =
|
||||
WebGPURenderTarget::getLoadOperation(params, getTargetBufferFlagsAt(i)),
|
||||
.storeOp = WebGPURenderTarget::getStoreOperation(params,
|
||||
getTargetBufferFlagsAt(i)),
|
||||
.loadOp = WebGPURenderTarget::getLoadOperation(params, getTargetBufferFlagsAt(i)),
|
||||
.storeOp =
|
||||
WebGPURenderTarget::getStoreOperation(params, getTargetBufferFlagsAt(i)),
|
||||
.clearValue = { .r = params.clearColor.r,
|
||||
.g = params.clearColor.g,
|
||||
.b = params.clearColor.b,
|
||||
|
||||
@@ -46,7 +46,6 @@ public:
|
||||
// For default render target:
|
||||
wgpu::TextureView const& defaultColorTextureView,
|
||||
wgpu::TextureView const& defaultDepthStencilTextureView,
|
||||
wgpu::TextureFormat const& defaultDepthStencilFormat,
|
||||
// For custom render targets:
|
||||
wgpu::TextureView const* customColorTextureViews, // Array of views
|
||||
uint32_t customColorTextureViewCount,
|
||||
|
||||
@@ -54,50 +54,52 @@ utils::io::ostream& operator<<(utils::io::ostream& out,
|
||||
}
|
||||
|
||||
void printSurfaceCapabilitiesDetails(wgpu::SurfaceCapabilities const& capabilities) {
|
||||
FWGPU_LOGI << "WebGPU surface capabilities:";
|
||||
FWGPU_LOGI << " surface usages: " << capabilities.usages;
|
||||
FWGPU_LOGI << " surface formats (" << capabilities.formatCount << "):";
|
||||
FWGPU_LOGI << "WebGPU surface capabilities:" << utils::io::endl;
|
||||
FWGPU_LOGI << " surface usages: " << capabilities.usages << utils::io::endl;
|
||||
FWGPU_LOGI << " surface formats (" << capabilities.formatCount << "):" << utils::io::endl;
|
||||
if (capabilities.formatCount > 0 && capabilities.formats != nullptr) {
|
||||
std::for_each(capabilities.formats, capabilities.formats + capabilities.formatCount,
|
||||
[](wgpu::TextureFormat const format) {
|
||||
FWGPU_LOGI << " " << format;
|
||||
FWGPU_LOGI << " " << format << utils::io::endl;
|
||||
});
|
||||
}
|
||||
FWGPU_LOGI << " surface present modes (" << capabilities.presentModeCount << "):";
|
||||
FWGPU_LOGI << " surface present modes (" << capabilities.presentModeCount
|
||||
<< "):" << utils::io::endl;
|
||||
if (capabilities.presentModeCount > 0 && capabilities.presentModes != nullptr) {
|
||||
std::for_each(capabilities.presentModes,
|
||||
capabilities.presentModes + capabilities.presentModeCount,
|
||||
[](wgpu::PresentMode const presentMode) {
|
||||
FWGPU_LOGI << " " << presentMode;
|
||||
FWGPU_LOGI << " " << presentMode << utils::io::endl;
|
||||
});
|
||||
}
|
||||
FWGPU_LOGI << " surface alpha modes (" << capabilities.alphaModeCount << "):";
|
||||
FWGPU_LOGI << " surface alpha modes (" << capabilities.alphaModeCount
|
||||
<< "):" << utils::io::endl;
|
||||
if (capabilities.alphaModeCount > 0 && capabilities.alphaModes != nullptr) {
|
||||
std::for_each(capabilities.alphaModes,
|
||||
capabilities.alphaModes + capabilities.alphaModeCount,
|
||||
[](wgpu::CompositeAlphaMode const alphaMode) {
|
||||
FWGPU_LOGI << " " << alphaMode;
|
||||
FWGPU_LOGI << " " << alphaMode << utils::io::endl;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void printSurfaceConfiguration(wgpu::SurfaceConfiguration const& config,
|
||||
wgpu::TextureFormat depthFormat) {
|
||||
FWGPU_LOGI << "WebGPU surface configuration:";
|
||||
FWGPU_LOGI << " surface format: " << config.format;
|
||||
FWGPU_LOGI << " surface usage: " << config.usage;
|
||||
FWGPU_LOGI << " surface view formats (" << config.viewFormatCount << "):";
|
||||
FWGPU_LOGI << "WebGPU surface configuration:" << utils::io::endl;
|
||||
FWGPU_LOGI << " surface format: " << config.format << utils::io::endl;
|
||||
FWGPU_LOGI << " surface usage: " << config.usage << utils::io::endl;
|
||||
FWGPU_LOGI << " surface view formats (" << config.viewFormatCount << "):" << utils::io::endl;
|
||||
if (config.viewFormatCount > 0 && config.viewFormats != nullptr) {
|
||||
std::for_each(config.viewFormats, config.viewFormats + config.viewFormatCount,
|
||||
[](wgpu::TextureFormat const viewFormat) {
|
||||
FWGPU_LOGI << " " << viewFormat;
|
||||
FWGPU_LOGI << " " << viewFormat << utils::io::endl;
|
||||
});
|
||||
}
|
||||
FWGPU_LOGI << " surface alpha mode: " << config.alphaMode;
|
||||
FWGPU_LOGI << " surface width: " << config.width;
|
||||
FWGPU_LOGI << " surface height: " << config.height;
|
||||
FWGPU_LOGI << " surface present mode: " << config.presentMode;
|
||||
FWGPU_LOGI << "WebGPU selected depth format: " << depthFormat;
|
||||
FWGPU_LOGI << " surface alpha mode: " << config.alphaMode << utils::io::endl;
|
||||
FWGPU_LOGI << " surface width: " << config.width << utils::io::endl;
|
||||
FWGPU_LOGI << " surface height: " << config.height << utils::io::endl;
|
||||
FWGPU_LOGI << " surface present mode: " << config.presentMode << utils::io::endl;
|
||||
FWGPU_LOGI << "WebGPU selected depth format: " << depthFormat << utils::io::endl;
|
||||
}
|
||||
#endif// FWGPU_ENABLED(FWGPU_PRINT_SYSTEM)
|
||||
|
||||
@@ -187,7 +189,8 @@ void printSurfaceConfiguration(wgpu::SurfaceConfiguration const& config,
|
||||
// We prefer premultiplied to unpremuliplied until that assumption should be adjusted.
|
||||
FWGPU_LOGW << "Auto, Inherit, & Opaque composite alpha modes not supported. Filament has "
|
||||
"historically used these. Premultiplied alpha composite mode for "
|
||||
"transparency is being selected as a fallback, but may not work as expected.";
|
||||
"transparency is being selected as a fallback, but may not work as expected."
|
||||
<< utils::io::endl;
|
||||
return wgpu::CompositeAlphaMode::Premultiplied;
|
||||
} else {
|
||||
FILAMENT_CHECK_POSTCONDITION(unpremultipliedAvailable)
|
||||
@@ -197,7 +200,8 @@ void printSurfaceConfiguration(wgpu::SurfaceConfiguration const& config,
|
||||
FWGPU_LOGW << "Auto, Inherit, & Opaque composite alpha modes not supported. Filament has "
|
||||
"historically used these. Unpremultiplied alpha composite mode for "
|
||||
"transparency is being selected as a fallback "
|
||||
"(premulitipled is not available either), but may not work as expected.";
|
||||
"(premulitipled is not available either), but may not work as expected."
|
||||
<< utils::io::endl;
|
||||
return wgpu::CompositeAlphaMode::Unpremultiplied;
|
||||
}
|
||||
}
|
||||
@@ -270,7 +274,7 @@ WebGPUSwapChain::WebGPUSwapChain(wgpu::Surface&& surface, wgpu::Extent2D const&
|
||||
mDepthTextureView(createDepthTextureView(mDepthTexture, mDepthFormat, mNeedStencil)) {
|
||||
wgpu::SurfaceCapabilities capabilities = {};
|
||||
if (!mSurface.GetCapabilities(adapter, &capabilities)) {
|
||||
FWGPU_LOGW << "Failed to get WebGPU surface capabilities";
|
||||
FWGPU_LOGW << "Failed to get WebGPU surface capabilities" << utils::io::endl;
|
||||
} else {
|
||||
#if FWGPU_ENABLED(FWGPU_PRINT_SYSTEM)
|
||||
printSurfaceCapabilitiesDetails(capabilities);
|
||||
@@ -293,7 +297,8 @@ void WebGPUSwapChain::setExtent(wgpu::Extent2D const& currentSurfaceSize) {
|
||||
if (mConfig.width != currentSurfaceSize.width || mConfig.height != currentSurfaceSize.height) {
|
||||
mConfig.width = currentSurfaceSize.width;
|
||||
mConfig.height = currentSurfaceSize.height;
|
||||
FWGPU_LOGD << "Resizing to width " << mConfig.width << " height " << mConfig.height;
|
||||
FWGPU_LOGD << "Resizing to width " << mConfig.width << " height " << mConfig.height
|
||||
<< utils::io::endl;
|
||||
#if FWGPU_ENABLED(FWGPU_PRINT_SYSTEM)
|
||||
printSurfaceConfiguration(mConfig, mDepthFormat);
|
||||
#endif
|
||||
|
||||
@@ -249,17 +249,18 @@ void assertLimitsAreExpressedInRequirementsStruct() {
|
||||
void printInstanceDetails(wgpu::Instance const& instance) {
|
||||
wgpu::SupportedWGSLLanguageFeatures supportedWGSLLanguageFeatures{};
|
||||
if (!instance.GetWGSLLanguageFeatures(&supportedWGSLLanguageFeatures)) {
|
||||
FWGPU_LOGW << "Failed to get WebGPU instance supported WGSL language features";
|
||||
FWGPU_LOGW << "Failed to get WebGPU instance supported WGSL language features"
|
||||
<< utils::io::endl;
|
||||
} else {
|
||||
FWGPU_LOGI << "WebGPU instance supported WGSL language features ("
|
||||
<< supportedWGSLLanguageFeatures.featureCount << "):";
|
||||
<< supportedWGSLLanguageFeatures.featureCount << "):" << utils::io::endl;
|
||||
if (supportedWGSLLanguageFeatures.featureCount > 0 &&
|
||||
supportedWGSLLanguageFeatures.features != nullptr) {
|
||||
std::for_each(supportedWGSLLanguageFeatures.features,
|
||||
supportedWGSLLanguageFeatures.features +
|
||||
supportedWGSLLanguageFeatures.featureCount,
|
||||
[](wgpu::WGSLLanguageFeatureName const featureName) {
|
||||
FWGPU_LOGI << " " << featureName;
|
||||
FWGPU_LOGI << " " << featureName << utils::io::endl;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -271,7 +272,7 @@ void printInstanceDetails(wgpu::Instance const& instance) {
|
||||
wgpu::DawnTogglesDescriptor dawnTogglesDescriptor{};
|
||||
#if defined(FILAMENT_WEBGPU_IMMEDIATE_ERROR_HANDLING)
|
||||
#if FWGPU_ENABLED(FWGPU_PRINT_SYSTEM)
|
||||
FWGPU_LOGI << "setting on toggle enable_immediate_error_handling";
|
||||
FWGPU_LOGI << "setting on toggle enable_immediate_error_handling" << utils::io::endl;
|
||||
#endif
|
||||
/**
|
||||
* Have the un-captured error callback invoked immediately when an error occurs, rather than
|
||||
@@ -315,7 +316,7 @@ void printLimit(std::string_view name, const std::variant<uint32_t, uint64_t> va
|
||||
if (undefined) {
|
||||
FWGPU_LOGI << "UNDEFINED";
|
||||
}
|
||||
FWGPU_LOGI << "";
|
||||
FWGPU_LOGI << utils::io::endl;
|
||||
}
|
||||
#endif// FWGPU_ENABLED(FWGPU_PRINT_SYSTEM)
|
||||
|
||||
@@ -402,23 +403,23 @@ STREAM_TYPE& operator<<(STREAM_TYPE& out, AdapterDetails const& details) noexcep
|
||||
|
||||
#if FWGPU_ENABLED(FWGPU_PRINT_SYSTEM)
|
||||
void printAdapterDetails(AdapterDetails const& details) {
|
||||
FWGPU_LOGI << "Selected WebGPU adapter info: " << details;
|
||||
FWGPU_LOGI << "Selected WebGPU adapter info: " << details << utils::io::endl;
|
||||
wgpu::SupportedFeatures supportedFeatures{};
|
||||
details.adapter.GetFeatures(&supportedFeatures);
|
||||
FWGPU_LOGI << "WebGPU adapter supported features (" << supportedFeatures.featureCount
|
||||
<< "):";
|
||||
<< "):" << utils::io::endl;
|
||||
if (supportedFeatures.featureCount > 0 && supportedFeatures.features != nullptr) {
|
||||
std::for_each(supportedFeatures.features,
|
||||
supportedFeatures.features + supportedFeatures.featureCount,
|
||||
[](wgpu::FeatureName const featureName) {
|
||||
FWGPU_LOGI << " " << featureName;
|
||||
FWGPU_LOGI << " " << featureName << utils::io::endl;
|
||||
});
|
||||
}
|
||||
wgpu::Limits supportedLimits{};
|
||||
if (!details.adapter.GetLimits(&supportedLimits)) {
|
||||
FWGPU_LOGW << "Failed to get WebGPU adapter supported limits";
|
||||
FWGPU_LOGW << "Failed to get WebGPU adapter supported limits" << utils::io::endl;
|
||||
} else {
|
||||
FWGPU_LOGI << "WebGPU adapter supported limits:";
|
||||
FWGPU_LOGI << "WebGPU adapter supported limits:" << utils::io::endl;
|
||||
printLimits(supportedLimits);
|
||||
}
|
||||
}
|
||||
@@ -445,14 +446,14 @@ struct AdapterDetailsHash final {
|
||||
})) {
|
||||
#if FWGPU_ENABLED(FWGPU_PRINT_SYSTEM)
|
||||
FWGPU_LOGI << "WebGPU adapter " << details
|
||||
<< " does not have the minimum required features.";
|
||||
FWGPU_LOGI << "Missing required feature(s): ";
|
||||
<< " does not have the minimum required features." << utils::io::endl;
|
||||
FWGPU_LOGI << " Missing required feature(s): ";
|
||||
for (wgpu::FeatureName const& requiredFeature: REQUIRED_FEATURES) {
|
||||
if (!details.adapter.HasFeature(requiredFeature)) {
|
||||
FWGPU_LOGI << requiredFeature;
|
||||
FWGPU_LOGI << requiredFeature << " ";
|
||||
}
|
||||
}
|
||||
FWGPU_LOGI << "";
|
||||
FWGPU_LOGI << utils::io::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@@ -461,7 +462,7 @@ struct AdapterDetailsHash final {
|
||||
<< "Failed to get limits for WebGPU adapter: " << details;
|
||||
if (!satisfiesLimits(supportedLimits)) {
|
||||
#if FWGPU_ENABLED(FWGPU_PRINT_SYSTEM)
|
||||
FWGPU_LOGI << " (for WebGPU adapter " << details << ")";
|
||||
FWGPU_LOGI << " (for WebGPU adapter " << details << ")" << utils::io::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@@ -517,9 +518,9 @@ struct AdapterDetailsHash final {
|
||||
}
|
||||
FILAMENT_CHECK_POSTCONDITION(!compatibleAdapters.empty()) << "No WebGPU adapters found!";
|
||||
#if FWGPU_ENABLED(FWGPU_PRINT_SYSTEM)
|
||||
FWGPU_LOGI << compatibleAdapters.size() << " WebGPU adapter(s) found:";
|
||||
FWGPU_LOGI << compatibleAdapters.size() << " WebGPU adapter(s) found:" << utils::io::endl;
|
||||
for (auto& details: compatibleAdapters) {
|
||||
FWGPU_LOGI << " WebGPU adapter: " << details;
|
||||
FWGPU_LOGI << " WebGPU adapter: " << details << utils::io::endl;
|
||||
}
|
||||
#endif
|
||||
return compatibleAdapters;
|
||||
@@ -581,19 +582,19 @@ void printDeviceDetails(wgpu::Device const& device) {
|
||||
wgpu::SupportedFeatures supportedFeatures{};
|
||||
device.GetFeatures(&supportedFeatures);
|
||||
FWGPU_LOGI << "WebGPU device supported features (" << supportedFeatures.featureCount
|
||||
<< "):";
|
||||
<< "):" << utils::io::endl;
|
||||
if (supportedFeatures.featureCount > 0 && supportedFeatures.features != nullptr) {
|
||||
std::for_each(supportedFeatures.features,
|
||||
supportedFeatures.features + supportedFeatures.featureCount,
|
||||
[](wgpu::FeatureName const featureName) {
|
||||
FWGPU_LOGI << " " << featureName;
|
||||
FWGPU_LOGI << " " << featureName << utils::io::endl;
|
||||
});
|
||||
}
|
||||
wgpu::Limits supportedLimits{};
|
||||
if (!device.GetLimits(&supportedLimits)) {
|
||||
FWGPU_LOGW << "Failed to get WebGPU supported device limits";
|
||||
FWGPU_LOGW << "Failed to get WebGPU supported device limits" << utils::io::endl;
|
||||
} else {
|
||||
FWGPU_LOGI << "WebGPU device supported limits:";
|
||||
FWGPU_LOGI << "WebGPU device supported limits:" << utils::io::endl;
|
||||
printLimits(supportedLimits);
|
||||
}
|
||||
}
|
||||
@@ -634,7 +635,8 @@ wgpu::Device WebGPUPlatform::requestDevice(wgpu::Adapter const& adapter) {
|
||||
wgpu::StringView message) {
|
||||
if (reason == wgpu::DeviceLostReason::Destroyed) {
|
||||
#if FWGPU_ENABLED(FWGPU_DEBUG_VALIDATION)
|
||||
FWGPU_LOGD << "WebGPU device lost due to being destroyed (expected)";
|
||||
FWGPU_LOGD << "WebGPU device lost due to being destroyed (expected)"
|
||||
<< utils::io::endl;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
@@ -646,7 +648,7 @@ wgpu::Device WebGPUPlatform::requestDevice(wgpu::Adapter const& adapter) {
|
||||
deviceDescriptor.SetUncapturedErrorCallback(
|
||||
[](wgpu::Device const&, wgpu::ErrorType errorType, wgpu::StringView message) {
|
||||
FWGPU_LOGE << "WebGPU device error: " << errorTypeToString(errorType) << " "
|
||||
<< message.data;
|
||||
<< message.data << utils::io::endl;
|
||||
});
|
||||
wgpu::Device device = nullptr;
|
||||
wgpu::WaitStatus status = mInstance.WaitAny(
|
||||
@@ -699,7 +701,8 @@ Driver* WebGPUPlatform::createDriver(void* sharedContext,
|
||||
const Platform::DriverConfig& driverConfig) noexcept {
|
||||
if (sharedContext) {
|
||||
FWGPU_LOGW << "sharedContext is ignored/unused in the WebGPU backend. A non-null "
|
||||
"sharedContext was provided, but it will be ignored.";
|
||||
"sharedContext was provided, but it will be ignored."
|
||||
<< utils::io::endl;
|
||||
}
|
||||
return WebGPUDriver::create(*this, driverConfig);
|
||||
}
|
||||
|
||||
@@ -84,8 +84,6 @@ std::string ScreenshotParams::expectedFilePath() const {
|
||||
}
|
||||
|
||||
const std::string ScreenshotParams::filePrefix() const {
|
||||
// TODO(b/422804941): If there are platform specific goldens, when on those platforms append a
|
||||
// unique platform identifying string to this.
|
||||
return mFileName;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ namespace test {
|
||||
*/
|
||||
class ScreenshotParams {
|
||||
public:
|
||||
// TODO(b/422804941): Add a set of environments where this test should use a different golden.
|
||||
ScreenshotParams(int width, int height, std::string fileName, uint32_t expectedPixelHash,
|
||||
bool isSrgb = false);
|
||||
|
||||
|
||||
@@ -41,8 +41,6 @@ Shader::Shader(DriverApi& api, Cleanup& cleanup, ShaderConfig config) : mCleanup
|
||||
descriptors[kDescriptorSetIndex][i] = {
|
||||
config.uniforms[i].name, kLayouts[i], config.uniforms[i].samplerInfo };
|
||||
}
|
||||
// TODO(b/422803382): When the shader language isn't GLSL dont' use the ShaderGenerator to
|
||||
// compile the shader.
|
||||
ShaderGenerator shaderGen(
|
||||
std::move(config.vertexShader), std::move(config.fragmentShader), BackendTest::sBackend,
|
||||
BackendTest::sIsMobilePlatform, std::move(descriptors));
|
||||
|
||||
@@ -31,9 +31,7 @@ struct UniformConfig {
|
||||
|
||||
// All describing a shader that should be created.
|
||||
struct ShaderConfig {
|
||||
filament::backend::ShaderLanguage vertexLanguage;
|
||||
std::string vertexShader;
|
||||
filament::backend::ShaderLanguage fragmentLanguage;
|
||||
std::string fragmentShader;
|
||||
std::vector<UniformConfig> uniforms;
|
||||
};
|
||||
|
||||
@@ -215,20 +215,18 @@ Shader SharedShaders::makeShader(filament::backend::DriverApi& api, Cleanup& cle
|
||||
std::optional<ShaderText> fragment;
|
||||
std::optional<std::string> uniform;
|
||||
if (getShaderLanguage(BackendTest::sBackend) != ShaderLanguage::GLSL) {
|
||||
// TODO(b/422803382): If any shaders need backend/shader language specific shaders rather
|
||||
// than transpiled versions of the GLSL shader, check here and create a shader with that
|
||||
// config instead
|
||||
// TODO: If any shaders need backend/shader language specific shaders rather than transpiled
|
||||
// versions of the GLSL shader, check environment.
|
||||
}
|
||||
vertex = GetGlslVertexShader(request.mVertexType);
|
||||
fragment = GetGlslFragmentShader(request.mFragmentType);
|
||||
uniform = GetGlslUniform(request.mUniformType);
|
||||
if (vertex.has_value() && fragment.has_value() && uniform.has_value()) {
|
||||
return Shader(api, cleanup,
|
||||
ShaderConfig{ .vertexLanguage = filament::backend::ShaderLanguage::ESSL3,
|
||||
.vertexShader = vertex->withUniform(*uniform),
|
||||
.fragmentLanguage = filament::backend::ShaderLanguage::ESSL3,
|
||||
.fragmentShader = fragment->withUniform(*uniform),
|
||||
.uniforms = GetUniformConfig(request.mUniformType) });
|
||||
return Shader(
|
||||
api, cleanup, ShaderConfig{
|
||||
vertex->withUniform(*uniform), fragment->withUniform(*uniform),
|
||||
GetUniformConfig(request.mUniformType)}
|
||||
);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <utils/Hash.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
@@ -137,7 +137,8 @@ TEST_F(BackendTest, FeedbackLoops) {
|
||||
// Create a RenderTarget for each miplevel.
|
||||
Handle<HwRenderTarget> renderTargets[kNumLevels];
|
||||
for (uint8_t level = 0; level < kNumLevels; level++) {
|
||||
LOG(INFO) << "Level " << int(level) << ": " << (kTexWidth >> level) << "x" << (kTexHeight >> level);
|
||||
slog.i << "Level " << int(level) << ": " <<
|
||||
(kTexWidth >> level) << "x" << (kTexHeight >> level) << io::endl;
|
||||
renderTargets[level] = cleanup.add(api.createRenderTarget( TargetBufferFlags::COLOR,
|
||||
kTexWidth >> level, kTexHeight >> level, 1, 0, { texture, level, 0 }, {}, {}));
|
||||
}
|
||||
|
||||
@@ -317,15 +317,6 @@ public:
|
||||
*/
|
||||
size_t metalUploadBufferSizeBytes = 512 * 1024;
|
||||
|
||||
/**
|
||||
* The action to take if a Drawable cannot be acquired.
|
||||
*
|
||||
* Each frame rendered requires a CAMetalDrawable texture, which is
|
||||
* presented on-screen at the completion of each frame. These are
|
||||
* limited and provided round-robin style by the system.
|
||||
*/
|
||||
bool metalDisablePanicOnDrawableFailure = false;
|
||||
|
||||
/**
|
||||
* Set to `true` to forcibly disable parallel shader compilation in the backend.
|
||||
* Currently only honored by the GL and Metal backends.
|
||||
|
||||
@@ -86,6 +86,9 @@ public:
|
||||
std::is_same_v<math::mat3f, T>
|
||||
>;
|
||||
|
||||
template<typename T>
|
||||
using is_supported_constant_parameter_t = std::enable_if_t<std::is_same_v<bool, T>>;
|
||||
|
||||
/**
|
||||
* Creates a new MaterialInstance using another MaterialInstance as a template for initialization.
|
||||
* The new MaterialInstance is an instance of the same Material of the template instance and
|
||||
@@ -237,13 +240,13 @@ public:
|
||||
|
||||
/**
|
||||
* Gets the value of a parameter by name.
|
||||
*
|
||||
*
|
||||
* Note: Only supports non-texture parameters such as numeric and math types.
|
||||
*
|
||||
*
|
||||
* @param name Name of the parameter as defined by Material. Cannot be nullptr.
|
||||
* @param nameLength Length in `char` of the name parameter.
|
||||
* @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled.
|
||||
*
|
||||
*
|
||||
* @see Material::hasParameter
|
||||
*/
|
||||
template<typename T>
|
||||
@@ -261,6 +264,53 @@ public:
|
||||
return getParameter<T>(name, strlen(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a mutable constant parameter by name.
|
||||
*
|
||||
* @param name Name of the parameter as defined by Material. Cannot be nullptr.
|
||||
* @param nameLength Length in `char` of the name parameter.
|
||||
* @param value Value of the parameter to set.
|
||||
* @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled.
|
||||
*/
|
||||
template<typename T, typename = is_supported_constant_parameter_t<T>>
|
||||
void setConstant(const char* UTILS_NONNULL name, size_t nameLength, T const& value);
|
||||
|
||||
/** inline helper to provide the name as a null-terminated string literal */
|
||||
template<typename T, typename = is_supported_constant_parameter_t<T>>
|
||||
void setConstant(StringLiteral const name, T const& value) {
|
||||
setConstant<T>(name.data, name.size, value);
|
||||
}
|
||||
|
||||
/** inline helper to provide the name as a null-terminated C string */
|
||||
template<typename T, typename = is_supported_constant_parameter_t<T>>
|
||||
void setConstant(const char* UTILS_NONNULL name, T const& value) {
|
||||
setConstant<T>(name, strlen(name), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the value of a mutable constant parameter by name.
|
||||
*
|
||||
* @param name Name of the parameter as defined by Material. Cannot be nullptr.
|
||||
* @param nameLength Length in `char` of the name parameter.
|
||||
* @throws utils::PreConditionPanic if name doesn't exist or no-op if exceptions are disabled.
|
||||
*
|
||||
* @see Material::hasConstant
|
||||
*/
|
||||
template<typename T, typename = is_supported_constant_parameter_t<T>>
|
||||
T getConstant(const char* UTILS_NONNULL name, size_t nameLength) const;
|
||||
|
||||
/** inline helper to provide the name as a null-terminated C string */
|
||||
template<typename T, typename = is_supported_constant_parameter_t<T>>
|
||||
T getConstant(StringLiteral const name) const {
|
||||
return getConstant<T>(name.data, name.size);
|
||||
}
|
||||
|
||||
/** inline helper to provide the name as a null-terminated C string */
|
||||
template<typename T, typename = is_supported_constant_parameter_t<T>>
|
||||
T getConstant(const char* UTILS_NONNULL name) const {
|
||||
return getConstant<T>(name, strlen(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set-up a custom scissor rectangle; by default it is disabled.
|
||||
*
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -112,11 +112,13 @@ void FrameInfoManager::beginFrame(DriverApi& driver, Config const& config, uint3
|
||||
using namespace utils;
|
||||
auto h = getFrameInfoHistory(1);
|
||||
if (!h.empty()) {
|
||||
DLOG(INFO) << frameId << ": " << h[0].frameId << " (" << frameId - h[0].frameId << ")"
|
||||
<< ", Dm=" << h[0].endFrame - h[0].beginFrame
|
||||
<< ", L =" << h[0].backendBeginFrame - h[0].beginFrame
|
||||
<< ", Db=" << h[0].backendEndFrame - h[0].backendBeginFrame
|
||||
<< ", T =" << h[0].frameTime;
|
||||
slog.d << frameId << ": "
|
||||
<< h[0].frameId << " (" << frameId - h[0].frameId << ")"
|
||||
<< ", Dm=" << h[0].endFrame - h[0].beginFrame
|
||||
<< ", L =" << h[0].backendBeginFrame - h[0].beginFrame
|
||||
<< ", Db=" << h[0].backendEndFrame - h[0].backendBeginFrame
|
||||
<< ", T =" << h[0].frameTime
|
||||
<< io::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#include <utils/BinaryTreeArray.h>
|
||||
#include <utils/JobSystem.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Slice.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
@@ -366,12 +366,14 @@ bool Froxelizer::update() noexcept {
|
||||
|
||||
uniformsNeedUpdating = true;
|
||||
|
||||
DLOG(INFO) << "Froxel: " << viewport.width << "x" << viewport.height << " / "
|
||||
<< froxelDimension.x << "x" << froxelDimension.y << io::endl
|
||||
<< "Froxel: " << froxelCountX << "x" << froxelCountY << "x" << froxelCountZ
|
||||
<< " = " << (froxelCountX * froxelCountY * froxelCountZ) << " ("
|
||||
<< getFroxelBufferEntryCount() - froxelCountX * froxelCountY * froxelCountZ
|
||||
<< " lost)";
|
||||
#ifndef NDEBUG
|
||||
slog.d << "Froxel: " << viewport.width << "x" << viewport.height << " / "
|
||||
<< froxelDimension.x << "x" << froxelDimension.y << io::endl
|
||||
<< "Froxel: " << froxelCountX << "x" << froxelCountY << "x" << froxelCountZ
|
||||
<< " = " << (froxelCountX * froxelCountY * froxelCountZ)
|
||||
<< " (" << getFroxelBufferEntryCount() - froxelCountX * froxelCountY * froxelCountZ << " lost)"
|
||||
<< io::endl;
|
||||
#endif
|
||||
|
||||
mFroxelCountX = froxelCountX;
|
||||
mFroxelCountY = froxelCountY;
|
||||
@@ -710,7 +712,9 @@ void Froxelizer::froxelizeAssignRecordsCompress() noexcept {
|
||||
const size_t lightCount = entry.count();
|
||||
|
||||
if (UTILS_UNLIKELY(offset + lightCount >= RECORD_BUFFER_ENTRY_COUNT)) {
|
||||
DLOG(INFO) << "out of space: " << i << ", at " << offset;
|
||||
#ifndef NDEBUG
|
||||
slog.d << "out of space: " << i << ", at " << offset << io::endl;
|
||||
#endif
|
||||
// note: instead of dropping froxels we could look for similar records we've already
|
||||
// filed up.
|
||||
do {
|
||||
|
||||
@@ -232,6 +232,46 @@ template UTILS_PUBLIC mat3f MaterialInstance::getParameter<mat3f> (const ch
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
template<>
|
||||
inline void FMaterialInstance::setConstantImpl<bool>(std::string_view const name, bool const& value) {
|
||||
std::optional<uint32_t> id = mMaterial->getMutableConstantId(name);
|
||||
FILAMENT_CHECK_PRECONDITION(id.has_value()) << "No mutable constant with name " << name;
|
||||
mConstants.set(*id, value);
|
||||
}
|
||||
|
||||
template<typename T, typename>
|
||||
void MaterialInstance::setConstant(const char* name, size_t nameLength, T const& value) {
|
||||
downcast(this)->setConstantImpl({ name, nameLength }, value);
|
||||
}
|
||||
|
||||
// Explicit template instantiation of our supported types.
|
||||
//
|
||||
// Mutable spec constants will probably only ever allow bools, but it's nice to keep the API
|
||||
// forwards-compatible.
|
||||
template UTILS_PUBLIC void MaterialInstance::setConstant<bool>(const char* name, size_t nameLength, bool const& v);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
template<>
|
||||
inline bool FMaterialInstance::getConstantImpl<bool>(std::string_view const name) const {
|
||||
std::optional<uint32_t> id = mMaterial->getMutableConstantId(name);
|
||||
FILAMENT_CHECK_PRECONDITION(id.has_value()) << "No mutable constant with name " << name;
|
||||
return mConstants[*id];
|
||||
}
|
||||
|
||||
template<typename T, typename>
|
||||
T MaterialInstance::getConstant(const char* name, size_t nameLength) const {
|
||||
return downcast(this)->getConstantImpl<T>({ name, nameLength });
|
||||
}
|
||||
|
||||
// Explicit template instantiation of our supported types.
|
||||
//
|
||||
// Mutable spec constants will probably only ever allow bools, but it's nice to keep the API
|
||||
// forwards-compatible.
|
||||
template UTILS_PUBLIC bool MaterialInstance::getConstant<bool>(const char* name, size_t nameLength) const;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
Material const* MaterialInstance::getMaterial() const noexcept {
|
||||
return downcast(this)->getMaterial();
|
||||
}
|
||||
|
||||
@@ -229,6 +229,11 @@ bool MaterialParser::getConstants(FixedCapacityVector<MaterialConstant>* contain
|
||||
return get<ChunkMaterialConstants>(container);
|
||||
}
|
||||
|
||||
bool MaterialParser::getMutableConstants(
|
||||
FixedCapacityVector<MaterialMutableConstant>* container) const noexcept {
|
||||
return get<ChunkMaterialMutableConstants>(container);
|
||||
}
|
||||
|
||||
bool MaterialParser::getPushConstants(CString* structVarName,
|
||||
FixedCapacityVector<MaterialPushConstant>* value) const noexcept {
|
||||
auto [start, end] = mImpl.mChunkContainer.getChunkRange(MaterialPushConstants);
|
||||
@@ -751,6 +756,38 @@ bool ChunkMaterialConstants::unflatten(Unflattener& unflattener,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChunkMaterialMutableConstants::unflatten(Unflattener& unflattener,
|
||||
FixedCapacityVector<MaterialMutableConstant>* materialConstants) {
|
||||
assert_invariant(materialConstants);
|
||||
|
||||
// Read number of constants.
|
||||
uint64_t numConstants = 0;
|
||||
if (!unflattener.read(&numConstants)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
materialConstants->reserve(numConstants);
|
||||
materialConstants->resize(numConstants);
|
||||
|
||||
for (uint64_t i = 0; i < numConstants; i++) {
|
||||
CString constantName;
|
||||
bool defaultValue;
|
||||
|
||||
if (!unflattener.read(&constantName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!unflattener.read(&defaultValue)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
(*materialConstants)[i].name = std::move(constantName);
|
||||
(*materialConstants)[i].defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChunkMaterialPushConstants::unflatten(Unflattener& unflattener,
|
||||
CString* structVarName,
|
||||
FixedCapacityVector<MaterialPushConstant>* materialPushConstants) {
|
||||
|
||||
@@ -49,6 +49,7 @@ class BufferInterfaceBlock;
|
||||
class SamplerInterfaceBlock;
|
||||
struct SubpassInfo;
|
||||
struct MaterialConstant;
|
||||
struct MaterialMutableConstant;
|
||||
struct MaterialPushConstant;
|
||||
|
||||
class MaterialParser {
|
||||
@@ -79,6 +80,8 @@ public:
|
||||
bool getShaderModels(uint32_t* value) const noexcept;
|
||||
bool getMaterialProperties(uint64_t* value) const noexcept;
|
||||
bool getConstants(utils::FixedCapacityVector<MaterialConstant>* value) const noexcept;
|
||||
bool getMutableConstants(utils::FixedCapacityVector<MaterialMutableConstant>* value)
|
||||
const noexcept;
|
||||
bool getPushConstants(utils::CString* structVarName,
|
||||
utils::FixedCapacityVector<MaterialPushConstant>* value) const noexcept;
|
||||
|
||||
@@ -237,6 +240,13 @@ struct ChunkMaterialConstants {
|
||||
static filamat::ChunkType const tag = filamat::MaterialConstants;
|
||||
};
|
||||
|
||||
struct ChunkMaterialMutableConstants {
|
||||
static bool unflatten(filaflat::Unflattener& unflattener,
|
||||
utils::FixedCapacityVector<MaterialMutableConstant>* materialConstants);
|
||||
using Container = utils::FixedCapacityVector<MaterialMutableConstant>;
|
||||
static filamat::ChunkType const tag = filamat::MaterialMutableConstants;
|
||||
};
|
||||
|
||||
struct ChunkMaterialPushConstants {
|
||||
static bool unflatten(filaflat::Unflattener& unflattener, utils::CString* structVarName,
|
||||
utils::FixedCapacityVector<MaterialPushConstant>* materialPushConstants);
|
||||
|
||||
@@ -187,7 +187,10 @@ FMaterial* PostProcessManager::PostProcessMaterial::getMaterial(FEngine& engine,
|
||||
if (UTILS_UNLIKELY(mSize)) {
|
||||
loadMaterial(engine);
|
||||
}
|
||||
mMaterial->prepareProgram(Variant{ Variant::type_t(variant) });
|
||||
mMaterial->prepareProgram(Variant{ Variant::type_t(variant) },
|
||||
// TODO(exv): allow post process materials to use mutable spec constants?
|
||||
Program::MutableSpecConstantsInfo(0)
|
||||
);
|
||||
return mMaterial;
|
||||
}
|
||||
|
||||
@@ -423,7 +426,10 @@ UTILS_NOINLINE
|
||||
PipelineState PostProcessManager::getPipelineState(
|
||||
FMaterial const* const ma, PostProcessVariant variant) const noexcept {
|
||||
return {
|
||||
.program = ma->getProgram(Variant{ Variant::type_t(variant) }),
|
||||
.program = ma->getProgram(Variant{ Variant::type_t(variant) },
|
||||
// TODO(exv): allow post process materials to use mutable spec constants?
|
||||
Program::MutableSpecConstantsInfo(0)
|
||||
),
|
||||
.vertexBufferInfo = mFullScreenQuadVbih,
|
||||
.pipelineLayout = {
|
||||
.setLayout = {
|
||||
|
||||
@@ -42,12 +42,12 @@
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/JobSystem.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Range.h>
|
||||
#include <utils/Slice.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/JobSystem.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Slice.h>
|
||||
#include <utils/Range.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
@@ -246,7 +246,8 @@ void RenderPass::appendCommands(FEngine const& engine,
|
||||
for (Command const* first = curr, *last = curr + commandCount ; first != last ; ++first) {
|
||||
if (UTILS_LIKELY((first->key & CUSTOM_MASK) == uint64_t(CustomCommand::PASS))) {
|
||||
auto ma = first->info.mi->getMaterial();
|
||||
ma->prepareProgram(first->info.materialVariant);
|
||||
ma->prepareProgram(first->info.materialVariant,
|
||||
first->info.mi->getMutableSpecConstants());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -407,8 +408,8 @@ RenderPass::Command* RenderPass::instanceify(DriverApi& driver,
|
||||
}
|
||||
|
||||
if (UTILS_UNLIKELY(firstSentinel)) {
|
||||
// DLOG(INFO) << "auto-instancing, saving " << drawCallsSavedCount << " draw calls, out of "
|
||||
// << count;
|
||||
//slog.d << "auto-instancing, saving " << drawCallsSavedCount << " draw calls, out of "
|
||||
// << count << io::endl;
|
||||
// we have instanced primitives
|
||||
// copy our instanced ubo data
|
||||
driver.updateBufferObjectUnsynchronized(mInstancedUboHandle, {
|
||||
@@ -1098,7 +1099,8 @@ void RenderPass::Executor::execute(FEngine const& engine, DriverApi& driver,
|
||||
}
|
||||
|
||||
assert_invariant(ma);
|
||||
pipeline.program = ma->getProgram(info.materialVariant);
|
||||
pipeline.program = ma->getProgram(info.materialVariant,
|
||||
info.mi->getMutableSpecConstants());
|
||||
|
||||
if (UTILS_UNLIKELY(memcmp(&pipeline, ¤tPipeline, sizeof(PipelineState)) != 0)) {
|
||||
currentPipeline = pipeline;
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
|
||||
#include "private/backend/DriverApi.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/bitset.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <array>
|
||||
@@ -291,16 +291,17 @@ void ResourceAllocator::gc(bool const skippedFrame) noexcept {
|
||||
UTILS_NOINLINE
|
||||
void ResourceAllocator::dump(bool const brief) const noexcept {
|
||||
constexpr float MiB = 1.0f / float(1u << 20u);
|
||||
DLOG(INFO) << "# entries=" << mTextureCache.size() << ", sz=" << (float) mCacheSize * MiB
|
||||
<< " MiB"
|
||||
<< ", max=" << (float) mCacheSizeHiWaterMark * MiB << " MiB";
|
||||
slog.d << "# entries=" << mTextureCache.size()
|
||||
<< ", sz=" << (float)mCacheSize * MiB << " MiB"
|
||||
<< ", max=" << (float)mCacheSizeHiWaterMark * MiB << " MiB"
|
||||
<< io::endl;
|
||||
if (!brief) {
|
||||
for (auto const& it : mTextureCache) {
|
||||
auto w = it.first.width;
|
||||
auto h = it.first.height;
|
||||
auto f = FTexture::getFormatSize(it.first.format);
|
||||
DLOG(INFO) << it.first.name << ": w=" << w << ", h=" << h << ", f=" << f
|
||||
<< ", sz=" << (float) it.second.size * MiB;
|
||||
slog.d << it.first.name << ": w=" << w << ", h=" << h << ", f=" << f << ", sz="
|
||||
<< (float)it.second.size * MiB << io::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,7 +309,7 @@ void ResourceAllocator::dump(bool const brief) const noexcept {
|
||||
ResourceAllocator::CacheContainer::iterator
|
||||
ResourceAllocator::purge(
|
||||
CacheContainer::iterator const& pos) {
|
||||
// DLOG(INFO) << "purging " << pos->second.handle.getId() << ", age=" << pos->second.age;
|
||||
//slog.d << "purging " << pos->second.handle.getId() << ", age=" << pos->second.age << io::endl;
|
||||
mBackend.destroyTexture(pos->second.handle);
|
||||
mCacheSize -= pos->second.size;
|
||||
return mTextureCache.erase(pos);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "ResourceList.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -32,7 +32,7 @@ ResourceListBase::ResourceListBase(const char* typeName)
|
||||
ResourceListBase::~ResourceListBase() noexcept {
|
||||
#ifndef NDEBUG
|
||||
if (!mList.empty()) {
|
||||
DLOG(INFO) << "leaked " << mList.size() << " " << mTypeName;
|
||||
utils::slog.d << "leaked " << mList.size() << " " << mTypeName << utils::io::endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "details/Camera.h"
|
||||
|
||||
#include <utils/Entity.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
using namespace utils;
|
||||
@@ -36,7 +36,10 @@ FCameraManager::~FCameraManager() noexcept = default;
|
||||
void FCameraManager::terminate(FEngine& engine) noexcept {
|
||||
auto& manager = mManager;
|
||||
if (!manager.empty()) {
|
||||
DLOG(INFO) << "cleaning up " << manager.getComponentCount() << " leaked Camera components";
|
||||
#ifndef NDEBUG
|
||||
slog.d << "cleaning up " << manager.getComponentCount()
|
||||
<< " leaked Camera components" << io::endl;
|
||||
#endif
|
||||
Slice<Entity> const entities{ manager.getEntities(), manager.getComponentCount() };
|
||||
for (Entity const e : entities) {
|
||||
destroy(engine, e);
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
|
||||
#include <filament/LightManager.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <math/fast.h>
|
||||
@@ -230,7 +230,8 @@ void FLightManager::terminate() noexcept {
|
||||
auto& manager = mManager;
|
||||
if (!manager.empty()) {
|
||||
#ifndef NDEBUG
|
||||
DLOG(INFO) << "cleaning up " << manager.getComponentCount() << " leaked Light components";
|
||||
slog.d << "cleaning up " << manager.getComponentCount()
|
||||
<< " leaked Light components" << io::endl;
|
||||
#endif
|
||||
while (!manager.empty()) {
|
||||
Instance const ci = manager.end() - 1;
|
||||
|
||||
@@ -39,15 +39,14 @@
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/EntityManager.h>
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Slice.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <math/mat4.h>
|
||||
#include <math/scalar.h>
|
||||
@@ -397,11 +396,10 @@ void RenderableManager::BuilderDetails::processBoneIndicesAndWights(Engine& engi
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
else {
|
||||
LOG(WARNING) << "Warning of skinning: [entity=%" << entity.getId()
|
||||
<< ", primitive @ %" << primitiveIndex
|
||||
<< "] sum of bone weights of vertex=" << iVertex << " is "
|
||||
<< boneWeightsSum
|
||||
<< ", it should be one. Weights will be normalized.";
|
||||
slog.w << "Warning of skinning: [entity=%" << entity.getId()
|
||||
<< ", primitive @ %" << primitiveIndex
|
||||
<< "] sum of bone weights of vertex=" << iVertex << " is " << boneWeightsSum
|
||||
<< ", it should be one. Weights will be normalized." << io::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -500,9 +498,9 @@ RenderableManager::Builder::Result RenderableManager::Builder::build(Engine& eng
|
||||
AttributeBitset const declared = downcast(entry.vertices)->getDeclaredAttributes();
|
||||
AttributeBitset const required = material->getRequiredAttributes();
|
||||
if ((declared & required) != required) {
|
||||
LOG(WARNING) << "[entity=" << entity.getId() << ", primitive @ " << i
|
||||
<< "] missing required attributes (" << required
|
||||
<< "), declared=" << declared;
|
||||
slog.w << "[entity=" << entity.getId() << ", primitive @ " << i
|
||||
<< "] missing required attributes ("
|
||||
<< required << "), declared=" << declared << io::endl;
|
||||
}
|
||||
|
||||
// we have at least one valid primitive
|
||||
@@ -728,8 +726,10 @@ void FRenderableManager::destroy(Entity const e) noexcept {
|
||||
void FRenderableManager::terminate() noexcept {
|
||||
auto& manager = mManager;
|
||||
if (!manager.empty()) {
|
||||
DLOG(INFO) << "cleaning up " << manager.getComponentCount()
|
||||
<< " leaked Renderable components";
|
||||
#ifndef NDEBUG
|
||||
slog.d << "cleaning up " << manager.getComponentCount()
|
||||
<< " leaked Renderable components" << io::endl;
|
||||
#endif
|
||||
while (!manager.empty()) {
|
||||
Instance const ci = manager.end() - 1;
|
||||
destroyComponent(ci);
|
||||
@@ -811,9 +811,9 @@ void FRenderableManager::setMaterialInstanceAt(Instance const instance, uint8_t
|
||||
// emitting many invalid warnings as the `declared` bitset is not populated yet.
|
||||
bool const isPrimitiveInitialized = !!primitives[primitiveIndex].getHwHandle();
|
||||
if (UTILS_UNLIKELY(isPrimitiveInitialized && (declared & required) != required)) {
|
||||
LOG(WARNING) << "[instance=" << instance.asValue() << ", primitive @ "
|
||||
<< primitiveIndex << "] missing required attributes (" << required
|
||||
<< "), declared=" << declared;
|
||||
slog.w << "[instance=" << instance.asValue() << ", primitive @ " << primitiveIndex
|
||||
<< "] missing required attributes ("
|
||||
<< required << "), declared=" << declared << io::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -868,7 +868,7 @@ FColorGrading::FColorGrading(FEngine& engine, const Builder& builder) {
|
||||
}
|
||||
|
||||
//std::chrono::duration<float, std::milli> duration = std::chrono::steady_clock::now() - now;
|
||||
//DLOG(INFO) << "LUT generation time: " << duration.count() << " ms";
|
||||
//slog.d << "LUT generation time: " << duration.count() << " ms" << io::endl;
|
||||
|
||||
if (converted) {
|
||||
free(data);
|
||||
|
||||
@@ -54,14 +54,14 @@
|
||||
|
||||
#include <utils/Allocator.h>
|
||||
#include <utils/CallStack.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Invocable.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/PrivateImplementation-impl.h>
|
||||
#include <utils/ThreadUtils.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/ostream.h>
|
||||
|
||||
#include <math/vec3.h>
|
||||
#include <math/vec4.h>
|
||||
@@ -127,7 +127,7 @@ Engine* FEngine::create(Builder const& builder) {
|
||||
instance->mOwnPlatform = true;
|
||||
}
|
||||
if (platform == nullptr) {
|
||||
LOG(ERROR) << "Selected backend not supported in this build.";
|
||||
slog.e << "Selected backend not supported in this build." << io::endl;
|
||||
delete instance;
|
||||
return nullptr;
|
||||
}
|
||||
@@ -140,7 +140,6 @@ Engine* FEngine::create(Builder const& builder) {
|
||||
.forceGLES2Context = instance->getConfig().forceGLES2Context,
|
||||
.stereoscopicType = instance->getConfig().stereoscopicType,
|
||||
.assertNativeWindowIsValid = instance->features.backend.opengl.assert_native_window_is_valid,
|
||||
.metalDisablePanicOnDrawableFailure = instance->getConfig().metalDisablePanicOnDrawableFailure,
|
||||
};
|
||||
instance->mDriver = platform->createDriver(sharedContext, driverConfig);
|
||||
|
||||
@@ -281,8 +280,8 @@ FEngine::FEngine(Builder const& builder) :
|
||||
// (it may not be the case)
|
||||
mJobSystem.adopt();
|
||||
|
||||
LOG(INFO) << "FEngine (" << sizeof(void*) * 8 << " bits) created at " << this << " "
|
||||
<< "(threading is " << (UTILS_HAS_THREADING ? "enabled)" : "disabled)");
|
||||
slog.i << "FEngine (" << sizeof(void*) * 8 << " bits) created at " << this << " "
|
||||
<< "(threading is " << (UTILS_HAS_THREADING ? "enabled)" : "disabled)") << io::endl;
|
||||
}
|
||||
|
||||
uint32_t FEngine::getJobSystemThreadPoolSize(Config const& config) noexcept {
|
||||
@@ -317,8 +316,8 @@ void FEngine::init() {
|
||||
assert_invariant(mActiveFeatureLevel > FeatureLevel::FEATURE_LEVEL_0);
|
||||
#endif
|
||||
|
||||
LOG(INFO) << "Backend feature level: " << int(driverApi.getFeatureLevel());
|
||||
LOG(INFO) << "FEngine feature level: " << int(mActiveFeatureLevel);
|
||||
slog.i << "Backend feature level: " << int(driverApi.getFeatureLevel()) << io::endl;
|
||||
slog.i << "FEngine feature level: " << int(mActiveFeatureLevel) << io::endl;
|
||||
|
||||
|
||||
mResourceAllocatorDisposer = std::make_shared<ResourceAllocatorDisposer>(driverApi);
|
||||
@@ -545,7 +544,8 @@ void FEngine::shutdown() {
|
||||
// print out some statistics about this run
|
||||
size_t const wm = mCommandBufferQueue.getHighWatermark();
|
||||
size_t const wmpct = wm / (getCommandBufferSize() / 100);
|
||||
DLOG(INFO) << "CircularBuffer: High watermark " << wm / 1024 << " KiB (" << wmpct << "%)";
|
||||
slog.d << "CircularBuffer: High watermark "
|
||||
<< wm / 1024 << " KiB (" << wmpct << "%)" << io::endl;
|
||||
#endif
|
||||
|
||||
DriverApi& driver = getDriverApi();
|
||||
@@ -740,9 +740,9 @@ int FEngine::loop() {
|
||||
if (mPlatform == nullptr) {
|
||||
mPlatform = PlatformFactory::create(&mBackend);
|
||||
mOwnPlatform = true;
|
||||
LOG(INFO) << "FEngine resolved backend: " << to_string(mBackend);
|
||||
slog.i << "FEngine resolved backend: " << to_string(mBackend) << io::endl;
|
||||
if (mPlatform == nullptr) {
|
||||
LOG(ERROR) << "Selected backend not supported in this build.";
|
||||
slog.e << "Selected backend not supported in this build." << io::endl;
|
||||
mDriverBarrier.latch();
|
||||
return 0;
|
||||
}
|
||||
@@ -760,7 +760,6 @@ int FEngine::loop() {
|
||||
.forceGLES2Context = mConfig.forceGLES2Context,
|
||||
.stereoscopicType = mConfig.stereoscopicType,
|
||||
.assertNativeWindowIsValid = features.backend.opengl.assert_native_window_is_valid,
|
||||
.metalDisablePanicOnDrawableFailure = mConfig.metalDisablePanicOnDrawableFailure,
|
||||
};
|
||||
mDriver = mPlatform->createDriver(mSharedGLContext, driverConfig);
|
||||
|
||||
@@ -1043,8 +1042,8 @@ UTILS_NOINLINE
|
||||
void FEngine::cleanupResourceList(ResourceList<T>&& list) {
|
||||
if (UTILS_UNLIKELY(!list.empty())) {
|
||||
#ifndef NDEBUG
|
||||
DLOG(INFO) << "cleaning up " << list.size() << " leaked "
|
||||
<< CallStack::typeName<T>().c_str();
|
||||
slog.d << "cleaning up " << list.size()
|
||||
<< " leaked " << CallStack::typeName<T>().c_str() << io::endl;
|
||||
#endif
|
||||
list.forEach([this, &allocator = mHeapAllocator](T* item) {
|
||||
item->terminate(*this);
|
||||
@@ -1241,10 +1240,11 @@ bool FEngine::destroy(const FMaterialInstance* p) {
|
||||
<< ri.asValue() << ", index=" << j << ")";
|
||||
} else {
|
||||
if (UTILS_UNLIKELY(mi == p)) {
|
||||
LOG(ERROR) << "destroying MaterialInstance \"" << mi->getName()
|
||||
<< "\" which is still in use by Renderable (entity="
|
||||
<< entity.getId() << ", instance=" << ri.asValue()
|
||||
<< ", index=" << j << ")";
|
||||
slog.e << "destroying MaterialInstance \""
|
||||
<< mi->getName() << "\" which is still in use by Renderable (entity="
|
||||
<< entity.getId() << ", instance="
|
||||
<< ri.asValue() << ", index=" << j << ")"
|
||||
<< io::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
#include <utils/FixedCapacityVector.h>
|
||||
#include <utils/Hash.h>
|
||||
#include <utils/Invocable.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/bitset.h>
|
||||
#include <utils/compiler.h>
|
||||
@@ -169,16 +169,6 @@ template Material::Builder& Material::Builder::constant<int32_t>(const char*, si
|
||||
template Material::Builder& Material::Builder::constant<float>(const char*, size_t, float);
|
||||
template Material::Builder& Material::Builder::constant<bool>(const char*, size_t, bool);
|
||||
|
||||
|
||||
const char* toString(ShaderModel model) {
|
||||
switch (model) {
|
||||
case ShaderModel::MOBILE:
|
||||
return "mobile";
|
||||
case ShaderModel::DESKTOP:
|
||||
return "desktop";
|
||||
}
|
||||
}
|
||||
|
||||
Material* Material::Builder::build(Engine& engine) const {
|
||||
std::unique_ptr<MaterialParser> materialParser = createParser(
|
||||
downcast(engine).getBackend(), downcast(engine).getShaderLanguage(),
|
||||
@@ -197,11 +187,17 @@ Material* Material::Builder::build(Engine& engine) const {
|
||||
if (!shaderModels.test(static_cast<uint32_t>(shaderModel))) {
|
||||
CString name;
|
||||
materialParser->getName(&name);
|
||||
char shaderModelsString[16];
|
||||
snprintf(shaderModelsString, sizeof(shaderModelsString), "%#x", shaderModels.getValue());
|
||||
LOG(ERROR) << "The material '" << name.c_str_safe() << "' was not built for "
|
||||
<< toString(shaderModel) << ".";
|
||||
LOG(ERROR) << "Compiled material contains shader models " << shaderModelsString << ".";
|
||||
slog.e << "The material '" << name.c_str_safe() << "' was not built for ";
|
||||
switch (shaderModel) {
|
||||
case ShaderModel::MOBILE:
|
||||
slog.e << "mobile.\n";
|
||||
break;
|
||||
case ShaderModel::DESKTOP:
|
||||
slog.e << "desktop.\n";
|
||||
break;
|
||||
}
|
||||
slog.e << "Compiled material contains shader models 0x"
|
||||
<< io::hex << shaderModels.getValue() << io::dec << "." << io::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -221,10 +217,10 @@ Material* Material::Builder::build(Engine& engine) const {
|
||||
if (materialStereoscopicType != engineStereoscopicType) {
|
||||
CString name;
|
||||
materialParser->getName(&name);
|
||||
LOG(WARNING) << "The stereoscopic type in the compiled material '"
|
||||
<< name.c_str_safe() << "' is " << (int) materialStereoscopicType
|
||||
<< ", which is not compatiable with the engine's setting "
|
||||
<< (int) engineStereoscopicType << ".";
|
||||
slog.w << "The stereoscopic type in the compiled material '" << name.c_str_safe()
|
||||
<< "' is " << (int)materialStereoscopicType
|
||||
<< ", which is not compatiable with the engine's setting "
|
||||
<< (int)engineStereoscopicType << "." << io::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -342,8 +338,24 @@ FMaterial::FMaterial(FEngine& engine, const Builder& builder,
|
||||
|
||||
processBlendingMode(parser);
|
||||
processSpecializationConstants(engine, builder, parser);
|
||||
processMutableSpecializationConstants(engine, builder, parser);
|
||||
processPushConstants(engine, parser);
|
||||
processDescriptorSets(engine, parser);
|
||||
|
||||
switch (mMaterialDomain) {
|
||||
case filament::MaterialDomain::SURFACE:
|
||||
mVariantBits = VARIANT_BITS;
|
||||
break;
|
||||
case filament::MaterialDomain::POST_PROCESS:
|
||||
mVariantBits = POST_PROCESS_VARIANT_BITS;
|
||||
break;
|
||||
case filament::MaterialDomain::COMPUTE:
|
||||
mVariantBits = 0;
|
||||
break;
|
||||
}
|
||||
mCachedPrograms = FixedCapacityVector<backend::Handle<backend::HwProgram>>(
|
||||
1 << (mVariantBits + mMaterialMutableConstants.size()));
|
||||
|
||||
precacheDepthVariants(engine);
|
||||
|
||||
#if FILAMENT_ENABLE_MATDBG
|
||||
@@ -366,12 +378,9 @@ void FMaterial::invalidate(Variant::type_t variantMask, Variant::type_t variantV
|
||||
!mHasCustomDepthShader) {
|
||||
// it would be unsafe to invalidate any of the cached depth variant
|
||||
if (UTILS_UNLIKELY(!((variantMask & Variant::DEP) && !(variantValue & Variant::DEP)))) {
|
||||
char variantMaskString[16];
|
||||
snprintf(variantMaskString, sizeof(variantMaskString), "%#x", +variantMask);
|
||||
char variantValueString[16];
|
||||
snprintf(variantValueString, sizeof(variantValueString), "%#x", +variantValue);
|
||||
LOG(WARNING) << "FMaterial::invalidate(" << variantMaskString << ", "
|
||||
<< variantValueString << ") would corrupt the depth variant cache";
|
||||
slog.w << io::hex << "FMaterial::invalidate("
|
||||
<< +variantMask << ", " << +variantValue
|
||||
<< ") would corrupt the depth variant cache" << io::endl;
|
||||
}
|
||||
variantMask |= Variant::DEP;
|
||||
variantValue &= ~Variant::DEP;
|
||||
@@ -397,8 +406,8 @@ void FMaterial::terminate(FEngine& engine) {
|
||||
<< pos->second.size() << " instances still alive.";
|
||||
} else {
|
||||
if (UTILS_UNLIKELY(!pos->second.empty())) {
|
||||
LOG(ERROR) << "destroying material \"" << this->getName().c_str_safe() << "\" but "
|
||||
<< pos->second.size() << " instances still alive.";
|
||||
slog.e << "destroying material \"" << this->getName().c_str_safe() << "\" but "
|
||||
<< pos->second.size() << " instances still alive." << io::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -449,13 +458,17 @@ void FMaterial::compile(CompilerPriorityQueue const priority,
|
||||
UserVariantFilterMask const variantFilter =
|
||||
~variantSpec & UserVariantFilterMask(UserVariantFilterBit::ALL);
|
||||
|
||||
int mutableConstantVariations = 1 << mMaterialMutableConstants.size();
|
||||
|
||||
if (UTILS_LIKELY(mEngine.getDriverApi().isParallelShaderCompileSupported())) {
|
||||
auto const& variants = isVariantLit() ?
|
||||
VariantUtils::getLitVariants() : VariantUtils::getUnlitVariants();
|
||||
for (auto const variant: variants) {
|
||||
if (!variantFilter || variant == Variant::filterUserVariant(variant, variantFilter)) {
|
||||
if (hasVariant(variant)) {
|
||||
prepareProgram(variant, priority);
|
||||
for (int spec = 0; spec < mutableConstantVariations; spec++) {
|
||||
prepareProgram(variant, Program::MutableSpecConstantsInfo(spec), priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -496,6 +509,11 @@ FMaterialInstance* FMaterial::getDefaultInstance() noexcept {
|
||||
return mDefaultMaterialInstance;
|
||||
}
|
||||
|
||||
bool FMaterial::isCached(Variant const variant,
|
||||
const backend::Program::MutableSpecConstantsInfo mutableSpecConstants) const noexcept {
|
||||
return bool(mCachedPrograms[getCachedProgramIndex(variant, mutableSpecConstants)]);
|
||||
}
|
||||
|
||||
bool FMaterial::hasParameter(const char* name) const noexcept {
|
||||
return mUniformInterfaceBlock.hasField(name) ||
|
||||
mSamplerInterfaceBlock.hasSampler(name) ||
|
||||
@@ -536,14 +554,15 @@ bool FMaterial::hasVariant(Variant const variant) const noexcept {
|
||||
}
|
||||
|
||||
void FMaterial::prepareProgramSlow(Variant const variant,
|
||||
const backend::Program::MutableSpecConstantsInfo mutableSpecConstants,
|
||||
backend::CompilerPriorityQueue const priorityQueue) const noexcept {
|
||||
assert_invariant(mEngine.hasFeatureLevel(mFeatureLevel));
|
||||
switch (getMaterialDomain()) {
|
||||
case MaterialDomain::SURFACE:
|
||||
getSurfaceProgramSlow(variant, priorityQueue);
|
||||
getSurfaceProgramSlow(variant, mutableSpecConstants, priorityQueue);
|
||||
break;
|
||||
case MaterialDomain::POST_PROCESS:
|
||||
getPostProcessProgramSlow(variant, priorityQueue);
|
||||
getPostProcessProgramSlow(variant, mutableSpecConstants, priorityQueue);
|
||||
break;
|
||||
case MaterialDomain::COMPUTE:
|
||||
// TODO: implement MaterialDomain::COMPUTE
|
||||
@@ -552,6 +571,7 @@ void FMaterial::prepareProgramSlow(Variant const variant,
|
||||
}
|
||||
|
||||
void FMaterial::getSurfaceProgramSlow(Variant const variant,
|
||||
const backend::Program::MutableSpecConstantsInfo mutableSpecConstants,
|
||||
CompilerPriorityQueue const priorityQueue) const noexcept {
|
||||
// filterVariant() has already been applied in generateCommands(), shouldn't be needed here
|
||||
// if we're unlit, we don't have any bits that correspond to lit materials
|
||||
@@ -562,25 +582,25 @@ void FMaterial::getSurfaceProgramSlow(Variant const variant,
|
||||
Variant const vertexVariant = Variant::filterVariantVertex(variant);
|
||||
Variant const fragmentVariant = Variant::filterVariantFragment(variant);
|
||||
|
||||
Program pb{ getProgramWithVariants(variant, vertexVariant, fragmentVariant) };
|
||||
Program pb{ getProgramWithVariants(variant, vertexVariant, fragmentVariant, mutableSpecConstants) };
|
||||
pb.priorityQueue(priorityQueue);
|
||||
pb.multiview(
|
||||
mEngine.getConfig().stereoscopicType == StereoscopicType::MULTIVIEW &&
|
||||
Variant::isStereoVariant(variant));
|
||||
createAndCacheProgram(std::move(pb), variant);
|
||||
createAndCacheProgram(std::move(pb), variant, mutableSpecConstants);
|
||||
}
|
||||
|
||||
void FMaterial::getPostProcessProgramSlow(Variant const variant,
|
||||
const backend::Program::MutableSpecConstantsInfo mutableSpecConstants,
|
||||
CompilerPriorityQueue const priorityQueue) const noexcept {
|
||||
Program pb{ getProgramWithVariants(variant, variant, variant) };
|
||||
Program pb{ getProgramWithVariants(variant, variant, variant, mutableSpecConstants) };
|
||||
pb.priorityQueue(priorityQueue);
|
||||
createAndCacheProgram(std::move(pb), variant);
|
||||
createAndCacheProgram(std::move(pb), variant, mutableSpecConstants);
|
||||
}
|
||||
|
||||
Program FMaterial::getProgramWithVariants(
|
||||
Variant variant,
|
||||
Variant vertexVariant,
|
||||
Variant fragmentVariant) const {
|
||||
Program FMaterial::getProgramWithVariants(Variant variant,
|
||||
Variant vertexVariant, Variant fragmentVariant,
|
||||
const backend::Program::MutableSpecConstantsInfo mutableSpecConstants) const {
|
||||
FEngine const& engine = mEngine;
|
||||
const ShaderModel sm = engine.getShaderModel();
|
||||
const bool isNoop = engine.getBackend() == Backend::NOOP;
|
||||
@@ -641,29 +661,34 @@ Program FMaterial::getProgramWithVariants(
|
||||
mProgramDescriptorBindings[+DescriptorSetBindingPoints::PER_RENDERABLE]);
|
||||
program.descriptorBindings(+DescriptorSetBindingPoints::PER_MATERIAL,
|
||||
mProgramDescriptorBindings[+DescriptorSetBindingPoints::PER_MATERIAL]);
|
||||
program.specializationConstants(mSpecializationConstants);
|
||||
program.specializationConstants(mSpecializationConstants,
|
||||
CONFIG_MAX_RESERVED_SPEC_CONSTANTS + mMaterialConstants.size(), mutableSpecConstants);
|
||||
|
||||
program.pushConstants(ShaderStage::VERTEX, mPushConstants[uint8_t(ShaderStage::VERTEX)]);
|
||||
program.pushConstants(ShaderStage::FRAGMENT, mPushConstants[uint8_t(ShaderStage::FRAGMENT)]);
|
||||
|
||||
program.cacheId(hash::combine(size_t(mCacheId), variant.key));
|
||||
program.cacheId(
|
||||
hash::combine(size_t(mCacheId),
|
||||
hash::combine(variant.key, mutableSpecConstants.getValue())));
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
void FMaterial::createAndCacheProgram(Program&& p, Variant const variant) const noexcept {
|
||||
void FMaterial::createAndCacheProgram(Program&& p, Variant const variant,
|
||||
Program::MutableSpecConstantsInfo const mutableSpecConstants) const noexcept {
|
||||
FEngine const& engine = mEngine;
|
||||
DriverApi& driverApi = mEngine.getDriverApi();
|
||||
|
||||
bool const isShared = isSharedVariant(variant);
|
||||
size_t const cacheIndex = getCachedProgramIndex(variant, mutableSpecConstants);
|
||||
|
||||
// Check if the default material has this program cached
|
||||
if (isShared) {
|
||||
FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial();
|
||||
if (pDefaultMaterial) {
|
||||
auto const program = pDefaultMaterial->mCachedPrograms[variant.key];
|
||||
auto const program = pDefaultMaterial->mCachedPrograms[cacheIndex];
|
||||
if (program) {
|
||||
mCachedPrograms[variant.key] = program;
|
||||
mCachedPrograms[cacheIndex] = program;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -672,17 +697,17 @@ void FMaterial::createAndCacheProgram(Program&& p, Variant const variant) const
|
||||
auto const program = driverApi.createProgram(std::move(p));
|
||||
driverApi.setDebugTag(program.getId(), mName);
|
||||
assert_invariant(program);
|
||||
mCachedPrograms[variant.key] = program;
|
||||
mCachedPrograms[cacheIndex] = program;
|
||||
|
||||
// If the default material doesn't already have this program cached, and all caching conditions
|
||||
// are met (Surface Domain and no custom depth shader), cache it now.
|
||||
// New Materials will inherit these program automatically.
|
||||
if (isShared) {
|
||||
FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial();
|
||||
if (pDefaultMaterial && !pDefaultMaterial->mCachedPrograms[variant.key]) {
|
||||
if (pDefaultMaterial && !pDefaultMaterial->mCachedPrograms[cacheIndex]) {
|
||||
// set the tag to the default material name
|
||||
driverApi.setDebugTag(program.getId(), mName);
|
||||
pDefaultMaterial->mCachedPrograms[variant.key] = program;
|
||||
pDefaultMaterial->mCachedPrograms[cacheIndex] = program;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -730,6 +755,14 @@ size_t FMaterial::getParameters(ParameterInfo* parameters, size_t count) const n
|
||||
return count;
|
||||
}
|
||||
|
||||
std::optional<uint32_t> FMaterial::getMutableConstantId(std::string_view name) const noexcept {
|
||||
auto const pos = mMutableSpecializationConstantsNameToIndex.find(name);
|
||||
if (pos != mMutableSpecializationConstantsNameToIndex.end()) {
|
||||
return pos->second;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#if FILAMENT_ENABLE_MATDBG
|
||||
|
||||
// Swaps in an edited version of the original package that was used to create the material. The
|
||||
@@ -738,7 +771,7 @@ size_t FMaterial::getParameters(ParameterInfo* parameters, size_t count) const n
|
||||
// source strings, so here we trigger a rebuild of the HwProgram objects.
|
||||
void FMaterial::applyPendingEdits() noexcept {
|
||||
const char* name = mName.c_str();
|
||||
DLOG(INFO) << "Applying edits to " << (name ? name : "(untitled)");
|
||||
slog.d << "Applying edits to " << (name ? name : "(untitled)") << io::endl;
|
||||
destroyPrograms(mEngine); // FIXME: this will not destroy the shared variants
|
||||
latchPendingEdits();
|
||||
}
|
||||
@@ -788,7 +821,9 @@ void FMaterial::onQueryCallback(void* userdata, VariantList* pActiveVariants) {
|
||||
|
||||
#endif // FILAMENT_ENABLE_MATDBG
|
||||
|
||||
[[nodiscard]] Handle<HwProgram> FMaterial::getProgramWithMATDBG(Variant const variant) const noexcept {
|
||||
[[nodiscard]] Handle<HwProgram> FMaterial::getProgramWithMATDBG(Variant const variant,
|
||||
Program::MutableSpecConstantsInfo const mutableSpecConstants) const noexcept {
|
||||
size_t cacheIndex = getCachedProgramIndex(variant, mutableSpecConstants);
|
||||
#if FILAMENT_ENABLE_MATDBG
|
||||
assert_invariant((size_t)variant.key < VARIANT_COUNT);
|
||||
std::unique_lock lock(mActiveProgramsLock);
|
||||
@@ -803,13 +838,13 @@ void FMaterial::onQueryCallback(void* userdata, VariantList* pActiveVariants) {
|
||||
lock.unlock();
|
||||
if (isSharedVariant(variant)) {
|
||||
FMaterial const* const pDefaultMaterial = mEngine.getDefaultMaterial();
|
||||
if (pDefaultMaterial && pDefaultMaterial->mCachedPrograms[variant.key]) {
|
||||
return pDefaultMaterial->getProgram(variant);
|
||||
if (pDefaultMaterial && pDefaultMaterial->mCachedPrograms[cacheIndex]) {
|
||||
return pDefaultMaterial->getProgram(variant, mutableSpecConstants);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
assert_invariant(mCachedPrograms[variant.key]);
|
||||
return mCachedPrograms[variant.key];
|
||||
assert_invariant(mCachedPrograms[cacheIndex]);
|
||||
return mCachedPrograms[cacheIndex];
|
||||
}
|
||||
|
||||
void FMaterial::destroyPrograms(FEngine& engine,
|
||||
@@ -822,7 +857,7 @@ void FMaterial::destroyPrograms(FEngine& engine,
|
||||
case MaterialDomain::SURFACE: {
|
||||
if (mIsDefaultMaterial || mHasCustomDepthShader) {
|
||||
// default material, or we have custom depth shaders, we destroy all variants
|
||||
for (size_t k = 0, n = VARIANT_COUNT; k < n; ++k) {
|
||||
for (size_t k = 0, n = cachedPrograms.size(); k < n; ++k) {
|
||||
if ((k & variantMask) == variantValue) {
|
||||
// Only destroy if the handle is valid. Not strictly needed, but we have a lot
|
||||
// of variants, and this generates traffic in the command queue.
|
||||
@@ -840,7 +875,7 @@ void FMaterial::destroyPrograms(FEngine& engine,
|
||||
UTILS_UNUSED_IN_RELEASE
|
||||
auto const UTILS_NULLABLE pDefaultMaterial = engine.getDefaultMaterial();
|
||||
|
||||
for (size_t k = 0, n = VARIANT_COUNT; k < n; ++k) {
|
||||
for (size_t k = 0, n = cachedPrograms.size(); k < n; ++k) {
|
||||
if ((k & variantMask) == variantValue) {
|
||||
// Only destroy if the handle is valid. Not strictly needed, but we have a lot
|
||||
// of variant, and this generates traffic in the command queue.
|
||||
@@ -852,7 +887,7 @@ void FMaterial::destroyPrograms(FEngine& engine,
|
||||
// During Engine::shutdown, auto-cleanup destroys the
|
||||
// default material first
|
||||
assert_invariant(!pDefaultMaterial ||
|
||||
pDefaultMaterial->mCachedPrograms[k]);
|
||||
pDefaultMaterial->mCachedPrograms[k & (VARIANT_COUNT - 1)]);
|
||||
// we don't own this variant, skip, but clear the entry.
|
||||
cachedPrograms[k].clear();
|
||||
continue;
|
||||
@@ -866,7 +901,7 @@ void FMaterial::destroyPrograms(FEngine& engine,
|
||||
break;
|
||||
}
|
||||
case MaterialDomain::POST_PROCESS: {
|
||||
for (size_t k = 0, n = POST_PROCESS_VARIANT_COUNT; k < n; ++k) {
|
||||
for (size_t k = 0, n = cachedPrograms.size(); k < n; ++k) {
|
||||
if ((k & variantMask) == variantValue) {
|
||||
// Only destroy if the handle is valid. Not strictly needed, but we have a lot
|
||||
// of variant, and this generates traffic in the command queue.
|
||||
@@ -878,8 +913,13 @@ void FMaterial::destroyPrograms(FEngine& engine,
|
||||
break;
|
||||
}
|
||||
case MaterialDomain::COMPUTE: {
|
||||
// Compute programs don't have variants
|
||||
driverApi.destroyProgram(std::move(cachedPrograms[0]));
|
||||
for (size_t k = 0, n = cachedPrograms.size(); k < n; ++k) {
|
||||
// Only destroy if the handle is valid. Not strictly needed, but we have a lot
|
||||
// of variant, and this generates traffic in the command queue.
|
||||
if (cachedPrograms[k]) {
|
||||
driverApi.destroyProgram(std::move(cachedPrograms[k]));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1114,6 +1154,19 @@ void FMaterial::processSpecializationConstants(FEngine& engine, Builder const& b
|
||||
}
|
||||
}
|
||||
|
||||
void FMaterial::processMutableSpecializationConstants(FEngine& engine, Builder const& builder,
|
||||
MaterialParser const* const parser) {
|
||||
// Older materials won't have a mutable constants chunk, but that's okay.
|
||||
parser->getMutableConstants(&mMaterialMutableConstants);
|
||||
for (size_t i = 0, c = mMaterialMutableConstants.size(); i < c; i++) {
|
||||
auto& item = mMaterialMutableConstants[i];
|
||||
// the key can be a string_view because mMaterialMutableConstants owns the CString
|
||||
std::string_view const key{ item.name.data(), item.name.size() };
|
||||
mMutableSpecializationConstantsNameToIndex[key] = i;
|
||||
mDefaultMutableSpecializationConstants.set(i, item.defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
void FMaterial::processPushConstants(FEngine&, MaterialParser const* parser) {
|
||||
FixedCapacityVector<Program::PushConstant>& vertexConstants =
|
||||
mPushConstants[uint8_t(ShaderStage::VERTEX)];
|
||||
@@ -1169,7 +1222,8 @@ void FMaterial::precacheDepthVariants(FEngine& engine) {
|
||||
}
|
||||
assert_invariant(Variant::isValidDepthVariant(variant));
|
||||
if (hasVariant(variant)) {
|
||||
prepareProgram(variant);
|
||||
// The default material shouldn't ever have mutable spec constants.
|
||||
prepareProgram(variant, Program::MutableSpecConstantsInfo(0));
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -1182,9 +1236,16 @@ void FMaterial::precacheDepthVariants(FEngine& engine) {
|
||||
FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial();
|
||||
assert_invariant(pDefaultMaterial);
|
||||
auto const allDepthVariants = VariantUtils::getDepthVariants();
|
||||
int mutableConstantVariations = 1 << mMaterialMutableConstants.size();
|
||||
for (auto const variant: allDepthVariants) {
|
||||
assert_invariant(Variant::isValidDepthVariant(variant));
|
||||
mCachedPrograms[variant.key] = pDefaultMaterial->mCachedPrograms[variant.key];
|
||||
size_t defaultCacheIndex = pDefaultMaterial->getCachedProgramIndex(variant,
|
||||
Program::MutableSpecConstantsInfo(0));
|
||||
for (int spec = 0; spec < mutableConstantVariations; spec++) {
|
||||
size_t cacheIndex = getCachedProgramIndex(variant,
|
||||
Program::MutableSpecConstantsInfo(spec));
|
||||
mCachedPrograms[cacheIndex] = pDefaultMaterial->mCachedPrograms[defaultCacheIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,9 +122,8 @@ public:
|
||||
|
||||
FEngine& getEngine() const noexcept { return mEngine; }
|
||||
|
||||
bool isCached(Variant const variant) const noexcept {
|
||||
return bool(mCachedPrograms[variant.key]);
|
||||
}
|
||||
bool isCached(Variant const variant,
|
||||
const backend::Program::MutableSpecConstantsInfo mutableSpecConstants) const noexcept;
|
||||
|
||||
void invalidate(Variant::type_t variantMask = 0, Variant::type_t variantValue = 0) noexcept;
|
||||
|
||||
@@ -132,26 +131,31 @@ public:
|
||||
// Must be called outside of backend render pass.
|
||||
// Must be called before getProgram() below.
|
||||
void prepareProgram(Variant const variant,
|
||||
backend::Program::MutableSpecConstantsInfo const mutableSpecConstants,
|
||||
backend::CompilerPriorityQueue const priorityQueue = CompilerPriorityQueue::HIGH) const noexcept {
|
||||
// prepareProgram() is called for each RenderPrimitive in the scene, so it must be efficient.
|
||||
if (UTILS_UNLIKELY(!isCached(variant))) {
|
||||
prepareProgramSlow(variant, priorityQueue);
|
||||
if (UTILS_UNLIKELY(!isCached(variant, mutableSpecConstants))) {
|
||||
prepareProgramSlow(variant, mutableSpecConstants, priorityQueue);
|
||||
}
|
||||
}
|
||||
|
||||
// getProgram returns the backend program for the material's given variant.
|
||||
// getProgram returns the backend program for the material's given variant and set of mutable
|
||||
// spec constants.
|
||||
// Must be called after prepareProgram().
|
||||
[[nodiscard]]
|
||||
backend::Handle<backend::HwProgram> getProgram(Variant const variant) const noexcept {
|
||||
backend::Handle<backend::HwProgram> getProgram(Variant const variant,
|
||||
backend::Program::MutableSpecConstantsInfo const mutableSpecConstants) const noexcept {
|
||||
#if FILAMENT_ENABLE_MATDBG
|
||||
return getProgramWithMATDBG(variant);
|
||||
return getProgramWithMATDBG(variant, mutableSpecConstants);
|
||||
#endif
|
||||
assert_invariant(mCachedPrograms[variant.key]);
|
||||
return mCachedPrograms[variant.key];
|
||||
size_t index = getCachedProgramIndex(variant, mutableSpecConstants);
|
||||
assert_invariant(mCachedPrograms[index]);
|
||||
return mCachedPrograms[index];
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
backend::Handle<backend::HwProgram> getProgramWithMATDBG(Variant variant) const noexcept;
|
||||
backend::Handle<backend::HwProgram> getProgramWithMATDBG(Variant variant,
|
||||
backend::Program::MutableSpecConstantsInfo const mutableSpecConstants) const noexcept;
|
||||
|
||||
bool isVariantLit() const noexcept { return mIsVariantLit; }
|
||||
|
||||
@@ -208,6 +212,12 @@ public:
|
||||
}
|
||||
size_t getParameters(ParameterInfo* parameters, size_t count) const noexcept;
|
||||
|
||||
uint32_t getMutableConstantCount() const noexcept { return mMaterialMutableConstants.size(); }
|
||||
std::optional<uint32_t> getMutableConstantId(std::string_view name) const noexcept;
|
||||
backend::Program::MutableSpecConstantsInfo getDefaultMutableConstants() const noexcept {
|
||||
return mDefaultMutableSpecializationConstants;
|
||||
}
|
||||
|
||||
uint32_t generateMaterialInstanceId() const noexcept { return mMaterialInstanceId++; }
|
||||
|
||||
void destroyPrograms(FEngine& engine,
|
||||
@@ -261,34 +271,48 @@ public:
|
||||
private:
|
||||
bool hasVariant(Variant variant) const noexcept;
|
||||
void prepareProgramSlow(Variant variant,
|
||||
backend::Program::MutableSpecConstantsInfo mutableSpecConstants,
|
||||
CompilerPriorityQueue priorityQueue) const noexcept;
|
||||
void getSurfaceProgramSlow(Variant variant,
|
||||
backend::Program::MutableSpecConstantsInfo mutableSpecConstants,
|
||||
CompilerPriorityQueue priorityQueue) const noexcept;
|
||||
void getPostProcessProgramSlow(Variant variant,
|
||||
backend::Program::MutableSpecConstantsInfo mutableSpecConstants,
|
||||
CompilerPriorityQueue priorityQueue) const noexcept;
|
||||
backend::Program getProgramWithVariants(Variant variant,
|
||||
Variant vertexVariant, Variant fragmentVariant) const;
|
||||
Variant vertexVariant, Variant fragmentVariant,
|
||||
backend::Program::MutableSpecConstantsInfo mutableSpecConstants) const;
|
||||
|
||||
void processBlendingMode(MaterialParser const* parser);
|
||||
|
||||
void processSpecializationConstants(FEngine& engine, Builder const& builder,
|
||||
MaterialParser const* parser);
|
||||
|
||||
void processMutableSpecializationConstants(FEngine& engine, Builder const& builder,
|
||||
MaterialParser const* parser);
|
||||
|
||||
void processPushConstants(FEngine& engine, MaterialParser const* parser);
|
||||
|
||||
void precacheDepthVariants(FEngine& engine);
|
||||
|
||||
void processDescriptorSets(FEngine& engine, MaterialParser const* parser);
|
||||
|
||||
void createAndCacheProgram(backend::Program&& p, Variant variant) const noexcept;
|
||||
void createAndCacheProgram(backend::Program&& p, Variant variant,
|
||||
backend::Program::MutableSpecConstantsInfo mutableSpecConstants) const noexcept;
|
||||
|
||||
inline bool isSharedVariant(Variant const variant) const {
|
||||
return (mMaterialDomain == MaterialDomain::SURFACE) && !mIsDefaultMaterial &&
|
||||
!mHasCustomDepthShader && Variant::isValidDepthVariant(variant);
|
||||
}
|
||||
|
||||
inline size_t getCachedProgramIndex(const Variant variant,
|
||||
const backend::Program::MutableSpecConstantsInfo mutableSpecConstants) const noexcept {
|
||||
return static_cast<size_t>(variant.key) |
|
||||
(static_cast<size_t>(mutableSpecConstants.getValue()) << mVariantBits);
|
||||
}
|
||||
|
||||
// try to order by frequency of use
|
||||
mutable std::array<backend::Handle<backend::HwProgram>, VARIANT_COUNT> mCachedPrograms;
|
||||
mutable utils::FixedCapacityVector<backend::Handle<backend::HwProgram>> mCachedPrograms;
|
||||
DescriptorSetLayout mPerViewDescriptorSetLayout;
|
||||
DescriptorSetLayout mPerViewDescriptorSetLayoutVsm;
|
||||
DescriptorSetLayout mDescriptorSetLayout;
|
||||
@@ -324,6 +348,7 @@ private:
|
||||
bool mHasCustomDepthShader = false;
|
||||
bool mIsDefaultMaterial = false;
|
||||
bool mSpecularAntiAliasing = false;
|
||||
uint8_t mVariantBits;
|
||||
|
||||
// reserve some space to construct the default material instance
|
||||
mutable FMaterialInstance* mDefaultMaterialInstance = nullptr;
|
||||
@@ -348,6 +373,13 @@ private:
|
||||
// current specialization constants for the HwProgram
|
||||
utils::FixedCapacityVector<backend::Program::SpecializationConstant> mSpecializationConstants;
|
||||
|
||||
// Mutable constants defined by this Material.
|
||||
utils::FixedCapacityVector<MaterialMutableConstant> mMaterialMutableConstants;
|
||||
// A map from the Constant name to the mMutableMaterialConstant index
|
||||
std::unordered_map<std::string_view, uint32_t> mMutableSpecializationConstantsNameToIndex;
|
||||
// Default values for the mutable constants.
|
||||
backend::Program::MutableSpecConstantsInfo mDefaultMutableSpecializationConstants;
|
||||
|
||||
// current push constants for the HwProgram
|
||||
std::array<utils::FixedCapacityVector<backend::Program::PushConstant>,
|
||||
backend::Program::SHADER_TYPE_COUNT>
|
||||
|
||||
@@ -35,12 +35,12 @@
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <utils/BitmaskEnum.h>
|
||||
#include <utils/CString.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/CString.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <math/scalar.h>
|
||||
|
||||
@@ -63,6 +63,7 @@ FMaterialInstance::FMaterialInstance(FEngine& engine, FMaterial const* material,
|
||||
const char* name) noexcept
|
||||
: mMaterial(material),
|
||||
mDescriptorSet("MaterialInstance", material->getDescriptorSetLayout()),
|
||||
mConstants(material->getDefaultMutableConstants()),
|
||||
mCulling(CullingMode::BACK),
|
||||
mShadowCulling(CullingMode::BACK),
|
||||
mDepthFunc(RasterState::DepthFunc::LE),
|
||||
@@ -128,6 +129,7 @@ FMaterialInstance::FMaterialInstance(FEngine& engine,
|
||||
mTextureParameters(other->mTextureParameters),
|
||||
mDescriptorSet(other->mDescriptorSet.duplicate(
|
||||
"MaterialInstance", mMaterial->getDescriptorSetLayout())),
|
||||
mConstants(other->mConstants),
|
||||
mPolygonOffset(other->mPolygonOffset),
|
||||
mStencilState(other->mStencilState),
|
||||
mMaskThreshold(other->mMaskThreshold),
|
||||
@@ -340,7 +342,7 @@ float FMaterialInstance::getSpecularAntiAliasingThreshold() const noexcept {
|
||||
|
||||
void FMaterialInstance::setDoubleSided(bool const doubleSided) noexcept {
|
||||
if (UTILS_UNLIKELY(!mMaterial->hasDoubleSidedCapability())) {
|
||||
LOG(WARNING) << "Parent material does not have double-sided capability.";
|
||||
slog.w << "Parent material does not have double-sided capability." << io::endl;
|
||||
return;
|
||||
}
|
||||
setParameter("_doubleSided", doubleSided);
|
||||
@@ -383,18 +385,19 @@ void FMaterialInstance::use(FEngine::DriverApi& driver) const {
|
||||
if (UTILS_UNLIKELY(mMissingSamplerDescriptors.any())) {
|
||||
std::call_once(mMissingSamplersFlag, [this] {
|
||||
auto const& list = mMaterial->getSamplerInterfaceBlock().getSamplerInfoList();
|
||||
LOG(WARNING) << "sampler parameters not set in MaterialInstance \""
|
||||
<< mName.c_str_safe() << "\" or Material \""
|
||||
<< mMaterial->getName().c_str_safe() << "\":";
|
||||
slog.w << "sampler parameters not set in MaterialInstance \""
|
||||
<< mName.c_str_safe() << "\" or Material \""
|
||||
<< mMaterial->getName().c_str_safe() << "\":\n";
|
||||
mMissingSamplerDescriptors.forEachSetBit([&list](descriptor_binding_t binding) {
|
||||
auto const pos = std::find_if(list.begin(), list.end(), [binding](const auto& item) {
|
||||
return item.binding == binding;
|
||||
});
|
||||
// just safety-check, should never fail
|
||||
if (UTILS_LIKELY(pos != list.end())) {
|
||||
LOG(WARNING) << "[" << +binding << "] " << pos->name.c_str();
|
||||
slog.w << "[" << +binding << "] " << pos->name.c_str() << '\n';
|
||||
}
|
||||
});
|
||||
flush(slog.w);
|
||||
});
|
||||
mMissingSamplerDescriptors.clear();
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
#include <backend/Program.h>
|
||||
|
||||
#include <utils/BitmaskEnum.h>
|
||||
#include <utils/bitset.h>
|
||||
@@ -66,7 +67,7 @@ public:
|
||||
void terminate(FEngine& engine);
|
||||
|
||||
void commitStreamUniformAssociations(FEngine::DriverApi& driver);
|
||||
|
||||
|
||||
void commit(FEngine& engine) const;
|
||||
|
||||
void commit(FEngine::DriverApi& driver) const;
|
||||
@@ -242,6 +243,10 @@ public:
|
||||
|
||||
using MaterialInstance::setParameter;
|
||||
|
||||
const backend::Program::MutableSpecConstantsInfo getMutableSpecConstants() const noexcept {
|
||||
return mConstants;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class FMaterial;
|
||||
friend class MaterialInstance;
|
||||
@@ -264,6 +269,12 @@ private:
|
||||
template<typename T>
|
||||
T getParameterImpl(std::string_view name) const;
|
||||
|
||||
template<typename T>
|
||||
void setConstantImpl(std::string_view name, T const& value);
|
||||
|
||||
template<typename T>
|
||||
T getConstantImpl(std::string_view name) const;
|
||||
|
||||
// keep these grouped, they're accessed together in the render-loop
|
||||
FMaterial const* mMaterial = nullptr;
|
||||
|
||||
@@ -277,6 +288,7 @@ private:
|
||||
mutable DescriptorSet mDescriptorSet;
|
||||
UniformBuffer mUniforms;
|
||||
bool mHasStreamUniformAssociations = false;
|
||||
backend::Program::MutableSpecConstantsInfo mConstants;
|
||||
|
||||
backend::PolygonOffset mPolygonOffset{};
|
||||
backend::StencilState mStencilState{};
|
||||
|
||||
@@ -52,12 +52,12 @@
|
||||
|
||||
#include <private/utils/Tracing.h>
|
||||
|
||||
#include <utils/JobSystem.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/JobSystem.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <limits>
|
||||
@@ -155,10 +155,14 @@ FRenderer::FRenderer(FEngine& engine) :
|
||||
FRenderer::~FRenderer() noexcept {
|
||||
// There shouldn't be any resource left when we get here, but if there is, make sure
|
||||
// to free what we can (it would probably mean something when wrong).
|
||||
#ifndef NDEBUG
|
||||
size_t const wm = getCommandsHighWatermark();
|
||||
size_t const wmpct = wm / (mEngine.getPerFrameCommandsSize() / 100);
|
||||
DLOG(INFO) << "Renderer: Commands High watermark " << wm / 1024 << " KiB (" << wmpct << "%), "
|
||||
<< wm / sizeof(Command) << " commands, " << sizeof(Command) << " bytes/command";
|
||||
slog.d << "Renderer: Commands High watermark "
|
||||
<< wm / 1024 << " KiB (" << wmpct << "%), "
|
||||
<< wm / sizeof(Command) << " commands, " << sizeof(Command) << " bytes/command"
|
||||
<< io::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void FRenderer::terminate(FEngine& engine) {
|
||||
@@ -459,9 +463,10 @@ void FRenderer::readPixels(FRenderTarget* renderTarget,
|
||||
|
||||
// TODO: change the following to an assert when client call sites have addressed the issue.
|
||||
if (!renderTarget->supportsReadPixels()) {
|
||||
LOG(WARNING) << "readPixels() must be called with a renderTarget with COLOR0 created with "
|
||||
"TextureUsage::BLIT_SRC. This precondition will be asserted in a later "
|
||||
"release of Filament.";
|
||||
slog.w << "readPixels() must be called with a renderTarget with COLOR0 created with "
|
||||
"TextureUsage::BLIT_SRC. This precondition will be asserted in a later "
|
||||
"release of Filament."
|
||||
<< io::endl;
|
||||
}
|
||||
|
||||
RendererUtils::readPixels(mEngine.getDriverApi(), renderTarget->getHwHandle(),
|
||||
@@ -1476,9 +1481,7 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
|
||||
}
|
||||
#endif
|
||||
|
||||
//utils::io::sstream graphviz;
|
||||
//fg.export_graphviz(graphviz, view.getName());
|
||||
//DLOG(INFO) << graphviz.c_str();
|
||||
//fg.export_graphviz(slog.d, view.getName());
|
||||
|
||||
fg.execute(driver);
|
||||
|
||||
|
||||
@@ -27,14 +27,14 @@
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/BufferDescriptor.h>
|
||||
|
||||
#include <utils/CString.h>
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/StaticString.h>
|
||||
#include <utils/bitset.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/CString.h>
|
||||
#include <utils/StaticString.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
@@ -120,8 +120,8 @@ VertexBuffer::Builder& VertexBuffer::Builder::attribute(VertexAttribute const at
|
||||
|
||||
mImpl->mDeclaredAttributes.set(attribute);
|
||||
} else {
|
||||
LOG(WARNING) << "Ignoring VertexBuffer attribute, the limit of "
|
||||
<< MAX_VERTEX_ATTRIBUTE_COUNT << " attributes has been exceeded";
|
||||
utils::slog.w << "Ignoring VertexBuffer attribute, the limit of " <<
|
||||
MAX_VERTEX_ATTRIBUTE_COUNT << " attributes has been exceeded" << utils::io::endl;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
#include <backend/DriverEnums.h>
|
||||
#include <backend/Handle.h>
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/StaticString.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/debug.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Panic.h>
|
||||
#include <utils/ostream.h>
|
||||
#include <utils/StaticString.h>
|
||||
|
||||
#include <utility>
|
||||
#include <limits>
|
||||
@@ -108,8 +108,9 @@ void DescriptorSet::commitSlow(DescriptorSetLayout const& layout,
|
||||
auto const unsetValidDescriptors = layout.getValidDescriptors() & ~mValid;
|
||||
if (UTILS_VERY_UNLIKELY(!unsetValidDescriptors.empty())) {
|
||||
unsetValidDescriptors.forEachSetBit([&](auto i) {
|
||||
LOG(WARNING) << (layout.isSampler(i) ? "Sampler" : "Buffer") << " descriptor " << i
|
||||
<< " of " << mName.c_str() << " is not set. Please report this issue.";
|
||||
slog.w << (layout.isSampler(i) ? "Sampler" : "Buffer")
|
||||
<< " descriptor " << i << " of " << mName.c_str() << " is not set. "
|
||||
"Please report this issue." << io::endl;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -130,8 +131,9 @@ void DescriptorSet::bind(FEngine::DriverApi& driver, DescriptorSetBindingPoints
|
||||
// assert_invariant(mDirty.none());
|
||||
if (UTILS_VERY_UNLIKELY(mDirty.any() && !mSetAfterCommitWarning)) {
|
||||
mDirty.forEachSetBit([&](uint8_t const binding) {
|
||||
LOG(WARNING) << "Descriptor set (handle=" << mDescriptorSetHandle.getId()
|
||||
<< ") binding=" << (int) binding << " was set between begin/endRenderPass";
|
||||
utils::slog.w << "Descriptor set (handle=" << mDescriptorSetHandle.getId()
|
||||
<< ") binding=" << (int) binding
|
||||
<< " was set between begin/endRenderPass" << utils::io::endl;
|
||||
});
|
||||
mSetAfterCommitWarning = true;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
|
||||
#include "details/Texture.h"
|
||||
|
||||
#include <utils/Logger.h>
|
||||
|
||||
using namespace filament;
|
||||
using namespace backend;
|
||||
|
||||
@@ -78,9 +76,7 @@ protected:
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
//utils::io::sstream graphviz;
|
||||
//fg.export_graphviz(graphviz);
|
||||
//DLOG(INFO) << graphviz.c_str();
|
||||
//fg.export_graphviz(utils::slog.d);
|
||||
}
|
||||
|
||||
Backend backend = Backend::NOOP;
|
||||
@@ -111,9 +107,7 @@ TEST(DependencyGraphTest, Simple) {
|
||||
|
||||
graph.cull();
|
||||
|
||||
//utils::io::sstream graphviz;
|
||||
//graph.export_graphviz(graphviz);
|
||||
//DLOG(INFO) << graphviz.c_str();
|
||||
//graph.export_graphviz(utils::slog.d);
|
||||
|
||||
EXPECT_FALSE(n2->isCulled());
|
||||
EXPECT_FALSE(n1->isCulled());
|
||||
@@ -147,9 +141,7 @@ TEST(DependencyGraphTest, Culling1) {
|
||||
|
||||
graph.cull();
|
||||
|
||||
//utils::io::sstream graphviz;
|
||||
//graph.export_graphviz(graphviz);
|
||||
//DLOG(INFO) << graphviz.c_str();
|
||||
//graph.export_graphviz(utils::slog.d);
|
||||
|
||||
EXPECT_TRUE(n1_0->isCulled());
|
||||
EXPECT_TRUE(n1_0->isCulledCalled());
|
||||
@@ -190,9 +182,7 @@ TEST(DependencyGraphTest, Culling2) {
|
||||
|
||||
graph.cull();
|
||||
|
||||
//utils::io::sstream graphviz;
|
||||
//graph.export_graphviz(graphviz);
|
||||
//DLOG(INFO) << graphviz.c_str();
|
||||
//graph.export_graphviz(utils::slog.d);
|
||||
|
||||
EXPECT_TRUE(n1_0->isCulled());
|
||||
EXPECT_TRUE(n1_0_0->isCulled());
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user