From 20abfec7d3256f3437b402f10fa3bc909fc48388 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Mon, 12 Oct 2020 11:15:37 -0700 Subject: [PATCH 01/14] Minor change to adhere to CODE_STYLE. --- libs/image/src/ImageSampler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/image/src/ImageSampler.cpp b/libs/image/src/ImageSampler.cpp index fbc7a0ea02d..00385e93231 100644 --- a/libs/image/src/ImageSampler.cpp +++ b/libs/image/src/ImageSampler.cpp @@ -362,7 +362,7 @@ uint32_t getMipmapCount(const LinearImage& source) { Filter filterFromString(const char* rawname) { using namespace utils; - using namespace std; + using std::unordered_map; static const unordered_map map = { { "BOX", Filter::BOX}, { "NEAREST", Filter::NEAREST}, @@ -373,7 +373,7 @@ Filter filterFromString(const char* rawname) { { "LANCZOS", Filter::LANCZOS}, { "MINIMUM", Filter::MINIMUM}, }; - string name = rawname; + std::string name = rawname; for (auto& c: name) { c = toupper((unsigned char)c); } auto iter = map.find(StaticString::make(name.c_str(), name.size())); return iter == map.end() ? Filter::DEFAULT : iter->second; From 37768ed9e190f6acb5dd8adf09243a32d0fee06f Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Mon, 12 Oct 2020 17:09:04 -0700 Subject: [PATCH 02/14] Various changes to help clients upgrade Filament. The non-const getSkybox() method is especially useful to client code that needs to change the clear color, but does not have direct access to the Renderer object. --- filament/include/filament/Renderer.h | 2 ++ filament/include/filament/Scene.h | 16 +++++++++++++++- filament/src/Scene.cpp | 8 ++++++++ libs/utils/include/utils/compiler.h | 2 +- libs/utils/src/linux/futex.h | 2 ++ 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/filament/include/filament/Renderer.h b/filament/include/filament/Renderer.h index 00d465b621a..a8c95b54676 100644 --- a/filament/include/filament/Renderer.h +++ b/filament/include/filament/Renderer.h @@ -25,6 +25,8 @@ #include +#include + #include namespace filament { diff --git a/filament/include/filament/Scene.h b/filament/include/filament/Scene.h index 244106957c2..7ef5c22f93d 100644 --- a/filament/include/filament/Scene.h +++ b/filament/include/filament/Scene.h @@ -66,7 +66,7 @@ class UTILS_PUBLIC Scene : public FilamentAPI { public: /** - * Sets the SkyBox. + * Sets the Skybox. * * The Skybox is drawn last and covers all pixels not touched by geometry. * @@ -74,6 +74,20 @@ class UTILS_PUBLIC Scene : public FilamentAPI { */ void setSkybox(Skybox* skybox) noexcept; + /** + * Returns the Skybox associated with the Scene. + * + * @return The associated Skybox, or nullptr if there is none. + */ + Skybox* getSkybox() noexcept; + + /** + * Returns an immutable Skybox associated with the Scene. + * + * @return The associated Skybox, or nullptr if there is none. + */ + Skybox const* getSkybox() const noexcept; + /** * Set the IndirectLight to use when rendering the Scene. * diff --git a/filament/src/Scene.cpp b/filament/src/Scene.cpp index 2ca3f5d4baa..6d3e7e860c4 100644 --- a/filament/src/Scene.cpp +++ b/filament/src/Scene.cpp @@ -442,6 +442,14 @@ void Scene::setSkybox(Skybox* skybox) noexcept { upcast(this)->setSkybox(upcast(skybox)); } +Skybox* Scene::getSkybox() noexcept { + return upcast(this)->getSkybox(); +} + +Skybox const* Scene::getSkybox() const noexcept { + return upcast(this)->getSkybox(); +} + void Scene::setIndirectLight(IndirectLight const* ibl) noexcept { upcast(this)->setIndirectLight(upcast(ibl)); } diff --git a/libs/utils/include/utils/compiler.h b/libs/utils/include/utils/compiler.h index f6e61be5f79..97e479f30f4 100644 --- a/libs/utils/include/utils/compiler.h +++ b/libs/utils/include/utils/compiler.h @@ -190,7 +190,7 @@ // ssize_t is a POSIX type. #if defined(WIN32) || defined(_WIN32) -#include +#include typedef SSIZE_T ssize_t; #endif diff --git a/libs/utils/src/linux/futex.h b/libs/utils/src/linux/futex.h index 825ef2c8327..89134418e0f 100644 --- a/libs/utils/src/linux/futex.h +++ b/libs/utils/src/linux/futex.h @@ -23,6 +23,8 @@ #include #include +#include + struct timespec; namespace utils { From e74e583b979996156609c336c937f3f71868bfd6 Mon Sep 17 00:00:00 2001 From: Benjamin Doherty Date: Tue, 13 Oct 2020 15:16:25 -0600 Subject: [PATCH 03/14] Fix CocoaPod version --- ios/CocoaPods/Filament.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/CocoaPods/Filament.podspec b/ios/CocoaPods/Filament.podspec index 32eb26a0f4b..fe2ebb25865 100644 --- a/ios/CocoaPods/Filament.podspec +++ b/ios/CocoaPods/Filament.podspec @@ -6,7 +6,7 @@ Pod::Spec.new do |spec| spec.authors = "Google LLC." spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL." spec.platform = :ios, "11.0" - spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.3/filament-v1.9.3-ios.tgz" } + spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.4/filament-v1.9.4-ios.tgz" } # Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon. spec.pod_target_xcconfig = { From 62d06592d3b7032c6b1625b6c5407373935ee1ba Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Wed, 14 Oct 2020 11:48:23 -0600 Subject: [PATCH 04/14] VSM: add support for mipmaps and anisotropic sampling (#3185) --- RELEASE_NOTES.md | 3 ++ .../filament-android/src/main/cpp/View.cpp | 9 ++++ .../com/google/android/filament/View.java | 52 ++++++++++++++++++ filament/CMakeLists.txt | 1 + filament/include/filament/View.h | 38 +++++++++++++ filament/src/PostProcessManager.cpp | 54 ++++++++++++++++++- filament/src/PostProcessManager.h | 4 ++ filament/src/ShadowMapManager.cpp | 48 ++++++++++++++--- filament/src/View.cpp | 18 +++++-- filament/src/details/ShadowMapManager.h | 7 +-- filament/src/details/View.h | 9 ++++ filament/src/materials/vsmMipmap.mat | 42 +++++++++++++++ libs/filamat/src/Enums.cpp | 1 + libs/viewer/include/viewer/Settings.h | 2 + libs/viewer/src/Settings.cpp | 33 ++++++++++++ libs/viewer/src/SimpleViewer.cpp | 6 +++ libs/viewer/tests/test_settings.cpp | 3 ++ 17 files changed, 314 insertions(+), 16 deletions(-) create mode 100644 filament/src/materials/vsmMipmap.mat diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e8a6c0f68d3..4ce0e090205 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,6 +5,9 @@ A new header is inserted each time a *tag* is created. ## Next release (main branch) +- Added View::setVsmShadowOptions (experimental) +- Add anisotropic shadow map sampling with VSM (experimental) + ## v1.9.5 - Added a new Live Wallpaper Android sample diff --git a/android/filament-android/src/main/cpp/View.cpp b/android/filament-android/src/main/cpp/View.cpp index a68ccd61f9f..5bfe01e59d8 100644 --- a/android/filament-android/src/main/cpp/View.cpp +++ b/android/filament-android/src/main/cpp/View.cpp @@ -136,6 +136,15 @@ Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nati view->setShadowType((View::ShadowType) type); } +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_View_nSetVsmShadowOptions(JNIEnv*, jclass, jlong nativeView, + jint anisotropy) { + View* view = (View*) nativeView; + View::VsmShadowOptions options; + options.anisotropy = (uint8_t) anisotropy; + view->setVsmShadowOptions(options); +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_View_nSetRenderQuality(JNIEnv*, jclass, diff --git a/android/filament-android/src/main/java/com/google/android/filament/View.java b/android/filament-android/src/main/java/com/google/android/filament/View.java index a3cf9719333..55398823bd7 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/View.java +++ b/android/filament-android/src/main/java/com/google/android/filament/View.java @@ -75,6 +75,7 @@ public class View { private VignetteOptions mVignetteOptions; private ColorGrading mColorGrading; private TemporalAntiAliasingOptions mTemporalAntiAliasingOptions; + private VsmShadowOptions mVsmShadowOptions; /** * Generic quality level. @@ -582,6 +583,25 @@ public enum ShadowType { VSM } + /** + * View-level options for VSM shadowing. + * + * @see View#setVsmShadowOptions + */ + public static class VsmShadowOptions { + /** + * Sets the number of anisotropic samples to use when sampling a VSM shadow map. If greater + * than 0, mipmaps will automatically be generated each frame for all lights. + * + *

+ * The number of anisotropic samples = 2 ^ vsmAnisotropy. + *

+ * + * Warning: This API is still experimental and subject to change. + */ + public int anisotropy = 0; + } + /** * Used to select buffers. */ @@ -1182,6 +1202,37 @@ public void setShadowType(ShadowType type) { nSetShadowType(getNativeObject(), type.ordinal()); } + /** + * Sets VSM shadowing options that apply across the entire View. + * + * Additional light-specific VSM options can be set with + * {@link LightManager.Builder#shadowOptions}. + * + * Only applicable when shadow type is set to ShadowType::VSM. + * + * Warning: This API is still experimental and subject to change. + * + * @param options Options for shadowing. + * @see #setShadowType + */ + public void setVsmShadowOptions(@NonNull VsmShadowOptions options) { + mVsmShadowOptions = options; + nSetVsmShadowOptions(getNativeObject(), options.anisotropy); + } + + /** + * Gets the VSM shadowing options. + * @see #setVsmShadowOptions + * @return VSM shadow options currently set. + */ + @NonNull + public VsmShadowOptions getVsmShadowOptions() { + if (mVsmShadowOptions == null) { + mVsmShadowOptions = new VsmShadowOptions(); + } + return mVsmShadowOptions; + } + /** * Activates or deactivates ambient occlusion. * @see #setAmbientOcclusionOptions @@ -1374,6 +1425,7 @@ void clearNativeObject() { private static native void nSetRenderQuality(long nativeView, int hdrColorBufferQuality); private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar); private static native void nSetShadowType(long nativeView, int type); + private static native void nSetVsmShadowOptions(long nativeView, int anisotropy); private static native void nSetColorGrading(long nativeView, long nativeColorGrading); private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled); private static native boolean nIsPostProcessingEnabled(long nativeView); diff --git a/filament/CMakeLists.txt b/filament/CMakeLists.txt index 3132507ecc2..bbf09606884 100644 --- a/filament/CMakeLists.txt +++ b/filament/CMakeLists.txt @@ -170,6 +170,7 @@ set(MATERIAL_SRCS src/materials/separableGaussianBlur.mat src/materials/antiAliasing/fxaa.mat src/materials/antiAliasing/taa.mat + src/materials/vsmMipmap.mat ) # Embed the binary resource blob for materials. diff --git a/filament/include/filament/View.h b/filament/include/filament/View.h index 4e649a0b397..571acb51f0c 100644 --- a/filament/include/filament/View.h +++ b/filament/include/filament/View.h @@ -279,6 +279,22 @@ class UTILS_PUBLIC View : public FilamentAPI { VSM //!< variance shadows }; + /** + * View-level options for VSM Shadowing. + * @see setVsmShadowOptions() + */ + struct VsmShadowOptions { + /** + * Sets the number of anisotropic samples to use when sampling a VSM shadow map. If greater + * than 0, mipmaps will automatically be generated each frame for all lights. + * + * The number of anisotropic samples = 2 ^ vsmAnisotropy. + * + * @warning This API is still experimental and subject to change. + */ + uint8_t anisotropy = 0; + }; + /** * Sets the View's name. Only useful for debugging. * @param name Pointer to the View's name. The string is copied. @@ -702,6 +718,28 @@ class UTILS_PUBLIC View : public FilamentAPI { */ void setShadowType(ShadowType shadow) noexcept; + /** + * Sets VSM shadowing options that apply across the entire View. + * + * Additional light-specific VSM options can be set with LightManager::setShadowOptions. + * + * Only applicable when shadow type is set to ShadowType::VSM. + * + * @param options Options for shadowing. + * + * @see setShadowType + * + * @warning This API is still experimental and subject to change. + */ + void setVsmShadowOptions(VsmShadowOptions const& options) noexcept; + + /** + * Returns the VSM shadowing options associated with this View. + * + * @return value set by setVsmShadowOptions(). + */ + VsmShadowOptions getVsmShadowOptions() const noexcept; + /** * Enables or disables post processing. Enabled by default. * diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index ce6007c3e8c..133f52264ec 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -193,6 +193,7 @@ void PostProcessManager::init() noexcept { registerPostProcessMaterial("sao", MATERIAL(SAO)); registerPostProcessMaterial("mipmapDepth", MATERIAL(MIPMAPDEPTH)); + registerPostProcessMaterial("vsmMipmap", MATERIAL(VSMMIPMAP)); registerPostProcessMaterial("bilateralBlur", MATERIAL(BILATERALBLUR)); registerPostProcessMaterial("separableGaussianBlur", MATERIAL(SEPARABLEGAUSSIANBLUR)); registerPostProcessMaterial("bloomDownsample", MATERIAL(BLOOMDOWNSAMPLE)); @@ -336,7 +337,6 @@ FrameGraphId PostProcessManager::mipmapPass(FrameGraph& fg, FrameGraphId in; FrameGraphId out; FrameGraphRenderTargetHandle rt; - }; auto& depthMipmapPass = fg.addPass("Depth Mipmap Pass", @@ -1945,4 +1945,56 @@ FrameGraphId PostProcessManager::resolve(FrameGraph& fg, return ppResolve.getData().output; } +FrameGraphId PostProcessManager::vsmMipmapPass(FrameGraph& fg, + FrameGraphId input, uint8_t layer, size_t level) noexcept { + + struct VsmMipData { + FrameGraphId in; + FrameGraphId out; + FrameGraphRenderTargetHandle rt; + }; + + auto& depthMipmapPass = fg.addPass("VSM Generate Mipmap Pass", + [&](FrameGraph::Builder& builder, auto& data) { + const char* name = builder.getName(input); + data.in = builder.sample(input); + data.out = builder.write(data.in); + + data.rt = builder.createRenderTarget(name, { + .attachments = {{ data.out, uint8_t(level + 1), layer }}, + .clearColor = { 1.0f, 1.0f, 1.0f, 1.0f }, + .clearFlags = TargetBufferFlags::COLOR + }); + }, + [=](FrameGraphPassResources const& resources, + auto const& data, DriverApi& driver) { + + auto in = resources.getTexture(data.in); + auto out = resources.get(data.rt); + + auto width = resources.getDescriptor(data.in).width; + UTILS_UNUSED_IN_RELEASE auto height = resources.getDescriptor(data.in).height; + assert(width == height); + int dim = width >> (level + 1); + + auto& material = getPostProcessMaterial("vsmMipmap"); + FMaterialInstance* const mi = material.getMaterialInstance(); + mi->setParameter("color", in, { + .filterMag = SamplerMagFilter::LINEAR, + .filterMin = SamplerMinFilter::LINEAR_MIPMAP_NEAREST + }); + mi->setParameter("level", uint32_t(level)); + mi->setParameter("layer", uint32_t(layer)); + mi->setParameter("uvscale", 1.0f / dim); + + // When generating shadow map mip levels, we want to preserve the 1 texel border. + auto vpWidth = (uint32_t) std::max(0, dim - 2); + out.params.viewport = { 1, 1, vpWidth, vpWidth }; + + commitAndRender(out, material, driver); + }); + + return depthMipmapPass.getData().out; +} + } // namespace filament diff --git a/filament/src/PostProcessManager.h b/filament/src/PostProcessManager.h index 03b0eb5bf9e..0ec62a94b2d 100644 --- a/filament/src/PostProcessManager.h +++ b/filament/src/PostProcessManager.h @@ -123,6 +123,10 @@ class PostProcessManager { FrameGraphId resolve(FrameGraph& fg, const char* outputBufferName, FrameGraphId input) noexcept; + // VSM shadow mipmap pass + FrameGraphId vsmMipmapPass(FrameGraph& fg, + FrameGraphId input, uint8_t layer, size_t level) noexcept; + backend::Handle getOneTexture() const { return mDummyOneTexture; } backend::Handle getZeroTexture() const { return mDummyZeroTexture; } backend::Handle getOneTextureArray() const { return mDummyOneTextureArray; } diff --git a/filament/src/ShadowMapManager.cpp b/filament/src/ShadowMapManager.cpp index 77514bf059b..386553247f1 100644 --- a/filament/src/ShadowMapManager.cpp +++ b/filament/src/ShadowMapManager.cpp @@ -16,6 +16,7 @@ #include "details/ShadowMap.h" #include "details/ShadowMapManager.h" +#include "details/Texture.h" #include "details/View.h" #include "RenderPass.h" @@ -47,7 +48,7 @@ ShadowMapManager::ShadowTechnique ShadowMapManager::update( FEngine& engine, FView& view, UniformBuffer& perViewUb, UniformBuffer& shadowUb, FScene::RenderableSoa& renderableData, FScene::LightSoa& lightData) noexcept { - calculateTextureRequirements(engine, lightData); + calculateTextureRequirements(engine, view, lightData); ShadowTechnique shadowTechnique = {}; shadowTechnique |= updateCascadeShadowMaps(engine, view, perViewUb, renderableData, lightData); shadowTechnique |= updateSpotShadowMaps(engine, view, shadowUb, renderableData, lightData); @@ -131,7 +132,7 @@ void ShadowMapManager::render(FrameGraph& fg, FEngine& engine, FView& view, FrameGraphTexture::Descriptor shadowTextureDesc { .width = mTextureRequirements.size, .height = mTextureRequirements.size, .depth = mTextureRequirements.layers, - .levels = 1, + .levels = mTextureRequirements.levels, .type = SamplerType::SAMPLER_2D_ARRAY, .format = mTextureFormat, .usage = TextureUsage::DEPTH_ATTACHMENT | TextureUsage::SAMPLEABLE @@ -240,15 +241,35 @@ void ShadowMapManager::render(FrameGraph& fg, FEngine& engine, FView& view, shadows = debugPatternPass.getData().shadows; } + // If the shadow texture has more than one level, then anisotropy was specified and we should + // generate VSM mipmaps. + if (mTextureRequirements.levels > 1) { + auto& ppm = engine.getPostProcessManager(); + for (uint8_t layer = 0; layer < mTextureRequirements.layers; layer++) { + for (size_t level = 0; level < mTextureRequirements.levels - 1; level++) { + shadows = ppm.vsmMipmapPass(fg, shadows, layer, level); + } + } + } + fg.getBlackboard().put("shadows", shadows); } void ShadowMapManager::prepareShadow(backend::Handle texture, - backend::SamplerGroup& viewSib) const noexcept { - viewSib.setSampler(PerViewSib::SHADOW_MAP, { + FView const& view) const noexcept { + uint8_t anisotropy = 0; + SamplerMinFilter filterMin = SamplerMinFilter::LINEAR; + if (view.hasVsm()) { + anisotropy = view.getVsmShadowOptions().anisotropy; + if (anisotropy > 0) { + filterMin = SamplerMinFilter::LINEAR_MIPMAP_LINEAR; + } + } + view.getViewSamplers().setSampler(PerViewSib::SHADOW_MAP, { texture, { .filterMag = SamplerMagFilter::LINEAR, - .filterMin = SamplerMinFilter::LINEAR, + .filterMin = filterMin, + .anisotropyLog2 = anisotropy, .compareMode = SamplerCompareMode::COMPARE_TO_TEXTURE, .compareFunc = SamplerCompareFunc::GE }}); @@ -500,7 +521,7 @@ void ShadowMapManager::fillWithDebugPattern(backend::DriverApi& driverApi, } } -void ShadowMapManager::calculateTextureRequirements(FEngine& engine, +void ShadowMapManager::calculateTextureRequirements(FEngine& engine, FView& view, FScene::LightSoa& lightData) noexcept { auto& lcm = engine.getLightManager(); @@ -546,9 +567,22 @@ void ShadowMapManager::calculateTextureRequirements(FEngine& engine, } const uint8_t layersNeeded = layer; + + // Only generate mipmaps for VSM when anisotropy is enabled. + const bool useMipmapping = view.hasVsm() && view.getVsmShadowOptions().anisotropy > 0; + + uint8_t mipLevels = 1u; + if (useMipmapping) { + // Limit the lowest mipmap level to 256x256. + // This avoids artifacts on high derivative tangent surfaces. + int lowMipmapLevel = 7; // log2(256) - 1 + mipLevels = std::max(1, FTexture::maxLevelCount(maxDimension) - lowMipmapLevel); + } + mTextureRequirements = { maxDimension, - layersNeeded + layersNeeded, + mipLevels }; } diff --git a/filament/src/View.cpp b/filament/src/View.cpp index c121affbd2a..cbcf7b23bfa 100644 --- a/filament/src/View.cpp +++ b/filament/src/View.cpp @@ -677,7 +677,7 @@ void FView::prepareStructure(backend::Handle structure) cons } void FView::prepareShadow(backend::Handle texture) const noexcept { - mShadowMapManager.prepareShadow(texture, mPerViewSb); + mShadowMapManager.prepareShadow(texture, *this); } void FView::cleanupRenderPasses() const noexcept { @@ -993,6 +993,18 @@ void View::setDynamicLightingOptions(float zLightNear, float zLightFar) noexcept upcast(this)->setDynamicLightingOptions(zLightNear, zLightFar); } +void View::setShadowType(View::ShadowType shadow) noexcept { + upcast(this)->setShadowType(shadow); +} + +void View::setVsmShadowOptions(VsmShadowOptions const& options) noexcept { + upcast(this)->setVsmShadowOptions(options); +} + +View::VsmShadowOptions View::getVsmShadowOptions() const noexcept { + return upcast(this)->getVsmShadowOptions(); +} + void View::setAmbientOcclusion(View::AmbientOcclusion ambientOcclusion) noexcept { upcast(this)->setAmbientOcclusion(ambientOcclusion); } @@ -1005,10 +1017,6 @@ void View::setAmbientOcclusionOptions(View::AmbientOcclusionOptions const& optio upcast(this)->setAmbientOcclusionOptions(options); } -void View::setShadowType(View::ShadowType shadow) noexcept { - upcast(this)->setShadowType(shadow); -} - View::AmbientOcclusionOptions const& View::getAmbientOcclusionOptions() const noexcept { return upcast(this)->getAmbientOcclusionOptions(); } diff --git a/filament/src/details/ShadowMapManager.h b/filament/src/details/ShadowMapManager.h index cc088e47cf4..1d4fa75412d 100644 --- a/filament/src/details/ShadowMapManager.h +++ b/filament/src/details/ShadowMapManager.h @@ -74,8 +74,8 @@ class ShadowMapManager { RenderPass& pass) noexcept; // Prepares the shadow sampler. - void prepareShadow(backend::Handle texture, - backend::SamplerGroup& viewSib) const noexcept; + void prepareShadow(backend::Handle texture, FView const& view) + const noexcept; const ShadowMap* getCascadeShadowMap(size_t c) const noexcept { return mCascadeShadowMapCache[c].get(); @@ -92,6 +92,7 @@ class ShadowMapManager { struct TextureRequirements { uint16_t size = 0; uint8_t layers = 0; + uint8_t levels = 0; } mTextureRequirements; ShadowTechnique updateCascadeShadowMaps(FEngine& engine, FView& view, UniformBuffer& perViewUb, @@ -101,7 +102,7 @@ class ShadowMapManager { static void fillWithDebugPattern(backend::DriverApi& driverApi, backend::Handle texture, size_t dimensions) noexcept; - void calculateTextureRequirements(FEngine& engine, FScene::LightSoa& lightData) noexcept; + void calculateTextureRequirements(FEngine& engine, FView& view, FScene::LightSoa& lightData) noexcept; class ShadowMapEntry { public: diff --git a/filament/src/details/View.h b/filament/src/details/View.h index 8652956b953..202fd37bb30 100644 --- a/filament/src/details/View.h +++ b/filament/src/details/View.h @@ -319,6 +319,14 @@ class FView : public View { mShadowType = shadow; } + void setVsmShadowOptions(VsmShadowOptions const& options) noexcept { + mVsmShadowOptions = options; + } + + VsmShadowOptions getVsmShadowOptions() const noexcept { + return mVsmShadowOptions; + } + AmbientOcclusionOptions const& getAmbientOcclusionOptions() const noexcept { return mAmbientOcclusionOptions; } @@ -479,6 +487,7 @@ class FView : public View { bool mHasPostProcessPass = true; AmbientOcclusionOptions mAmbientOcclusionOptions{}; ShadowType mShadowType = ShadowType::PCF; + VsmShadowOptions mVsmShadowOptions = {}; BloomOptions mBloomOptions; FogOptions mFogOptions; DepthOfFieldOptions mDepthOfFieldOptions; diff --git a/filament/src/materials/vsmMipmap.mat b/filament/src/materials/vsmMipmap.mat new file mode 100644 index 00000000000..70e65b8f344 --- /dev/null +++ b/filament/src/materials/vsmMipmap.mat @@ -0,0 +1,42 @@ +material { + name : vsmMipmap, + parameters : [ + { + type : sampler2dArray, + name : color, + precision: high + }, + { + type : int, + name : layer + }, + { + type : int, + name : level + }, + { + type : float, + name : uvscale + } + ], + outputs : [ + { + name : color, + target : color, + type : float4 + } + ], + domain : postprocess, + depthWrite : false, + depthCulling : false, + culling: none +} + +fragment { + void postProcess(inout PostProcessInputs postProcess) { + highp vec2 uv = gl_FragCoord.xy * materialParams.uvscale; + postProcess.color = textureLod(materialParams_color, + vec3(uv, materialParams.layer), + float(materialParams.level)); + } +} diff --git a/libs/filamat/src/Enums.cpp b/libs/filamat/src/Enums.cpp index a1e319b1089..653d498e980 100644 --- a/libs/filamat/src/Enums.cpp +++ b/libs/filamat/src/Enums.cpp @@ -83,6 +83,7 @@ std::unordered_map& Enums::getMap() noexc std::unordered_map Enums::mStringToSamplerType = { { "sampler2d", SamplerType::SAMPLER_2D }, + { "sampler2dArray", SamplerType::SAMPLER_2D_ARRAY }, { "sampler3d", SamplerType::SAMPLER_3D }, { "samplerCubemap", SamplerType::SAMPLER_CUBEMAP }, { "samplerExternal", SamplerType::SAMPLER_EXTERNAL }, diff --git a/libs/viewer/include/viewer/Settings.h b/libs/viewer/include/viewer/Settings.h index e487807ba04..535733d2fb0 100644 --- a/libs/viewer/include/viewer/Settings.h +++ b/libs/viewer/include/viewer/Settings.h @@ -49,6 +49,7 @@ using ShadowType = filament::View::ShadowType; using TemporalAntiAliasingOptions = filament::View::TemporalAntiAliasingOptions; using ToneMapping = filament::ColorGrading::ToneMapping; using VignetteOptions = filament::View::VignetteOptions; +using VsmShadowOptions = filament::View::VsmShadowOptions; // Reads the given JSON blob and updates the corresponding fields in the given Settings object. // - The given JSON blob need not specify all settings. @@ -122,6 +123,7 @@ struct ViewSettings { RenderQuality renderQuality; DynamicLightingSettings dynamicLighting; ShadowType shadowType = ShadowType::PCF; + VsmShadowOptions vsmShadowOptions; bool postProcessingEnabled = true; }; diff --git a/libs/viewer/src/Settings.cpp b/libs/viewer/src/Settings.cpp index b721eceada2..a181e8d3e87 100644 --- a/libs/viewer/src/Settings.cpp +++ b/libs/viewer/src/Settings.cpp @@ -191,6 +191,27 @@ static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, ShadowTy return i + 1; } +static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, + VsmShadowOptions* out) { + CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int size = tokens[i++].size; + for (int j = 0; j < size; ++j) { + const jsmntok_t tok = tokens[i]; + CHECK_KEY(tok); + if (0 == compare(tok, jsonChunk, "anisotropy")) { + i = parse(tokens, i + 1, jsonChunk, &out->anisotropy); + } else { + slog.w << "Invalid shadow options key: '" << STR(tok, jsonChunk) << "'" << io::endl; + i = parse(tokens, i + 1); + } + if (i < 0) { + slog.e << "Invalid shadow options value: '" << STR(tok, jsonChunk) << "'" << io::endl; + return i; + } + } + return i; +} + static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, TemporalAntiAliasingOptions* out) { CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -555,6 +576,8 @@ static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, ViewSett i = parse(tokens, i + 1, jsonChunk, &out->dynamicLighting); } else if (compare(tok, jsonChunk, "shadowType") == 0) { i = parse(tokens, i + 1, jsonChunk, &out->shadowType); + } else if (compare(tok, jsonChunk, "vsmShadowOptions") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->vsmShadowOptions); } else if (compare(tok, jsonChunk, "postProcessingEnabled") == 0) { i = parse(tokens, i + 1, jsonChunk, &out->postProcessingEnabled); } else { @@ -686,6 +709,7 @@ void applySettings(const ViewSettings& settings, View* dest) { dest->setDynamicLightingOptions(settings.dynamicLighting.zLightNear, settings.dynamicLighting.zLightFar); dest->setShadowType(settings.shadowType); + dest->setVsmShadowOptions(settings.vsmShadowOptions); dest->setPostProcessingEnabled(settings.postProcessingEnabled); } @@ -1007,6 +1031,14 @@ std::string writeJson(const DynamicLightingSettings& in) { return oss.str(); } +std::string writeJson(const VsmShadowOptions& in) { + std::ostringstream oss; + oss << "{\n" + << "\"anisotropy\": " << writeJson(in.anisotropy) << "\n" + << "}"; + return oss.str(); +} + std::string writeJson(const ViewSettings& in) { std::ostringstream oss; oss << "{\n" @@ -1023,6 +1055,7 @@ std::string writeJson(const ViewSettings& in) { << "\"renderQuality\": " << writeJson(in.renderQuality) << ",\n" << "\"dynamicLighting\": " << writeJson(in.dynamicLighting) << ",\n" << "\"shadowType\": " << writeJson(in.shadowType) << ",\n" + << "\"vsmShadowOptions\": " << writeJson(in.vsmShadowOptions) << ",\n" << "\"postProcessingEnabled\": " << writeJson(in.postProcessingEnabled) << "\n" << "}"; return oss.str(); diff --git a/libs/viewer/src/SimpleViewer.cpp b/libs/viewer/src/SimpleViewer.cpp index 4fd9260401a..051a328edc1 100644 --- a/libs/viewer/src/SimpleViewer.cpp +++ b/libs/viewer/src/SimpleViewer.cpp @@ -55,6 +55,7 @@ SimpleViewer::SimpleViewer(filament::Engine* engine, filament::Scene* scene, fil mSidebarWidth(sidebarWidth) { mSettings.view.shadowType = ShadowType::PCF; + mSettings.view.vsmShadowOptions.anisotropy = 0; mSettings.view.dithering = Dithering::TEMPORAL; mSettings.view.antiAliasing = AntiAliasing::FXAA; mSettings.view.sampleCount = 4; @@ -344,6 +345,11 @@ void SimpleViewer::updateUserInterface() { snprintf(label, 32, "%d", 1 << mVsmMsaaSamplesLog2); ImGui::SliderInt("VSM MSAA samples", &mVsmMsaaSamplesLog2, 0, 3, label); + int vsmAnisotropy = mSettings.view.vsmShadowOptions.anisotropy; + snprintf(label, 32, "%d", 1 << vsmAnisotropy); + ImGui::SliderInt("VSM anisotropy", &vsmAnisotropy, 0, 3, label); + mSettings.view.vsmShadowOptions.anisotropy = vsmAnisotropy; + ImGui::SliderInt("Cascades", &mShadowCascades, 1, 4); ImGui::Checkbox("Debug cascades", debug.getPropertyAddress("d.shadowmap.visualize_cascades")); diff --git a/libs/viewer/tests/test_settings.cpp b/libs/viewer/tests/test_settings.cpp index 17fb9799469..400cdea76e5 100644 --- a/libs/viewer/tests/test_settings.cpp +++ b/libs/viewer/tests/test_settings.cpp @@ -123,6 +123,9 @@ static const char* JSON_TEST_DEFAULTS = R"TXT( "zLightFar": 100, }, "shadowType": "PCF", + "vsmShadowOptions": { + "anisotropy": 1 + }, "postProcessingEnabled": true } } From 30565a5afc85b1eff0b2b82f0af9dabad14d5690 Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Wed, 14 Oct 2020 12:43:05 -0600 Subject: [PATCH 05/14] Add capture frame button to gltf_viewer (#3189) --- filament/backend/src/metal/MetalDriver.mm | 8 ++- filament/docs/Debugging.md | 60 +++++++++++++++++++++-- filament/src/Renderer.cpp | 14 ++++++ filament/src/details/Engine.h | 7 ++- samples/gltf_viewer.cpp | 11 ++++- 5 files changed, 94 insertions(+), 6 deletions(-) diff --git a/filament/backend/src/metal/MetalDriver.mm b/filament/backend/src/metal/MetalDriver.mm index 30f70680543..c94f79a0ce0 100644 --- a/filament/backend/src/metal/MetalDriver.mm +++ b/filament/backend/src/metal/MetalDriver.mm @@ -849,8 +849,14 @@ #else MTLCaptureDescriptor* descriptor = [MTLCaptureDescriptor new]; descriptor.captureObject = mContext->device; + descriptor.destination = MTLCaptureDestinationGPUTraceDocument; + descriptor.outputURL = [[NSURL alloc] initFileURLWithPath:@"filament.gputrace"]; + NSError* error = nil; [[MTLCaptureManager sharedCaptureManager] startCaptureWithDescriptor:descriptor - error:nil]; + error:&error]; + if (error) { + NSLog(@"%@", [error localizedDescription]); + } #endif } diff --git a/filament/docs/Debugging.md b/filament/docs/Debugging.md index b852ef4a129..d0e570a8ade 100644 --- a/filament/docs/Debugging.md +++ b/filament/docs/Debugging.md @@ -1,6 +1,8 @@ -# Debugging Vulkan on Linux +# Filament Debugging -## Enable Validation Logs +## Debugging Vulkan on Linux + +### Enable Validation Logs Simply install the LunarG SDK (it's fast and easy), then make sure you've got the following environment variables set up in your **bashrc** file: @@ -14,7 +16,7 @@ export PATH="$VULKAN_SDK/bin:$PATH" As long as you're running a debug build of Filament, you should now see extra debugging spew in your console if there are any errors or performance issues being caught by validation. -## Frame Capture in RenderDoc +### Frame Capture in RenderDoc The following instructions assume you've already installed the LunarG SDK and therefore have the `VK_LAYER_PATH` environment variable. @@ -34,3 +36,55 @@ cp ~/Downloads/renderdoc_1.0/etc/vulkan/implicit_layer.d/renderdoc_capture.json directory, executable path, etc. 1. Click **Launch** in RenderDoc, then press **F12** in your app. You should see a new capture show up in RenderDoc. + +## Enable Metal Validation + +To enable the Metal validation layers when running a sample through the command-line, set the +following environment variable: + +``` +export METAL_DEVICE_WRAPPER_TYPE=1 +``` + +You should then see the following output when running a sample with the Metal backend: + +``` +2020-10-13 18:01:44.101 gltf_viewer[73303:4946828] Metal API Validation Enabled +``` + +## Metal Frame Capture from gltf_viewer + +To capture Metal frames from within gltf_viewer: + +### 1. Update deployment target + +`CMAKE_OSX_DEPLOYMENT_TARGET` in `CMakeCache.txt` must be set to at least 10.15. You can manually +edit it or run: + +``` +cmake . -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=10.15 +``` + +inside your CMake build directory (the build.sh script only sets it to 10.14). + +### 2. Create an Info.plist file + +Create an `Info.plist` file in the same directory as `gltf_viewer` (`cmake/samples`). Set its +contents to: + +``` + + + + + MetalCaptureEnabled + + + +``` + +### 3. Capture a frame + +Run gltf_viewer as normal, and hit the "Capture frame" button under the Debug menu. The captured +frame will be saved to `filament.gputrace` in the current working directory. This file can then be +opened with Xcode for inspection. diff --git a/filament/src/Renderer.cpp b/filament/src/Renderer.cpp index 659edb14721..d5ec8e21a97 100644 --- a/filament/src/Renderer.cpp +++ b/filament/src/Renderer.cpp @@ -61,6 +61,9 @@ FRenderer::FRenderer(FEngine& engine) : { FDebugRegistry& debugRegistry = engine.getDebugRegistry(); debugRegistry.registerProperty("d.ssao.enabled", &engine.debug.ssao.enabled); + + debugRegistry.registerProperty("d.renderer.doFrameCapture", + &engine.debug.renderer.doFrameCapture); } void FRenderer::init() noexcept { @@ -885,6 +888,11 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN FEngine& engine = getEngine(); FEngine::DriverApi& driver = engine.getDriverApi(); + // start a frame capture, if requested. + if (UTILS_UNLIKELY(engine.debug.renderer.doFrameCapture)) { + driver.startCapture(); + } + // latch the frame time std::chrono::duration time(appVsync - mUserEpoch); float h = float(time.count()); @@ -1017,6 +1025,12 @@ void FRenderer::endFrame() { // gives the backend a chance to execute periodic tasks driver.tick(); + // stop the frame capture, if one was requested + if (UTILS_UNLIKELY(engine.debug.renderer.doFrameCapture)) { + driver.stopCapture(); + engine.debug.renderer.doFrameCapture = false; + } + // do this before engine.flush() engine.getResourceAllocator().gc(); diff --git a/filament/src/details/Engine.h b/filament/src/details/Engine.h index c05c614bf99..f86117f67a2 100644 --- a/filament/src/details/Engine.h +++ b/filament/src/details/Engine.h @@ -410,7 +410,12 @@ class FEngine : public Engine { struct { bool camera_at_origin = true; } view; - matdbg::DebugServer* server = nullptr; + struct { + // When set to true, the backend will attempt to capture the next frame and write the + // capture to file. At the moment, only supported by the Metal backend. + bool doFrameCapture = false; + } renderer; + matdbg::DebugServer* server = nullptr; } debug; }; diff --git a/samples/gltf_viewer.cpp b/samples/gltf_viewer.cpp index b1c22042da2..89e7e5f2acf 100644 --- a/samples/gltf_viewer.cpp +++ b/samples/gltf_viewer.cpp @@ -745,7 +745,7 @@ int main(int argc, char** argv) { createGroundPlane(engine, scene, app); - app.viewer->setUiCallback([&app, scene, view] () { + app.viewer->setUiCallback([&app, scene, view, engine] () { auto& automation = *app.automationEngine; float progress = app.resourceLoader->asyncGetLoadProgress(); @@ -872,6 +872,15 @@ int main(int argc, char** argv) { colorGradingUI(app); + if (ImGui::CollapsingHeader("Debug")) { + if (ImGui::Button("Capture frame")) { + auto& debug = engine->getDebugRegistry(); + bool* captureFrame = + debug.getPropertyAddress("d.renderer.doFrameCapture"); + *captureFrame = true; + } + } + if (ImGui::BeginPopupModal("MessageBox", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::Text("%s", app.messageBoxText.c_str()); if (ImGui::Button("OK", ImVec2(120, 0))) { From 4f58a7e5fb2dd3e9ee0361f6391b32aef1120d31 Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Thu, 15 Oct 2020 12:00:42 -0600 Subject: [PATCH 06/14] Fix Vulkan black screen on Windows with NVIDIA hardware (#3190) --- filament/backend/src/vulkan/VulkanContext.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/filament/backend/src/vulkan/VulkanContext.cpp b/filament/backend/src/vulkan/VulkanContext.cpp index d749d53cbc9..3ef4527f154 100644 --- a/filament/backend/src/vulkan/VulkanContext.cpp +++ b/filament/backend/src/vulkan/VulkanContext.cpp @@ -519,6 +519,7 @@ void makeSwapChainPresentable(VulkanContext& context) { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, .dstAccessMask = 0, + .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .newLayout = swapContext.attachment.layout, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, From 7eec70276e2f18cd9f15abe5339133e48e138778 Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Thu, 15 Oct 2020 12:57:38 -0600 Subject: [PATCH 07/14] Add release scripts and RELEASE_GUIDE (#3191) --- BRANCHING.md | 52 ----------- RELEASE_GUIDE.md | 138 +++++++++++++++++++++++++++ build/common/bump-version.sh | 75 +++++++++++++++ build/common/release.sh | 175 +++++++++++++++++++++++++++++++++++ 4 files changed, 388 insertions(+), 52 deletions(-) create mode 100644 RELEASE_GUIDE.md create mode 100755 build/common/bump-version.sh create mode 100755 build/common/release.sh diff --git a/BRANCHING.md b/BRANCHING.md index 7c628fc88be..cf15e12754d 100644 --- a/BRANCHING.md +++ b/BRANCHING.md @@ -27,55 +27,3 @@ Bugs are defined as one of the following _introduced since the prior release_: - unintentional public API changes For example, a long-standing crash just recently discovered would not necessitate a bug fix PR. - -## Creating a GitHub Release - -Be sure to choose the *release* branch when drafting a GitHub release. - -## Git Commands - -These commands assume a release candidate branch called *rc/1.9.0*. - -### Creating a Release Candidate Branch - -``` -$ git checkout main -$ git pull -$ git branch rc/1.9.0 -$ git push origin rc/1.9.0 -``` - -### Merging the Release Candidate Branch Into Release - -There may be temporary hotfixes in the release branch that should be overriden by the new release -candidate. To accomplish this, we first merge release into rc using the _ours_ strategy. Then we -merge rc into release. - -``` -$ git checkout rc/1.9.0 -$ git pull -$ git fetch origin release:release -$ git merge -s ours release -$ git checkout release -$ git merge --no-ff rc/1.9.0 -$ git push origin release -``` - -### Deleting the Release Candidate Branch - -``` -$ git branch -d rc/1.9.0 -$ git push origin --delete rc/1.9.0 -``` - -### See a History of the Release Branch - -``` -$ git log --oneline --first-parent - -442b061 (HEAD -> release) Merge branch 'rc/1.9.2' into release -ac50d21 Hotfix -94dc2f7 Hotfix -b34ed5b Merge branch 'rc/1.9.1' into release -aeef498 Merge branch 'rc/1.9.0' into release -``` diff --git a/RELEASE_GUIDE.md b/RELEASE_GUIDE.md new file mode 100644 index 00000000000..8e9aa4f267d --- /dev/null +++ b/RELEASE_GUIDE.md @@ -0,0 +1,138 @@ +# Filament Release Guide + +This guide makes use of some "environment variables": +- $RELEASE = the new version of Filament we are releasing today. (e.g., 1.9.3) +- $NEXT_RELEASE = the version we plan to release next week (e.g., 1.9.4) + +Before starting, ensure that each of these branches is up-to-date with origin: +- release +- rc/$RELEASE +- main + +## 0. Make sure the rc/$RELEASE branch has the correct version. + +It should have the version corresponding to its name, $RELEASE. + +## 1. Update RELEASE_NOTES.md on the rc branch. + +Checkout the rc/$RELEASE branch. In RELEASE_NOTES.md, locate the header corresponding to $RELEASE +and write release notes. To see which commits make up the release, run: + +``` +build/common/release.sh -c rc/$RELEASE +``` + +Commit the changes to rc/$RELEASE with the title: + +``` +Update RELEASE_NOTES for $RELEASE +``` + +## 2. Bump versions on main to $RELEASE. + +Checkout main and run the following command to bump Filament's version to $RELEASE: + +``` +build/common/bump-version.sh $RELEASE +``` + +Commit changes to main with the title: + +``` +Bump version to $RELEASE +``` + +Do not push to origin yet. + +## 3. Cherry-pick RELEASE_NOTES change from rc branch to main. + +``` +git cherry-pick rc/$RELEASE +``` + +Update the headers. The "Next release" header becomes a header for $NEXT_RELEASE, and a new "Next +release" header is added. + +For example, this: + +``` +## Next release (main branch) +- foo +- bar + +## v1.9.3 +- baz +- bat +``` + +becomes: + +``` +## Next release (main branch) + +## v1.9.4 +- foo +- bar + +## v1.9.3 +- baz +- bat +``` + +Ammend these changes to the cherry-picked change. + +``` +git add -u +git commit --amend --no-edit +``` + +## 4. Run release script. + +``` +build/common/release.sh rc/$RELEASE rc/$NEXT_RELEASE +``` + +This script will merge rc/$RELEASE into release, delete the rc branch, and create a new rc +branch called rc/$NEXT_RELEASE. Verify that everything looks okay locally. + +## 5. Push the release branch. + +``` +git push origin release +``` + +## 6. Create the GitHub release. + +Use the GitHub UI to create a GitHub release corresponding to $RELEASE version. +Make sure the target is set to the release branch. + +## 7. Delete the old rc branch. + +``` +git push origin --delete rc/$RELEASE +``` + +## 8. Bump the version on the new rc branch to $NEXT_RELEASE. + +``` +git checkout rc/$NEXT_RELEASE +build/common/bump-version.sh $NEXT_RELEASE +``` + +Commit the changes to rc/$NEXT_RELEASE with the title: + +``` +Bump version to $NEXT_RELEASE +``` + +## 9. Push main. + +``` +git push origin main +``` + +## 10. Push the new rc branch. + +``` +git push origin rc/$NEXT_RELEASE +``` diff --git a/build/common/bump-version.sh b/build/common/bump-version.sh new file mode 100755 index 00000000000..2a8bcb135d9 --- /dev/null +++ b/build/common/bump-version.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +set -e + +function print_help { + local SELF_NAME + SELF_NAME=$(basename "$0") + echo "$SELF_NAME. Update the Filament version number." + echo "" + echo "Usage:" + echo " $SELF_NAME " + echo "" + echo " should be a 3 part semantic version, such as 1.9.3" + echo "" + echo "This script does not interface with git. It is up to the user to commit the change." + echo "" + echo "Options:" + echo " -h" + echo " Print this help message and exit." +} + +while getopts "h" opt; do + case ${opt} in + h) + print_help + exit 0 + ;; + *) + print_help + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +if [[ "$#" -ne 1 ]]; then + print_help + exit 1 +fi + +VERSION_REGEX="[[:digit:]]+.[[:digit:]]+.[[:digit:]]+" +NEW_VERSION="$1" + +function replace { + FIND_STR="${1//\{\{VERSION\}\}/${VERSION_REGEX}}" + REPLACE_STR="${1//\{\{VERSION\}\}/${NEW_VERSION}}" + local FILE_NAME="$2" + sed -i '' -E "s/${FIND_STR}/${REPLACE_STR}/" "${FILE_NAME}" +} + +# The following are the canonical locations where the Filament version number is referenced. + +replace \ + "implementation 'com.google.android.filament:filament-android:{{VERSION}}'" \ + README.md + +replace \ + "pod 'Filament', '~> {{VERSION}}'" \ + README.md + +replace \ + "VERSION_NAME={{VERSION}}" \ + android/gradle.properties + +replace \ + "spec.version = \"{{VERSION}}\"" \ + ios/CocoaPods/Filament.podspec + +replace \ + ":http => \"https:\/\/github.com\/google\/filament\/releases\/download\/v{{VERSION}}\/filament-v{{VERSION}}-ios.tgz\" }" \ + ios/CocoaPods/Filament.podspec + +replace \ + "\"version\": \"{{VERSION}}\"" \ + web/filament-js/package.json diff --git a/build/common/release.sh b/build/common/release.sh new file mode 100755 index 00000000000..81c87e303b2 --- /dev/null +++ b/build/common/release.sh @@ -0,0 +1,175 @@ +#!/usr/bin/env bash + +set -e + +function print_help { + local SELF_NAME + SELF_NAME=$(basename "$0") + echo "$SELF_NAME. Merge the release candidate (rc) branch into release and cut a new rc branch." + echo "" + echo "Usage:" + echo " $SELF_NAME [options] " + echo " $SELF_NAME -c " + echo "" + echo "current rc branch name should be the name of an existing rc/* branch" + echo "new rc branch name should be the new rc branch name and should not exist" + echo "" + echo "Example:" + echo " $SELF_NAME rc/1.9.3 rc/1.9.4" + echo "" + echo "Options:" + echo " -c" + echo " List the commits that make up a release and exit." + echo " -h" + echo " Print this help message and exit." + echo " -p" + echo " Automatically push changes to origin (dangerous)." +} + +function list_commits { + git log --oneline release.."$1" +} + +PUSH_CHANGES=false +LIST_COMMITS=false +while getopts "hpc" opt; do + case ${opt} in + h) + print_help + exit 0 + ;; + p) + PUSH_CHANGES=true + ;; + c) + LIST_COMMITS=true + ;; + *) + print_help + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +if [[ "${LIST_COMMITS}" == "true" ]]; then + if [[ "$#" -ne 1 ]]; then + print_help + exit 1 + fi + + RC_BRANCH=$1 + + list_commits "${RC_BRANCH}" + exit 0 +fi + +if [[ "$#" -ne 2 ]]; then + print_help + exit 1 +fi + +RC_BRANCH=$1 +NEW_RC_BRANCH=$2 + +#################################################################################################### +# Preamble +#################################################################################################### + +# Check that the RC_BRANCH is a real branch. +git show-branch "${RC_BRANCH}" >/dev/null 2>&1 || { + echo "Branch ${RC_BRANCH} does not exist (try running git fetch first)." + exit 1 +} + +# Ensure no staged or working changes +if [ ! -z "$(git status --untracked-files=no --porcelain)" ]; then + echo "You have uncommited changes. Please stash or commit before running." + exit 1 +fi + +# Make sure release, main, and the release candidate branch are up-to-date. +git checkout main +git pull origin main --rebase + +git checkout "${RC_BRANCH}" +git pull origin "${RC_BRANCH}" --rebase + +git checkout release +git pull origin release --rebase + +#################################################################################################### +# Merge rc branch into release +#################################################################################################### + +# We need to merge rc into release in a somewhat roundabout way because we want the merge to always +# favor the changes on the rc branch. Any commits *only* on the release branch should be lost. These +# abandonded commits should only ever be temporary hotfixes. +# See the last part of https://stackoverflow.com/a/27338013/2671441 for more details. +# The benefit of this strategy is that we'll never get any merge conflicts. All of these commands +# can run without human intervention. + +git checkout release + +# Do a merge commit. The content of this commit does not matter, so we use a strategy that never +# fails. This advances release. +git merge --no-edit -s ours "${RC_BRANCH}" + +# Change working tree and index to desired content. +# --detach ensures rc branch will not move when doing the reset in the next step. +git checkout --detach "${RC_BRANCH}" + +# Move HEAD to release without changing contents of working tree and index. +git reset --soft release + +# 'attach' HEAD to release. +# This ensures release will move when doing 'commit --amend'. +git checkout release + +# Change content of merge commit to current index (i.e. content of rc branch). +git commit --amend -C HEAD + +#################################################################################################### +# Cut a new release candidate branch +#################################################################################################### + +git checkout main +git branch --track "${NEW_RC_BRANCH}" + +#################################################################################################### +# Delete the old release candidate branch +#################################################################################################### + +git branch -D "${RC_BRANCH}" + +#################################################################################################### +# Push changes +#################################################################################################### + +if [[ "${PUSH_CHANGES}" == "true" ]]; then + # Push the release branch + git push origin release + + # Delete the old rc branch remotely + git push origin --delete "${RC_BRANCH}" + + # Push the new rc branch + git push origin "${NEW_RC_BRANCH}" +else + echo "" + echo "Done." + echo "" + echo "Changes have not been pushed." + echo "If everything looks good locally, run the following:" + echo "---------------------------------------------------------" + echo "git push origin release" + echo "git push origin --delete ${RC_BRANCH}" + echo "git push origin ${NEW_RC_BRANCH}" + echo "---------------------------------------------------------" + echo "Or, to undo everything:" + echo "---------------------------------------------------------" + echo "git checkout release && git reset --hard origin/release" + echo "git branch -D ${NEW_RC_BRANCH}" + echo "git checkout --track origin/rc/${RC_BRANCH}" + echo "---------------------------------------------------------" +fi From d14ba856a7f3b32a30444d409e8c6cb99abbc8b1 Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Thu, 15 Oct 2020 14:11:46 -0600 Subject: [PATCH 08/14] matc: fix some compilation failures still exit with code 0 (#3192) --- RELEASE_NOTES.md | 1 + libs/filamat/include/filamat/Package.h | 5 ++++- libs/filamat/src/MaterialBuilder.cpp | 6 +++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 4ce0e090205..e5a0400b355 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -7,6 +7,7 @@ A new header is inserted each time a *tag* is created. - Added View::setVsmShadowOptions (experimental) - Add anisotropic shadow map sampling with VSM (experimental) +- matc: fixed bug where some compilation failures still exited with code 0 ## v1.9.5 diff --git a/libs/filamat/include/filamat/Package.h b/libs/filamat/include/filamat/Package.h index f5a53cb7506..93e74a5868f 100644 --- a/libs/filamat/include/filamat/Package.h +++ b/libs/filamat/include/filamat/Package.h @@ -42,15 +42,18 @@ class UTILS_PUBLIC Package { } // Move Constructor - Package(Package&& other) noexcept : mPayload(other.mPayload), mSize(other.mSize) { + Package(Package&& other) noexcept : mPayload(other.mPayload), mSize(other.mSize), + mValid(other.mValid) { other.mPayload = nullptr; other.mSize = 0; + other.mValid = false; } // Move assignment Package& operator=(Package&& other) noexcept { std::swap(mPayload, other.mPayload); std::swap(mSize, other.mSize); + std::swap(mValid, other.mValid); return *this; } diff --git a/libs/filamat/src/MaterialBuilder.cpp b/libs/filamat/src/MaterialBuilder.cpp index c4d73ff4fc8..910c733e24e 100644 --- a/libs/filamat/src/MaterialBuilder.cpp +++ b/libs/filamat/src/MaterialBuilder.cpp @@ -813,11 +813,15 @@ Package MaterialBuilder::build() noexcept { determinePostProcessVariants(); bool success = generateShaders(variants, container, info); + if (!success) { + // Return an empty package to signal a failure to build the material. + return Package::invalidPackage(); + } + // Flatten all chunks in the container into a Package. Package package(container.getSize()); Flattener f(package); container.flatten(f); - package.setValid(success); return package; } From 5ceb9fc5d5ddd34cdb6d9fdbc5729c213daa8414 Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Fri, 16 Oct 2020 16:11:05 -0700 Subject: [PATCH 09/14] Add optional XCB support to PlatformVkLinux. This allows clients to build the Vulkan backend with either XLIB or XCB support. I did a quick smoke test of the XCB option, but for now we are continuing to default to XLIB. Note that the native window type used to create the swap chain differs between these two API's. --- .../backend/src/vulkan/PlatformVkLinux.cpp | 47 ++++++++++++++----- filament/backend/src/vulkan/PlatformVkLinux.h | 8 ++++ libs/bluevk/include/vulkan/vk_platform.h | 4 ++ 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/filament/backend/src/vulkan/PlatformVkLinux.cpp b/filament/backend/src/vulkan/PlatformVkLinux.cpp index c1d8010b683..94e89b3e5ac 100644 --- a/filament/backend/src/vulkan/PlatformVkLinux.cpp +++ b/filament/backend/src/vulkan/PlatformVkLinux.cpp @@ -34,15 +34,18 @@ constexpr VkAllocationCallbacks* VKALLOC = nullptr; static constexpr const char* LIBRARY_X11 = "libX11.so.6"; +#ifdef FILAMENT_SUPPORTS_XCB +typedef xcb_connection_t* (*XCB_CONNECT)(const char *displayname, int *screenp); +#else typedef Display* (*X11_OPEN_DISPLAY)(const char*); -typedef Display* (*X11_CLOSE_DISPLAY)(Display*); -typedef Status (*X11_GET_GEOMETRY)(Display*, Drawable, Window*, int*, int*, unsigned int*, - unsigned int*, unsigned int*, unsigned int*); +#endif struct X11Functions { +#ifdef FILAMENT_SUPPORTS_XCB + XCB_CONNECT xcbConnect; +#else X11_OPEN_DISPLAY openDisplay; - X11_CLOSE_DISPLAY closeDisplay; - X11_GET_GEOMETRY getGeometry; +#endif void* library = nullptr; } g_x11; @@ -50,7 +53,11 @@ Driver* PlatformVkLinux::createDriver(void* const sharedContext) noexcept { ASSERT_PRECONDITION(sharedContext == nullptr, "Vulkan does not support shared contexts."); const char* requiredInstanceExtensions[] = { "VK_KHR_surface", +#ifdef FILAMENT_SUPPORTS_XCB + "VK_KHR_xcb_surface", +#else "VK_KHR_xlib_surface", +#endif "VK_KHR_get_physical_device_properties2", #if VK_ENABLE_VALIDATION "VK_EXT_debug_utils", @@ -61,22 +68,40 @@ Driver* PlatformVkLinux::createDriver(void* const sharedContext) noexcept { } void* PlatformVkLinux::createVkSurfaceKHR(void* nativeWindow, void* instance) noexcept { +#ifdef FILAMENT_SUPPORTS_XCB + if (g_x11.library == nullptr) { + g_x11.library = dlopen(LIBRARY_X11, RTLD_LOCAL | RTLD_NOW); + ASSERT_PRECONDITION(g_x11.library, "Unable to open X11 library."); + g_x11.xcbConnect = (XCB_CONNECT) dlsym(g_x11.library, "xcb_connect"); + int screen; + mConnection = g_x11.xcbConnect(nullptr, &screen); + } + ASSERT_POSTCONDITION(vkCreateXcbSurfaceKHR, "Unable to load vkCreateXcbSurfaceKHR function."); + VkSurfaceKHR surface = nullptr; + const uint64_t ptrval = reinterpret_cast(nativeWindow); + VkXcbSurfaceCreateInfoKHR createInfo = { + .sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, + .connection = mConnection, + .window = (xcb_window_t) ptrval, + }; + VkResult result = vkCreateXcbSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC, &surface); +#else if (g_x11.library == nullptr) { g_x11.library = dlopen(LIBRARY_X11, RTLD_LOCAL | RTLD_NOW); ASSERT_PRECONDITION(g_x11.library, "Unable to open X11 library."); g_x11.openDisplay = (X11_OPEN_DISPLAY) dlsym(g_x11.library, "XOpenDisplay"); - g_x11.closeDisplay = (X11_CLOSE_DISPLAY) dlsym(g_x11.library, "XCloseDisplay"); - g_x11.getGeometry = (X11_GET_GEOMETRY) dlsym(g_x11.library, "XGetGeometry"); mDisplay = g_x11.openDisplay(NULL); ASSERT_PRECONDITION(mDisplay, "Unable to open X11 display."); } ASSERT_POSTCONDITION(vkCreateXlibSurfaceKHR, "Unable to load vkCreateXlibSurfaceKHR function."); VkSurfaceKHR surface = nullptr; - VkXlibSurfaceCreateInfoKHR createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; - createInfo.dpy = mDisplay; - createInfo.window = (Window) nativeWindow; + VkXlibSurfaceCreateInfoKHR createInfo = { + .sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, + .dpy = mDisplay, + .window = (Window) nativeWindow, + }; VkResult result = vkCreateXlibSurfaceKHR((VkInstance) instance, &createInfo, VKALLOC, &surface); +#endif ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateXlibSurfaceKHR error."); return surface; } diff --git a/filament/backend/src/vulkan/PlatformVkLinux.h b/filament/backend/src/vulkan/PlatformVkLinux.h index fbbc07d757e..c112ecd628c 100644 --- a/filament/backend/src/vulkan/PlatformVkLinux.h +++ b/filament/backend/src/vulkan/PlatformVkLinux.h @@ -22,7 +22,11 @@ #include #include "VulkanPlatform.h" +#ifdef FILAMENT_SUPPORTS_XCB +#include +#else #include +#endif namespace filament { @@ -36,7 +40,11 @@ class PlatformVkLinux final : public backend::VulkanPlatform { int getOSVersion() const noexcept override { return 0; } private: +#ifdef FILAMENT_SUPPORTS_XCB + xcb_connection_t* mConnection; +#else Display* mDisplay; +#endif }; } // namespace filament diff --git a/libs/bluevk/include/vulkan/vk_platform.h b/libs/bluevk/include/vulkan/vk_platform.h index 830b8e780ea..4bfd1f0c1af 100644 --- a/libs/bluevk/include/vulkan/vk_platform.h +++ b/libs/bluevk/include/vulkan/vk_platform.h @@ -26,7 +26,11 @@ #elif defined(IOS) #define VK_USE_PLATFORM_IOS_MVK 1 #elif defined(__linux__) +#if defined(FILAMENT_SUPPORTS_XCB) +#define VK_USE_PLATFORM_XCB_KHR 1 +#else #define VK_USE_PLATFORM_XLIB_KHR 1 +#endif #elif defined(__APPLE__) #define VK_USE_PLATFORM_MACOS_MVK 1 #elif defined(WIN32) From 07fd883f9a123eee747ba7e8d36a27d5e43c5f8b Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Mon, 19 Oct 2020 09:34:59 -0700 Subject: [PATCH 10/14] Vulkan + Android: fix build break. Fixes #3200. --- filament/backend/src/vulkan/VulkanDriver.cpp | 4 ++-- filament/backend/src/vulkan/VulkanHandles.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 421c6a243ab..8339307b24f 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -1428,7 +1428,7 @@ void VulkanDriver::readPixels(Handle src, // Create a disposable to defer execution of the following code until after // the work command buffer has completed. - mDisposer.createDisposable(stagingImage, [=] () { + mDisposer.createDisposable((VulkanDisposer::Key) stagingImage, [=] () { VkImageSubresource subResource { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT }; VkSubresourceLayout subResourceLayout; @@ -1474,7 +1474,7 @@ void VulkanDriver::readPixels(Handle src, // Next we reduce the ref count of the image to zero, which schedules the above callback to be // executed on the next beginFrame(), after the work command buffer is completed. - mDisposer.removeReference(stagingImage); + mDisposer.removeReference((VulkanDisposer::Key) stagingImage); } void VulkanDriver::readStreamPixels(Handle sh, uint32_t x, uint32_t y, uint32_t width, diff --git a/filament/backend/src/vulkan/VulkanHandles.cpp b/filament/backend/src/vulkan/VulkanHandles.cpp index 94f31fad14c..2df78b52f9c 100644 --- a/filament/backend/src/vulkan/VulkanHandles.cpp +++ b/filament/backend/src/vulkan/VulkanHandles.cpp @@ -201,7 +201,7 @@ VulkanSwapChain::VulkanSwapChain(VulkanContext& context, VkSurfaceKHR vksurface) // Headless SwapChain constructor. (does not create a VkSwapChainKHR) VulkanSwapChain::VulkanSwapChain(VulkanContext& context, uint32_t width, uint32_t height) { - surfaceContext.surface = nullptr; + surfaceContext.surface = VK_NULL_HANDLE; getHeadlessQueue(context, surfaceContext); surfaceContext.surfaceFormat.format = VK_FORMAT_R8G8B8A8_UNORM; From de75b9d125d1154a8d96c9af192790c242fd5544 Mon Sep 17 00:00:00 2001 From: Benjamin Doherty Date: Mon, 19 Oct 2020 11:49:57 -0600 Subject: [PATCH 11/14] Bump version to 1.9.5 --- README.md | 4 ++-- android/gradle.properties | 2 +- ios/CocoaPods/Filament.podspec | 4 ++-- web/filament-js/package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c8d4c3b18ea..a5d46b834dd 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ repositories { } dependencies { - implementation 'com.google.android.filament:filament-android:1.9.4' + implementation 'com.google.android.filament:filament-android:1.9.5' } ``` @@ -63,7 +63,7 @@ A much smaller alternative to `filamat-android` that can only generate OpenGL sh iOS projects can use CocoaPods to install the latest release: ``` -pod 'Filament', '~> 1.9.4' +pod 'Filament', '~> 1.9.5' ``` ### Snapshots diff --git a/android/gradle.properties b/android/gradle.properties index 0bb0355b4d1..0ad0816b065 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ GROUP=com.google.android.filament -VERSION_NAME=1.9.4 +VERSION_NAME=1.9.5 POM_DESCRIPTION=Real-time physically based rendering engine for Android. diff --git a/ios/CocoaPods/Filament.podspec b/ios/CocoaPods/Filament.podspec index fe2ebb25865..f5d1d41b7da 100644 --- a/ios/CocoaPods/Filament.podspec +++ b/ios/CocoaPods/Filament.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |spec| spec.name = "Filament" - spec.version = "1.9.4" + spec.version = "1.9.5" spec.license = { :type => "Apache 2.0", :file => "LICENSE" } spec.homepage = "https://google.github.io/filament" spec.authors = "Google LLC." spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL." spec.platform = :ios, "11.0" - spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.4/filament-v1.9.4-ios.tgz" } + spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.5/filament-v1.9.5-ios.tgz" } # Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon. spec.pod_target_xcconfig = { diff --git a/web/filament-js/package.json b/web/filament-js/package.json index d5b79beec65..8e26fc510c5 100644 --- a/web/filament-js/package.json +++ b/web/filament-js/package.json @@ -1,6 +1,6 @@ { "name": "filament", - "version": "1.9.4", + "version": "1.9.5", "description": "Real-time physically based rendering engine", "main": "filament.js", "module": "filament.js", From 37d080dfd1d1fdb4993df14e2e21cf867fb307a8 Mon Sep 17 00:00:00 2001 From: Benjamin Doherty Date: Mon, 19 Oct 2020 11:49:05 -0600 Subject: [PATCH 12/14] Update RELEASE_NOTES for 1.9.5 --- RELEASE_NOTES.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e5a0400b355..47f49bea7cd 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,6 +5,8 @@ A new header is inserted each time a *tag* is created. ## Next release (main branch) +## v1.9.6 + - Added View::setVsmShadowOptions (experimental) - Add anisotropic shadow map sampling with VSM (experimental) - matc: fixed bug where some compilation failures still exited with code 0 @@ -12,8 +14,15 @@ A new header is inserted each time a *tag* is created. ## v1.9.5 - Added a new Live Wallpaper Android sample -- `UiHelper` now supports managing a `SurfaceHolder`. +- `UiHelper` now supports managing a `SurfaceHolder` - Fix: an internal texture resource was never destroyed +- Fix: hang on 2-CPU machines +- Fix: Vulkan crash when using shadow cascades +- Linux fixes for headless SwiftShader +- Fix null pointer dereference in `FIndirectLight` +- Fix Windows build by avoiding nested initializers +- Vulkan: support readPixels and headless swap chains +- VSM improvements ## v1.9.4 From a37b431e87f381066710853c622363bdf6453775 Mon Sep 17 00:00:00 2001 From: Benjamin Doherty Date: Mon, 19 Oct 2020 11:55:13 -0600 Subject: [PATCH 13/14] Bump version to 1.9.6 --- README.md | 4 ++-- android/gradle.properties | 2 +- ios/CocoaPods/Filament.podspec | 4 ++-- web/filament-js/package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a5d46b834dd..7da889b3164 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ repositories { } dependencies { - implementation 'com.google.android.filament:filament-android:1.9.5' + implementation 'com.google.android.filament:filament-android:1.9.6' } ``` @@ -63,7 +63,7 @@ A much smaller alternative to `filamat-android` that can only generate OpenGL sh iOS projects can use CocoaPods to install the latest release: ``` -pod 'Filament', '~> 1.9.5' +pod 'Filament', '~> 1.9.6' ``` ### Snapshots diff --git a/android/gradle.properties b/android/gradle.properties index 0ad0816b065..cb256dbd8de 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ GROUP=com.google.android.filament -VERSION_NAME=1.9.5 +VERSION_NAME=1.9.6 POM_DESCRIPTION=Real-time physically based rendering engine for Android. diff --git a/ios/CocoaPods/Filament.podspec b/ios/CocoaPods/Filament.podspec index f5d1d41b7da..72a38fdf8dc 100644 --- a/ios/CocoaPods/Filament.podspec +++ b/ios/CocoaPods/Filament.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |spec| spec.name = "Filament" - spec.version = "1.9.5" + spec.version = "1.9.6" spec.license = { :type => "Apache 2.0", :file => "LICENSE" } spec.homepage = "https://google.github.io/filament" spec.authors = "Google LLC." spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL." spec.platform = :ios, "11.0" - spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.5/filament-v1.9.5-ios.tgz" } + spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.6/filament-v1.9.6-ios.tgz" } # Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon. spec.pod_target_xcconfig = { diff --git a/web/filament-js/package.json b/web/filament-js/package.json index 8e26fc510c5..3c9364a33a4 100644 --- a/web/filament-js/package.json +++ b/web/filament-js/package.json @@ -1,6 +1,6 @@ { "name": "filament", - "version": "1.9.5", + "version": "1.9.6", "description": "Real-time physically based rendering engine", "main": "filament.js", "module": "filament.js", From fe1de41b8e0918b6a14274b39e4ed570c59e961b Mon Sep 17 00:00:00 2001 From: Benjamin Doherty Date: Mon, 26 Oct 2020 11:25:31 -0600 Subject: [PATCH 14/14] Update RELEASE_NOTES for 1.9.6 --- RELEASE_NOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 47f49bea7cd..52d73579aee 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -10,6 +10,9 @@ A new header is inserted each time a *tag* is created. - Added View::setVsmShadowOptions (experimental) - Add anisotropic shadow map sampling with VSM (experimental) - matc: fixed bug where some compilation failures still exited with code 0 +- Vulkan + Android: fix build break +- Add optional XCB support to PlatformVkLinux +- Fix Vulkan black screen on Windows with NVIDIA hardware ## v1.9.5