Merge branch 'main' into ma/descriptor-sets

This commit is contained in:
Mathias Agopian
2024-06-21 09:50:29 -07:00
committed by GitHub
19 changed files with 169 additions and 27 deletions
@@ -571,3 +571,9 @@ Java_com_google_android_filament_Engine_nBuilderBuild(JNIEnv*, jclass, jlong nat
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
return (jlong) builder->build();
}
extern "C"
JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_getSteadyClockTimeNano(JNIEnv *env, jclass clazz) {
return (jlong)Engine::getSteadyClockTimeNano();
}
@@ -25,12 +25,17 @@ using namespace filament;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
jlong nativeEngine, jobject buffer_, jint size) {
jlong nativeEngine, jobject buffer_, jint size, jint shBandCount) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, buffer_, size);
Material* material = Material::Builder()
auto builder = Material::Builder();
if (shBandCount) {
builder.sphericalHarmonicsBandCount(shBandCount);
}
Material* material = builder
.package(buffer.getData(), buffer.getSize())
.build(*engine);
return (jlong) material;
}
@@ -187,3 +187,10 @@ Java_com_google_android_filament_Renderer_nSetPresentationTime(JNIEnv *, jclass
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->setPresentationTime(monotonicClockNanos);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Renderer_nSetVsyncTime(JNIEnv *, jclass,
jlong nativeRenderer, jlong steadyClockTimeNano) {
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->setVsyncTime(steadyClockTimeNano);
}
@@ -1292,7 +1292,6 @@ public class Engine {
/**
* Switch the command queue to unprotected mode. Protected mode can be activated via
* Renderer::beginFrame() using a protected SwapChain.
* @see Renderer
* @see SwapChain
*/
@@ -1300,6 +1299,13 @@ public class Engine {
nUnprotected(getNativeObject());
}
/**
* Get the current time. This is a convenience function that simply returns the
* time in nanosecond since epoch of std::chrono::steady_clock.
* @return current time in nanosecond since epoch of std::chrono::steady_clock.
* @see Renderer#beginFrame
*/
public static native long getSteadyClockTimeNano();
@UsedByReflection("TextureHelper.java")
public long getNativeObject() {
@@ -346,6 +346,7 @@ public class Material {
public static class Builder {
private Buffer mBuffer;
private int mSize;
private int mShBandCount = 0;
/**
* Specifies the material data. The material data is a binary blob produced by
@@ -361,6 +362,22 @@ public class Material {
return this;
}
/**
* Sets the quality of the indirect lights computations. This is only taken into account
* if this material is lit and in the surface domain. This setting will affect the
* IndirectLight computation if one is specified on the Scene and Spherical Harmonics
* are used for the irradiance.
*
* @param shBandCount Number of spherical harmonic bands. Must be 1, 2 or 3 (default).
* @return Reference to this Builder for chaining calls.
* @see IndirectLight
*/
@NonNull
public Builder sphericalHarmonicsBandCount(@IntRange(from = 0) int shBandCount) {
mShBandCount = shBandCount;
return this;
}
/**
* Creates and returns the Material object.
*
@@ -372,7 +389,8 @@ public class Material {
*/
@NonNull
public Material build(@NonNull Engine engine) {
long nativeMaterial = nBuilderBuild(engine.getNativeObject(), mBuffer, mSize);
long nativeMaterial = nBuilderBuild(engine.getNativeObject(),
mBuffer, mSize, mShBandCount);
if (nativeMaterial == 0) throw new IllegalStateException("Couldn't create Material");
return new Material(nativeMaterial);
}
@@ -1023,7 +1041,7 @@ public class Material {
mNativeObject = 0;
}
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size);
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size, int shBandCount);
private static native long nCreateInstance(long nativeMaterial);
private static native long nCreateInstanceWithName(long nativeMaterial, @NonNull String name);
private static native long nGetDefaultInstance(long nativeMaterial);
@@ -284,6 +284,19 @@ public class Renderer {
nSetPresentationTime(getNativeObject(), monotonicClockNanos);
}
/**
* The use of this method is optional. It sets the VSYNC time expressed as the duration in
* nanosecond since epoch of std::chrono::steady_clock.
* If called, passing 0 to frameTimeNanos in Renderer.BeginFrame will use this
* time instead.
* @param steadyClockTimeNano duration in nanosecond since epoch of std::chrono::steady_clock
* @see Engine#getSteadyClockTimeNano
* @see Renderer#beginFrame
*/
public void setVsyncTime(long steadyClockTimeNano) {
nSetVsyncTime(getNativeObject(), steadyClockTimeNano);
}
/**
* Sets up a frame for this <code>Renderer</code>.
* <p><code>beginFrame</code> manages frame pacing, and returns whether or not a frame should be
@@ -702,6 +715,7 @@ public class Renderer {
}
private static native void nSetPresentationTime(long nativeObject, long monotonicClockNanos);
private static native void nSetVsyncTime(long nativeObject, long steadyClockTimeNano);
private static native boolean nBeginFrame(long nativeRenderer, long nativeSwapChain, long frameTimeNanos);
private static native void nEndFrame(long nativeRenderer);
private static native void nRender(long nativeRenderer, long nativeView);
+15
View File
@@ -1021,6 +1021,21 @@ public:
void resetBackendState() noexcept;
#endif
/**
* Get the current time. This is a convenience function that simply returns the
* time in nanosecond since epoch of std::chrono::steady_clock.
* A possible implementation is:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* return std::chrono::steady_clock::now().time_since_epoch().count();
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @return current time in nanosecond since epoch of std::chrono::steady_clock.
* @see Renderer::beginFrame()
*/
static uint64_t getSteadyClockTimeNano() noexcept;
DebugRegistry& getDebugRegistry() noexcept;
protected:
@@ -158,6 +158,8 @@ public:
*
* @return This Builder, for chaining calls.
*
* @see Material::Builder::sphericalHarmonicsBandCount()
*
* @note
* Because the coefficients are pre-scaled, `sh[0]` is the environment's
* average irradiance.
+12
View File
@@ -140,6 +140,18 @@ public:
return constant(name, strlen(name), value);
}
/**
* Sets the quality of the indirect lights computations. This is only taken into account
* if this material is lit and in the surface domain. This setting will affect the
* IndirectLight computation if one is specified on the Scene and Spherical Harmonics
* are used for the irradiance.
*
* @param shBandCount Number of spherical harmonic bands. Must be 1, 2 or 3 (default).
* @return Reference to this Builder for chaining calls.
* @see IndirectLight
*/
Builder& sphericalHarmonicsBandCount(size_t shBandCount) noexcept;
/**
* Creates the Material object and returns a pointer to it.
*
+11
View File
@@ -227,6 +227,17 @@ public:
static constexpr CopyFrameFlag CLEAR = 0x4;
/**
* The use of this method is optional. It sets the VSYNC time expressed as the duration in
* nanosecond since epoch of std::chrono::steady_clock.
* If called, passing 0 to vsyncSteadyClockTimeNano in Renderer::BeginFrame will use this
* time instead.
* @param steadyClockTimeNano duration in nanosecond since epoch of std::chrono::steady_clock
* @see Engine::getSteadyClockTimeNano()
* @see Renderer::BeginFrame()
*/
void setVsyncTime(uint64_t steadyClockTimeNano) noexcept;
/**
* Set-up a frame for this Renderer.
*
+7 -1
View File
@@ -39,6 +39,8 @@
#include <utils/compiler.h>
#include <utils/Panic.h>
#include <chrono>
#include <stddef.h>
#include <stdint.h>
@@ -361,7 +363,7 @@ const Engine::Config& Engine::getConfig() const noexcept {
return downcast(this)->getConfig();
}
bool Engine::isStereoSupported(StereoscopicType stereoscopicType) const noexcept {
bool Engine::isStereoSupported(StereoscopicType) const noexcept {
return downcast(this)->isStereoSupported();
}
@@ -369,6 +371,10 @@ size_t Engine::getMaxStereoscopicEyes() noexcept {
return FEngine::getMaxStereoscopicEyes();
}
uint64_t Engine::getSteadyClockTimeNano() noexcept {
return std::chrono::steady_clock::now().time_since_epoch().count();
}
#if defined(__EMSCRIPTEN__)
void Engine::resetBackendState() noexcept {
downcast(this)->resetBackendState();
+4
View File
@@ -89,4 +89,8 @@ void Renderer::renderStandaloneView(View const* view) {
downcast(this)->renderStandaloneView(downcast(view));
}
void Renderer::setVsyncTime(uint64_t steadyClockTimeNano) noexcept {
downcast(this)->setVsyncTime(steadyClockTimeNano);
}
} // namespace filament
+8
View File
@@ -122,6 +122,7 @@ struct Material::BuilderDetails {
const void* mPayload = nullptr;
size_t mSize = 0;
bool mDefaultMaterial = false;
int32_t mShBandsCount = 3;
std::unordered_map<
utils::CString,
std::variant<int32_t, float, bool>,
@@ -146,6 +147,11 @@ Material::Builder& Material::Builder::package(const void* payload, size_t size)
return *this;
}
Material::Builder& Material::Builder::sphericalHarmonicsBandCount(size_t shBandCount) noexcept {
mImpl->mShBandsCount = math::clamp(shBandCount, size_t(1), size_t(3));
return *this;
}
template<typename T, typename>
Material::Builder& Material::Builder::constant(const char* name, size_t nameLength, T value) {
FILAMENT_CHECK_PRECONDITION(name != nullptr) << "name cannot be null";
@@ -889,6 +895,8 @@ void FMaterial::processSpecializationConstants(FEngine& engine, Material::Builde
mSpecializationConstants.push_back({
+ReservedSpecializationConstants::CONFIG_STEREO_EYE_COUNT,
(int)engine.getConfig().stereoscopicEyeCount });
mSpecializationConstants.push_back({
+ReservedSpecializationConstants::CONFIG_SH_BANDS_COUNT, builder->mShBandsCount });
if (UTILS_UNLIKELY(parser->getShaderLanguage() == ShaderLanguage::ESSL1)) {
// The actual value of this spec-constant is set in the OpenGLDriver backend.
mSpecializationConstants.push_back({
+9
View File
@@ -232,6 +232,10 @@ void FRenderer::setPresentationTime(int64_t monotonic_clock_ns) {
driver.setPresentationTime(monotonic_clock_ns);
}
void FRenderer::setVsyncTime(uint64_t steadyClockTimeNano) noexcept {
mVsyncSteadyClockTimeNano = steadyClockTimeNano;
}
bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeNano) {
assert_invariant(swapChain);
@@ -252,6 +256,11 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN
}
#endif
if (!vsyncSteadyClockTimeNano) {
vsyncSteadyClockTimeNano = mVsyncSteadyClockTimeNano;
mVsyncSteadyClockTimeNano = 0;
}
// get the timestamp as soon as possible
using namespace std::chrono;
const steady_clock::time_point now{ steady_clock::now() };
+13 -3
View File
@@ -29,9 +29,6 @@
#include "backend/DriverApiForward.h"
#include <fg/FrameGraphId.h>
#include <fg/FrameGraphTexture.h>
#include <filament/Renderer.h>
#include <filament/Viewport.h>
@@ -41,8 +38,18 @@
#include <utils/compiler.h>
#include <utils/Allocator.h>
#include <math/vec4.h>
#include <tsl/robin_set.h>
#include <algorithm>
#include <chrono>
#include <functional>
#include <utility>
#include <stddef.h>
#include <stdint.h>
namespace filament {
namespace backend {
@@ -78,6 +85,8 @@ public:
void setPresentationTime(int64_t monotonic_clock_ns);
void setVsyncTime(uint64_t steadyClockTimeNano) noexcept;
// start a frame
bool beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeNano);
@@ -187,6 +196,7 @@ private:
backend::TargetBufferFlags mClearFlags{};
tsl::robin_set<FRenderTarget*> mPreviousRenderTargets;
std::function<void()> mBeginFrameInternal;
uint64_t mVsyncSteadyClockTimeNano = 0;
};
FILAMENT_DOWNCAST(Renderer)
@@ -81,6 +81,7 @@ enum class ReservedSpecializationConstants : uint8_t {
CONFIG_DEBUG_DIRECTIONAL_SHADOWMAP = 6,
CONFIG_DEBUG_FROXEL_VISUALIZATION = 7,
CONFIG_STEREO_EYE_COUNT = 8, // don't change (hardcoded in ShaderCompilerService.cpp)
CONFIG_SH_BANDS_COUNT = 9
};
enum class PushConstantIds : uint8_t {
@@ -334,6 +334,9 @@ utils::io::sstream& CodeGenerator::generateProlog(utils::io::sstream& out, Shade
generateSpecializationConstant(out, "CONFIG_STEREO_EYE_COUNT",
+ReservedSpecializationConstants::CONFIG_STEREO_EYE_COUNT, material.stereoscopicEyeCount);
generateSpecializationConstant(out, "CONFIG_SH_BANDS_COUNT",
+ReservedSpecializationConstants::CONFIG_SH_BANDS_COUNT, 3);
// CONFIG_MAX_STEREOSCOPIC_EYES is used to size arrays and on Adreno GPUs + vulkan, this has to
// be explicitly, statically defined (as in #define). Otherwise (using const int for
// example), we'd run into a GPU crash.
+19 -18
View File
@@ -2,9 +2,6 @@
// Image based lighting configuration
//------------------------------------------------------------------------------
// Number of spherical harmonics bands (1, 2 or 3)
#define SPHERICAL_HARMONICS_BANDS 3
// IBL integration algorithm
#define IBL_INTEGRATION_PREFILTERED_CUBEMAP 0
#define IBL_INTEGRATION_IMPORTANCE_SAMPLING 1
@@ -44,21 +41,25 @@ vec3 prefilteredDFG(float perceptualRoughness, float NoV) {
//------------------------------------------------------------------------------
vec3 Irradiance_SphericalHarmonics(const vec3 n) {
return max(
frameUniforms.iblSH[0]
#if SPHERICAL_HARMONICS_BANDS >= 2
+ frameUniforms.iblSH[1] * (n.y)
+ frameUniforms.iblSH[2] * (n.z)
+ frameUniforms.iblSH[3] * (n.x)
#endif
#if SPHERICAL_HARMONICS_BANDS >= 3
+ frameUniforms.iblSH[4] * (n.y * n.x)
+ frameUniforms.iblSH[5] * (n.y * n.z)
+ frameUniforms.iblSH[6] * (3.0 * n.z * n.z - 1.0)
+ frameUniforms.iblSH[7] * (n.z * n.x)
+ frameUniforms.iblSH[8] * (n.x * n.x - n.y * n.y)
#endif
, 0.0);
vec3 sphericalHarmonics = frameUniforms.iblSH[0];
if (CONFIG_SH_BANDS_COUNT >= 2) {
sphericalHarmonics +=
frameUniforms.iblSH[1] * (n.y)
+ frameUniforms.iblSH[2] * (n.z)
+ frameUniforms.iblSH[3] * (n.x);
}
if (CONFIG_SH_BANDS_COUNT >= 3) {
sphericalHarmonics +=
frameUniforms.iblSH[4] * (n.y * n.x)
+ frameUniforms.iblSH[5] * (n.y * n.z)
+ frameUniforms.iblSH[6] * (3.0 * n.z * n.z - 1.0)
+ frameUniforms.iblSH[7] * (n.z * n.x)
+ frameUniforms.iblSH[8] * (n.x * n.x - n.y * n.y);
}
return max(sphericalHarmonics, 0.0);
}
vec3 Irradiance_RoughnessOne(const vec3 n) {
+4
View File
@@ -388,6 +388,8 @@ class_<Engine>("Engine")
return Engine::create();
}, allow_raw_pointers())
.class_function("getSteadyClockTimeNano", &Engine::getSteadyClockTimeNano)
.function("unprotected", &Engine::unprotected)
.function("enableAccurateTranslations", &Engine::enableAccurateTranslations)
@@ -623,6 +625,8 @@ class_<Renderer>("Renderer")
}), allow_raw_pointers())
.function("_setClearOptions", &Renderer::setClearOptions, allow_raw_pointers())
.function("getClearOptions", &Renderer::getClearOptions)
.function("setPresentationTime", &Renderer::setPresentationTime)
.function("setVsyncTime", &Renderer::setVsyncTime)
.function("beginFrame", EMBIND_LAMBDA(bool, (Renderer* self, SwapChain* swapChain), {
return self->beginFrame(swapChain);
}), allow_raw_pointers())