From c6cef9ff9c66d9238734afd4487410c672c29980 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Fri, 5 Oct 2018 14:31:42 -0700 Subject: [PATCH] NEW API: add RGBM flag to Texture. This change will allow the skybox use a compressed texture format. For now, the old internal format "RGBM" is still honored, but in a forthcoming change we will replace the enum with UNUSED. --- .../filament-android/src/main/cpp/Texture.cpp | 13 +++++++++++++ .../com/google/android/filament/Texture.java | 11 ++++++++++- .../com/google/android/filament/ibl/IblLoader.kt | 6 ++++-- filament/include/filament/Texture.h | 16 ++++++++++++++++ filament/src/Engine.cpp | 9 +++++---- filament/src/IndirectLight.cpp | 6 ++++++ filament/src/Skybox.cpp | 8 +++++--- filament/src/Texture.cpp | 11 +++++++++++ filament/src/details/Engine.h | 2 +- filament/src/details/Skybox.h | 2 +- filament/src/details/Texture.h | 2 ++ .../include/filament/driver/DriverEnums.h | 4 +++- samples/app/IBL.cpp | 3 ++- samples/web/filaweb.cpp | 6 ++++-- .../android/filament/tungsten/ui/preview/Ibl.kt | 3 ++- 15 files changed, 85 insertions(+), 17 deletions(-) diff --git a/android/filament-android/src/main/cpp/Texture.cpp b/android/filament-android/src/main/cpp/Texture.cpp index 051f62b1b0..8f74bc7f3a 100644 --- a/android/filament-android/src/main/cpp/Texture.cpp +++ b/android/filament-android/src/main/cpp/Texture.cpp @@ -100,6 +100,13 @@ Java_com_google_android_filament_Texture_nBuilderFormat(JNIEnv *env, jclass type builder->format((Texture::InternalFormat) format); } +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_Texture_nBuilderRgbm(JNIEnv *env, jclass type, + jlong nativeBuilder, jboolean enable) { + Texture::Builder *builder = (Texture::Builder *) nativeBuilder; + builder->rgbm(enable); +} + extern "C" JNIEXPORT jlong JNICALL Java_com_google_android_filament_Texture_nBuilderBuild(JNIEnv *env, jclass type, jlong nativeBuilder, jlong nativeEngine) { @@ -150,6 +157,12 @@ Java_com_google_android_filament_Texture_nGetInternalFormat(JNIEnv *env, jclass return (jint) texture->getFormat(); } +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_Texture_nGetRgbm(JNIEnv *env, jclass type, jlong nativeTexture) { + Texture *texture = (Texture *) nativeTexture; + return texture->isRgbm(); +} + extern "C" JNIEXPORT jint JNICALL Java_com_google_android_filament_Texture_nSetImage(JNIEnv *env, jclass type_, jlong nativeTexture, jlong nativeEngine, jint level, jint xoffset, jint yoffset, jint width, jint height, diff --git a/android/filament-android/src/main/java/com/google/android/filament/Texture.java b/android/filament-android/src/main/java/com/google/android/filament/Texture.java index 97ad8e91b1..8c8e00dd0c 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/Texture.java +++ b/android/filament-android/src/main/java/com/google/android/filament/Texture.java @@ -59,7 +59,9 @@ public class Texture { R32F, R32UI, R32I, RG16F, RG16UI, RG16I, R11F_G11F_B10F, - RGBA8, SRGB8_A8, RGBA8_SNORM, RGBM, RGB10_A2, RGBA8UI, RGBA8I, + RGBA8, SRGB8_A8, RGBA8_SNORM, + RGBM, // Deprecated but still honored; see Texture.Builder.rgbm + RGB10_A2, RGBA8UI, RGBA8I, DEPTH32F, DEPTH24_STENCIL8, DEPTH32F_STENCIL8, // 48-bits per element @@ -331,6 +333,12 @@ public class Texture { return this; } + @NonNull + public Builder rgbm(@NonNull boolean enabled) { + nBuilderRgbm(mNativeBuilder, enabled); + return this; + } + @NonNull public Texture build(@NonNull Engine engine) { long nativeTexture = nBuilderBuild(mNativeBuilder, engine.getNativeObject()); @@ -484,6 +492,7 @@ public class Texture { private static native void nBuilderLevels(long nativeBuilder, int levels); private static native void nBuilderSampler(long nativeBuilder, int sampler); private static native void nBuilderFormat(long nativeBuilder, int format); + private static native void nBuilderRgbm(long nativeBuilder, boolean enabled); private static native long nBuilderBuild(long nativeBuilder, long nativeEngine); private static native int nGetWidth(long nativeTexture, int level); diff --git a/android/samples/image-based-lighting/app/src/main/java/com/google/android/filament/ibl/IblLoader.kt b/android/samples/image-based-lighting/app/src/main/java/com/google/android/filament/ibl/IblLoader.kt index 4e4ba76135..b5e391b9e0 100644 --- a/android/samples/image-based-lighting/app/src/main/java/com/google/android/filament/ibl/IblLoader.kt +++ b/android/samples/image-based-lighting/app/src/main/java/com/google/android/filament/ibl/IblLoader.kt @@ -65,7 +65,8 @@ private fun loadIndirectLight( .width(w) .height(h) .levels(log2(w.toFloat()).toInt() + 1) - .format(Texture.InternalFormat.RGBM) + .format(Texture.InternalFormat.RGBA8) + .rgbm(true) .sampler(Texture.Sampler.SAMPLER_CUBEMAP) .build(engine) @@ -105,7 +106,8 @@ private fun loadSkybox(assets: AssetManager, name: String, engine: Engine): Pair .width(w) .height(h) .levels(1) - .format(Texture.InternalFormat.RGBM) + .format(Texture.InternalFormat.RGBA8) + .rgbm(true) .sampler(Texture.Sampler.SAMPLER_CUBEMAP) .build(engine) diff --git a/filament/include/filament/Texture.h b/filament/include/filament/Texture.h index 502299ebe9..5186bbf8e5 100644 --- a/filament/include/filament/Texture.h +++ b/filament/include/filament/Texture.h @@ -159,6 +159,16 @@ public: */ Builder& usage(Usage usage) noexcept; + /** + * Specifies that the alpha channel contains a color multiplier (e.g. for HDR) + * The default value is false. + * + * @param enabled True if the shader should interpret alpha as a color multiplier + * + * @return This Builder, for chaining calls. + */ + Builder& rgbm(bool enabled) noexcept; + /** * Creates the Texture object and returns a pointer to it. * @@ -224,6 +234,12 @@ public: */ InternalFormat getFormat() const noexcept; + /** + * Return if this texture has RGBM data as set by Builder::rgbm(). + * @return if this texture has RGBM data as set by Builder::rgbm(). + */ + bool isRgbm() const noexcept; + /** * Specify the image of a 2D texture for a level. * diff --git a/filament/src/Engine.cpp b/filament/src/Engine.cpp index 35fdeacb7b..2706306526 100644 --- a/filament/src/Engine.cpp +++ b/filament/src/Engine.cpp @@ -213,7 +213,8 @@ void FEngine::init() { mDefaultIblTexture = upcast(Texture::Builder() .width(1).height(1).levels(1) - .format(Texture::InternalFormat::RGBM) + .format(Texture::InternalFormat::RGBA8) + .rgbm(true) .sampler(Texture::Sampler::SAMPLER_CUBEMAP) .build(*this)); static uint32_t pixel = 0; @@ -416,11 +417,11 @@ void FEngine::flushCommandBuffer(CommandBufferQueue& commandQueue) { commandQueue.flush(); } -const FMaterial* FEngine::getSkyboxMaterial(driver::TextureFormat format) const noexcept { - size_t index = (format == driver::TextureFormat::RGBM) ? 0 : 1; +const FMaterial* FEngine::getSkyboxMaterial(bool rgbm) const noexcept { + size_t index = rgbm ? 0 : 1; FMaterial const* material = mSkyboxMaterials[index]; if (UTILS_UNLIKELY(material == nullptr)) { - material = FSkybox::createMaterial(*const_cast(this), format); + material = FSkybox::createMaterial(*const_cast(this), rgbm); mSkyboxMaterials[index] = material; } return material; diff --git a/filament/src/IndirectLight.cpp b/filament/src/IndirectLight.cpp index a82994477f..21965120d5 100644 --- a/filament/src/IndirectLight.cpp +++ b/filament/src/IndirectLight.cpp @@ -90,6 +90,12 @@ IndirectLight* IndirectLight::Builder::build(Engine& engine) { return nullptr; } + if (!ASSERT_POSTCONDITION_NON_FATAL( mImpl->mReflectionsMap->isRgbm() || + mImpl->mReflectionsMap->getFormat() == Texture::InternalFormat::RGBM, + "reflection map must have RGBM enabled")) { + return nullptr; + } + if (!ASSERT_POSTCONDITION_NON_FATAL(mImpl->mReflectionsMap->getLevels() == 9 || mImpl->mReflectionsMap->getLevels() == 1, "reflection map must be 256x256 and have 9 mipmap levels")) { diff --git a/filament/src/Skybox.cpp b/filament/src/Skybox.cpp index 6db7d7db95..a182b0f971 100644 --- a/filament/src/Skybox.cpp +++ b/filament/src/Skybox.cpp @@ -95,7 +95,9 @@ FSkybox::FSkybox(FEngine& engine, const Builder& builder) noexcept : mSkyboxTexture(upcast(builder->mEnvironmentMap)), mRenderableManager(engine.getRenderableManager()) { - FMaterial const* material = engine.getSkyboxMaterial(mSkyboxTexture->getFormat()); + const bool rgbm = mSkyboxTexture->getFormat() == Texture::InternalFormat::RGBM || + mSkyboxTexture->isRgbm(); + FMaterial const* material = engine.getSkyboxMaterial(rgbm); mSkyboxMaterialInstance = material->createInstance(); TextureSampler sampler(TextureSampler::MagFilter::LINEAR, TextureSampler::WrapMode::REPEAT); @@ -116,8 +118,8 @@ FSkybox::FSkybox(FEngine& engine, const Builder& builder) noexcept .build(engine, mSkybox); } -FMaterial const* FSkybox::createMaterial(FEngine& engine, driver::TextureFormat format) { - if (format == driver::TextureFormat::RGBM) { +FMaterial const* FSkybox::createMaterial(FEngine& engine, bool rgbm) { + if (rgbm) { FMaterial const* material = upcast(Material::Builder().package( (void*)SKYBOXRGBM_MATERIAL_PACKAGE, sizeof(SKYBOXRGBM_MATERIAL_PACKAGE)).build(engine)); diff --git a/filament/src/Texture.cpp b/filament/src/Texture.cpp index efa4f0a7e3..be4da9e087 100644 --- a/filament/src/Texture.cpp +++ b/filament/src/Texture.cpp @@ -35,6 +35,7 @@ struct Texture::BuilderDetails { uint8_t mLevels = 1; Sampler mTarget = Sampler::SAMPLER_2D; InternalFormat mFormat = InternalFormat::RGBA8; + bool mRgbm = false; Usage mUsage = Usage::DEFAULT; }; @@ -77,6 +78,11 @@ Texture::Builder& Texture::Builder::format(Texture::InternalFormat format) noexc return *this; } +Texture::Builder& Texture::Builder::rgbm(bool enabled) noexcept { + mImpl->mRgbm = enabled; + return *this; +} + Texture::Builder& Texture::Builder::usage(Texture::Usage usage) noexcept { mImpl->mUsage = usage; return *this; @@ -98,6 +104,7 @@ FTexture::FTexture(FEngine& engine, const Builder& builder) { mWidth = static_cast(builder->mWidth); mHeight = static_cast(builder->mHeight); mFormat = builder->mFormat; + mRgbm = builder->mRgbm; mUsage = builder->mUsage; mTarget = builder->mTarget; mDepth = static_cast(builder->mDepth); @@ -308,6 +315,10 @@ Texture::InternalFormat Texture::getFormat() const noexcept { return upcast(this)->getFormat(); } +bool Texture::isRgbm() const noexcept { + return upcast(this)->isRgbm(); +} + void Texture::setImage(Engine& engine, size_t level, Texture::PixelBufferDescriptor&& buffer) const noexcept { upcast(this)->setImage(upcast(engine), diff --git a/filament/src/details/Engine.h b/filament/src/details/Engine.h index cc17510ff3..7ef2f07bfc 100644 --- a/filament/src/details/Engine.h +++ b/filament/src/details/Engine.h @@ -207,7 +207,7 @@ public: uint32_t getMaterialId() const noexcept { return mMaterialId++; } const FMaterial* getDefaultMaterial() const noexcept { return mDefaultMaterial; } - const FMaterial* getSkyboxMaterial(driver::TextureFormat format) const noexcept; + const FMaterial* getSkyboxMaterial(bool rgbm) const noexcept; const FIndirectLight* getDefaultIndirectLight() const noexcept { return mDefaultIbl; } Handle getPostProcessProgramSlow(PostProcessStage stage) const noexcept; diff --git a/filament/src/details/Skybox.h b/filament/src/details/Skybox.h index e396f614ed..62db032b13 100644 --- a/filament/src/details/Skybox.h +++ b/filament/src/details/Skybox.h @@ -42,7 +42,7 @@ class FSkybox : public Skybox { public: FSkybox(FEngine& engine, const Builder& builder) noexcept; - static FMaterial const* createMaterial(FEngine& engine, driver::TextureFormat format); + static FMaterial const* createMaterial(FEngine& engine, bool rgbm); void terminate(FEngine& engine) noexcept; diff --git a/filament/src/details/Texture.h b/filament/src/details/Texture.h index 1f796d3dd0..dc9fc80fab 100644 --- a/filament/src/details/Texture.h +++ b/filament/src/details/Texture.h @@ -50,6 +50,7 @@ public: size_t getLevels() const noexcept { return mLevels; } Sampler getTarget() const noexcept { return mTarget; } InternalFormat getFormat() const noexcept { return mFormat; } + bool isRgbm() const noexcept { return mRgbm; } void setImage(FEngine& engine, size_t level, uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height, @@ -80,6 +81,7 @@ private: uint32_t mHeight = 1; uint32_t mDepth = 1; InternalFormat mFormat = InternalFormat::RGBA8; + bool mRgbm = false; Sampler mTarget = Sampler::SAMPLER_2D; uint8_t mLevels = 1; uint8_t mSampleCount = 1; diff --git a/libs/filabridge/include/filament/driver/DriverEnums.h b/libs/filabridge/include/filament/driver/DriverEnums.h index 752f47e22b..4e8ff87d22 100644 --- a/libs/filabridge/include/filament/driver/DriverEnums.h +++ b/libs/filabridge/include/filament/driver/DriverEnums.h @@ -367,7 +367,9 @@ enum class TextureFormat : uint16_t { R32F, R32UI, R32I, RG16F, RG16UI, RG16I, R11F_G11F_B10F, - RGBA8, SRGB8_A8,RGBA8_SNORM, RGBM, RGB10_A2, RGBA8UI, RGBA8I, + RGBA8, SRGB8_A8,RGBA8_SNORM, + RGBM, // Deprecated but still honored; see Texture::Builder::rgbm + RGB10_A2, RGBA8UI, RGBA8I, DEPTH32F, DEPTH24_STENCIL8, DEPTH32F_STENCIL8, // 48-bits per element diff --git a/samples/app/IBL.cpp b/samples/app/IBL.cpp index 4fa750916d..53597c96ae 100644 --- a/samples/app/IBL.cpp +++ b/samples/app/IBL.cpp @@ -115,7 +115,8 @@ bool IBL::loadCubemapLevel(filament::Texture** texture, const utils::Path& path, .width((uint32_t)size) .height((uint32_t)size) .levels((uint8_t)numLevels) - .format(Texture::InternalFormat::RGBM) + .format(Texture::InternalFormat::RGBA8) + .rgbm(true) .sampler(Texture::Sampler::SAMPLER_CUBEMAP) .build(mEngine); } diff --git a/samples/web/filaweb.cpp b/samples/web/filaweb.cpp index e00142464c..a78ae627ac 100644 --- a/samples/web/filaweb.cpp +++ b/samples/web/filaweb.cpp @@ -240,7 +240,8 @@ SkyLight getSkyLight(Engine& engine, const char* name) { .width(info.pixelWidth) .height(info.pixelHeight) .levels(nmips) - .format(Texture::InternalFormat::RGBM) + .format(Texture::InternalFormat::RGBA8) + .rgbm(true) .sampler(Texture::Sampler::SAMPLER_CUBEMAP) .build(engine); size_t size = info.pixelWidth; @@ -282,7 +283,8 @@ SkyLight getSkyLight(Engine& engine, const char* name) { .width(size) .height(size) .levels(1) - .format(Texture::InternalFormat::RGBM) + .format(Texture::InternalFormat::RGBA8) + .rgbm(true) .sampler(Texture::Sampler::SAMPLER_CUBEMAP) .build(engine); { diff --git a/tools/tungsten/core/src/com/google/android/filament/tungsten/ui/preview/Ibl.kt b/tools/tungsten/core/src/com/google/android/filament/tungsten/ui/preview/Ibl.kt index a9be42523d..8e1da70528 100644 --- a/tools/tungsten/core/src/com/google/android/filament/tungsten/ui/preview/Ibl.kt +++ b/tools/tungsten/core/src/com/google/android/filament/tungsten/ui/preview/Ibl.kt @@ -128,7 +128,8 @@ internal class Ibl(val engine: Engine, private val pathPrefix: String) { .width(size) .height(size) .levels(levels) - .format(Texture.InternalFormat.RGBM) + .format(Texture.InternalFormat.RGBA8) + .rgbm() .sampler(Texture.Sampler.SAMPLER_CUBEMAP) .build(engine)