Compare commits

...

9 Commits

Author SHA1 Message Date
Powei Feng
6cf499326e github: fix windows release version (#9671)
Use "call" to ensure execution continues after
the batch file.
2026-02-04 21:59:46 -08:00
rafadevai
8cdba6d12e VK: add back the removed vmaFlush for staging (#9674)
This line was removed by accident in the staging bypass
fix PR.
2026-02-03 13:51:14 -08:00
Eliza Velasquez
41923df669 engine: fix stereo and parallel shader compilation
Another thing that got lost in the sea of merge conflicts that plagued the
program cache feature...
2026-02-02 08:01:54 -08:00
Eliza Velasquez
51b59bd1c1 engine: fix TAA compilation failure 2026-02-02 08:01:44 -08:00
Powei Feng
9909fd1bf4 filamat: remove unnecessary std::decay_t (#9643) 2026-02-02 08:01:02 -08:00
haroonq
c9ed58733f Swap logic of how the EGL display is initialized. (#9634)
1. Iterate over system displays using eglQueryDevicesEXT and try to initialize them.
2. If no display initialized, then try to initialize the DEFAULT display.

FIXES=[478925865]
2026-02-02 08:00:40 -08:00
Serge Metral
e2c70201b5 External sampler bind index bug (#9664)
Patching a fix for the external sampler use case where the same sampler is bound to two different indices. As it stands, the code fails to differentiate between the two layouts.
2026-02-02 08:00:29 -08:00
Mathias Agopian
8d07604604 Fix possible buffer overflow in CommandStream (#9661)
Because of an improper boundary check caused a possible unsigned
integer overflow, it was possible to overrun the command stream
buffer in RenderPass::execute().

It would happen when the batch size was larger than the buffer
capacity (usually a few MB). 

FIXES=[474264976]
2026-01-29 11:22:12 -08:00
Benjamin Doherty
fafd8f8196 Bump version to 1.69.1 2026-01-27 14:50:29 -08:00
16 changed files with 53 additions and 36 deletions

View File

@@ -245,7 +245,8 @@ jobs:
env:
TAG: ${{ steps.git_ref.outputs.tag }}
run: |
build\windows\build-github.bat release
@REMARK 'call' is required to ensure control returns to this script after the batch file finishes.
call build\windows\build-github.bat release
echo on
move out\filament-windows.tgz out\filament-%TAG%-windows.tgz
shell: cmd

View File

@@ -6,3 +6,6 @@
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut
- engine: fix shader compilation failure in TAA material
- engine: fix stereo & parallel shader compilation

View File

@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.69.0'
implementation 'com.google.android.filament:filament-android:1.69.1'
}
```
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:
```shell
pod 'Filament', '~> 1.69.0'
pod 'Filament', '~> 1.69.1'
```
## Documentation

View File

@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.69.0
VERSION_NAME=1.69.1
POM_DESCRIPTION=Real-time physically based rendering engine for Android.

View File

@@ -120,27 +120,33 @@ bool PlatformEGL::isOpenGL() const noexcept {
PlatformEGL::ExternalImageEGL::~ExternalImageEGL() = default;
Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& driverConfig) {
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert_invariant(mEGLDisplay != EGL_NO_DISPLAY);
static constexpr int kMaxNumEGLDevices = 32;
EGLint major, minor;
EGLBoolean initialized = eglInitialize(mEGLDisplay, &major, &minor);
EGLBoolean initialized = false;
if (!initialized) {
EGLDeviceEXT eglDevice;
EGLint numDevices;
PFNEGLQUERYDEVICESEXTPROC const eglQueryDevicesEXT =
PFNEGLQUERYDEVICESEXTPROC(eglGetProcAddress("eglQueryDevicesEXT"));
if (eglQueryDevicesEXT != nullptr) {
eglQueryDevicesEXT(1, &eglDevice, &numDevices);
if(auto* getPlatformDisplay = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(
eglGetProcAddress("eglGetPlatformDisplay"))) {
mEGLDisplay = getPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, eglDevice, nullptr);
PFNEGLQUERYDEVICESEXTPROC const eglQueryDevicesEXT =
PFNEGLQUERYDEVICESEXTPROC(eglGetProcAddress("eglQueryDevicesEXT"));
PFNEGLGETPLATFORMDISPLAYEXTPROC const getPlatformDisplay =
PFNEGLGETPLATFORMDISPLAYEXTPROC(eglGetProcAddress("eglGetPlatformDisplay"));
if (eglQueryDevicesEXT != nullptr && getPlatformDisplay != nullptr) {
EGLint numDevices = 0;
EGLDeviceEXT eglDevices[kMaxNumEGLDevices];
if (eglQueryDevicesEXT(kMaxNumEGLDevices, eglDevices, &numDevices)) {
for (int i = 0; i < numDevices && !initialized; ++i) {
mEGLDisplay = getPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, eglDevices[i], nullptr);
initialized = eglInitialize(mEGLDisplay, &major, &minor);
}
}
}
if (!initialized) {
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert_invariant(mEGLDisplay != EGL_NO_DISPLAY);
initialized = eglInitialize(mEGLDisplay, &major, &minor);
}
if (UTILS_UNLIKELY(!initialized)) {
LOG(ERROR) << "eglInitialize failed";
return nullptr;

View File

@@ -76,6 +76,7 @@ void VulkanBufferProxy::loadFromCpu(VulkanCommandBuffer& commands, const void* c
assert_invariant(stage->memory());
commands.acquire(stage);
memcpy(stage->mapping(), cpuData, numBytes);
vmaFlushAllocation(mAllocator, stage->memory(), stage->offset(), numBytes);
// This means that we're recording a write into a command buffer with a previous read, so it
// needs to add a barrier (to protect the write from writing over a read).

View File

@@ -62,7 +62,7 @@ uint32_t appendBindings(VkDescriptorSetLayoutBinding* toBind, VkDescriptorType t
uint32_t appendSamplerBindings(VkDescriptorSetLayoutBinding* toBind,
fvkutils::SamplerBitmask const& mask, fvkutils::SamplerBitmask const& external,
utils::FixedCapacityVector<VkSampler> const& immutableSamplers) {
utils::FixedCapacityVector<std::pair<uint64_t, VkSampler>> const& immutableSamplers) {
using Bitmask = fvkutils::SamplerBitmask;
uint32_t count = 0;
Bitmask alreadySeen;
@@ -92,7 +92,7 @@ uint32_t appendSamplerBindings(VkDescriptorSetLayoutBinding* toBind,
.descriptorCount = 1,
.stageFlags = stages,
.pImmutableSamplers = external[index] && immutableSamplerCount > immutableIndex
? &immutableSamplers[immutableIndex++]
? &(immutableSamplers[immutableIndex++].second)
: nullptr,
};
}
@@ -100,14 +100,14 @@ uint32_t appendSamplerBindings(VkDescriptorSetLayoutBinding* toBind,
return count;
}
uint64_t computeImmutableSamplerHash(utils::FixedCapacityVector<VkSampler> const& samplers) {
uint64_t computeImmutableSamplerHash(
utils::FixedCapacityVector<std::pair<uint64_t, VkSampler>> const& samplers) {
size_t const size = samplers.size();
if (size == 0) {
return 0;
} else if (size == 1) {
return (uint64_t) samplers[0];
}
return utils::hash::murmur3((uint32_t*) samplers.data(), samplers.size() * 2, 0);
//64bit + 64bit per element = 4 words
return utils::hash::murmur3((uint32_t*) samplers.data(), samplers.size() * 4, 0);
}
} // anonymous namespace
@@ -128,7 +128,7 @@ void VulkanDescriptorSetLayoutCache::terminate() noexcept {
VkDescriptorSetLayout VulkanDescriptorSetLayoutCache::getVkLayout(
VulkanDescriptorSetLayout::Bitmask const& bitmasks,
fvkutils::SamplerBitmask externalSamplers,
utils::FixedCapacityVector<VkSampler> immutableSamplers) {
utils::FixedCapacityVector<std::pair<uint64_t, VkSampler>> immutableSamplers) {
LayoutKey key = {
.bitmask = bitmasks,
.immutableSamplerHash = computeImmutableSamplerHash(immutableSamplers),

View File

@@ -47,7 +47,7 @@ public:
// This method is meant to be used with external samplers
VkDescriptorSetLayout getVkLayout(VulkanDescriptorSetLayout::Bitmask const& bitmasks,
fvkutils::SamplerBitmask externalSamplers,
utils::FixedCapacityVector<VkSampler> immutableSamplers = {});
utils::FixedCapacityVector<std::pair<uint64_t, VkSampler>> immutableSamplers = {});
private:
VkDevice mDevice;

View File

@@ -882,7 +882,8 @@ void VulkanDriver::createProgramR(Handle<HwProgram> ph, Program&& program, utils
// formats. It seems to be enough, in practicce, to simply run through a list of the types of
// samplers that *might* appear. As long as the real pipeline is close enough to something that
// the driver has seen before, we are able to get a cache hit.
utils::FixedCapacityVector<VkSampler> externalSamplers (layouts[i]->bitmask.externalSampler.count(), externalSampler);
utils::FixedCapacityVector<std::pair<uint64_t, VkSampler>> externalSamplers(
layouts[i]->bitmask.externalSampler.count(), { 0, externalSampler });
vkLayouts[i] = mDescriptorSetLayoutCache.getVkLayout(
layouts[i]->bitmask, layouts[i]->bitmask.externalSampler, externalSamplers);
}

View File

@@ -142,10 +142,10 @@ void VulkanExternalImageManager::updateSetAndLayout(
return std::get<0>(a) < std::get<0>(b);
});
utils::FixedCapacityVector<VkSampler> outSamplers;
utils::FixedCapacityVector<std::pair<uint64_t,VkSampler>> outSamplers;
outSamplers.reserve(MAX_SAMPLER_COUNT);
std::for_each(samplerAndBindings.begin(), samplerAndBindings.end(),
[&](auto const& b) { outSamplers.push_back(std::get<1>(b)); });
[&](auto const& b) { outSamplers.push_back({ static_cast<uint64_t>(std::get<0>(b)), std::get<1>(b) }); });
VkDescriptorSetLayout const newLayout = mDescriptorSetLayoutCache->getVkLayout(layout->bitmask,
actualExternalSamplers, outSamplers);

View File

@@ -2903,7 +2903,7 @@ void PostProcessManager::configureTemporalAntiAliasingMaterial(backend::DriverAp
FMaterial* const ma = getPostProcessMaterial("taa").getMaterial(mEngine, driver);
FMaterial::SpecializationConstantsBuilder maConstants = ma->getSpecializationConstantsBuilder();
maConstants.set("upscaling", taaOptions.upscaling);
maConstants.set("upscaling", taaOptions.upscaling > 1.0f);
maConstants.set("historyReprojection", taaOptions.historyReprojection);
maConstants.set("filterHistory", taaOptions.filterHistory);
maConstants.set("filterInput", taaOptions.filterInput);

View File

@@ -969,7 +969,7 @@ void RenderPass::Executor::execute(FEngine const& engine, DriverApi& driver,
// check we have enough capacity to write these commandCount commands, if not,
// request a new CircularBuffer allocation of `capacity` bytes.
if (UTILS_UNLIKELY(circularBuffer.getUsed() > capacity - commandSizeInBytes)) {
if (UTILS_UNLIKELY(circularBuffer.getUsed() + commandSizeInBytes > capacity)) {
// FIXME: eventually we can't flush here because this will be a secondary
// command buffer. We will need another solution for overflows.
const_cast<FEngine&>(engine).flush();

View File

@@ -168,8 +168,13 @@ FMaterial::FMaterial(FEngine& engine, const Builder& builder, MaterialDefinition
FILAMENT_CHECK_PRECONDITION(!mUseUboBatching || engine.isUboBatchingEnabled())
<< "UBO batching is not enabled.";
mDepthPrecacheDisabled = engine.getDriverApi().isWorkaroundNeeded(
Workaround::DISABLE_DEPTH_PRECACHE_FOR_DEFAULT_MATERIAL);
DriverApi& driver = engine.getDriverApi();
mIsStereoSupported = driver.isStereoSupported();
mIsParallelShaderCompileSupported = driver.isParallelShaderCompileSupported();
mDepthPrecacheDisabled =
driver.isWorkaroundNeeded(Workaround::DISABLE_DEPTH_PRECACHE_FOR_DEFAULT_MATERIAL);
mDefaultMaterial = engine.getDefaultMaterial();
FixedCapacityVector<Program::SpecializationConstant> specializationConstants =
processSpecializationConstants(builder);

View File

@@ -1,12 +1,12 @@
Pod::Spec.new do |spec|
spec.name = "Filament"
spec.version = "1.69.0"
spec.version = "1.69.1"
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.69.0/filament-v1.69.0-ios.tgz" }
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.69.1/filament-v1.69.1-ios.tgz" }
spec.libraries = 'c++'

View File

@@ -583,7 +583,7 @@ public:
template<typename F>
void traverseAggregate(TIntermNode* root, F&& closure) {
AggregateTraverserAdapter adapter(std::forward<std::decay_t<F>>(closure));
AggregateTraverserAdapter adapter(std::forward<F>(closure));
root->traverse(&adapter);
}

View File

@@ -1,6 +1,6 @@
{
"name": "filament",
"version": "1.69.0",
"version": "1.69.1",
"description": "Real-time physically based rendering engine",
"main": "filament.js",
"module": "filament.js",