Compare commits

..
Author SHA1 Message Date
Sungun Park cf75b4489b feedback 2025-02-04 13:41:42 -08:00
Sungun Park 923ac98ea8 Add multiview_data for multiview information
Add a varying variable `multiview_data` for both surface and
post-processing shaders. Currently this only works as intended in
surface shader, and additional implementation to facilitate it for
post-processing will be following.

The `multiview_data` contains multiview information like whether
multiview is enabled for the current material and what the eye index is
in that case. This variable is globally available including fragment
shaders so that it can be referenced in user shaders in .material files.
Also this allows us to indirectly reference the constant variables such
as `gl_ViewID_OVR` and `gl_ViewIndex` in a platform-agnostic way.

Make the preprocessor `MATERIAL_FEATURE_LEVEL` available for both
surface and post-processing shaders, it used to be only available for
surface shader, and this will be referenced in post-processing shaders
later to support multiview for post-processing.
2025-02-03 19:48:20 -08:00
87 changed files with 688 additions and 1665 deletions
+10 -17
View File
@@ -667,6 +667,10 @@ function(list_licenses OUTPUT MODULES)
endfunction()
set(COMBINE_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/build/linux/combine-static-libs.sh")
if (WIN32)
set(COMBINE_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/build/windows/combine-static-libs.bat")
set(CMAKE_AR "lib.exe")
endif()
# Add a custom command to TARGET that combines the static libraries in DEPS into a single archive.
function(combine_static_libs TARGET OUTPUT DEPS)
@@ -681,22 +685,12 @@ function(combine_static_libs TARGET OUTPUT DEPS)
endif()
endforeach()
if (WIN32)
add_custom_command(
TARGET ${TARGET} POST_BUILD
COMMAND lib.exe /nologo /out:temp.lib ${DEPS_FILES}
COMMAND "${CMAKE_COMMAND}" -E rename temp.lib ${OUTPUT}
COMMENT "Combining ${target} dependencies into single shared library"
VERBATIM
)
else()
add_custom_command(
TARGET ${TARGET} POST_BUILD
COMMAND "${COMBINE_SCRIPT}" "${CMAKE_AR}" "${OUTPUT}" ${DEPS_FILES}
COMMENT "Combining ${target} dependencies into single shared library"
VERBATIM
)
endif()
add_custom_command(
TARGET ${TARGET} POST_BUILD
COMMAND "${COMBINE_SCRIPT}" "${CMAKE_AR}" "${OUTPUT}" ${DEPS_FILES}
COMMENT "Combining ${target} dependencies into single shared library"
VERBATIM
)
endfunction()
# ==================================================================================================
@@ -767,7 +761,6 @@ add_subdirectory(${LIBRARIES}/utils)
add_subdirectory(${LIBRARIES}/viewer)
add_subdirectory(${FILAMENT}/filament)
add_subdirectory(${FILAMENT}/shaders)
add_subdirectory(${EXTERNAL}/abseil/tnt)
add_subdirectory(${EXTERNAL}/basisu/tnt)
add_subdirectory(${EXTERNAL}/civetweb/tnt)
add_subdirectory(${EXTERNAL}/imgui/tnt)
+1 -1
View File
@@ -8,4 +8,4 @@ appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut
- Support including PlatformMetal.h in C++ files.
- matdbg: Add support for debugging ESSL 1.0 shaders
+2 -2
View File
@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.57.0'
implementation 'com.google.android.filament:filament-android:1.56.7'
}
```
@@ -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.57.0'
pod 'Filament', '~> 1.56.7'
```
## Documentation
-8
View File
@@ -7,14 +7,6 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
## v1.57.1
## v1.57.0
- matdbg: Add support for debugging ESSL 1.0 shaders
- backend: New platform API to better handle external textures [⚠️ **New Material Version**]
## v1.56.8
@@ -329,18 +329,6 @@ Java_com_google_android_filament_MaterialInstance_nSetCullingMode(JNIEnv*,
instance->setCullingMode((MaterialInstance::CullingMode) cullingMode);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetCullingModeSeparate(JNIEnv*, jclass,
jlong nativeMaterialInstance,
jlong colorPassCullingMode, jlong shadowPassCullingMode) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setCullingMode(
(MaterialInstance::CullingMode) colorPassCullingMode,
(MaterialInstance::CullingMode) shadowPassCullingMode);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetColorWrite(JNIEnv*,
@@ -517,14 +505,6 @@ Java_com_google_android_filament_MaterialInstance_nGetCullingMode(JNIEnv* env, j
return (jint)instance->getCullingMode();
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_google_android_filament_MaterialInstance_nGetShadowCullingMode(JNIEnv* env, jclass,
jlong nativeMaterialInstance) {
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return (jint)instance->getShadowCullingMode();
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MaterialInstance_nIsColorWriteEnabled(JNIEnv* env, jclass clazz,
@@ -1271,7 +1271,7 @@ public class Engine {
* {@link android.view.SurfaceHolder.Callback#surfaceDestroyed surfaceDestroyed}.</p>
*/
public void flushAndWait() {
boolean unused = flushAndWait(Fence.WAIT_FOR_EVER);
flushAndWait(Fence.WAIT_FOR_EVER);
}
/**
@@ -556,20 +556,6 @@ public class MaterialInstance {
nSetCullingMode(getNativeObject(), mode.ordinal());
}
/**
* Overrides the default triangle culling state that was set on the material separately for the
* color and shadow passes
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:culling">
* Rasterization: culling</a>
*/
public void setCullingMode(@NonNull Material.CullingMode colorPassCullingMode,
@NonNull Material.CullingMode shadowPassCullingMode) {
nSetCullingModeSeparate(getNativeObject(),
colorPassCullingMode.ordinal(), shadowPassCullingMode.ordinal());
}
/**
* Returns the face culling mode.
*/
@@ -578,14 +564,6 @@ public class MaterialInstance {
return sCullingModeValues[nGetCullingMode(getNativeObject())];
}
/**
* Returns the face culling mode for the shadow passes.
*/
@NonNull
public Material.CullingMode getShadowCullingMode() {
return sCullingModeValues[nGetShadowCullingMode(getNativeObject())];
}
/**
* Overrides the default color-buffer write state that was set on the material.
*
@@ -942,8 +920,6 @@ public class MaterialInstance {
private static native void nSetDoubleSided(long nativeMaterialInstance, boolean doubleSided);
private static native void nSetCullingMode(long nativeMaterialInstance, long mode);
private static native void nSetCullingModeSeparate(long nativeMaterialInstance,
long colorPassCullingMode, long shadowPassCullingMode);
private static native void nSetColorWrite(long nativeMaterialInstance, boolean enable);
private static native void nSetDepthWrite(long nativeMaterialInstance, boolean enable);
private static native void nSetStencilWrite(long nativeMaterialInstance, boolean enable);
@@ -976,7 +952,6 @@ public class MaterialInstance {
private static native float nGetSpecularAntiAliasingThreshold(long nativeMaterialInstance);
private static native boolean nIsDoubleSided(long nativeMaterialInstance);
private static native int nGetCullingMode(long nativeMaterialInstance);
private static native int nGetShadowCullingMode(long nativeMaterialInstance);
private static native boolean nIsColorWriteEnabled(long nativeMaterialInstance);
private static native boolean nIsDepthWriteEnabled(long nativeMaterialInstance);
private static native boolean nIsStencilWriteEnabled(long nativeMaterialInstance);
+1 -1
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.57.0
VERSION_NAME=1.56.7
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
+39
View File
@@ -0,0 +1,39 @@
@echo off
set selfName=%0
:: Check that we have at least 3 arguments.
set argC=0
for %%x in (%*) do Set /A argC+=1
if %argC% LSS 3 goto :print_help
set AR_TOOL=%1
shift
set OUTPUT_PATH=%1
shift
set ARCHIVES=
:loop
if [%1]==[] goto :finished
set ARCHIVES=%ARCHIVES% %1
shift
goto :loop
:finished
%AR_TOOL% /nologo /out:%OUTPUT_PATH% %ARCHIVES% || goto :error
exit /B %ERRORLEVEL%
:print_help
echo %selfName%. Combine multiple static libraries using an archiver tool.
echo;
echo Usage:
echo %selfName% ^<path-to-ar^> ^<output-archive^> ^<archives^>...
echo;
echo Notes:
echo ^<archives^> must be a list of absolute paths to static library archives.
echo This script creates a temporary working directory inside the current directory.
exit /B 1
:error
exit /B %ERRORLEVEL%
+1 -47
View File
@@ -25,8 +25,6 @@
#include <stddef.h>
#include <stdint.h>
#include <atomic>
namespace filament::backend {
class Driver;
@@ -43,50 +41,6 @@ public:
struct Fence {};
struct Stream {};
class ExternalImageHandle;
class ExternalImage {
friend class ExternalImageHandle;
std::atomic_uint32_t mRefCount{0};
protected:
virtual ~ExternalImage() noexcept;
};
class ExternalImageHandle {
ExternalImage* UTILS_NULLABLE mTarget = nullptr;
static void incref(ExternalImage* UTILS_NULLABLE p) noexcept;
static void decref(ExternalImage* UTILS_NULLABLE p) noexcept;
public:
ExternalImageHandle() noexcept;
~ExternalImageHandle() noexcept;
explicit ExternalImageHandle(ExternalImage* UTILS_NULLABLE p) noexcept;
ExternalImageHandle(ExternalImageHandle const& rhs) noexcept;
ExternalImageHandle(ExternalImageHandle&& rhs) noexcept;
ExternalImageHandle& operator=(ExternalImageHandle const& rhs) noexcept;
ExternalImageHandle& operator=(ExternalImageHandle&& rhs) noexcept;
explicit operator bool() const noexcept { return mTarget != nullptr; }
ExternalImage* UTILS_NULLABLE get() noexcept { return mTarget; }
ExternalImage const* UTILS_NULLABLE get() const noexcept { return mTarget; }
ExternalImage* UTILS_NULLABLE operator->() noexcept { return mTarget; }
ExternalImage const* UTILS_NULLABLE operator->() const noexcept { return mTarget; }
ExternalImage& operator*() noexcept { return *mTarget; }
ExternalImage const& operator*() const noexcept { return *mTarget; }
void clear() noexcept;
void reset(ExternalImage* UTILS_NULLABLE p) noexcept;
private:
friend utils::io::ostream& operator<<(utils::io::ostream& out,
ExternalImageHandle const& handle);
};
using ExternalImageHandleRef = ExternalImageHandle const&;
/**
* The type of technique for stereoscopic rendering. (Note that the materials used will need to
* be compatible with the chosen technique.)
@@ -169,7 +123,7 @@ public:
*
* @return nullptr on failure, or a pointer to the newly created driver.
*/
virtual Driver* UTILS_NULLABLE createDriver(void* UTILS_NULLABLE sharedContext,
virtual backend::Driver* UTILS_NULLABLE createDriver(void* UTILS_NULLABLE sharedContext,
const DriverConfig& driverConfig) noexcept = 0;
/**
@@ -23,7 +23,6 @@
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <utils/CString.h>
#include <stddef.h>
#include <stdint.h>
@@ -52,23 +51,12 @@ protected:
~OpenGLPlatform() noexcept override;
public:
struct ExternalTexture {
unsigned int target; // GLenum target
unsigned int id; // GLuint id
unsigned int target; // GLenum target
unsigned int id; // GLuint id
};
/**
* Return the OpenGL vendor string of the specified Driver instance.
* @return The GL_VENDOR string
*/
static utils::CString getVendorString(Driver const* UTILS_NONNULL driver);
/**
* Return the OpenGL vendor string of the specified Driver instance
* @return The GL_RENDERER string
*/
static utils::CString getRendererString(Driver const* UTILS_NONNULL driver);
/**
* Called by the driver to destroy the OpenGL context. This should clean up any windows
* or buffers from initialization. This is for instance where `eglDestroyContext` would be
@@ -336,45 +324,36 @@ public:
* Destroys an external texture handle and associated data.
* @param texture a pointer to the handle to destroy.
*/
virtual void destroyExternalImageTexture(ExternalTexture* UTILS_NONNULL texture) noexcept;
virtual void destroyExternalImage(ExternalTexture* UTILS_NONNULL texture) noexcept;
// called on the application thread to allow Filament to take ownership of the image
/**
* Takes ownership of the externalImage. The externalImage parameter depends on the Platform's
* concrete implementation. Ownership is released when destroyExternalImageTexture() is called.
* concrete implementation. Ownership is released when destroyExternalImage() is called.
*
* WARNING: This is called synchronously from the application thread (NOT the Driver thread)
*
* @param externalImage A token representing the platform's external image.
* @see destroyExternalImage
* @{
*/
virtual void retainExternalImage(void* UTILS_NONNULL externalImage) noexcept;
virtual void retainExternalImage(ExternalImageHandleRef externalImage) noexcept;
/** @}*/
/**
* Called to bind the platform-specific externalImage to an ExternalTexture.
* ExternalTexture::id is guaranteed to be bound when this method is called and ExternalTexture
* is updated with new values for id/target if necessary.
*
* WARNING: this method is not allowed to change the bound texture, or must restore the previous
* binding upon return. This is to avoid a problem with a backend doing state caching.
* binding upon return. This is to avoid problem with a backend doing state caching.
*
* @param externalImage The platform-specific external image.
* @param texture an in/out pointer to ExternalTexture, id and target can be updated if necessary.
* @return true on success, false on error.
* @{
*/
virtual bool setExternalImage(void* UTILS_NONNULL externalImage,
ExternalTexture* UTILS_NONNULL texture) noexcept;
virtual bool setExternalImage(ExternalImageHandleRef externalImage,
ExternalTexture* UTILS_NONNULL texture) noexcept;
/** @}*/
/**
* The method allows platforms to convert a user-supplied external image object into a new type
* (e.g. HardwareBuffer => EGLImage). The default implementation returns source.
@@ -17,6 +17,7 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#include <backend/DriverEnums.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <stdint.h>
@@ -33,14 +34,12 @@ public:
PlatformCocoaGL();
~PlatformCocoaGL() noexcept override;
ExternalImageHandle createExternalImage(void* cvPixelBuffer) noexcept;
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedContext,
const DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) noexcept override;
// Currently returns 0
int getOSVersion() const noexcept override;
@@ -60,12 +59,10 @@ protected:
void destroySwapChain(SwapChain* swapChain) noexcept override;
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImageTexture(ExternalTexture* texture) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImage(ExternalTexture* texture) noexcept override;
void retainExternalImage(void* externalImage) noexcept override;
bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept override;
void retainExternalImage(ExternalImageHandleRef externalImage) noexcept override;
bool setExternalImage(ExternalImageHandleRef externalImage, ExternalTexture* texture) noexcept override;
private:
PlatformCocoaGLImpl* pImpl = nullptr;
@@ -32,13 +32,11 @@ public:
PlatformCocoaTouchGL();
~PlatformCocoaTouchGL() noexcept override;
ExternalImageHandle createExternalImage(void* cvPixelBuffer) noexcept;
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const DriverConfig& driverConfig) noexcept override;
const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept final { return 0; }
@@ -58,12 +56,10 @@ public:
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImageTexture(ExternalTexture* texture) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImage(ExternalTexture* texture) noexcept override;
void retainExternalImage(void* externalImage) noexcept override;
bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept override;
void retainExternalImage(ExternalImageHandleRef externalImage) noexcept override;
bool setExternalImage(ExternalImageHandleRef externalImage, ExternalTexture* texture) noexcept override;
private:
PlatformCocoaTouchGLImpl* pImpl = nullptr;
@@ -47,11 +47,6 @@ public:
// Return true if we're on an OpenGL platform (as opposed to OpenGL ES). false by default.
virtual bool isOpenGL() const noexcept;
/**
* Creates an ExternalImage from a EGLImageKHR
*/
ExternalImageHandle createExternalImage(EGLImageKHR eglImage) noexcept;
protected:
// --------------------------------------------------------------------------------------------
// Helper for EGL configs and attributes parameters
@@ -80,7 +75,8 @@ protected:
* Initializes EGL, creates the OpenGL context and returns a concrete Driver implementation
* that supports OpenGL/OpenGL ES.
*/
Driver* createDriver(void* sharedContext, const DriverConfig& driverConfig) noexcept override;
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
/**
* This returns zero. This method can be overridden to return something more useful.
@@ -122,10 +118,9 @@ protected:
void destroyFence(Fence* fence) noexcept override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImageTexture(ExternalTexture* texture) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImage(ExternalTexture* texture) noexcept override;
bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept override;
bool setExternalImage(ExternalImageHandleRef externalImage, ExternalTexture* texture) noexcept override;
/**
* Logs glGetError() to slog.e
@@ -193,12 +188,6 @@ protected:
void initializeGlExtensions() noexcept;
struct ExternalImageEGL : public ExternalImage {
EGLImageKHR eglImage = EGL_NO_IMAGE;
protected:
~ExternalImageEGL() override;
};
protected:
EGLConfig findSwapChainConfig(uint64_t flags, bool window, bool pbuffer) const;
@@ -57,11 +57,6 @@ protected:
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
/**
* Creates an ExternalImage from a EGLImageKHR
*/
ExternalImageHandle createExternalImage(AHardwareBuffer const *buffer, bool sRGB) noexcept;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
@@ -94,15 +89,6 @@ protected:
*/
AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept override;
bool setExternalImage(ExternalImageHandleRef externalImage, ExternalTexture* texture) noexcept override;
struct ExternalImageEGLAndroid : public ExternalImageEGL {
AHardwareBuffer* aHardwareBuffer = nullptr;
bool sRGB = false;
protected:
~ExternalImageEGLAndroid() override;
};
protected:
bool makeCurrent(ContextType type,
SwapChain* drawSwapChain,
@@ -1,38 +0,0 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_PLATFORMMETAL_OBJC_H
#define TNT_FILAMENT_BACKEND_PRIVATE_PLATFORMMETAL_OBJC_H
#import <Metal/Metal.h>
namespace filament::backend {
struct MetalDevice {
id<MTLDevice> device;
};
struct MetalCommandQueue {
id<MTLCommandQueue> commandQueue;
};
struct MetalCommandBuffer {
id<MTLCommandBuffer> commandBuffer;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_PLATFORMMETAL_OBJC_H
@@ -20,17 +20,12 @@
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#import <Metal/Metal.h>
namespace filament::backend {
struct PlatformMetalImpl;
// In order for this header to be compatible with Objective-C and C++, we use these wrappers around
// id<MTL*> objects.
// See PlatformMetal-Objc.h.
struct MetalDevice;
struct MetalCommandQueue;
struct MetalCommandBuffer;
class PlatformMetal final : public Platform {
public:
PlatformMetal();
@@ -46,22 +41,21 @@ public:
* free to decide which one to use. On mobile systems with a single GPU, implementations should
* simply return the result of MTLCreateSystemDefaultDevice();
*/
virtual void createDevice(MetalDevice& outDevice) noexcept;
virtual id<MTLDevice> createDevice() noexcept;
/**
* Create a command submission queue on the Metal device object.
*
* @param device The device which was returned from createDevice()
*/
virtual void createCommandQueue(
MetalDevice& device, MetalCommandQueue& outCommandQueue) noexcept;
virtual id<MTLCommandQueue> createCommandQueue(id<MTLDevice> device) noexcept;
/**
* Obtain a MTLCommandBuffer enqueued on this Platform's MTLCommandQueue. The command buffer is
* guaranteed to execute before all subsequent command buffers created either by Filament, or
* further calls to this method.
*/
void createAndEnqueueCommandBuffer(MetalCommandBuffer& outCommandBuffer) noexcept;
id<MTLCommandBuffer> createAndEnqueueCommandBuffer() noexcept;
/**
* The action to take if a Drawable cannot be acquired.
@@ -71,9 +71,6 @@ public:
// where the gpu only has one graphics queue. Then the client needs to ensure that no
// concurrent access can occur.
uint32_t graphicsQueueIndex = 0xFFFFFFFF;
bool debugUtilsSupported = false;
bool debugMarkersSupported = false;
bool multiviewSupported = false;
};
/**
@@ -91,7 +88,6 @@ public:
VkFormat colorFormat = VK_FORMAT_UNDEFINED;
VkFormat depthFormat = VK_FORMAT_UNDEFINED;
VkExtent2D extent = {0, 0};
uint32_t layerCount = 1;
bool isProtected = false;
};
@@ -307,11 +303,6 @@ public:
*/
uint32_t height;
/**
* The layerCount of the external image
*/
uint32_t layerCount;
/**
* The layer count of the external image
*/
@@ -50,7 +50,7 @@
#include <stdint.h>
// Set to true to print every command out on log.d. This requires RTTI and DEBUG
#define DEBUG_COMMAND_STREAM true
#define DEBUG_COMMAND_STREAM false
namespace filament::backend {
@@ -215,14 +215,6 @@ DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureViewSwizzle,
backend::TextureSwizzle, b,
backend::TextureSwizzle, a)
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureExternalImage2,
backend::SamplerType, target,
backend::TextureFormat, format,
uint32_t, width,
uint32_t, height,
backend::TextureUsage, usage,
backend::Platform::ExternalImageHandleRef, image)
DECL_DRIVER_API_R_N(backend::TextureHandle, createTextureExternalImage,
backend::SamplerType, target,
backend::TextureFormat, format,
@@ -363,7 +355,6 @@ DECL_DRIVER_API_SYNCHRONOUS_0(bool, isDepthClampSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(uint8_t, getMaxDrawBuffers)
DECL_DRIVER_API_SYNCHRONOUS_0(size_t, getMaxUniformBufferSize)
DECL_DRIVER_API_SYNCHRONOUS_0(math::float2, getClipSpaceParams)
DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage2, backend::Platform::ExternalImageHandleRef, image)
DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage, void*, image)
DECL_DRIVER_API_SYNCHRONOUS_N(backend::TimerQueryResult, getTimerQueryValue, backend::TimerQueryHandle, query, uint64_t*, elapsedTime)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isWorkaroundNeeded, backend::Workaround, workaround)
-94
View File
@@ -16,102 +16,8 @@
#include <backend/Platform.h>
#include <utils/compiler.h>
#include <atomic>
#include <utility>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
void Platform::ExternalImageHandle::incref(ExternalImage* p) noexcept {
if (p) {
// incrementing the ref-count doesn't acquire or release anything
p->mRefCount.fetch_add(1, std::memory_order_relaxed);
}
}
void Platform::ExternalImageHandle::decref(ExternalImage* p) noexcept {
if (p) {
// When decrementing the ref-count, unless it reaches zero, there is no need to acquire
// data; we need to release all previous writes though so they can be visible to the thread
// that will actually delete the object.
if (p->mRefCount.fetch_sub(1, std::memory_order_release) == 1) {
// if we reach zero, we're about to delete the object, we need to acquire all previous
// writes from other threads (i.e.: the memory from other threads prior to the decref()
// need to be visible now.
std::atomic_thread_fence(std::memory_order_acquire);
delete p;
}
}
}
Platform::ExternalImageHandle::ExternalImageHandle() noexcept = default;
Platform::ExternalImageHandle::~ExternalImageHandle() noexcept {
decref(mTarget);
}
Platform::ExternalImageHandle::ExternalImageHandle(ExternalImage* p) noexcept
: mTarget(p) {
incref(mTarget);
}
Platform::ExternalImageHandle::ExternalImageHandle(ExternalImageHandle const& rhs) noexcept
: mTarget(rhs.mTarget) {
incref(mTarget);
}
Platform::ExternalImageHandle::ExternalImageHandle(ExternalImageHandle&& rhs) noexcept
: mTarget(rhs.mTarget) {
rhs.mTarget = nullptr;
}
Platform::ExternalImageHandle& Platform::ExternalImageHandle::operator=(
ExternalImageHandle const& rhs) noexcept {
if (UTILS_LIKELY(this != &rhs)) {
incref(rhs.mTarget);
decref(mTarget);
mTarget = rhs.mTarget;
}
return *this;
}
Platform::ExternalImageHandle& Platform::ExternalImageHandle::operator=(
ExternalImageHandle&& rhs) noexcept {
if (UTILS_LIKELY(this != &rhs)) {
decref(mTarget);
mTarget = rhs.mTarget;
rhs.mTarget = nullptr;
}
return *this;
}
void Platform::ExternalImageHandle::clear() noexcept {
decref(mTarget);
mTarget = nullptr;
}
void Platform::ExternalImageHandle::reset(ExternalImage* p) noexcept {
incref(p);
decref(mTarget);
mTarget = p;
}
utils::io::ostream& operator<<(utils::io::ostream& out,
Platform::ExternalImageHandle const& handle) {
out << "ExternalImageHandle{" << handle.mTarget << "}";
return out;
}
// --------------------------------------------------------------------------------------------------------------------
Platform::ExternalImage::~ExternalImage() noexcept = default;
// --------------------------------------------------------------------------------------------------------------------
Platform::Platform() noexcept = default;
// this generates the vtable in this translation unit
+2 -27
View File
@@ -31,7 +31,6 @@
#include "MetalTimerQuery.h"
#include <backend/platforms/PlatformMetal.h>
#include <backend/platforms/PlatformMetal-ObjC.h>
#include <CoreVideo/CVMetalTexture.h>
#include <CoreVideo/CVPixelBuffer.h>
@@ -121,10 +120,7 @@ MetalDriver::MetalDriver(
TrackedMetalBuffer::setPlatform(platform);
ScopedAllocationTimer::setPlatform(platform);
MetalDevice device;
device.device = nil;
mPlatform.createDevice(device);
mContext->device = device.device;
mContext->device = mPlatform.createDevice();
assert_invariant(mContext->device);
mContext->emptyBuffer = [mContext->device newBufferWithLength:16
@@ -190,12 +186,7 @@ MetalDriver::MetalDriver(
[mContext->device.name containsString:@"Apple A8 GPU"] ||
[mContext->device.name containsString:@"Apple A7 GPU"];
MetalCommandQueue commandQueue;
commandQueue.commandQueue = nil;
mPlatform.createCommandQueue(device, commandQueue);
assert_invariant(commandQueue.commandQueue);
mContext->commandQueue = commandQueue.commandQueue;
mContext->commandQueue = mPlatform.createCommandQueue(mContext->device);
mContext->pipelineStateCache.setDevice(mContext->device);
mContext->depthStencilStateCache.setDevice(mContext->device);
mContext->samplerStateCache.setDevice(mContext->device);
@@ -522,14 +513,6 @@ void MetalDriver::createTextureViewSwizzleR(Handle<HwTexture> th, Handle<HwTextu
mContext->textures.insert(construct_handle<MetalTexture>(th, *mContext, src, r, g, b, a));
}
void MetalDriver::createTextureExternalImage2R(Handle<HwTexture> th,
backend::SamplerType target,
backend::TextureFormat format,
uint32_t width, uint32_t height, backend::TextureUsage usage,
Platform::ExternalImageHandleRef image) {
// FIXME: implement createTextureExternalImage2R
}
void MetalDriver::createTextureExternalImageR(Handle<HwTexture> th,
backend::SamplerType target,
backend::TextureFormat format,
@@ -764,10 +747,6 @@ Handle<HwTexture> MetalDriver::createTextureViewSwizzleS() noexcept {
return alloc_handle<MetalTexture>();
}
Handle<HwTexture> MetalDriver::createTextureExternalImage2S() noexcept {
return alloc_handle<MetalTexture>();
}
Handle<HwTexture> MetalDriver::createTextureExternalImageS() noexcept {
return alloc_handle<MetalTexture>();
}
@@ -1239,10 +1218,6 @@ void MetalDriver::update3DImage(Handle<HwTexture> th, uint32_t level,
th.getId(), level, xoffset, yoffset, zoffset, width, height, depth);
}
void MetalDriver::setupExternalImage2(Platform::ExternalImageHandleRef image) {
// FIXME: implement setupExternalImage2
}
void MetalDriver::setupExternalImage(void* image) {
// setupExternalImage is called on the Filament thread when creating a Texture or SwapChain from
// a CVPixelBuffer external image. Here we take ownership of the passed in buffer by calling
+7 -9
View File
@@ -15,7 +15,6 @@
*/
#include <backend/platforms/PlatformMetal.h>
#include <backend/platforms/PlatformMetal-ObjC.h>
#include "MetalDriverFactory.h"
@@ -48,7 +47,7 @@ Driver* PlatformMetal::createDriver(void* /*sharedContext*/, const Platform::Dri
return MetalDriverFactory::create(this, driverConfig);
}
void PlatformMetal::createDevice(MetalDevice& outDevice) noexcept {
id<MTLDevice> PlatformMetal::createDevice() noexcept {
id<MTLDevice> result;
#if !defined(FILAMENT_IOS)
@@ -73,20 +72,19 @@ void PlatformMetal::createDevice(MetalDevice& outDevice) noexcept {
<< [result.name cStringUsingEncoding:NSUTF8StringEncoding] << "'"
<< utils::io::endl;
outDevice.device = result;
return result;
}
void PlatformMetal::createCommandQueue(
MetalDevice& device, MetalCommandQueue& outCommandQueue) noexcept {
pImpl->mCommandQueue = [device.device newCommandQueue];
id<MTLCommandQueue> PlatformMetal::createCommandQueue(id<MTLDevice> device) noexcept {
pImpl->mCommandQueue = [device newCommandQueue];
pImpl->mCommandQueue.label = @"Filament";
outCommandQueue.commandQueue = pImpl->mCommandQueue;
return pImpl->mCommandQueue;
}
void PlatformMetal::createAndEnqueueCommandBuffer(MetalCommandBuffer& outCommandBuffer) noexcept {
id<MTLCommandBuffer> PlatformMetal::createAndEnqueueCommandBuffer() noexcept {
id<MTLCommandBuffer> commandBuffer = [pImpl->mCommandQueue commandBuffer];
[commandBuffer enqueue];
outCommandBuffer.commandBuffer = commandBuffer;
return commandBuffer;
}
void PlatformMetal::setDrawableFailureBehavior(DrawableFailureBehavior behavior) noexcept {
-10
View File
@@ -14,16 +14,9 @@
* limitations under the License.
*/
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include "noop/NoopDriver.h"
#include "CommandStreamDispatcher.h"
#include <backend/Handle.h>
#include <stdint.h>
namespace filament::backend {
Driver* NoopDriver::create() {
@@ -269,9 +262,6 @@ void NoopDriver::update3DImage(Handle<HwTexture> th,
scheduleDestroy(std::move(data));
}
void NoopDriver::setupExternalImage2(Platform::ExternalImageHandleRef image) {
}
void NoopDriver::setupExternalImage(void* image) {
}
+23 -44
View File
@@ -18,7 +18,6 @@
#define TNT_FILAMENT_BACKEND_OPENGL_GLUTILS_H
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/Log.h>
#include <backend/DriverEnums.h>
@@ -26,8 +25,6 @@
#include <string_view>
#include <unordered_set>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "gl_headers.h"
@@ -53,7 +50,7 @@ void assertFramebufferStatus(utils::io::ostream& out, GLenum target, const char*
# define CHECK_GL_FRAMEBUFFER_STATUS(out, target) { GLUtils::checkFramebufferStatus(out, target, __func__, __LINE__); }
#endif
constexpr GLuint getComponentCount(ElementType type) noexcept {
constexpr inline GLuint getComponentCount(ElementType type) noexcept {
using ElementType = ElementType;
switch (type) {
case ElementType::BYTE:
@@ -93,7 +90,7 @@ constexpr GLuint getComponentCount(ElementType type) noexcept {
// Our enums to GLenum conversions
// ------------------------------------------------------------------------------------------------
constexpr GLbitfield getAttachmentBitfield(TargetBufferFlags flags) noexcept {
constexpr inline GLbitfield getAttachmentBitfield(TargetBufferFlags flags) noexcept {
GLbitfield mask = 0;
if (any(flags & TargetBufferFlags::COLOR_ALL)) {
mask |= (GLbitfield)GL_COLOR_BUFFER_BIT;
@@ -107,7 +104,7 @@ constexpr GLbitfield getAttachmentBitfield(TargetBufferFlags flags) noexcept {
return mask;
}
constexpr GLenum getBufferUsage(BufferUsage usage) noexcept {
constexpr inline GLenum getBufferUsage(BufferUsage usage) noexcept {
switch (usage) {
case BufferUsage::STATIC:
return GL_STATIC_DRAW;
@@ -116,7 +113,7 @@ constexpr GLenum getBufferUsage(BufferUsage usage) noexcept {
}
}
constexpr GLenum getBufferBindingType(BufferObjectBinding bindingType) noexcept {
constexpr inline GLenum getBufferBindingType(BufferObjectBinding bindingType) noexcept {
switch (bindingType) {
case BufferObjectBinding::VERTEX:
return GL_ARRAY_BUFFER;
@@ -137,11 +134,11 @@ constexpr GLenum getBufferBindingType(BufferObjectBinding bindingType) noexcept
}
}
constexpr GLboolean getNormalization(bool normalized) noexcept {
constexpr inline GLboolean getNormalization(bool normalized) noexcept {
return GLboolean(normalized ? GL_TRUE : GL_FALSE);
}
constexpr GLenum getComponentType(ElementType type) noexcept {
constexpr inline GLenum getComponentType(ElementType type) noexcept {
using ElementType = ElementType;
switch (type) {
case ElementType::BYTE:
@@ -186,30 +183,12 @@ constexpr GLenum getComponentType(ElementType type) noexcept {
}
}
constexpr GLenum getTextureTargetNotExternal(SamplerType target) noexcept {
switch (target) {
case SamplerType::SAMPLER_2D:
return GL_TEXTURE_2D;
case SamplerType::SAMPLER_3D:
return GL_TEXTURE_3D;
case SamplerType::SAMPLER_2D_ARRAY:
return GL_TEXTURE_2D_ARRAY;
case SamplerType::SAMPLER_CUBEMAP:
return GL_TEXTURE_CUBE_MAP;
case SamplerType::SAMPLER_CUBEMAP_ARRAY:
return GL_TEXTURE_CUBE_MAP_ARRAY;
case SamplerType::SAMPLER_EXTERNAL:
// we should never be here
return GL_TEXTURE_2D;
}
}
constexpr GLenum getCubemapTarget(uint16_t layer) noexcept {
constexpr inline GLenum getCubemapTarget(uint16_t layer) noexcept {
assert_invariant(layer <= 5);
return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
}
constexpr GLenum getWrapMode(SamplerWrapMode mode) noexcept {
constexpr inline GLenum getWrapMode(SamplerWrapMode mode) noexcept {
using SamplerWrapMode = SamplerWrapMode;
switch (mode) {
case SamplerWrapMode::REPEAT:
@@ -221,7 +200,7 @@ constexpr GLenum getWrapMode(SamplerWrapMode mode) noexcept {
}
}
constexpr GLenum getTextureFilter(SamplerMinFilter filter) noexcept {
constexpr inline GLenum getTextureFilter(SamplerMinFilter filter) noexcept {
using SamplerMinFilter = SamplerMinFilter;
switch (filter) {
case SamplerMinFilter::NEAREST:
@@ -236,12 +215,12 @@ constexpr GLenum getTextureFilter(SamplerMinFilter filter) noexcept {
}
}
constexpr GLenum getTextureFilter(SamplerMagFilter filter) noexcept {
constexpr inline GLenum getTextureFilter(SamplerMagFilter filter) noexcept {
return GL_NEAREST + GLenum(filter);
}
constexpr GLenum getBlendEquationMode(BlendEquation mode) noexcept {
constexpr inline GLenum getBlendEquationMode(BlendEquation mode) noexcept {
using BlendEquation = BlendEquation;
switch (mode) {
case BlendEquation::ADD: return GL_FUNC_ADD;
@@ -252,7 +231,7 @@ constexpr GLenum getBlendEquationMode(BlendEquation mode) noexcept {
}
}
constexpr GLenum getBlendFunctionMode(BlendFunction mode) noexcept {
constexpr inline GLenum getBlendFunctionMode(BlendFunction mode) noexcept {
using BlendFunction = BlendFunction;
switch (mode) {
case BlendFunction::ZERO: return GL_ZERO;
@@ -269,7 +248,7 @@ constexpr GLenum getBlendFunctionMode(BlendFunction mode) noexcept {
}
}
constexpr GLenum getCompareFunc(SamplerCompareFunc func) noexcept {
constexpr inline GLenum getCompareFunc(SamplerCompareFunc func) noexcept {
switch (func) {
case SamplerCompareFunc::LE: return GL_LEQUAL;
case SamplerCompareFunc::GE: return GL_GEQUAL;
@@ -283,25 +262,25 @@ constexpr GLenum getCompareFunc(SamplerCompareFunc func) noexcept {
}
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
constexpr GLenum getTextureCompareMode(SamplerCompareMode mode) noexcept {
constexpr inline GLenum getTextureCompareMode(SamplerCompareMode mode) noexcept {
return mode == SamplerCompareMode::NONE ?
GL_NONE : GL_COMPARE_REF_TO_TEXTURE;
}
constexpr GLenum getTextureCompareFunc(SamplerCompareFunc func) noexcept {
constexpr inline GLenum getTextureCompareFunc(SamplerCompareFunc func) noexcept {
return getCompareFunc(func);
}
#endif
constexpr GLenum getDepthFunc(SamplerCompareFunc func) noexcept {
constexpr inline GLenum getDepthFunc(SamplerCompareFunc func) noexcept {
return getCompareFunc(func);
}
constexpr GLenum getStencilFunc(SamplerCompareFunc func) noexcept {
constexpr inline GLenum getStencilFunc(SamplerCompareFunc func) noexcept {
return getCompareFunc(func);
}
constexpr GLenum getStencilOp(StencilOperation op) noexcept {
constexpr inline GLenum getStencilOp(StencilOperation op) noexcept {
switch (op) {
case StencilOperation::KEEP: return GL_KEEP;
case StencilOperation::ZERO: return GL_ZERO;
@@ -314,7 +293,7 @@ constexpr GLenum getStencilOp(StencilOperation op) noexcept {
}
}
constexpr GLenum getFormat(PixelDataFormat format) noexcept {
constexpr inline GLenum getFormat(PixelDataFormat format) noexcept {
using PixelDataFormat = PixelDataFormat;
switch (format) {
case PixelDataFormat::RGB: return GL_RGB;
@@ -338,7 +317,7 @@ constexpr GLenum getFormat(PixelDataFormat format) noexcept {
}
}
constexpr GLenum getType(PixelDataType type) noexcept {
constexpr inline GLenum getType(PixelDataType type) noexcept {
using PixelDataType = PixelDataType;
switch (type) {
case PixelDataType::UBYTE: return GL_UNSIGNED_BYTE;
@@ -363,7 +342,7 @@ constexpr GLenum getType(PixelDataType type) noexcept {
}
#if !defined(__EMSCRIPTEN__) && !defined(FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2)
constexpr GLenum getSwizzleChannel(TextureSwizzle c) noexcept {
constexpr inline GLenum getSwizzleChannel(TextureSwizzle c) noexcept {
using TextureSwizzle = TextureSwizzle;
switch (c) {
case TextureSwizzle::SUBSTITUTE_ZERO: return GL_ZERO;
@@ -376,7 +355,7 @@ constexpr GLenum getSwizzleChannel(TextureSwizzle c) noexcept {
}
#endif
constexpr GLenum getCullingMode(CullingMode mode) noexcept {
constexpr inline GLenum getCullingMode(CullingMode mode) noexcept {
switch (mode) {
case CullingMode::NONE:
// should never happen
@@ -391,7 +370,7 @@ constexpr GLenum getCullingMode(CullingMode mode) noexcept {
}
// ES2 supported internal formats for texturing and how they map to a format/type
constexpr std::pair<GLenum, GLenum> textureFormatToFormatAndType(
constexpr inline std::pair<GLenum, GLenum> textureFormatToFormatAndType(
TextureFormat format) noexcept {
switch (format) {
case TextureFormat::R8: return { 0x1909 /*GL_LUMINANCE*/, GL_UNSIGNED_BYTE };
+64 -116
View File
@@ -39,7 +39,6 @@
#include <backend/Program.h>
#include <backend/TargetBufferInfo.h>
#include "private/backend/CommandStream.h"
#include "private/backend/Dispatcher.h"
#include "private/backend/DriverApi.h"
@@ -47,11 +46,9 @@
#include <utils/BitmaskEnum.h>
#include <utils/FixedCapacityVector.h>
#include <utils/CString.h>
#include <utils/Invocable.h>
#include <utils/Log.h>
#include <utils/Panic.h>
#include <utils/Systrace.h>
#include <utils/Slice.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ostream.h>
@@ -157,8 +154,8 @@ using namespace GLUtils;
// ------------------------------------------------------------------------------------------------
UTILS_NOINLINE
OpenGLDriver* OpenGLDriver::create(OpenGLPlatform* const platform,
void* const /*sharedGLContext*/, const Platform::DriverConfig& driverConfig) noexcept {
Driver* OpenGLDriver::create(OpenGLPlatform* const platform,
void* const sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept {
assert_invariant(platform);
OpenGLPlatform* const ec = platform;
@@ -225,7 +222,7 @@ OpenGLDriver* OpenGLDriver::create(OpenGLPlatform* const platform,
}
#endif
constexpr size_t defaultSize = FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U;
size_t const defaultSize = FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U;
Platform::DriverConfig validConfig{ driverConfig };
validConfig.handleArenaSize = std::max(driverConfig.handleArenaSize, defaultSize);
OpenGLDriver* const driver = new(std::nothrow) OpenGLDriver(ec, validConfig);
@@ -280,6 +277,7 @@ OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfi
driverConfig.disableHandleUseAfterFreeCheck),
mDriverConfig(driverConfig),
mCurrentPushConstants(new(std::nothrow) PushConstantBundle{}) {
// set a reasonable default value for our stream array
mTexturesWithStreamsAttached.reserve(8);
mStreamsWithPendingAcquiredImage.reserve(8);
@@ -368,8 +366,8 @@ void OpenGLDriver::bindSampler(GLuint unit, GLuint sampler) noexcept {
mContext.bindSampler(unit, sampler);
}
void OpenGLDriver::setPushConstant(ShaderStage stage, uint8_t index,
PushConstantVariant value) {
void OpenGLDriver::setPushConstant(backend::ShaderStage stage, uint8_t index,
backend::PushConstantVariant value) {
assert_invariant(stage == ShaderStage::VERTEX || stage == ShaderStage::FRAGMENT);
#if FILAMENT_ENABLE_MATDBG
@@ -378,7 +376,7 @@ void OpenGLDriver::setPushConstant(ShaderStage stage, uint8_t index,
}
#endif
Slice<std::pair<GLint, ConstantType>> constants;
utils::Slice<std::pair<GLint, ConstantType>> constants;
if (stage == ShaderStage::VERTEX) {
constants = mCurrentPushConstants->vertexConstants;
} else if (stage == ShaderStage::FRAGMENT) {
@@ -584,10 +582,6 @@ Handle<HwTexture> OpenGLDriver::createTextureViewSwizzleS() noexcept {
return initHandle<GLTexture>();
}
Handle<HwTexture> OpenGLDriver::createTextureExternalImage2S() noexcept {
return initHandle<GLTexture>();
}
Handle<HwTexture> OpenGLDriver::createTextureExternalImageS() noexcept {
return initHandle<GLTexture>();
}
@@ -683,7 +677,7 @@ void OpenGLDriver::createBufferObjectR(Handle<HwBufferObject> boh,
bo->gl.buffer = malloc(byteCount);
memset(bo->gl.buffer, 0, byteCount);
} else {
bo->gl.binding = getBufferBindingType(bindingType);
bo->gl.binding = GLUtils::getBufferBindingType(bindingType);
glGenBuffers(1, &bo->gl.id);
gl.bindBuffer(bo->gl.binding, bo->gl.id);
glBufferData(bo->gl.binding, byteCount, nullptr, getBufferUsage(usage));
@@ -760,7 +754,7 @@ void OpenGLDriver::createProgramR(Handle<HwProgram> ph, Program&& program) {
}
UTILS_NOINLINE
void OpenGLDriver::textureStorage(GLTexture* t,
void OpenGLDriver::textureStorage(OpenGLDriver::GLTexture* t,
uint32_t width, uint32_t height, uint32_t depth, bool useProtectedMemory) noexcept {
auto& gl = mContext;
@@ -909,7 +903,25 @@ void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint
t->gl.internalFormat = internalFormat;
t->gl.target = getTextureTargetNotExternal(target);
switch (target) {
case SamplerType::SAMPLER_EXTERNAL:
// we can't be here -- doesn't matter what we do
case SamplerType::SAMPLER_2D:
t->gl.target = GL_TEXTURE_2D;
break;
case SamplerType::SAMPLER_3D:
t->gl.target = GL_TEXTURE_3D;
break;
case SamplerType::SAMPLER_2D_ARRAY:
t->gl.target = GL_TEXTURE_2D_ARRAY;
break;
case SamplerType::SAMPLER_CUBEMAP:
t->gl.target = GL_TEXTURE_CUBE_MAP;
break;
case SamplerType::SAMPLER_CUBEMAP_ARRAY:
t->gl.target = GL_TEXTURE_CUBE_MAP_ARRAY;
break;
}
if (t->samples > 1) {
// Note: we can't be here in practice because filament's user API doesn't
@@ -983,7 +995,8 @@ void OpenGLDriver::createTextureViewR(Handle<HwTexture> th,
}
void OpenGLDriver::createTextureViewSwizzleR(Handle<HwTexture> th, Handle<HwTexture> srch,
TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, TextureSwizzle a) {
backend::TextureSwizzle r, backend::TextureSwizzle g, backend::TextureSwizzle b,
backend::TextureSwizzle a) {
DEBUG_MARKER()
GLTexture const* const src = handle_cast<GLTexture const*>(srch);
@@ -1045,57 +1058,6 @@ void OpenGLDriver::createTextureViewSwizzleR(Handle<HwTexture> th, Handle<HwText
CHECK_GL_ERROR(utils::slog.e)
}
void OpenGLDriver::createTextureExternalImage2R(Handle<HwTexture> th, SamplerType target,
TextureFormat format, uint32_t width, uint32_t height, TextureUsage usage,
Platform::ExternalImageHandleRef image) {
DEBUG_MARKER()
usage |= TextureUsage::SAMPLEABLE;
usage &= ~TextureUsage::UPLOADABLE;
auto& gl = mContext;
GLenum internalFormat = getInternalFormat(format);
if (UTILS_UNLIKELY(gl.isES2())) {
// on ES2, format and internal format must match
// FIXME: handle compressed texture format
internalFormat = textureFormatToFormatAndType(format).first;
}
assert_invariant(internalFormat);
GLTexture* const t = construct<GLTexture>(th, target, 1, 1, width, height, 1, format, usage);
assert_invariant(t);
t->externalTexture = mPlatform.createExternalImageTexture();
if (t->externalTexture) {
if (target == SamplerType::SAMPLER_EXTERNAL) {
if (UTILS_LIKELY(gl.ext.OES_EGL_image_external_essl3)) {
t->externalTexture->target = GL_TEXTURE_EXTERNAL_OES;
} else {
// revert to texture 2D if external is not supported; what else can we do?
t->externalTexture->target = GL_TEXTURE_2D;
}
} else {
t->externalTexture->target = getTextureTargetNotExternal(target);
}
t->gl.target = t->externalTexture->target;
t->gl.id = t->externalTexture->id;
// internalFormat actually depends on the external image, but it doesn't matter
// because it's not used anywhere for anything important.
t->gl.internalFormat = internalFormat;
t->gl.baseLevel = 0;
t->gl.maxLevel = 0;
t->gl.external = true; // forces bindTexture() call (they're never cached)
}
bindTexture(OpenGLContext::DUMMY_TEXTURE_BINDING, t);
if (mPlatform.setExternalImage(image, t->externalTexture)) {
// the target and id can be reset each time
t->gl.target = t->externalTexture->target;
t->gl.id = t->externalTexture->id;
}
}
void OpenGLDriver::createTextureExternalImageR(Handle<HwTexture> th, SamplerType target,
TextureFormat format, uint32_t width, uint32_t height, TextureUsage usage, void* image) {
DEBUG_MARKER()
@@ -1117,16 +1079,6 @@ void OpenGLDriver::createTextureExternalImageR(Handle<HwTexture> th, SamplerType
t->externalTexture = mPlatform.createExternalImageTexture();
if (t->externalTexture) {
if (target == SamplerType::SAMPLER_EXTERNAL) {
if (UTILS_LIKELY(gl.ext.OES_EGL_image_external_essl3)) {
t->externalTexture->target = GL_TEXTURE_EXTERNAL_OES;
} else {
// revert to texture 2D if external is not supported; what else can we do?
t->externalTexture->target = GL_TEXTURE_2D;
}
} else {
t->externalTexture->target = getTextureTargetNotExternal(target);
}
t->gl.target = t->externalTexture->target;
t->gl.id = t->externalTexture->id;
// internalFormat actually depends on the external image, but it doesn't matter
@@ -1146,7 +1098,7 @@ void OpenGLDriver::createTextureExternalImageR(Handle<HwTexture> th, SamplerType
}
void OpenGLDriver::createTextureExternalImagePlaneR(Handle<HwTexture> th,
TextureFormat format, uint32_t width, uint32_t height, TextureUsage usage,
backend::TextureFormat format, uint32_t width, uint32_t height, backend::TextureUsage usage,
void* image, uint32_t plane) {
// not relevant for the OpenGL backend
}
@@ -1462,7 +1414,7 @@ void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
&& ((gl.ext.EXT_multisampled_render_to_texture && attachment == GL_COLOR_ATTACHMENT0)
|| gl.ext.EXT_multisampled_render_to_texture2)) {
assert_invariant(rt->gl.samples > 1);
// We have a multi-sample rendertarget, and we have EXT_multisampled_render_to_texture,
// We have a multi-sample rendertarget and we have EXT_multisampled_render_to_texture,
// so, we can directly use a 1-sample texture as attachment, multi-sample resolve,
// will happen automagically and efficiently in the driver.
// This extension only exists on OpenGL ES.
@@ -1662,9 +1614,9 @@ void OpenGLDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
rt->gl.samples = samples;
rt->targets = targets;
UTILS_UNUSED_IN_RELEASE vec2<uint32_t> tmin = { std::numeric_limits<uint32_t>::max() };
UTILS_UNUSED_IN_RELEASE vec2<uint32_t> tmax = { 0 };
auto checkDimensions = [&tmin, &tmax](GLTexture const* t, uint8_t level) {
UTILS_UNUSED_IN_RELEASE math::vec2<uint32_t> tmin = { std::numeric_limits<uint32_t>::max() };
UTILS_UNUSED_IN_RELEASE math::vec2<uint32_t> tmax = { 0 };
auto checkDimensions = [&tmin, &tmax](GLTexture* t, uint8_t level) {
const auto twidth = std::max(1u, t->width >> level);
const auto theight = std::max(1u, t->height >> level);
tmin = { std::min(tmin.x, twidth), std::min(tmin.y, theight) };
@@ -1918,7 +1870,7 @@ void OpenGLDriver::destroyTexture(Handle<HwTexture> th) {
detachStream(t);
}
if (UTILS_UNLIKELY(t->target == SamplerType::SAMPLER_EXTERNAL)) {
mPlatform.destroyExternalImageTexture(t->externalTexture);
mPlatform.destroyExternalImage(t->externalTexture);
} else {
glDeleteTextures(1, &t->gl.id);
}
@@ -2366,11 +2318,11 @@ bool OpenGLDriver::isStereoSupported() {
return false;
}
switch (mDriverConfig.stereoscopicType) {
case StereoscopicType::INSTANCED:
case backend::StereoscopicType::INSTANCED:
return mContext.ext.EXT_clip_cull_distance;
case StereoscopicType::MULTIVIEW:
case backend::StereoscopicType::MULTIVIEW:
return mContext.ext.OVR_multiview2;
case StereoscopicType::NONE:
case backend::StereoscopicType::NONE:
return false;
}
}
@@ -2383,7 +2335,7 @@ bool OpenGLDriver::isDepthStencilResolveSupported() {
return true;
}
bool OpenGLDriver::isDepthStencilBlitSupported(TextureFormat) {
bool OpenGLDriver::isDepthStencilBlitSupported(TextureFormat format) {
return true;
}
@@ -2417,12 +2369,12 @@ FeatureLevel OpenGLDriver::getFeatureLevel() {
return mContext.getFeatureLevel();
}
float2 OpenGLDriver::getClipSpaceParams() {
math::float2 OpenGLDriver::getClipSpaceParams() {
return mContext.ext.EXT_clip_control ?
// z-coordinate of virtual and physical clip-space is in [-w, 0]
float2{ 1.0f, 0.0f } :
math::float2{ 1.0f, 0.0f } :
// z-coordinate of virtual clip-space is in [-w,0], physical is in [-w, w]
float2{ 2.0f, -1.0f };
math::float2{ 2.0f, -1.0f };
}
uint8_t OpenGLDriver::getMaxDrawBuffers() {
@@ -2486,7 +2438,7 @@ void OpenGLDriver::makeCurrent(Handle<HwSwapChain> schDraw, Handle<HwSwapChain>
// Updating driver objects
// ------------------------------------------------------------------------------------------------
void OpenGLDriver::setDebugTag(HandleBase::HandleId handleId, CString tag) {
void OpenGLDriver::setDebugTag(HandleBase::HandleId handleId, utils::CString tag) {
mHandleAllocator.associateTagToHandle(handleId, std::move(tag));
}
@@ -2662,7 +2614,7 @@ void OpenGLDriver::generateMipmaps(Handle<HwTexture> th) {
CHECK_GL_ERROR(utils::slog.e)
}
void OpenGLDriver::setTextureData(GLTexture const* t, uint32_t level,
void OpenGLDriver::setTextureData(GLTexture* t, uint32_t level,
uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
uint32_t width, uint32_t height, uint32_t depth,
PixelBufferDescriptor&& p) {
@@ -2771,7 +2723,7 @@ void OpenGLDriver::setTextureData(GLTexture const* t, uint32_t level,
CHECK_GL_ERROR(utils::slog.e)
}
void OpenGLDriver::setCompressedTextureData(GLTexture const* t, uint32_t level,
void OpenGLDriver::setCompressedTextureData(GLTexture* t, uint32_t level,
uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
uint32_t width, uint32_t height, uint32_t depth,
PixelBufferDescriptor&& p) {
@@ -2857,10 +2809,6 @@ void OpenGLDriver::setCompressedTextureData(GLTexture const* t, uint32_t level,
CHECK_GL_ERROR(utils::slog.e)
}
void OpenGLDriver::setupExternalImage2(Platform::ExternalImageHandleRef image) {
mPlatform.retainExternalImage(image);
}
void OpenGLDriver::setupExternalImage(void* image) {
mPlatform.retainExternalImage(image);
}
@@ -3412,8 +3360,8 @@ void OpenGLDriver::readPixels(Handle<HwRenderTarget> src,
#endif
}
void OpenGLDriver::readBufferSubData(BufferObjectHandle boh,
uint32_t offset, uint32_t size, BufferDescriptor&& p) {
void OpenGLDriver::readBufferSubData(backend::BufferObjectHandle boh,
uint32_t offset, uint32_t size, backend::BufferDescriptor&& p) {
UTILS_UNUSED_IN_RELEASE auto& gl = mContext;
assert_invariant(!gl.isES2());
@@ -3560,13 +3508,13 @@ void OpenGLDriver::beginFrame(
}
}
void OpenGLDriver::setFrameScheduledCallback(Handle<HwSwapChain>, CallbackHandler*,
FrameScheduledCallback&& /*callback*/, uint64_t /*flags*/) {
void OpenGLDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch, CallbackHandler* handler,
FrameScheduledCallback&& callback, uint64_t flags) {
DEBUG_MARKER()
}
void OpenGLDriver::setFrameCompletedCallback(Handle<HwSwapChain>,
CallbackHandler*, Invocable<void()>&& /*callback*/) {
void OpenGLDriver::setFrameCompletedCallback(Handle<HwSwapChain> sch,
CallbackHandler* handler, utils::Invocable<void(void)>&& callback) {
DEBUG_MARKER()
}
@@ -3597,9 +3545,9 @@ void OpenGLDriver::endFrame(UTILS_UNUSED uint32_t frameId) {
}
void OpenGLDriver::updateDescriptorSetBuffer(
DescriptorSetHandle dsh,
descriptor_binding_t binding,
BufferObjectHandle boh,
backend::DescriptorSetHandle dsh,
backend::descriptor_binding_t binding,
backend::BufferObjectHandle boh,
uint32_t offset, uint32_t size) {
GLDescriptorSet* ds = handle_cast<GLDescriptorSet*>(dsh);
GLBufferObject* bo = boh ? handle_cast<GLBufferObject*>(boh) : nullptr;
@@ -3607,9 +3555,9 @@ void OpenGLDriver::updateDescriptorSetBuffer(
}
void OpenGLDriver::updateDescriptorSetTexture(
DescriptorSetHandle dsh,
descriptor_binding_t binding,
TextureHandle th,
backend::DescriptorSetHandle dsh,
backend::descriptor_binding_t binding,
backend::TextureHandle th,
SamplerParams params) {
GLDescriptorSet* ds = handle_cast<GLDescriptorSet*>(dsh);
GLTexture* t = th ? handle_cast<GLTexture*>(th) : nullptr;
@@ -3642,7 +3590,7 @@ void OpenGLDriver::finish(int) {
UTILS_NOINLINE
void OpenGLDriver::clearWithRasterPipe(TargetBufferFlags clearFlags,
float4 const& linearColor, GLfloat depth, GLint stencil) noexcept {
math::float4 const& linearColor, GLfloat depth, GLint stencil) noexcept {
if (any(clearFlags & TargetBufferFlags::COLOR_ALL)) {
mContext.colorMask(GL_TRUE);
@@ -3965,9 +3913,9 @@ void OpenGLDriver::bindRenderPrimitive(Handle<HwRenderPrimitive> rph) {
}
void OpenGLDriver::bindDescriptorSet(
DescriptorSetHandle dsh,
descriptor_set_t set,
DescriptorSetOffsetArray&& offsets) {
backend::DescriptorSetHandle dsh,
backend::descriptor_set_t set,
backend::DescriptorSetOffsetArray&& offsets) {
if (UTILS_UNLIKELY(!dsh)) {
mBoundDescriptorSets[set].dsh = dsh;
@@ -3999,7 +3947,7 @@ void OpenGLDriver::bindDescriptorSet(
}
}
void OpenGLDriver::updateDescriptors(bitset8 invalidDescriptorSets) noexcept {
void OpenGLDriver::updateDescriptors(utils::bitset8 invalidDescriptorSets) noexcept {
assert_invariant(mBoundProgram);
auto const offsetOnly = mInvalidDescriptorSetBindingOffsets & ~mInvalidDescriptorSetBindings;
invalidDescriptorSets.forEachSetBit([this, offsetOnly,
@@ -4111,7 +4059,7 @@ void OpenGLDriver::draw(PipelineState state, Handle<HwRenderPrimitive> rph,
}
}
void OpenGLDriver::dispatchCompute(Handle<HwProgram> program, uint3 workGroupCount) {
void OpenGLDriver::dispatchCompute(Handle<HwProgram> program, math::uint3 workGroupCount) {
DEBUG_MARKER()
getShaderCompilerService().tick();
+21 -30
View File
@@ -19,7 +19,6 @@
#include "DriverBase.h"
#include "OpenGLContext.h"
#include "OpenGLDriverBase.h"
#include "OpenGLTimerQuery.h"
#include "GLBufferObject.h"
#include "GLDescriptorSet.h"
@@ -27,10 +26,11 @@
#include "GLTexture.h"
#include "ShaderCompilerService.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/AcquiredImage.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <backend/PipelineState.h>
#include <backend/Platform.h>
#include <backend/Program.h>
#include <backend/TargetBufferInfo.h>
@@ -41,7 +41,6 @@
#include <utils/bitset.h>
#include <utils/FixedCapacityVector.h>
#include <utils/compiler.h>
#include <utils/CString.h>
#include <utils/debug.h>
#include <math/vec4.h>
@@ -75,14 +74,14 @@ class OpenGLProgram;
class TimerQueryFactoryInterface;
struct PushConstantBundle;
class OpenGLDriver final : public OpenGLDriverBase {
class OpenGLDriver final : public DriverBase {
inline explicit OpenGLDriver(OpenGLPlatform* platform,
const Platform::DriverConfig& driverConfig) noexcept;
~OpenGLDriver() noexcept override;
Dispatcher getDispatcher() const noexcept override;
~OpenGLDriver() noexcept final;
Dispatcher getDispatcher() const noexcept final;
public:
static OpenGLDriver* create(OpenGLPlatform* platform, void* sharedGLContext,
static Driver* create(OpenGLPlatform* platform, void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept;
class DebugMarker {
@@ -185,7 +184,7 @@ public:
std::condition_variable cond;
FenceStatus status{ FenceStatus::TIMEOUT_EXPIRED };
};
std::shared_ptr<State> state{ std::make_shared<State>() };
std::shared_ptr<State> state{ std::make_shared<GLFence::State>() };
};
OpenGLDriver(OpenGLDriver const&) = delete;
@@ -204,21 +203,13 @@ private:
return mShaderCompilerService;
}
ShaderModel getShaderModel() const noexcept override;
ShaderLanguage getShaderLanguage() const noexcept override;
ShaderModel getShaderModel() const noexcept final;
ShaderLanguage getShaderLanguage() const noexcept final;
/*
* OpenGLDriver interface
* Driver interface
*/
utils::CString getVendorString() const noexcept override {
return utils::CString{ mContext.state.vendor };
}
utils::CString getRendererString() const noexcept override {
return utils::CString{ mContext.state.renderer };
}
template<typename T>
friend class ConcreteDispatcher;
@@ -245,21 +236,21 @@ private:
}
template<typename D, typename B, typename ... ARGS>
std::enable_if_t<std::is_base_of_v<B, D>, D>*
typename std::enable_if<std::is_base_of<B, D>::value, D>::type*
construct(Handle<B> const& handle, ARGS&& ... args) {
return mHandleAllocator.destroyAndConstruct<D, B>(handle, std::forward<ARGS>(args) ...);
}
template<typename B, typename D,
typename = std::enable_if_t<std::is_base_of_v<B, D>, D>>
typename = typename std::enable_if<std::is_base_of<B, D>::value, D>::type>
void destruct(Handle<B>& handle, D const* p) noexcept {
return mHandleAllocator.deallocate(handle, p);
}
template<typename Dp, typename B>
std::enable_if_t<
typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, std::remove_pointer_t<Dp>>, Dp>
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B>& handle) {
return mHandleAllocator.handle_cast<Dp, B>(handle);
}
@@ -270,9 +261,9 @@ private:
}
template<typename Dp, typename B>
std::enable_if_t<
inline typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, std::remove_pointer_t<Dp>>, Dp>
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B> const& handle) {
return mHandleAllocator.handle_cast<Dp, B>(handle);
}
@@ -297,13 +288,13 @@ private:
void setStencilState(StencilState ss) noexcept;
void setTextureData(GLTexture const* t,
void setTextureData(GLTexture* t,
uint32_t level,
uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
uint32_t width, uint32_t height, uint32_t depth,
PixelBufferDescriptor&& p);
void setCompressedTextureData(GLTexture const* t,
void setCompressedTextureData(GLTexture* t,
uint32_t level,
uint32_t xoffset, uint32_t yoffset, uint32_t zoffset,
uint32_t width, uint32_t height, uint32_t depth,
@@ -312,7 +303,7 @@ private:
void renderBufferStorage(GLuint rbo, GLenum internalformat, uint32_t width,
uint32_t height, uint8_t samples) const noexcept;
void textureStorage(GLTexture* t, uint32_t width, uint32_t height,
void textureStorage(OpenGLDriver::GLTexture* t, uint32_t width, uint32_t height,
uint32_t depth, bool useProtectedMemory) noexcept;
/* State tracking GL wrappers... */
@@ -344,9 +335,9 @@ private:
void updateDescriptors(utils::bitset8 invalidDescriptorSets) noexcept;
struct {
DescriptorSetHandle dsh;
backend::DescriptorSetHandle dsh;
std::array<uint32_t, CONFIG_UNIFORM_BINDING_COUNT> offsets;
} mBoundDescriptorSets[MAX_DESCRIPTOR_SET_COUNT] = {};
} mBoundDescriptorSets[MAX_DESCRIPTOR_SET_COUNT];
void clearWithRasterPipe(TargetBufferFlags clearFlags,
math::float4 const& linearColor, GLfloat depth, GLint stencil) noexcept;
@@ -1,37 +0,0 @@
/*
* Copyright (C) 2025 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGLDRIVERBASE_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGLDRIVERBASE_H
#include "DriverBase.h"
#include <utils/CString.h>
namespace filament::backend {
class OpenGLDriverBase : public DriverBase {
protected:
~OpenGLDriverBase() override;
public:
virtual utils::CString getVendorString() const noexcept = 0;
virtual utils::CString getRendererString() const noexcept = 0;
};
} // filament::backend
#endif //TNT_FILAMENT_BACKEND_OPENGL_OPENGLDRIVERBASE_H
+3 -38
View File
@@ -16,7 +16,6 @@
#include <backend/platforms/OpenGLPlatform.h>
#include "OpenGLDriverBase.h"
#include "OpenGLDriverFactory.h"
#include <backend/AcquiredImage.h>
@@ -24,45 +23,21 @@
#include <backend/Platform.h>
#include <utils/compiler.h>
#include <utils/Panic.h>
#include <utils/CString.h>
#include <utils/Invocable.h>
#include <utils/Invocable.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "OpenGLDriver.h"
namespace filament::backend {
OpenGLDriverBase::~OpenGLDriverBase() = default;
Driver* OpenGLPlatform::createDefaultDriver(OpenGLPlatform* platform,
void* sharedContext, const DriverConfig& driverConfig) {
void* sharedContext, const Platform::DriverConfig& driverConfig) {
return OpenGLDriverFactory::create(platform, sharedContext, driverConfig);
}
OpenGLPlatform::~OpenGLPlatform() noexcept = default;
utils::CString OpenGLPlatform::getVendorString(Driver const* driver) {
auto const p = static_cast<OpenGLDriverBase const*>(driver);
#if UTILS_HAS_RTTI
FILAMENT_CHECK_POSTCONDITION(dynamic_cast<OpenGLDriverBase const*>(driver))
<< "Driver* has not been allocated with OpenGLPlatform";
#endif
return p->getVendorString();
}
utils::CString OpenGLPlatform::getRendererString(Driver const* driver) {
auto const p = static_cast<OpenGLDriverBase const*>(driver);
#if UTILS_HAS_RTTI
FILAMENT_CHECK_POSTCONDITION(dynamic_cast<OpenGLDriverBase const*>(driver))
<< "Driver* has not been allocated with OpenGLPlatform";
#endif
return p->getRendererString();
}
void OpenGLPlatform::makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain,
utils::Invocable<void()>, utils::Invocable<void(size_t)>) noexcept {
makeCurrent(getCurrentContextType(), drawSwapChain, readSwapChain);
@@ -146,24 +121,14 @@ OpenGLPlatform::ExternalTexture* OpenGLPlatform::createExternalImageTexture() no
return nullptr;
}
void OpenGLPlatform::destroyExternalImageTexture(
void OpenGLPlatform::destroyExternalImage(
UTILS_UNUSED ExternalTexture* texture) noexcept {
}
void OpenGLPlatform::retainExternalImage(
UTILS_UNUSED ExternalImageHandleRef externalImage) noexcept {
}
void OpenGLPlatform::retainExternalImage(
UTILS_UNUSED void* externalImage) noexcept {
}
bool OpenGLPlatform::setExternalImage(
UTILS_UNUSED ExternalImageHandleRef externalImage,
UTILS_UNUSED ExternalTexture* texture) noexcept {
return false;
}
bool OpenGLPlatform::setExternalImage(
UTILS_UNUSED void* externalImage,
UTILS_UNUSED ExternalTexture* texture) noexcept {
@@ -54,15 +54,8 @@ struct PlatformCocoaGLImpl {
CVOpenGLTextureCacheRef mTextureCache = nullptr;
std::unique_ptr<CocoaExternalImage::SharedGl> mExternalImageSharedGl;
void updateOpenGLContext(NSView *nsView, bool resetView, bool clearView);
struct ExternalImageCocoaGL : public Platform::ExternalImage {
CVPixelBufferRef cvBuffer;
protected:
~ExternalImageCocoaGL() noexcept final;
};
};
PlatformCocoaGLImpl::ExternalImageCocoaGL::~ExternalImageCocoaGL() noexcept = default;
CocoaGLSwapChain::CocoaGLSwapChain( NSView* inView )
: view(inView)
, previousBounds(NSZeroRect)
@@ -316,12 +309,17 @@ OpenGLPlatform::ExternalTexture* PlatformCocoaGL::createExternalImageTexture() n
if (!pImpl->mExternalImageSharedGl) {
pImpl->mExternalImageSharedGl = std::make_unique<CocoaExternalImage::SharedGl>();
}
ExternalTexture* outTexture = new CocoaExternalImage(pImpl->mTextureCache,
*pImpl->mExternalImageSharedGl);
// the actual id/target will be set in setExternalImage.
outTexture->id = 0;
outTexture->target = GL_TEXTURE_2D;
return outTexture;
}
void PlatformCocoaGL::destroyExternalImageTexture(ExternalTexture* texture) noexcept {
void PlatformCocoaGL::destroyExternalImage(ExternalTexture* texture) noexcept {
auto* p = static_cast<CocoaExternalImage*>(texture);
delete p;
}
@@ -346,36 +344,6 @@ bool PlatformCocoaGL::setExternalImage(void* externalImage, ExternalTexture* tex
return true;
}
Platform::ExternalImageHandle PlatformCocoaGL::createExternalImage(void* cvPixelBuffer) noexcept {
auto* p = new(std::nothrow) PlatformCocoaGLImpl::ExternalImageCocoaGL;
p->cvBuffer = (CVPixelBufferRef) cvPixelBuffer;
return ExternalImageHandle{ p };
}
void PlatformCocoaGL::retainExternalImage(ExternalImageHandleRef externalImage) noexcept {
auto const* const cocoaGlExternalImage
= static_cast<PlatformCocoaGLImpl::ExternalImageCocoaGL const*>(externalImage.get());
// Take ownership of the passed in buffer. It will be released the next time
// setExternalImage is called, or when the texture is destroyed.
CVPixelBufferRef pixelBuffer = cocoaGlExternalImage->cvBuffer;
CVPixelBufferRetain(pixelBuffer);
}
bool PlatformCocoaGL::setExternalImage(ExternalImageHandleRef externalImage, ExternalTexture* texture) noexcept {
auto const* const cocoaGlExternalImage
= static_cast<PlatformCocoaGLImpl::ExternalImageCocoaGL const*>(externalImage.get());
CVPixelBufferRef cvPixelBuffer = cocoaGlExternalImage->cvBuffer;
CocoaExternalImage* cocoaExternalImage = static_cast<CocoaExternalImage*>(texture);
if (!cocoaExternalImage->set(cvPixelBuffer)) {
return false;
}
texture->target = cocoaExternalImage->getTarget();
texture->id = cocoaExternalImage->getGlTexture();
// we used to set the internalFormat, but it's not used anywhere on the gl backend side
// cocoaExternalImage->getInternalFormat();
return true;
}
void PlatformCocoaGLImpl::updateOpenGLContext(NSView *nsView, bool resetView,
bool clearView) {
NSOpenGLContext* glContext = mGLContext;
@@ -47,15 +47,8 @@ struct PlatformCocoaTouchGLImpl {
GLuint mDefaultDepthbuffer = 0;
CVOpenGLESTextureCacheRef mTextureCache = nullptr;
CocoaTouchExternalImage::SharedGl* mExternalImageSharedGl = nullptr;
struct ExternalImageCocoaTouchGL : public Platform::ExternalImage {
CVPixelBufferRef cvBuffer;
protected:
~ExternalImageCocoaTouchGL() noexcept final;
};
};
PlatformCocoaTouchGLImpl::ExternalImageCocoaTouchGL::~ExternalImageCocoaTouchGL() noexcept = default;
PlatformCocoaTouchGL::PlatformCocoaTouchGL()
: pImpl(new PlatformCocoaTouchGLImpl) {
}
@@ -205,10 +198,13 @@ void PlatformCocoaTouchGL::commit(Platform::SwapChain* swapChain) noexcept {
OpenGLPlatform::ExternalTexture* PlatformCocoaTouchGL::createExternalImageTexture() noexcept {
ExternalTexture* outTexture = new CocoaTouchExternalImage(pImpl->mTextureCache,
*pImpl->mExternalImageSharedGl);
// the actual id/target will be set in setExternalImage*(
outTexture->id = 0;
outTexture->target = GL_TEXTURE_2D;
return outTexture;
}
void PlatformCocoaTouchGL::destroyExternalImageTexture(ExternalTexture* texture) noexcept {
void PlatformCocoaTouchGL::destroyExternalImage(ExternalTexture* texture) noexcept {
auto* p = static_cast<CocoaTouchExternalImage*>(texture);
delete p;
}
@@ -233,35 +229,4 @@ bool PlatformCocoaTouchGL::setExternalImage(void* externalImage, ExternalTexture
return true;
}
Platform::ExternalImageHandle PlatformCocoaTouchGL::createExternalImage(void* cvPixelBuffer) noexcept {
auto* p = new(std::nothrow) PlatformCocoaTouchGLImpl::ExternalImageCocoaTouchGL;
p->cvBuffer = (CVPixelBufferRef) cvPixelBuffer;
return ExternalImageHandle{ p };
}
void PlatformCocoaTouchGL::retainExternalImage(ExternalImageHandleRef externalImage) noexcept {
auto const* const cocoaTouchGlExternalImage
= static_cast<PlatformCocoaTouchGLImpl::ExternalImageCocoaTouchGL const*>(externalImage.get());
// Take ownership of the passed in buffer. It will be released the next time
// setExternalImage is called, or when the texture is destroyed.
CVPixelBufferRef pixelBuffer = cocoaTouchGlExternalImage->cvBuffer;
CVPixelBufferRetain(pixelBuffer);
}
bool PlatformCocoaTouchGL::setExternalImage(ExternalImageHandleRef externalImage, ExternalTexture* texture) noexcept {
auto const* const cocoaTouchGlExternalImage
= static_cast<PlatformCocoaTouchGLImpl::ExternalImageCocoaTouchGL const*>(externalImage.get());
CVPixelBufferRef cvPixelBuffer = cocoaTouchGlExternalImage->cvBuffer;
CocoaTouchExternalImage* cocoaExternalImage = static_cast<CocoaTouchExternalImage*>(texture);
if (!cocoaExternalImage->set(cvPixelBuffer)) {
return false;
}
texture->target = cocoaExternalImage->getTarget();
texture->id = cocoaExternalImage->getGlTexture();
// we used to set the internalFormat, but it's not used anywhere on the gl backend side
// cocoaExternalImage->getInternalFormat();
return true;
}
} // namespace filament::backend
@@ -117,9 +117,7 @@ bool PlatformEGL::isOpenGL() const noexcept {
return false;
}
PlatformEGL::ExternalImageEGL::~ExternalImageEGL() = default;
Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& driverConfig) noexcept {
Driver* PlatformEGL::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert_invariant(mEGLDisplay != EGL_NO_DISPLAY);
@@ -297,7 +295,7 @@ Driver* PlatformEGL::createDriver(void* sharedContext, const DriverConfig& drive
clearGlError();
// success!!
return createDefaultDriver(this, sharedContext, driverConfig);
return OpenGLPlatform::createDefaultDriver(this, sharedContext, driverConfig);
error:
// if we're here, we've failed
@@ -551,7 +549,7 @@ Platform::SwapChain* PlatformEGL::createSwapChain(
return sc;
}
void PlatformEGL::destroySwapChain(SwapChain* swapChain) noexcept {
void PlatformEGL::destroySwapChain(Platform::SwapChain* swapChain) noexcept {
if (swapChain) {
SwapChainEGL const* const sc = static_cast<SwapChainEGL const*>(swapChain);
if (sc->sur != EGL_NO_SURFACE) {
@@ -564,7 +562,7 @@ void PlatformEGL::destroySwapChain(SwapChain* swapChain) noexcept {
}
}
bool PlatformEGL::isSwapChainProtected(SwapChain* swapChain) noexcept {
bool PlatformEGL::isSwapChainProtected(Platform::SwapChain* swapChain) noexcept {
if (swapChain) {
SwapChainEGL const* const sc = static_cast<SwapChainEGL const*>(swapChain);
return bool(sc->flags & SWAP_CHAIN_CONFIG_PROTECTED_CONTENT);
@@ -585,10 +583,10 @@ bool PlatformEGL::makeCurrent(ContextType type,
return success == EGL_TRUE ? true : false;
}
void PlatformEGL::makeCurrent(SwapChain* drawSwapChain,
SwapChain* readSwapChain,
Invocable<void()> preContextChange,
Invocable<void(size_t index)> postContextChange) noexcept {
void PlatformEGL::makeCurrent(Platform::SwapChain* drawSwapChain,
Platform::SwapChain* readSwapChain,
utils::Invocable<void()> preContextChange,
utils::Invocable<void(size_t index)> postContextChange) noexcept {
assert_invariant(drawSwapChain);
assert_invariant(readSwapChain);
@@ -647,7 +645,7 @@ void PlatformEGL::makeCurrent(SwapChain* drawSwapChain,
}
}
void PlatformEGL::commit(SwapChain* swapChain) noexcept {
void PlatformEGL::commit(Platform::SwapChain* swapChain) noexcept {
if (swapChain) {
SwapChainEGL const* const sc = static_cast<SwapChainEGL const*>(swapChain);
if (sc->sur != EGL_NO_SURFACE) {
@@ -670,7 +668,7 @@ Platform::Fence* PlatformEGL::createFence() noexcept {
return f;
}
void PlatformEGL::destroyFence(Fence* fence) noexcept {
void PlatformEGL::destroyFence(Platform::Fence* fence) noexcept {
#ifdef EGL_KHR_reusable_sync
EGLSyncKHR sync = (EGLSyncKHR) fence;
if (sync != EGL_NO_SYNC_KHR) {
@@ -680,7 +678,7 @@ void PlatformEGL::destroyFence(Fence* fence) noexcept {
}
FenceStatus PlatformEGL::waitFence(
Fence* fence, uint64_t timeout) noexcept {
Platform::Fence* fence, uint64_t timeout) noexcept {
#ifdef EGL_KHR_reusable_sync
EGLSyncKHR sync = (EGLSyncKHR) fence;
if (sync != EGL_NO_SYNC_KHR) {
@@ -701,10 +699,16 @@ FenceStatus PlatformEGL::waitFence(
OpenGLPlatform::ExternalTexture* PlatformEGL::createExternalImageTexture() noexcept {
ExternalTexture* outTexture = new(std::nothrow) ExternalTexture{};
glGenTextures(1, &outTexture->id);
if (UTILS_LIKELY(ext.gl.OES_EGL_image_external_essl3)) {
outTexture->target = GL_TEXTURE_EXTERNAL_OES;
} else {
// if texture external is not supported, revert to texture 2d
outTexture->target = GL_TEXTURE_2D;
}
return outTexture;
}
void PlatformEGL::destroyExternalImageTexture(ExternalTexture* texture) noexcept {
void PlatformEGL::destroyExternalImage(ExternalTexture* texture) noexcept {
glDeleteTextures(1, &texture->id);
delete texture;
}
@@ -724,18 +728,6 @@ bool PlatformEGL::setExternalImage(void* externalImage,
return true;
}
Platform::ExternalImageHandle PlatformEGL::createExternalImage(EGLImageKHR eglImage) noexcept {
auto* const p = new(std::nothrow) ExternalImageEGL;
p->eglImage = eglImage;
return ExternalImageHandle{p};
}
bool PlatformEGL::setExternalImage(ExternalImageHandleRef externalImage,
UTILS_UNUSED_IN_RELEASE ExternalTexture* texture) noexcept {
auto const* const eglExternalImage = static_cast<ExternalImageEGL const*>(externalImage.get());
return setExternalImage(eglExternalImage->eglImage, texture);
}
// -----------------------------------------------------------------------------------------------
void PlatformEGL::initializeGlExtensions() noexcept {
@@ -746,7 +738,7 @@ void PlatformEGL::initializeGlExtensions() noexcept {
ext.gl.OES_EGL_image_external_essl3 = glExtensions.has("GL_OES_EGL_image_external_essl3");
}
EGLContext PlatformEGL::getContextForType(ContextType type) const noexcept {
EGLContext PlatformEGL::getContextForType(OpenGLPlatform::ContextType type) const noexcept {
switch (type) {
case ContextType::NONE:
return EGL_NO_CONTEXT;
@@ -231,26 +231,6 @@ Driver* PlatformEGLAndroid::createDriver(void* sharedContext,
return driver;
}
PlatformEGLAndroid::ExternalImageEGLAndroid::~ExternalImageEGLAndroid() = default;
Platform::ExternalImageHandle PlatformEGLAndroid::createExternalImage(AHardwareBuffer const* buffer, bool sRGB) noexcept {
auto* const p = new(std::nothrow) ExternalImageEGLAndroid;
p->aHardwareBuffer = const_cast<AHardwareBuffer*>(buffer);
p->sRGB = sRGB;
return ExternalImageHandle{ p };
}
bool PlatformEGLAndroid::setExternalImage(ExternalImageHandleRef externalImage,
UTILS_UNUSED_IN_RELEASE ExternalTexture* texture) noexcept {
auto const* const eglExternalImage = static_cast<ExternalImageEGLAndroid const*>(externalImage.get());
if (eglExternalImage->aHardwareBuffer) {
// TODO: implement PlatformEGLAndroid::setExternalImage w/ AHardwareBuffer
return true;
}
// not a AHardwareBuffer, fallback to the inherited version
return PlatformEGL::setExternalImage(externalImage, texture);
}
void PlatformEGLAndroid::setPresentationTime(int64_t presentationTimeInNanosecond) noexcept {
EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
if (currentDrawSurface != EGL_NO_SURFACE) {
+2 -13
View File
@@ -163,24 +163,13 @@ public:
return mProtectedMemorySupported;
}
inline bool isImageView2DOn3DImageSupported() const noexcept {
return mPortabilitySubsetFeatures.imageView2DOn3DImage == VK_TRUE;
}
private:
VkPhysicalDeviceMemoryProperties mMemoryProperties = {};
VkPhysicalDeviceProperties2 mPhysicalDeviceProperties = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2
};
VkPhysicalDeviceFeatures2 mPhysicalDeviceFeatures = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
};
VkPhysicalDevicePortabilitySubsetFeaturesKHR mPortabilitySubsetFeatures = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR,
// By default, on platforms where we don't have portability subset, then this feature must
// exists. We only fill this struct only when portability subset is needed (i.e.
// non-conformant vulkan implementation).
.imageView2DOn3DImage = VK_TRUE,
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2
};
bool mDebugMarkersSupported = false;
bool mDebugUtilsSupported = false;
+1 -17
View File
@@ -552,15 +552,6 @@ void VulkanDriver::createTextureViewSwizzleR(Handle<HwTexture> th, Handle<HwText
texture.inc();
}
void VulkanDriver::createTextureExternalImage2R(Handle<HwTexture> th,
backend::SamplerType target, backend::TextureFormat format,
uint32_t width, uint32_t height, backend::TextureUsage usage,
Platform::ExternalImageHandleRef externalImage) {
FVK_SYSTRACE_SCOPE();
// FIXME: implement createTextureExternalImage2R
}
void VulkanDriver::createTextureExternalImageR(Handle<HwTexture> th, backend::SamplerType target,
backend::TextureFormat format, uint32_t width, uint32_t height, backend::TextureUsage usage,
void* externalImage) {
@@ -579,7 +570,7 @@ void VulkanDriver::createTextureExternalImageR(Handle<HwTexture> th, backend::Sa
auto texture = resource_ptr<VulkanTexture>::make(&mResourceManager, th, mPlatform->getDevice(),
mAllocator, &mResourceManager, &mCommands, data.first, data.second, metadata.format,
1, metadata.width, metadata.height, /*depth=*/1, usage, mStagePool);
1, metadata.width, metadata.height, usage, mStagePool);
texture.inc();
}
@@ -801,10 +792,6 @@ Handle<HwTexture> VulkanDriver::createTextureViewSwizzleS() noexcept {
return mResourceManager.allocHandle<VulkanTexture>();
}
Handle<HwTexture> VulkanDriver::createTextureExternalImage2S() noexcept {
return mResourceManager.allocHandle<VulkanTexture>();
}
Handle<HwTexture> VulkanDriver::createTextureExternalImageS() noexcept {
return mResourceManager.allocHandle<VulkanTexture>();
}
@@ -1184,9 +1171,6 @@ void VulkanDriver::update3DImage(Handle<HwTexture> th, uint32_t level, uint32_t
scheduleDestroy(std::move(data));
}
void VulkanDriver::setupExternalImage2(Platform::ExternalImageHandleRef image) {
}
void VulkanDriver::setupExternalImage(void* image) {
}
+4 -12
View File
@@ -128,15 +128,6 @@ fvkmemory::resource_ptr<VulkanTexture> initMsaaTexture(
return msTexture;
}
VulkanAttachment createSwapchainAttachment(const fvkmemory::resource_ptr<VulkanTexture> texture) {
return VulkanAttachment {
.texture = texture,
.level = 0,
.layerCount = static_cast<uint8_t>(texture ? texture->getPrimaryViewRange().layerCount : 1),
.layer = 0,
};
}
} // anonymous namespace
void VulkanDescriptorSet::acquire(fvkmemory::resource_ptr<VulkanTexture> texture) {
@@ -283,21 +274,22 @@ void VulkanRenderTarget::bindToSwapChain(fvkmemory::resource_ptr<VulkanSwapChain
height = extent.height;
mProtected = swapchain->isProtected();
VulkanAttachment color = createSwapchainAttachment(swapchain->getCurrentColor());
VulkanAttachment color = {};
color.texture = swapchain->getCurrentColor();
mInfo->attachments = {color};
auto& fbkey = mInfo->fbkey;
auto& rpkey = mInfo->rpkey;
rpkey.colorFormat[0] = color.getFormat();
rpkey.viewCount = color.layerCount;
fbkey.width = width;
fbkey.height = height;
fbkey.color[0] = color.getImageView();
fbkey.resolve[0] = VK_NULL_HANDLE;
if (swapchain->getDepth()) {
VulkanAttachment depth = createSwapchainAttachment(swapchain->getDepth());
VulkanAttachment depth = {};
depth.texture = swapchain->getDepth();
mInfo->attachments.push_back(depth);
mInfo->depthIndex = 1;
@@ -218,6 +218,12 @@ struct VulkanProgram : public HwProgram, fvkmemory::Resource {
mInfo->pushConstantDescription.write(cmdbuf, layout, stage, index, value);
}
#if FVK_ENABLED_DEBUG_SAMPLER_NAME
inline utils::FixedCapacityVector<std::string> const& getBindingToName() const {
return mInfo->bindingToName;
}
#endif
// TODO: handle compute shaders.
// The expected order of shaders - from frontend to backend - is vertex, fragment, compute.
static constexpr uint8_t const MAX_SHADER_MODULES = 2;
@@ -40,8 +40,6 @@ VulkanSwapChain::VulkanSwapChain(VulkanPlatform* platform, VulkanContext const&
mFlushAndWaitOnResize(platform->getCustomization().flushAndWaitOnWindowResize),
mTransitionSwapChainImageLayoutForPresent(
platform->getCustomization().transitionSwapChainImageLayoutForPresent),
mLayerCount(1),
mCurrentSwapIndex(0),
mAcquired(false),
mIsFirstRenderPass(true) {
swapChain = mPlatform->createSwapChain(nativeWindow, flags, extent);
@@ -78,18 +76,17 @@ void VulkanSwapChain::update() {
for (auto const color: bundle.colors) {
auto colorTexture = fvkmemory::resource_ptr<VulkanTexture>::construct(mResourceManager,
device, mAllocator, mResourceManager, mCommands, color, VK_NULL_HANDLE,
bundle.colorFormat, 1, bundle.extent.width, bundle.extent.height, bundle.layerCount, colorUsage,
bundle.colorFormat, 1, bundle.extent.width, bundle.extent.height, colorUsage,
mStagePool);
mColors.push_back(colorTexture);
}
mDepth = fvkmemory::resource_ptr<VulkanTexture>::construct(mResourceManager, device,
mAllocator, mResourceManager, mCommands, bundle.depth, VK_NULL_HANDLE,
bundle.depthFormat, 1, bundle.extent.width, bundle.extent.height, bundle.layerCount, depthUsage,
bundle.depthFormat, 1, bundle.extent.width, bundle.extent.height, depthUsage,
mStagePool);
mExtent = bundle.extent;
mLayerCount = bundle.layerCount;
}
void VulkanSwapChain::present() {
@@ -100,7 +97,7 @@ void VulkanSwapChain::present() {
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = mLayerCount,
.layerCount = 1,
};
mColors[mCurrentSwapIndex]->transitionLayout(&commands, subresources, VulkanLayout::PRESENT);
}
@@ -96,7 +96,6 @@ private:
utils::FixedCapacityVector<fvkmemory::resource_ptr<VulkanTexture>> mColors;
fvkmemory::resource_ptr<VulkanTexture> mDepth;
VkExtent2D mExtent;
uint32_t mLayerCount;
uint32_t mCurrentSwapIndex;
std::function<void(Platform::SwapChain* handle)> mExplicitImageReadyWait = nullptr;
bool mAcquired;
+12 -31
View File
@@ -144,16 +144,6 @@ inline VulkanLayout getDefaultLayoutImpl(VkImageUsageFlags vkusage) {
return getDefaultLayoutImpl(usage);
}
SamplerType getSamplerTypeFromDepth(uint32_t const depth) {
return depth > 1 ? SamplerType::SAMPLER_2D_ARRAY
: SamplerType::SAMPLER_2D;
}
uint8_t getLayerCountFromDepth(uint32_t const depth) {
return getLayerCount(getSamplerTypeFromDepth(depth), depth);
}
} // anonymous namespace
VulkanTextureState::VulkanTextureState(VkDevice device, VmaAllocator allocator,
@@ -175,12 +165,12 @@ VulkanTextureState::VulkanTextureState(VkDevice device, VmaAllocator allocator,
VulkanTexture::VulkanTexture(VkDevice device, VmaAllocator allocator,
fvkmemory::ResourceManager* resourceManager, VulkanCommands* commands, VkImage image,
VkDeviceMemory memory, VkFormat format, uint8_t samples, uint32_t width,
uint32_t height, uint32_t depth, TextureUsage tusage, VulkanStagePool& stagePool)
: HwTexture(getSamplerTypeFromDepth(depth), 1, samples, width, height, depth, TextureFormat::UNUSED,
uint32_t height, TextureUsage tusage, VulkanStagePool& stagePool)
: HwTexture(SamplerType::SAMPLER_2D, 1, samples, width, height, 1, TextureFormat::UNUSED,
tusage),
mState(fvkmemory::resource_ptr<VulkanTextureState>::construct(resourceManager, device,
allocator, commands, stagePool, format, fvkutils::getViewType(SamplerType::SAMPLER_2D),
/*mipLevels=*/1, getLayerCountFromDepth(depth), getDefaultLayoutImpl(tusage), any(usage & TextureUsage::PROTECTED))) {
1, 1, getDefaultLayoutImpl(tusage), any(usage & TextureUsage::PROTECTED))) {
mState->mTextureImage = image;
mState->mTextureImageMemory = memory;
mPrimaryViewRange = mState->mFullViewRange;
@@ -193,6 +183,7 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice,
uint8_t levels, TextureFormat tformat, uint8_t samples, uint32_t w, uint32_t h,
uint32_t depth, TextureUsage tusage, VulkanStagePool& stagePool)
: HwTexture(target, levels, samples, w, h, depth, tformat, tusage),
mState(fvkmemory::resource_ptr<VulkanTextureState>::construct(resourceManager, device,
allocator, commands, stagePool, fvkutils::getVkFormat(tformat),
fvkutils::getViewType(target), levels, getLayerCount(target, depth),
@@ -208,20 +199,11 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = 0,
};
if (target == SamplerType::SAMPLER_3D && any(tusage & TextureUsage::ALL_ATTACHMENTS)) {
if (context.isImageView2DOn3DImageSupported()) {
// Note that VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT is only meant to create 2D views of
// a 3D image in the case where the image is the render target. So, for example, it's
// not meant to allow for 2D views that can be used with a sampler.
imageInfo.flags = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
} else {
FVK_LOGW << "Note: creating 2D views on 3D image is not available on this platform. "
<< "i.e. we cannot render to slices of a 3D image" << utils::io::endl;
}
} else if (target == SamplerType::SAMPLER_CUBEMAP) {
if (target == SamplerType::SAMPLER_CUBEMAP) {
imageInfo.arrayLayers = 6;
imageInfo.flags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
} else if (target == SamplerType::SAMPLER_2D_ARRAY) {
}
if (target == SamplerType::SAMPLER_2D_ARRAY) {
imageInfo.arrayLayers = depth;
imageInfo.extent.depth = 1;
// NOTE: We do not use VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT here because:
@@ -265,9 +247,9 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice,
#if FVK_ENABLED(FVK_DEBUG_TEXTURE)
// Validate that the format is actually sampleable.
VkFormatProperties props;
vkGetPhysicalDeviceFormatProperties(physicalDevice, mState->mVkFormat, &props);
vkGetPhysicalDeviceFormatProperties(physicalDevice, state->mVkFormat, &props);
if (!(props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
FVK_LOGW << "Texture usage is SAMPLEABLE but format " << mState->mVkFormat << " is not "
FVK_LOGW << "Texture usage is SAMPLEABLE but format " << state->mVkFormat << " is not "
"sampleable with optimal tiling." << utils::io::endl;
}
#endif
@@ -649,16 +631,15 @@ bool VulkanTexture::transitionLayout(VkCommandBuffer cmdbuf, VkImageSubresourceR
if (hasTransitions) {
#if FVK_ENABLED(FVK_DEBUG_LAYOUT_TRANSITION)
FVK_LOGD << "transition texture=" << mState->mTextureImage << " (" << range.baseArrayLayer
FVK_LOGD << "transition texture=" << state->mTextureImage << " (" << range.baseArrayLayer
<< "," << range.baseMipLevel << ")" << " count=(" << range.layerCount << ","
<< range.levelCount << ")" << " from=" << oldLayout << " to=" << newLayout
<< " format=" << mState->mVkFormat << " depth="
<< fvkutils::isVkDepthFormat(mState->mVkFormat)
<< " format=" << state->mVkFormat << " depth=" << isVkDepthFormat(state->mVkFormat)
<< " slice-by-slice=" << transitionSliceBySlice << utils::io::endl;
#endif
} else {
#if FVK_ENABLED(FVK_DEBUG_LAYOUT_TRANSITION)
FVK_LOGD << "transition texture=" << mState->mTextureImage << " (" << range.baseArrayLayer
FVK_LOGD << "transition texture=" << state->mTextureImage << " (" << range.baseArrayLayer
<< "," << range.baseMipLevel << ")" << " count=(" << range.layerCount << ","
<< range.levelCount << ")" << " to=" << newLayout
<< " is skipped because of no change in layout" << utils::io::endl;
+1 -1
View File
@@ -94,7 +94,7 @@ struct VulkanTexture : public HwTexture, fvkmemory::Resource {
// The texture will never destroy the given VkImage, but it does manages its subresources.
VulkanTexture(VkDevice device, VmaAllocator allocator,
fvkmemory::ResourceManager* resourceManager, VulkanCommands* commands, VkImage image,
VkDeviceMemory memory, VkFormat format, uint8_t samples, uint32_t width, uint32_t height, uint32_t depth,
VkDeviceMemory memory, VkFormat format, uint8_t samples, uint32_t width, uint32_t height,
TextureUsage tusage, VulkanStagePool& stagePool);
// Constructor for creating a texture view for wrt specific mip range
@@ -18,7 +18,6 @@
#include <backend/DriverEnums.h>
#include "vulkan/VulkanContext.h"
#include "vulkan/platform/VulkanPlatformSwapChainImpl.h"
#include "vulkan/VulkanConstants.h"
#include "vulkan/VulkanDriver.h"
@@ -69,7 +68,7 @@ FixedCapacityVector<const char*> getEnabledLayers() {
constexpr size_t kMaxEnabledLayersCount = sizeof(DESIRED_LAYERS) / sizeof(DESIRED_LAYERS[0]);
const FixedCapacityVector<VkLayerProperties> availableLayers
= fvkutils::enumerate(vkEnumerateInstanceLayerProperties);
= filament::backend::enumerate(vkEnumerateInstanceLayerProperties);
auto enabledLayers = FixedCapacityVector<const char*>::with_capacity(kMaxEnabledLayersCount);
for (auto const& desired: DESIRED_LAYERS) {
@@ -85,13 +84,6 @@ FixedCapacityVector<const char*> getEnabledLayers() {
}
#endif // FVK_EANBLED(FVK_DEBUG_VALIDATION)
template<typename StructA, typename StructB>
StructA* chainStruct(StructA* structA, StructB* structB) {
structB->pNext = const_cast<void*>(structA->pNext);
structA->pNext = (void*) structB;
return structA;
}
void printDeviceInfo(VkInstance instance, VkPhysicalDevice device) {
// Print some driver or MoltenVK information if it is available.
if (vkGetPhysicalDeviceProperties2) {
@@ -100,8 +92,8 @@ void printDeviceInfo(VkInstance instance, VkPhysicalDevice device) {
};
VkPhysicalDeviceProperties2 physicalDeviceProperties2 = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
.pNext = &driverProperties,
};
chainStruct(&physicalDeviceProperties2, &driverProperties);
vkGetPhysicalDeviceProperties2(device, &physicalDeviceProperties2);
FVK_LOGI << "Vulkan device driver: " << driverProperties.driverName << " "
<< driverProperties.driverInfo << utils::io::endl;
@@ -151,7 +143,7 @@ void printDepthFormats(VkPhysicalDevice device) {
const VkFormatFeatureFlags required = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
| VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
FVK_LOGI << "Sampleable depth formats: ";
for (VkFormat format : fvkutils::ALL_VK_FORMATS) {
for (VkFormat format : ALL_VK_FORMATS) {
VkFormatProperties props;
vkGetPhysicalDeviceFormatProperties(device, format, &props);
if ((props.optimalTilingFeatures & required) == required) {
@@ -202,7 +194,7 @@ ExtensionSet getDeviceExtensions(VkPhysicalDevice device) {
#if FVK_ENABLED(FVK_DEBUG_DEBUG_UTILS)
VK_EXT_DEBUG_MARKER_EXTENSION_NAME,
#endif
// We only support external image for Android for now, but nothing bars us from
// We only support external image for Android for now, but nothing bars us from
// supporting other platforms.
#if defined(__ANDROID__)
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
@@ -239,9 +231,7 @@ ExtensionSet getDeviceExtensions(VkPhysicalDevice device) {
VkInstance createInstance(ExtensionSet const& requiredExts) {
VkInstance instance;
VkInstanceCreateInfo instanceCreateInfo = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
};
VkInstanceCreateInfo instanceCreateInfo = {};
bool validationFeaturesSupported = false;
#if FVK_ENABLED(FVK_DEBUG_VALIDATION)
@@ -249,7 +239,7 @@ VkInstance createInstance(ExtensionSet const& requiredExts) {
if (!enabledLayers.empty()) {
// If layers are supported, Check if VK_EXT_validation_features is supported.
FixedCapacityVector<VkExtensionProperties> const availableValidationExts
= fvkutils::enumerate(vkEnumerateInstanceExtensionProperties,
= filament::backend::enumerate(vkEnumerateInstanceExtensionProperties,
"VK_LAYER_KHRONOS_validation");
for (auto const& extProps: availableValidationExts) {
if (!strcmp(extProps.extensionName, VK_EXT_VALIDATION_FEATURES_EXTENSION_NAME)) {
@@ -292,6 +282,7 @@ VkInstance createInstance(ExtensionSet const& requiredExts) {
appInfo.pEngineName = "Filament";
appInfo.apiVersion
= VK_MAKE_API_VERSION(0, FVK_REQUIRED_VERSION_MAJOR, FVK_REQUIRED_VERSION_MINOR, 0);
instanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.pApplicationInfo = &appInfo;
instanceCreateInfo.enabledExtensionCount = enabledExtensionCount;
instanceCreateInfo.ppEnabledExtensionNames = ppEnabledExtensions;
@@ -299,17 +290,16 @@ VkInstance createInstance(ExtensionSet const& requiredExts) {
instanceCreateInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
}
VkValidationFeaturesEXT features = {
.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT,
};
VkValidationFeaturesEXT features = {};
VkValidationFeatureEnableEXT enables[] = {
VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT,
VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT,
};
if (validationFeaturesSupported) {
features.sType = VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT;
features.enabledValidationFeatureCount = sizeof(enables) / sizeof(enables[0]);
features.pEnabledValidationFeatures = enables;
chainStruct(&instanceCreateInfo, &features);
instanceCreateInfo.pNext = &features;
}
VkResult result = vkCreateInstance(&instanceCreateInfo, VKALLOC, &instance);
@@ -320,13 +310,11 @@ VkInstance createInstance(ExtensionSet const& requiredExts) {
VkDevice createLogicalDevice(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceFeatures2 const& features, uint32_t graphicsQueueFamilyIndex,
uint32_t protectedGraphicsQueueFamilyIndex, ExtensionSet const& deviceExtensions,
bool requestImageView2DOn3DImage) {
uint32_t protectedGraphicsQueueFamilyIndex, ExtensionSet const& deviceExtensions) {
VkDevice device;
float queuePriority[] = {1.0f};
VkDeviceCreateInfo deviceCreateInfo = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
};
VkDeviceQueueCreateInfo deviceQueueCreateInfo[2] = {};
const float queuePriority[] = {1.0f};
VkDeviceCreateInfo deviceCreateInfo = {};
FixedCapacityVector<const char*> requestExtensions;
requestExtensions.reserve(deviceExtensions.size() + 1);
@@ -335,7 +323,6 @@ VkDevice createLogicalDevice(VkPhysicalDevice physicalDevice,
for (auto const& ext: deviceExtensions) {
requestExtensions.push_back(ext.data());
}
VkDeviceQueueCreateInfo deviceQueueCreateInfo[2] = {};
deviceQueueCreateInfo[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
deviceQueueCreateInfo[0].queueFamilyIndex = graphicsQueueFamilyIndex;
deviceQueueCreateInfo[0].queueCount = 1;
@@ -347,6 +334,7 @@ VkDevice createLogicalDevice(VkPhysicalDevice physicalDevice,
deviceQueueCreateInfo[1].queueCount = 1;
deviceQueueCreateInfo[1].pQueuePriorities = &queuePriority[0];
deviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
bool const hasProtectedQueue = protectedGraphicsQueueFamilyIndex != INVALID_VK_INDEX;
deviceCreateInfo.queueCreateInfoCount = hasProtectedQueue ? 2 : 1;
deviceCreateInfo.pQueueCreateInfos = deviceQueueCreateInfo;
@@ -365,35 +353,42 @@ VkDevice createLogicalDevice(VkPhysicalDevice physicalDevice,
deviceCreateInfo.enabledExtensionCount = (uint32_t) requestExtensions.size();
deviceCreateInfo.ppEnabledExtensionNames = requestExtensions.data();
void* pNext = nullptr;
VkPhysicalDevicePortabilitySubsetFeaturesKHR portability = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR,
.imageViewFormatSwizzle = VK_TRUE,
.imageView2DOn3DImage = requestImageView2DOn3DImage ? VK_TRUE : VK_FALSE,
.mutableComparisonSamplers = VK_TRUE,
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR,
.pNext = nullptr,
.imageViewFormatSwizzle = VK_TRUE,
.mutableComparisonSamplers = VK_TRUE,
};
if (setContains(deviceExtensions, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) {
chainStruct(&deviceCreateInfo, &portability);
portability.pNext = pNext;
pNext = &portability;
}
VkPhysicalDeviceMultiviewFeaturesKHR multiview = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR,
.multiview = VK_TRUE,
.multiviewGeometryShader = VK_FALSE,
.multiviewTessellationShader = VK_FALSE,
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR,
.pNext = nullptr,
.multiview = VK_TRUE,
.multiviewGeometryShader = VK_FALSE,
.multiviewTessellationShader = VK_FALSE
};
if (setContains(deviceExtensions, VK_KHR_MULTIVIEW_EXTENSION_NAME)) {
chainStruct(&deviceCreateInfo, &multiview);
multiview.pNext = pNext;
pNext = &multiview;
}
VkPhysicalDeviceProtectedMemoryFeatures protectedMemory = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,
.protectedMemory = VK_TRUE,
};
if (hasProtectedQueue) {
// Enable protected memory, if requested.
chainStruct(&deviceCreateInfo, &protectedMemory);
protectedMemory.protectedMemory = VK_TRUE;
protectedMemory.pNext = pNext;
pNext = &protectedMemory;
}
deviceCreateInfo.pNext = pNext;
VkResult result = vkCreateDevice(physicalDevice, &deviceCreateInfo, VKALLOC, &device);
FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS)
<< "vkCreateDevice error=" << static_cast<int32_t>(result);
@@ -506,7 +501,7 @@ VkPhysicalDevice selectPhysicalDevice(VkInstance instance,
// Does the device have any command queues that support graphics?
// In theory, we should also ensure that the device supports presentation of our
// particular VkSurface, but we don't have a VkSurface yet, so we'll skip this requirement.
if (identifyGraphicsQueueFamilyIndex(candidateDevice, VK_QUEUE_GRAPHICS_BIT)
if (identifyGraphicsQueueFamilyIndex(candidateDevice, VK_QUEUE_GRAPHICS_BIT)
== INVALID_VK_INDEX) {
continue;
}
@@ -726,11 +721,14 @@ Driver* VulkanPlatform::createDriver(void* sharedContext,
VkPhysicalDeviceProtectedMemoryFeatures queryProtectedMemoryFeatures = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,
};
// Chain to the pNext linked list
queryProtectedMemoryFeatures.pNext = context.mPhysicalDeviceFeatures.pNext;
context.mPhysicalDeviceFeatures.pNext = &queryProtectedMemoryFeatures;
VkPhysicalDeviceProtectedMemoryProperties protectedMemoryProperties = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES,
};
chainStruct(&context.mPhysicalDeviceFeatures, &queryProtectedMemoryFeatures);
chainStruct(&context.mPhysicalDeviceProperties, &protectedMemoryProperties);
protectedMemoryProperties.pNext = context.mPhysicalDeviceProperties.pNext;
context.mPhysicalDeviceProperties.pNext = &protectedMemoryProperties;
// Initialize the following fields: physicalDeviceProperties, memoryProperties,
// physicalDeviceFeatures, graphicsQueueFamilyIndex.
@@ -740,17 +738,17 @@ Driver* VulkanPlatform::createDriver(void* sharedContext,
mImpl->mGraphicsQueueFamilyIndex
= mImpl->mGraphicsQueueFamilyIndex == INVALID_VK_INDEX
? identifyGraphicsQueueFamilyIndex(mImpl->mPhysicalDevice,
? identifyGraphicsQueueFamilyIndex(mImpl->mPhysicalDevice,
VK_QUEUE_GRAPHICS_BIT)
: mImpl->mGraphicsQueueFamilyIndex;
assert_invariant(mImpl->mGraphicsQueueFamilyIndex != INVALID_VK_INDEX);
// We know we need to allocate the protected version of the VK objects
context.mProtectedMemorySupported =
context.mProtectedMemorySupported =
static_cast<bool>(queryProtectedMemoryFeatures.protectedMemory);
if (context.mProtectedMemorySupported) {
mImpl->mProtectedGraphicsQueueFamilyIndex
= identifyGraphicsQueueFamilyIndex(mImpl->mPhysicalDevice,
= identifyGraphicsQueueFamilyIndex(mImpl->mPhysicalDevice,
(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_PROTECTED_BIT));
assert_invariant(mImpl->mProtectedGraphicsQueueFamilyIndex != INVALID_VK_INDEX);
}
@@ -770,7 +768,7 @@ Driver* VulkanPlatform::createDriver(void* sharedContext,
// Applying the same logic to the protected queue index (Not sure about shared context and protection)
mImpl->mProtectedGraphicsQueueIndex
= mImpl->mProtectedGraphicsQueueIndex == INVALID_VK_INDEX ? 0 :
= mImpl->mProtectedGraphicsQueueIndex == INVALID_VK_INDEX ? 0 :
mImpl->mProtectedGraphicsQueueIndex;
ExtensionSet deviceExts;
@@ -787,23 +785,11 @@ Driver* VulkanPlatform::createDriver(void* sharedContext,
}
}
bool requestPortabilitySubsetImageView2DOn3DImage = false;
if (setContains(deviceExts, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) {
// We are on a non-conformant vulkan implementation so we need to ascertain if the features
// we need are available.
chainStruct(&context.mPhysicalDeviceFeatures, &context.mPortabilitySubsetFeatures);
vkGetPhysicalDeviceFeatures2(mImpl->mPhysicalDevice, &context.mPhysicalDeviceFeatures);
requestPortabilitySubsetImageView2DOn3DImage =
context.mPortabilitySubsetFeatures.imageView2DOn3DImage == VK_TRUE;
}
mImpl->mDevice =
mImpl->mDevice == VK_NULL_HANDLE
? createLogicalDevice(mImpl->mPhysicalDevice, context.mPhysicalDeviceFeatures,
mImpl->mGraphicsQueueFamilyIndex,
mImpl->mProtectedGraphicsQueueFamilyIndex, deviceExts,
requestPortabilitySubsetImageView2DOn3DImage)
: mImpl->mDevice;
mImpl->mDevice
= mImpl->mDevice == VK_NULL_HANDLE ? createLogicalDevice(mImpl->mPhysicalDevice,
context.mPhysicalDeviceFeatures, mImpl->mGraphicsQueueFamilyIndex,
mImpl->mProtectedGraphicsQueueFamilyIndex, deviceExts)
: mImpl->mDevice;
assert_invariant(mImpl->mDevice != VK_NULL_HANDLE);
vkGetDeviceQueue(mImpl->mDevice, mImpl->mGraphicsQueueFamilyIndex, mImpl->mGraphicsQueueIndex,
@@ -820,16 +806,9 @@ Driver* VulkanPlatform::createDriver(void* sharedContext,
}
// Store the extension support in the context
if (!mImpl->mSharedContext) {
context.mDebugUtilsSupported = setContains(instExts, VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
context.mDebugMarkersSupported = setContains(deviceExts, VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
context.mMultiviewEnabled = setContains(deviceExts, VK_KHR_MULTIVIEW_EXTENSION_NAME);
} else {
VulkanSharedContext const* scontext = (VulkanSharedContext const*) sharedContext;
context.mDebugUtilsSupported = scontext->debugUtilsSupported;
context.mDebugMarkersSupported = scontext->debugMarkersSupported;
context.mMultiviewEnabled = scontext->multiviewSupported;
}
context.mDebugUtilsSupported = setContains(instExts, VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
context.mDebugMarkersSupported = setContains(deviceExts, VK_EXT_DEBUG_MARKER_EXTENSION_NAME);
context.mMultiviewEnabled = setContains(deviceExts, VK_KHR_MULTIVIEW_EXTENSION_NAME);
// Check the availability of lazily allocated memory
{
+1 -1
View File
@@ -214,7 +214,7 @@ bool operator<(const VkImageSubresourceRange& a, const VkImageSubresourceRange&
case filament::backend::VulkanLayout::VALUE: { \
out << #VALUE; \
out << " [" \
<< filament::backend::fvkutils::getVkLayout( \
<< filament::backend::imgutil::getVkLayout( \
filament::backend::VulkanLayout::VALUE) \
<< "]"; \
break; \
-12
View File
@@ -17,7 +17,6 @@
#ifndef TNT_FILAMENT_ENGINE_H
#define TNT_FILAMENT_ENGINE_H
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
@@ -33,7 +32,6 @@
#include <stdint.h>
#include <stddef.h>
namespace utils {
class Entity;
class EntityManager;
@@ -42,10 +40,6 @@ class JobSystem;
namespace filament {
namespace backend {
class Driver;
} // backend
class BufferObject;
class Camera;
class ColorGrading;
@@ -189,7 +183,6 @@ public:
using DriverConfig = backend::Platform::DriverConfig;
using FeatureLevel = backend::FeatureLevel;
using StereoscopicType = backend::StereoscopicType;
using Driver = backend::Driver;
/**
* Config is used to define the memory footprint used by the engine, such as the
@@ -589,11 +582,6 @@ public:
static Engine* UTILS_NULLABLE getEngine(void* UTILS_NONNULL token);
#endif
/**
* @return the Driver instance used by this Engine.
* @see OpenGLPlatform
*/
backend::Driver const* UTILS_NONNULL getDriver() const noexcept;
/**
* Destroy the Engine instance and all associated resources.
+9 -20
View File
@@ -121,7 +121,7 @@ public:
/** inline helper to provide the name as a null-terminated string literal */
template<typename T, typename = is_supported_parameter_t<T>>
void setParameter(StringLiteral const name, T const& value) {
void setParameter(StringLiteral name, T const& value) {
setParameter<T>(name.data, name.size, value);
}
@@ -148,14 +148,14 @@ public:
/** inline helper to provide the name as a null-terminated string literal */
template<typename T, typename = is_supported_parameter_t<T>>
void setParameter(StringLiteral const name, const T* UTILS_NONNULL values, size_t const count) {
void setParameter(StringLiteral name, const T* UTILS_NONNULL values, size_t count) {
setParameter<T>(name.data, name.size, values, count);
}
/** inline helper to provide the name as a null-terminated C string */
template<typename T, typename = is_supported_parameter_t<T>>
void setParameter(const char* UTILS_NONNULL name,
const T* UTILS_NONNULL values, size_t const count) {
const T* UTILS_NONNULL values, size_t count) {
setParameter<T>(name, strlen(name), values, count);
}
@@ -176,7 +176,7 @@ public:
Texture const* UTILS_NULLABLE texture, TextureSampler const& sampler);
/** inline helper to provide the name as a null-terminated string literal */
void setParameter(StringLiteral const name,
void setParameter(StringLiteral name,
Texture const* UTILS_NULLABLE texture, TextureSampler const& sampler) {
setParameter(name.data, name.size, texture, sampler);
}
@@ -202,12 +202,12 @@ public:
RgbType type, math::float3 color);
/** inline helper to provide the name as a null-terminated string literal */
void setParameter(StringLiteral const name, RgbType const type, math::float3 const color) {
void setParameter(StringLiteral name, RgbType type, math::float3 color) {
setParameter(name.data, name.size, type, color);
}
/** inline helper to provide the name as a null-terminated C string */
void setParameter(const char* UTILS_NONNULL name, RgbType const type, math::float3 const color) {
void setParameter(const char* UTILS_NONNULL name, RgbType type, math::float3 color) {
setParameter(name, strlen(name), type, color);
}
@@ -226,12 +226,12 @@ public:
RgbaType type, math::float4 color);
/** inline helper to provide the name as a null-terminated string literal */
void setParameter(StringLiteral const name, RgbaType const type, math::float4 const color) {
void setParameter(StringLiteral name, RgbaType type, math::float4 color) {
setParameter(name.data, name.size, type, color);
}
/** inline helper to provide the name as a null-terminated C string */
void setParameter(const char* UTILS_NONNULL name, RgbaType const type, math::float4 const color) {
void setParameter(const char* UTILS_NONNULL name, RgbaType type, math::float4 color) {
setParameter(name, strlen(name), type, color);
}
@@ -251,7 +251,7 @@ public:
/** inline helper to provide the name as a null-terminated C string */
template<typename T, typename = is_supported_parameter_t<T>>
T getParameter(StringLiteral const name) const {
T getParameter(StringLiteral name) const {
return getParameter<T>(name.data, name.size);
}
@@ -376,22 +376,11 @@ public:
*/
void setCullingMode(CullingMode culling) noexcept;
/**
* Overrides the default triangle culling state that was set on the material separately for the
* color and shadow passes
*/
void setCullingMode(CullingMode colorPassCullingMode, CullingMode shadowPassCullingMode) noexcept;
/**
* Returns the face culling mode.
*/
CullingMode getCullingMode() const noexcept;
/**
* Returns the face culling mode for the shadow passes.
*/
CullingMode getShadowCullingMode() const noexcept;
/**
* Overrides the default color-buffer write state that was set on the material.
*/
-5
View File
@@ -141,11 +141,6 @@ public:
*/
void removeEntities(const utils::Entity* UTILS_NONNULL entities, size_t count);
/**
* Remove all entities to the Scene.
*/
void removeAllEntities() noexcept;
/**
* Returns the total number of Entities in the Scene, whether alive or not.
* @return Total number of Entities in the Scene.
+22 -47
View File
@@ -23,7 +23,6 @@
#include <backend/DriverEnums.h>
#include <backend/PixelBufferDescriptor.h>
#include <backend/Platform.h>
#include <utils/compiler.h>
@@ -71,7 +70,7 @@ class UTILS_PUBLIC Texture : public FilamentAPI {
struct BuilderDetails;
public:
static constexpr size_t BASE_LEVEL = 0;
static constexpr const size_t BASE_LEVEL = 0;
//! Face offsets for all faces of a cubemap
struct FaceOffsets;
@@ -85,16 +84,14 @@ public:
using CompressedType = backend::CompressedPixelDataType; //!< Compressed pixel data format
using Usage = backend::TextureUsage; //!< Usage affects texel layout
using Swizzle = backend::TextureSwizzle; //!< Texture swizzle
using ExternalImageHandle = backend::Platform::ExternalImageHandle;
using ExternalImageHandleRef = backend::Platform::ExternalImageHandleRef;
/** @return Whether a backend supports a particular format. */
/** @return whether a backend supports a particular format. */
static bool isTextureFormatSupported(Engine& engine, InternalFormat format) noexcept;
/** @return Whether this backend supports protected textures. */
/** @return whether this backend supports protected textures. */
static bool isProtectedTexturesSupported(Engine& engine) noexcept;
/** @return Whether a backend supports texture swizzling. */
/** @return whether a backend supports texture swizzling. */
static bool isTextureSwizzleSupported(Engine& engine) noexcept;
static size_t computeTextureDataSize(Format format, Type type,
@@ -220,18 +217,6 @@ public:
*/
Builder& name(const char* UTILS_NONNULL name, size_t len) noexcept;
/**
* Creates an external texture. The content must be set using setExternalImage().
* The sampler can be SAMPLER_EXTERNAL or SAMPLER_2D depending on the format. Generally
* YUV formats must use SAMPLER_EXTERNAL. This depends on the backend features and is not
* validated.
*
* If the Sampler is set to SAMPLER_EXTERNAL, external() is implied.
*
* @return
*/
Builder& external() noexcept;
/**
* Creates the Texture object and returns a pointer to it.
*
@@ -276,6 +261,18 @@ public:
*/
Builder& import(intptr_t id) noexcept;
/**
* Creates an external texture. The content must be set using setExternalImage().
* The sampler can be SAMPLER_EXTERNAL or SAMPLER_2D depending on the format. Generally
* YUV formats must use SAMPLER_EXTERNAL. This depends on the backend features and is not
* validated.
*
* If the Sampler is set to SAMPLER_EXTERNAL, external() is implied.
*
* @return
*/
Builder& external() noexcept;
private:
friend class FTexture;
};
@@ -362,7 +359,7 @@ public:
* uint32_t width, uint32_t height, uint32_t depth,
* PixelBufferDescriptor&& buffer)
*/
void setImage(Engine& engine, size_t level, PixelBufferDescriptor&& buffer) const {
inline void setImage(Engine& engine, size_t level, PixelBufferDescriptor&& buffer) const {
setImage(engine, level, 0, 0, 0,
uint32_t(getWidth(level)), uint32_t(getHeight(level)), 1, std::move(buffer));
}
@@ -375,7 +372,7 @@ public:
* uint32_t width, uint32_t height, uint32_t depth,
* PixelBufferDescriptor&& buffer)
*/
void setImage(Engine& engine, size_t level,
inline void setImage(Engine& engine, size_t level,
uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height,
PixelBufferDescriptor&& buffer) const {
setImage(engine, level, xoffset, yoffset, 0, width, height, 1, std::move(buffer));
@@ -409,26 +406,6 @@ public:
PixelBufferDescriptor&& buffer, const FaceOffsets& faceOffsets) const;
/**
* Specify the external image to associate with this Texture. Typically, the external
* image is OS specific, and can be a video or camera frame.
* There are many restrictions when using an external image as a texture, such as:
* - only the level of detail (lod) 0 can be specified
* - only nearest or linear filtering is supported
* - the size and format of the texture is defined by the external image
* - only the CLAMP_TO_EDGE wrap mode is supported
*
* @param engine Engine this texture is associated to.
* @param image An opaque handle to a platform specific image. It must be created using Platform
* specific APIs. For example PlatformEGL::createExternalImage(EGLImageKHR eglImage)
*
* @see PlatformEGL::createExternalImage
* @see PlatformEGLAndroid::createExternalImage
* @see PlatformCocoaGL::createExternalImage
* @see PlatformCocoaTouchGL::createExternalImage
*/
void setExternalImage(Engine& engine, ExternalImageHandleRef image) noexcept;
/**
* Specify the external image to associate with this Texture. Typically, the external
* image is OS specific, and can be a video or camera frame.
@@ -451,9 +428,7 @@ public:
*
* @see Builder::sampler()
*
* @deprecated Instead, use setExternalImage(Engine& engine, ExternalImageHandleRef image)
*/
UTILS_DEPRECATED
void setExternalImage(Engine& engine, void* UTILS_NONNULL image) noexcept;
/**
@@ -488,7 +463,7 @@ public:
void setExternalImage(Engine& engine, void* UTILS_NONNULL image, size_t plane) noexcept;
/**
* Specify the external stream to associate with this Texture. Typically, the external
* Specify the external stream to associate with this Texture. Typically the external
* stream is OS specific, and can be a video or camera stream.
* There are many restrictions when using an external stream as a texture, such as:
* - only the level of detail (lod) 0 can be specified
@@ -499,7 +474,7 @@ public:
* @param stream A Stream object
*
* @attention \p engine must be the instance passed to Builder::build()
* @attention This Texture instance must use Sampler::SAMPLER_EXTERNAL, or it has no effect
* @attention This Texture instance must use Sampler::SAMPLER_EXTERNAL or it has no effect
*
* @see Builder::sampler(), Stream
*
@@ -547,9 +522,9 @@ public:
* @param buffer Client-side buffer containing the images to set.
* @param faceOffsets Offsets in bytes into \p buffer for all six images. The offsets
* are specified in the following order: +x, -x, +y, -y, +z, -z
* @param options Optional parameter controlling user-specified quality and options.
* @param options Optional parameter to controlling user-specified quality and options.
*
* @exception utils::PreConditionPanic If the source data constraints are not respected.
* @exception utils::PreConditionPanic if the source data constraints are not respected.
*
*/
void generatePrefilterMipmap(Engine& engine,
-4
View File
@@ -68,10 +68,6 @@ Engine* Engine::getEngine(void* token) {
}
#endif
Driver const* Engine::getDriver() const noexcept {
return std::addressof(downcast(this)->getDriver());
}
void Engine::destroy(Engine** pEngine) {
if (pEngine) {
Engine* engine = *pEngine;
+3 -32
View File
@@ -17,26 +17,6 @@
#include <filament/MaterialInstance.h>
#include "details/Material.h"
#include "details/MaterialInstance.h"
#include <filament/Color.h>
#include <filament/MaterialEnums.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <math/vec2.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <math/mat3.h>
#include <algorithm>
#include <string_view>
#include <stddef.h>
#include <stdint.h>
namespace filament {
@@ -105,7 +85,7 @@ void MaterialInstance::setParameter(const char* name, size_t nameLength, T const
template<>
UTILS_PUBLIC void MaterialInstance::setParameter(const char* name, size_t const nameLength, bool const& v) {
// this kills tail-call optimization
setParameter(name, nameLength, uint32_t(v));
setParameter(name, nameLength, (uint32_t)v);
}
template<>
@@ -145,8 +125,8 @@ template UTILS_PUBLIC void MaterialInstance::setParameter<mat4f> (const char*
// ------------------------------------------------------------------------------------------------
template <typename T, typename>
void MaterialInstance::setParameter(const char* name, size_t nameLength, const T* values, size_t count) {
downcast(this)->setParameterImpl({ name, nameLength }, values, count);
void MaterialInstance::setParameter(const char* name, size_t nameLength, const T* value, size_t count) {
downcast(this)->setParameterImpl({ name, nameLength }, value, count);
}
template<>
@@ -292,11 +272,6 @@ void MaterialInstance::setCullingMode(CullingMode const culling) noexcept {
downcast(this)->setCullingMode(culling);
}
void MaterialInstance::setCullingMode(CullingMode const colorPassCullingMode,
CullingMode const shadowPassCullingMode) noexcept {
downcast(this)->setCullingMode(colorPassCullingMode, shadowPassCullingMode);
}
void MaterialInstance::setColorWrite(bool const enable) noexcept {
downcast(this)->setColorWrite(enable);
}
@@ -378,10 +353,6 @@ CullingMode MaterialInstance::getCullingMode() const noexcept {
return downcast(this)->getCullingMode();
}
CullingMode MaterialInstance::getShadowCullingMode() const noexcept {
return downcast(this)->getShadowCullingMode();
}
bool MaterialInstance::isColorWriteEnabled() const noexcept {
return downcast(this)->isColorWriteEnabled();
}
+4 -11
View File
@@ -807,13 +807,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(CommandTypeFlags extraFlag
cmd.key &= ~Z_BUCKET_MASK;
cmd.key |= makeField(distanceBits >> 22u, Z_BUCKET_MASK, Z_BUCKET_SHIFT);
}
*curr = cmd;
// cancel command if both front and back faces are culled
curr->key |= select(mi->getCullingMode() == CullingMode::FRONT_AND_BACK);
} else if constexpr (isDepthPass) {
const CullingMode cullingMode = hasShadowing ? mi->getShadowCullingMode() : mi->getCullingMode();
const RasterState rs = ma->getRasterState();
const TransparencyMode mode = mi->getTransparencyMode();
const BlendingMode blendingMode = ma->getBlendingMode();
@@ -822,7 +816,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(CommandTypeFlags extraFlag
const bool isPickingVariant = Variant::isPickingVariant(variant);
cmd.key |= mi->getSortingKey(); // already all set-up for direct or'ing
cmd.info.rasterState.culling = cullingMode;
cmd.info.rasterState.culling = mi->getCullingMode();
// FIXME: should writeDepthForShadowCasters take precedence over mi->getDepthWrite()?
cmd.info.rasterState.depthWrite = (1 // only keep bit 0
@@ -831,12 +825,11 @@ RenderPass::Command* RenderPass::generateCommandsImpl(CommandTypeFlags extraFlag
& !(filterTranslucentObjects & translucent)
& !(depthFilterAlphaMaskedObjects & rs.alphaToCoverage))
| writeDepthForShadowCasters;
*curr = cmd;
// cancel command if both front and back faces are culled
curr->key |= select(cullingMode == CullingMode::FRONT_AND_BACK);
}
*curr = cmd;
// cancel command if both front and back faces are culled
curr->key |= select(mi->getCullingMode() == CullingMode::FRONT_AND_BACK);
++curr;
}
}
-4
View File
@@ -55,10 +55,6 @@ void Scene::removeEntities(const Entity* entities, size_t const count) {
downcast(this)->removeEntities(entities, count);
}
void Scene::removeAllEntities() noexcept {
downcast(this)->removeAllEntities();
}
size_t Scene::getEntityCount() const noexcept {
return downcast(this)->getEntityCount();
}
-4
View File
@@ -58,10 +58,6 @@ void Texture::setImage(Engine& engine, size_t const level,
downcast(this)->setImage(downcast(engine), level, std::move(buffer), faceOffsets);
}
void Texture::setExternalImage(Engine& engine, ExternalImageHandleRef image) noexcept {
downcast(this)->setExternalImage(downcast(engine), image);
}
void Texture::setExternalImage(Engine& engine, void* image) noexcept {
downcast(this)->setExternalImage(downcast(engine), image);
}
+57 -70
View File
@@ -25,9 +25,7 @@
#include "details/Fence.h"
#include "details/IndexBuffer.h"
#include "details/IndirectLight.h"
#include "details/InstanceBuffer.h"
#include "details/Material.h"
#include "details/MorphTargetBuffer.h"
#include "details/Renderer.h"
#include "details/Scene.h"
#include "details/SkinningBuffer.h"
@@ -38,39 +36,28 @@
#include "details/VertexBuffer.h"
#include "details/View.h"
#include <filament/ColorGrading.h>
#include <filament/Engine.h>
#include <filament/MaterialEnums.h>
#include <private/filament/DescriptorSets.h>
#include <private/filament/EngineEnums.h>
#include <private/filament/Variant.h>
#include <private/backend/PlatformFactory.h>
#include <backend/DriverEnums.h>
#include <utils/Allocator.h>
#include <utils/CallStack.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/Invocable.h>
#include <utils/Log.h>
#include <utils/ostream.h>
#include <utils/Panic.h>
#include <utils/PrivateImplementation-impl.h>
#include <utils/Systrace.h>
#include <utils/ThreadUtils.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <algorithm>
#include <chrono>
#include <initializer_list>
#include <memory>
#include <mutex>
#include <new>
#include <optional>
#include <thread>
#include <string_view>
@@ -79,7 +66,6 @@
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "generated/resources/materials.h"
@@ -115,7 +101,7 @@ Engine* FEngine::create(Builder const& builder) {
// Normally we launch a thread and create the context and Driver from there (see FEngine::loop).
// In the single-threaded case, we do so in the here and now.
if constexpr (!UTILS_HAS_THREADING) {
if (!UTILS_HAS_THREADING) {
Platform* platform = builder->mPlatform;
void* const sharedContext = builder->mSharedContext;
@@ -158,7 +144,7 @@ Engine* FEngine::create(Builder const& builder) {
// now we can initialize the largest part of the engine
instance->init();
if constexpr (!UTILS_HAS_THREADING) {
if (!UTILS_HAS_THREADING) {
instance->execute();
}
@@ -177,7 +163,7 @@ void FEngine::create(Builder const& builder, Invocable<void(void*)>&& callback)
instance->mDriverThread = std::thread(&FEngine::loop, instance);
// launch a thread to call the callback -- so it can't do any damage.
std::thread callbackThread = std::thread([instance, callback = std::move(callback)] {
std::thread callbackThread = std::thread([instance, callback = std::move(callback)]() {
instance->mDriverBarrier.await();
callback(instance);
});
@@ -210,7 +196,7 @@ FEngine* FEngine::getEngine(void* token) {
#endif
// These must be static because only a pointer is copied to the render stream
// these must be static because only a pointer is copied to the render stream
// Note that these coordinates are specified in OpenGL clip space. Other backends can transform
// these in the vertex shader as needed.
static constexpr float4 sFullScreenTriangleVertices[3] = {
@@ -220,7 +206,7 @@ static constexpr float4 sFullScreenTriangleVertices[3] = {
};
// these must be static because only a pointer is copied to the render stream
static constexpr uint16_t sFullScreenTriangleIndices[3] = { 0, 1, 2 };
static const uint16_t sFullScreenTriangleIndices[3] = { 0, 1, 2 };
FEngine::FEngine(Builder const& builder) :
mBackend(builder->mBackend),
@@ -230,6 +216,7 @@ FEngine::FEngine(Builder const& builder) :
mPostProcessManager(*this),
mEntityManager(EntityManager::get()),
mRenderableManager(*this),
mTransformManager(),
mLightManager(*this),
mCameraManager(*this),
mCommandBufferQueue(
@@ -287,7 +274,7 @@ uint32_t FEngine::getJobSystemThreadPoolSize(Config const& config) noexcept {
}
// 1 thread for the user, 1 thread for the backend
int threadCount = int(std::thread::hardware_concurrency()) - 2;
int threadCount = (int)std::thread::hardware_concurrency() - 2;
// make sure we have at least 1 thread though
threadCount = std::max(1, threadCount);
return threadCount;
@@ -360,8 +347,8 @@ void FEngine::init() {
}
// initialize the dummy textures so that their contents are not undefined
static constexpr uint32_t zeroes[6] = {};
static constexpr uint32_t ones = 0xffffffff;
static const uint32_t zeroes[6] = {0};
static const uint32_t ones = 0xffffffff;
mDefaultIblTexture = downcast(Texture::Builder()
.width(1).height(1).levels(1)
@@ -373,7 +360,7 @@ void FEngine::init() {
{ zeroes, sizeof(zeroes), Texture::Format::RGBA, Texture::Type::UBYTE });
// 3 bands = 9 float3
constexpr float sh[9 * 3] = { 0.0f };
const float sh[9 * 3] = { 0.0f };
mDefaultIbl = downcast(IndirectLight::Builder()
.irradiance(3, reinterpret_cast<const float3*>(sh))
.build(*this));
@@ -440,10 +427,10 @@ void FEngine::init() {
#endif
break;
}
mDefaultMaterial = downcast(defaultMaterialBuilder.build(*this));
mDefaultMaterial = downcast(defaultMaterialBuilder.build(*const_cast<FEngine*>(this)));
constexpr float3 dummyPositions[1] = {};
constexpr short4 dummyTangents[1] = {};
float3 dummyPositions[1] = {};
short4 dummyTangents[1] = {};
mDummyMorphTargetBuffer->setPositionsAt(*this, 0, dummyPositions, 1, 0);
mDummyMorphTargetBuffer->setTangentsAt(*this, 0, dummyTangents, 1, 0);
@@ -466,7 +453,7 @@ void FEngine::init() {
mPostProcessManager.init();
mDebugRegistry.registerProperty("d.shadowmap.debug_directional_shadowmap",
&debug.shadowmap.debug_directional_shadowmap, [this] {
&debug.shadowmap.debug_directional_shadowmap, [this]() {
mMaterials.forEach([this](FMaterial* material) {
if (material->getMaterialDomain() == MaterialDomain::SURFACE) {
@@ -482,7 +469,7 @@ void FEngine::init() {
});
mDebugRegistry.registerProperty("d.lighting.debug_froxel_visualization",
&debug.lighting.debug_froxel_visualization, [this] {
&debug.lighting.debug_froxel_visualization, [this]() {
mMaterials.forEach([this](FMaterial* material) {
if (material->getMaterialDomain() == MaterialDomain::SURFACE) {
@@ -620,7 +607,7 @@ void FEngine::shutdown() {
// now wait for all pending commands to be executed and the thread to exit
mCommandBufferQueue.requestExit();
if constexpr (!UTILS_HAS_THREADING) {
if (!UTILS_HAS_THREADING) {
execute();
getDriverApi().terminate();
} else {
@@ -651,13 +638,13 @@ void FEngine::prepare() {
DriverApi& driver = getDriverApi();
for (auto& materialInstanceList: mMaterialInstances) {
materialInstanceList.second.forEach([&driver](FMaterialInstance const* item) {
materialInstanceList.second.forEach([&driver](FMaterialInstance* item) {
item->commit(driver);
});
}
mMaterials.forEach([](FMaterial* material) {
#if FILAMENT_ENABLE_MATDBG // NOLINT(*-include-cleaner)
#if FILAMENT_ENABLE_MATDBG
material->checkProgramEdits();
#endif
});
@@ -681,7 +668,7 @@ void FEngine::flushAndWait() {
flushAndWait(FENCE_WAIT_FOR_EVER);
}
bool FEngine::flushAndWait(uint64_t const timeout) {
bool FEngine::flushAndWait(uint64_t timeout) {
FILAMENT_CHECK_PRECONDITION(!mCommandBufferQueue.isPaused())
<< "Cannot call Engine::flushAndWait() when rendering thread is paused!";
@@ -762,7 +749,7 @@ int FEngine::loop() {
}
#endif
#if FILAMENT_ENABLE_FGVIEWER // NOLINT(*-include-cleaner)
#if FILAMENT_ENABLE_FGVIEWER
#ifdef __ANDROID__
const char* fgviewerPortString = "8085";
#else
@@ -792,9 +779,9 @@ int FEngine::loop() {
return 0;
}
void FEngine::flushCommandBuffer(CommandBufferQueue& commandBufferQueue) const {
void FEngine::flushCommandBuffer(CommandBufferQueue& commandQueue) {
getDriver().purge();
commandBufferQueue.flush();
commandQueue.flush();
}
const FMaterial* FEngine::getSkyboxMaterial() const noexcept {
@@ -815,7 +802,7 @@ const FMaterial* FEngine::getSkyboxMaterial() const noexcept {
*/
template<typename T, typename ... ARGS>
T* FEngine::create(ResourceList<T>& list,
inline T* FEngine::create(ResourceList<T>& list,
typename T::Builder const& builder, ARGS&& ... args) noexcept {
T* p = mHeapAllocator.make<T>(*this, builder, std::forward<ARGS>(args)...);
if (UTILS_LIKELY(p)) {
@@ -893,7 +880,7 @@ FMaterialInstance* FEngine::createMaterialInstance(const FMaterial* material,
const FMaterialInstance* other, const char* name) noexcept {
FMaterialInstance* p = mHeapAllocator.make<FMaterialInstance>(*this, other, name);
if (UTILS_LIKELY(p)) {
auto const pos = mMaterialInstances.emplace(material, "MaterialInstance");
auto pos = mMaterialInstances.emplace(material, "MaterialInstance");
pos.first->second.insert(p);
}
return p;
@@ -971,7 +958,7 @@ FCamera* FEngine::createCamera(Entity const entity) noexcept {
}
FCamera* FEngine::getCameraComponent(Entity const entity) noexcept {
auto const ci = mCameraManager.getInstance(entity);
auto ci = mCameraManager.getInstance(entity);
return ci ? mCameraManager.getCamera(ci) : nullptr;
}
@@ -1024,16 +1011,16 @@ void FEngine::cleanupResourceListLocked(Lock& lock, ResourceList<T>&& list) {
template<typename T>
UTILS_ALWAYS_INLINE
bool FEngine::isValid(const T* ptr, ResourceList<T> const& list) const {
inline bool FEngine::isValid(const T* ptr, ResourceList<T> const& list) const {
auto& l = const_cast<ResourceList<T>&>(list);
return l.find(ptr) != l.end();
}
template<typename T>
UTILS_ALWAYS_INLINE
bool FEngine::terminateAndDestroy(const T* p, ResourceList<T>& list) {
if (p == nullptr) return true;
bool const success = list.remove(p);
inline bool FEngine::terminateAndDestroy(const T* ptr, ResourceList<T>& list) {
if (ptr == nullptr) return true;
bool const success = list.remove(ptr);
#if UTILS_HAS_RTTI
auto typeName = CallStack::typeName<T>();
@@ -1043,19 +1030,19 @@ bool FEngine::terminateAndDestroy(const T* p, ResourceList<T>& list) {
#endif
if (ASSERT_PRECONDITION_NON_FATAL(success,
"Object %s at %p doesn't exist (double free?)", typeNameCStr, p)) {
const_cast<T*>(p)->terminate(*this);
mHeapAllocator.destroy(const_cast<T*>(p));
"Object %s at %p doesn't exist (double free?)", typeNameCStr, ptr)) {
const_cast<T*>(ptr)->terminate(*this);
mHeapAllocator.destroy(const_cast<T*>(ptr));
}
return success;
}
template<typename T, typename Lock>
UTILS_ALWAYS_INLINE
bool FEngine::terminateAndDestroyLocked(Lock& lock, const T* p, ResourceList<T>& list) {
if (p == nullptr) return true;
inline bool FEngine::terminateAndDestroyLocked(Lock& lock, const T* ptr, ResourceList<T>& list) {
if (ptr == nullptr) return true;
lock.lock();
bool const success = list.remove(p);
bool const success = list.remove(ptr);
lock.unlock();
#if UTILS_HAS_RTTI
@@ -1066,9 +1053,9 @@ bool FEngine::terminateAndDestroyLocked(Lock& lock, const T* p, ResourceList<T>&
#endif
if (ASSERT_PRECONDITION_NON_FATAL(success,
"Object %s at %p doesn't exist (double free?)", typeNameCStr, p)) {
const_cast<T*>(p)->terminate(*this);
mHeapAllocator.destroy(const_cast<T*>(p));
"Object %s at %p doesn't exist (double free?)", typeNameCStr, ptr)) {
const_cast<T*>(ptr)->terminate(*this);
mHeapAllocator.destroy(const_cast<T*>(ptr));
}
return success;
}
@@ -1161,11 +1148,11 @@ bool FEngine::destroy(const FInstanceBuffer* p){
}
UTILS_NOINLINE
bool FEngine::destroy(const FMaterial* p) {
if (p == nullptr) return true;
bool const success = terminateAndDestroy(p, mMaterials);
bool FEngine::destroy(const FMaterial* ptr) {
if (ptr == nullptr) return true;
bool const success = terminateAndDestroy(ptr, mMaterials);
if (UTILS_LIKELY(success)) {
auto const pos = mMaterialInstances.find(p);
auto pos = mMaterialInstances.find(ptr);
if (UTILS_LIKELY(pos != mMaterialInstances.cend())) {
mMaterialInstances.erase(pos);
}
@@ -1174,8 +1161,8 @@ bool FEngine::destroy(const FMaterial* p) {
}
UTILS_NOINLINE
bool FEngine::destroy(const FMaterialInstance* p) {
if (p == nullptr) return true;
bool FEngine::destroy(const FMaterialInstance* ptr) {
if (ptr == nullptr) return true;
// Check that the material instance we're destroying is not in use in the RenderableManager
// To do this, we currently need to inspect all render primitives in the RenderableManager
@@ -1191,13 +1178,13 @@ bool FEngine::destroy(const FMaterialInstance* p) {
for (size_t j = 0; j < primitiveCount; j++) {
auto const* const mi = rcm.getMaterialInstanceAt(ri, 0, j);
if (features.engine.debug.assert_material_instance_in_use) {
FILAMENT_CHECK_PRECONDITION(mi != p)
FILAMENT_CHECK_PRECONDITION(mi != ptr)
<< "destroying MaterialInstance \""
<< mi->getName() << "\" which is still in use by Renderable (entity="
<< entity.getId() << ", instance="
<< ri.asValue() << ", index=" << j << ")";
} else {
if (UTILS_UNLIKELY(mi == p)) {
if (UTILS_UNLIKELY(mi == ptr)) {
slog.e << "destroying MaterialInstance \""
<< mi->getName() << "\" which is still in use by Renderable (entity="
<< entity.getId() << ", instance="
@@ -1209,11 +1196,11 @@ bool FEngine::destroy(const FMaterialInstance* p) {
}
}
if (p->isDefaultInstance()) return false;
auto const pos = mMaterialInstances.find(p->getMaterial());
if (ptr->isDefaultInstance()) return false;
auto pos = mMaterialInstances.find(ptr->getMaterial());
assert_invariant(pos != mMaterialInstances.cend());
if (pos != mMaterialInstances.cend()) {
return terminateAndDestroy(p, pos->second);
return terminateAndDestroy(ptr, pos->second);
}
// this shouldn't happen, this would be double-free
return false;
@@ -1266,7 +1253,7 @@ bool FEngine::isValid(const FMaterial* m, const FMaterialInstance* p) const {
}
// then find the material instance list for that material
auto const it = mMaterialInstances.find(m);
auto it = mMaterialInstances.find(m);
if (it == mMaterialInstances.end()) {
// this could happen if this material has no material instances at all
return false;
@@ -1355,7 +1342,7 @@ void* FEngine::streamAlloc(size_t const size, size_t const alignment) noexcept {
bool FEngine::execute() {
// wait until we get command buffers to be executed (or thread exit requested)
auto const buffers = mCommandBufferQueue.waitForCommands();
auto buffers = mCommandBufferQueue.waitForCommands();
if (UTILS_UNLIKELY(buffers.empty())) {
return false;
}
@@ -1394,7 +1381,7 @@ Engine::FeatureLevel FEngine::getSupportedFeatureLevel() const noexcept {
Engine::FeatureLevel FEngine::setActiveFeatureLevel(FeatureLevel featureLevel) {
FILAMENT_CHECK_PRECONDITION(featureLevel <= getSupportedFeatureLevel())
<< "Feature level " << unsigned(featureLevel) << " not supported";
<< "Feature level " << (unsigned)featureLevel << " not supported";
FILAMENT_CHECK_PRECONDITION(mActiveFeatureLevel >= FeatureLevel::FEATURE_LEVEL_1)
<< "Cannot adjust feature level beyond 0 at runtime";
return (mActiveFeatureLevel = std::max(mActiveFeatureLevel, featureLevel));
@@ -1413,7 +1400,7 @@ void FEngine::unprotected() noexcept {
mUnprotectedDummySwapchain->makeCurrent(getDriverApi());
}
bool FEngine::setFeatureFlag(char const* name, bool const value) const noexcept {
bool FEngine::setFeatureFlag(char const* name, bool const value) noexcept {
auto* const p = getFeatureFlagPtr(name);
if (p) {
*p = value;
@@ -1484,7 +1471,7 @@ Engine::Builder& Engine::Builder::feature(char const* name, bool const value) no
}
Engine::Builder& Engine::Builder::features(std::initializer_list<char const *> const list) noexcept {
for (auto const name : list) {
for (auto name : list) {
if (name) {
feature(name, true);
}
@@ -1513,15 +1500,15 @@ Engine::Config Engine::BuilderDetails::validateConfig(Config config) noexcept {
// Use at least the defaults set by the build system
config.minCommandBufferSizeMB = std::max(
config.minCommandBufferSizeMB,
uint32_t(FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB)); // NOLINT(*-include-cleaner)
(uint32_t)FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB);
config.perFrameCommandsSizeMB = std::max(
config.perFrameCommandsSizeMB,
uint32_t(FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB)); // NOLINT(*-include-cleaner)
(uint32_t)FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB);
config.perRenderPassArenaSizeMB = std::max(
config.perRenderPassArenaSizeMB,
uint32_t(FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB)); // NOLINT(*-include-cleaner)
(uint32_t)FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB);
config.commandBufferSizeMB = std::max(
config.commandBufferSizeMB,
+13 -15
View File
@@ -61,8 +61,6 @@
#include <filament/Texture.h>
#include <filament/VertexBuffer.h>
#include <backend/DriverEnums.h>
#include <utils/Allocator.h>
#include <utils/compiler.h>
#include <utils/CountDownLatch.h>
@@ -124,11 +122,12 @@ class ResourceAllocator;
*/
class FEngine : public Engine {
public:
void* operator new(std::size_t const size) noexcept {
inline void* operator new(std::size_t const size) noexcept {
return utils::aligned_alloc(size, alignof(FEngine));
}
void operator delete(void* p) noexcept {
inline void operator delete(void* p) noexcept {
utils::aligned_free(p);
}
@@ -491,7 +490,7 @@ public:
backend::Handle<backend::HwTexture> getOneTextureArray() const { return mDummyOneTextureArray; }
backend::Handle<backend::HwTexture> getZeroTextureArray() const { return mDummyZeroTextureArray; }
static constexpr size_t MiB = 1024u * 1024u;
static constexpr const size_t MiB = 1024u * 1024u;
size_t getMinCommandBufferSize() const noexcept { return mConfig.minCommandBufferSizeMB * MiB; }
size_t getCommandBufferSize() const noexcept { return mConfig.commandBufferSizeMB * MiB; }
size_t getPerFrameCommandsSize() const noexcept { return mConfig.perFrameCommandsSizeMB * MiB; }
@@ -511,15 +510,15 @@ public:
void resetBackendState() noexcept;
#endif
backend::Driver& getDriver() const noexcept { return *mDriver; }
private:
explicit FEngine(Builder const& builder);
void init();
void shutdown();
int loop();
void flushCommandBuffer(backend::CommandBufferQueue& commandBufferQueue) const;
void flushCommandBuffer(backend::CommandBufferQueue& commandBufferQueue);
backend::Driver& getDriver() const noexcept { return *mDriver; }
template<typename T>
bool isValid(const T* ptr, ResourceList<T> const& list) const;
@@ -691,9 +690,11 @@ public:
bool use_shadow_atlas = false;
} shadows;
struct {
// TODO: default the following two flags to true.
#ifndef NDEBUG
bool assert_material_instance_in_use = true;
#else
bool assert_material_instance_in_use = false;
bool assert_destroy_material_before_material_instance = false;
#endif
} debug;
} engine;
struct {
@@ -720,17 +721,14 @@ public:
&features.engine.shadows.use_shadow_atlas, false },
{ "features.engine.debug.assert_material_instance_in_use",
"Assert when a MaterialInstance is destroyed while it is in use by RenderableManager.",
&features.engine.debug.assert_material_instance_in_use, false },
{ "features.engine.debug.assert_destroy_material_before_material_instance",
"Assert when a Material is destroyed but its instances are still alive.",
&features.engine.debug.assert_destroy_material_before_material_instance, false },
&features.engine.debug.assert_material_instance_in_use, false }
}};
utils::Slice<const FeatureFlag> getFeatureFlags() const noexcept {
return { mFeatures.data(), mFeatures.size() };
}
bool setFeatureFlag(char const* name, bool value) const noexcept;
bool setFeatureFlag(char const* name, bool value) noexcept;
std::optional<bool> getFeatureFlag(char const* name) const noexcept;
bool* getFeatureFlagPtr(std::string_view name, bool allowConstant = false) const noexcept;
};
+3 -13
View File
@@ -383,14 +383,9 @@ void FMaterial::terminate(FEngine& engine) {
auto const& materialInstanceResourceList = engine.getMaterialInstanceResourceList();
auto pos = materialInstanceResourceList.find(this);
if (UTILS_LIKELY(pos != materialInstanceResourceList.cend())) {
if (engine.features.engine.debug.assert_destroy_material_before_material_instance) {
FILAMENT_CHECK_PRECONDITION(pos->second.empty())
<< "destroying material \"" << this->getName().c_str_safe() << "\" but "
<< pos->second.size() << " instances still alive.";
} else {
utils::slog.e << "destroying material \"" << this->getName().c_str_safe() << "\" but "
<< pos->second.size() << " instances still alive.";
}
FILAMENT_CHECK_PRECONDITION(pos->second.empty())
<< "destroying material \"" << this->getName().c_str_safe() << "\" but "
<< pos->second.size() << " instances still alive.";
}
@@ -1103,13 +1098,8 @@ void FMaterial::precacheDepthVariants(FEngine const& engine) {
// later, when/if needed by createAndCacheProgram(). Doing it now potentially uses more
// memory and increases init time, but reduces hiccups during the first frame.
if (UTILS_UNLIKELY(mIsDefaultMaterial)) {
const bool stereoSupported = mEngine.getDriverApi().isStereoSupported();
auto const allDepthVariants = VariantUtils::getDepthVariants();
for (auto const variant: allDepthVariants) {
// Don't precache any stereo variants if stereo is not supported.
if (!stereoSupported && Variant::isStereoVariant(variant)) {
continue;
}
assert_invariant(Variant::isValidDepthVariant(variant));
if (hasVariant(variant)) {
prepareProgram(variant);
+7 -7
View File
@@ -196,10 +196,10 @@ void FMaterialInstance::commit(DriverApi& driver) const {
for (auto const& [binding, p]: mTextureParameters) {
assert_invariant(p.texture);
// TODO: figure out a way to do this more efficiently (isValid() is a hashmap lookup)
FEngine const& engine = mMaterial->getEngine();
FEngine& engine = mMaterial->getEngine();
FILAMENT_CHECK_PRECONDITION(engine.isValid(p.texture))
<< "Invalid texture still bound to MaterialInstance: '" << getName() << "'\n";
Handle<HwTexture> const handle = p.texture->getHwHandleForSampling();
Handle<HwTexture> handle = p.texture->getHwHandleForSampling();
assert_invariant(handle);
mDescriptorSet.setSampler(binding, handle, p.params);
}
@@ -216,7 +216,7 @@ void FMaterialInstance::commit(DriverApi& driver) const {
void FMaterialInstance::setParameter(std::string_view const name,
Handle<HwTexture> texture, SamplerParams const params) {
auto const binding = mMaterial->getSamplerBinding(name);
auto binding = mMaterial->getSamplerBinding(name);
mDescriptorSet.setSampler(binding, texture, params);
}
@@ -243,7 +243,7 @@ void FMaterialInstance::setParameterImpl(std::string_view const name,
}
#endif
auto const binding = mMaterial->getSamplerBinding(name);
auto binding = mMaterial->getSamplerBinding(name);
if (texture && texture->textureHandleCanMutate()) {
mTextureParameters[binding] = { texture, sampler.getSamplerParams() };
} else {
@@ -328,13 +328,13 @@ const char* FMaterialInstance::getName() const noexcept {
void FMaterialInstance::use(FEngine::DriverApi& driver) const {
if (UTILS_UNLIKELY(mMissingSamplerDescriptors.any())) {
std::call_once(mMissingSamplersFlag, [this] {
std::call_once(mMissingSamplersFlag, [this]() {
auto const& list = mMaterial->getSamplerInterfaceBlock().getSamplerInfoList();
slog.w << "sampler parameters not set in MaterialInstance \""
<< mName.c_str_safe() << "\" or Material \""
<< mMaterial->getName().c_str_safe() << "\":\n";
mMissingSamplerDescriptors.forEachSetBit([&list](descriptor_binding_t binding) {
auto const pos = std::find_if(list.begin(), list.end(), [binding](const auto& item) {
auto pos = std::find_if(list.begin(), list.end(), [binding](const auto& item) {
return item.binding == binding;
});
// just safety-check, should never fail
@@ -368,7 +368,7 @@ void FMaterialInstance::fixMissingSamplers() const {
// here we need to set the samplers that are missing
auto const& list = mMaterial->getSamplerInterfaceBlock().getSamplerInfoList();
missingSamplerDescriptors.forEachSetBit([this, &list](descriptor_binding_t binding) {
auto const pos = std::find_if(list.begin(), list.end(), [binding](const auto& item) {
auto pos = std::find_if(list.begin(), list.end(), [binding](const auto& item) {
return item.binding == binding;
});
+2 -11
View File
@@ -94,8 +94,6 @@ public:
backend::CullingMode getCullingMode() const noexcept { return mCulling; }
backend::CullingMode getShadowCullingMode() const noexcept { return mShadowCulling; }
bool isColorWriteEnabled() const noexcept { return mColorWrite; }
bool isDepthWriteEnabled() const noexcept { return mDepthWrite; }
@@ -139,11 +137,6 @@ public:
void setCullingMode(CullingMode const culling) noexcept { mCulling = culling; }
void setCullingMode(CullingMode const color, CullingMode const shadow) noexcept {
mCulling = color;
mShadowCulling = shadow;
}
void setColorWrite(bool const enable) noexcept { mColorWrite = enable; }
void setDepthWrite(bool const enable) noexcept { mDepthWrite = enable; }
@@ -278,9 +271,7 @@ private:
float mSpecularAntiAliasingThreshold = 0.0f;
backend::CullingMode mCulling : 2;
backend::CullingMode mShadowCulling : 2;
backend::RasterState::DepthFunc mDepthFunc : 3;
bool mColorWrite : 1;
bool mDepthWrite : 1;
bool mHasScissor : 1;
@@ -292,8 +283,8 @@ private:
// Scissor rectangle is specified as: Left Bottom Width Height.
backend::Viewport mScissorRect = { 0, 0,
uint32_t(std::numeric_limits<int32_t>::max()),
uint32_t(std::numeric_limits<int32_t>::max())
(uint32_t)std::numeric_limits<int32_t>::max(),
(uint32_t)std::numeric_limits<int32_t>::max()
};
utils::CString mName;
+2 -5
View File
@@ -1351,11 +1351,8 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) {
}
if (hasFXAA) {
bool const preserveAlphaChannel =
// we're transparent -- alpha channel has user data
needsAlphaChannel ||
// the color-grading pass outputted the luminance channel, and we have an upscaling pass
(hasColorGrading && colorGradingConfig.outputLuminance && scaled);
bool const preserveAlphaChannel = needsAlphaChannel ||
(hasColorGrading && colorGradingConfig.outputLuminance);
input = ppm.fxaa(fg, input, xvp, colorGradingConfig.ldrFormat, preserveAlphaChannel);
// the padded buffer is resolved now
xvp.left = xvp.bottom = 0;
-5
View File
@@ -546,11 +546,6 @@ void FScene::removeEntities(const Entity* entities, size_t const count) {
}
}
UTILS_NOINLINE
void FScene::removeAllEntities() noexcept {
mEntities.clear();
}
UTILS_NOINLINE
size_t FScene::getRenderableCount() const noexcept {
FEngine& engine = mEngine;
-1
View File
@@ -199,7 +199,6 @@ private:
void addEntities(const utils::Entity* entities, size_t count);
void remove(utils::Entity entity);
void removeEntities(const utils::Entity* entities, size_t count);
void removeAllEntities() noexcept;
size_t getEntityCount() const noexcept { return mEntities.size(); }
size_t getRenderableCount() const noexcept;
size_t getLightCount() const noexcept;
-20
View File
@@ -469,26 +469,6 @@ void FTexture::setImage(FEngine& engine, size_t const level,
const_cast<FTexture*>(this)->updateLodRange(level);
}
void FTexture::setExternalImage(FEngine& engine, ExternalImageHandleRef image) noexcept {
FILAMENT_CHECK_PRECONDITION(mExternal) << "The texture must be external.";
// The call to setupExternalImage2 is synchronous, and allows the driver to take ownership of the
// external image on this thread, if necessary.
auto& api = engine.getDriverApi();
api.setupExternalImage2(image);
auto texture = api.createTextureExternalImage2(mTarget, mFormat, mWidth, mHeight, mUsage, image);
if (mTextureIsSwizzled) {
auto const& s = mSwizzle;
auto swizzleView = api.createTextureViewSwizzle(texture, s[0], s[1], s[2], s[3]);
api.destroyTexture(texture);
texture = swizzleView;
}
setHandles(texture);
}
void FTexture::setExternalImage(FEngine& engine, void* image) noexcept {
FILAMENT_CHECK_PRECONDITION(mExternal) << "The texture must be external.";
-1
View File
@@ -66,7 +66,6 @@ public:
PixelBufferDescriptor&& buffer, const FaceOffsets& faceOffsets,
PrefilterOptions const* options);
void setExternalImage(FEngine& engine, ExternalImageHandleRef image) noexcept;
void setExternalImage(FEngine& engine, void* image) noexcept;
void setExternalImage(FEngine& engine, void* image, size_t plane) noexcept;
void setExternalStream(FEngine& engine, FStream* stream) noexcept;
+2 -2
View File
@@ -1,12 +1,12 @@
Pod::Spec.new do |spec|
spec.name = "Filament"
spec.version = "1.57.0"
spec.version = "1.56.7"
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.57.0/filament-v1.57.0-ios.tgz" }
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.56.7/filament-v1.56.7-ios.tgz" }
# Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon.
spec.pod_target_xcconfig = {
@@ -28,7 +28,7 @@
namespace filament {
// update this when a new version of filament wouldn't work with older materials
static constexpr size_t MATERIAL_VERSION = 57;
static constexpr size_t MATERIAL_VERSION = 56;
/**
* Supported shading models
+5 -1
View File
@@ -365,6 +365,8 @@ utils::io::sstream& CodeGenerator::generateCommonProlog(utils::io::sstream& out,
out << '\n';
out << SHADERS_COMMON_DEFINES_GLSL_DATA;
CodeGenerator::generateDefine(out, "MATERIAL_FEATURE_LEVEL", uint32_t(mFeatureLevel));
if (material.featureLevel == FeatureLevel::FEATURE_LEVEL_0 &&
(mFeatureLevel > FeatureLevel::FEATURE_LEVEL_0
|| mTargetLanguage == TargetLanguage::SPIRV)) {
@@ -485,7 +487,7 @@ io::sstream& CodeGenerator::generateCommonVariable(io::sstream& out, ShaderStage
return out;
}
io::sstream& CodeGenerator::generateSurfaceShaderInputs(io::sstream& out, ShaderStage stage,
io::sstream& CodeGenerator::generateSurfaceInputs(io::sstream& out, ShaderStage stage,
const AttributeBitset& attributes, Interpolation interpolation,
MaterialBuilder::PushConstantList const& pushConstants) const {
auto const& attributeDatabase = MaterialBuilder::getAttributeDatabase();
@@ -517,6 +519,7 @@ io::sstream& CodeGenerator::generateSurfaceShaderInputs(io::sstream& out, Shader
}
out << "\n";
out << SHADERS_COMMON_VARYINGS_GLSL_DATA;
out << SHADERS_SURFACE_VARYINGS_GLSL_DATA;
return out;
}
@@ -1073,6 +1076,7 @@ io::sstream& CodeGenerator::generateSurfaceMaterial(io::sstream& out, ShaderStag
}
io::sstream& CodeGenerator::generatePostProcessInputs(io::sstream& out, ShaderStage stage) {
out << SHADERS_COMMON_VARYINGS_GLSL_DATA;
if (stage == ShaderStage::VERTEX) {
out << SHADERS_POST_PROCESS_INPUTS_VS_DATA;
} else if (stage == ShaderStage::FRAGMENT) {
+1 -1
View File
@@ -109,7 +109,7 @@ public:
const MaterialBuilder::CustomVariable& variable, size_t index);
// generate declarations for non-custom "in" variables
utils::io::sstream& generateSurfaceShaderInputs(utils::io::sstream& out, ShaderStage stage,
utils::io::sstream& generateSurfaceInputs(utils::io::sstream& out, ShaderStage stage,
const filament::AttributeBitset& attributes, filament::Interpolation interpolation,
MaterialBuilder::PushConstantList const& pushConstants) const;
static utils::io::sstream& generatePostProcessInputs(utils::io::sstream& out, ShaderStage stage);
+2 -3
View File
@@ -81,7 +81,6 @@ void ShaderGenerator::generateSurfaceMaterialVariantDefines(utils::io::sstream&
}
out << '\n';
CodeGenerator::generateDefine(out, "MATERIAL_FEATURE_LEVEL", uint32_t(featureLevel));
CodeGenerator::generateDefine(out, "MATERIAL_HAS_SHADOW_MULTIPLIER",
material.hasShadowMultiplier);
@@ -436,7 +435,7 @@ std::string ShaderGenerator::createSurfaceVertexProgram(ShaderModel shaderModel,
[](MaterialBuilder::PushConstant const& constant) {
return constant.stage == ShaderStage::VERTEX;
});
cg.generateSurfaceShaderInputs(vs, ShaderStage::VERTEX, attributes, interpolation,
cg.generateSurfaceInputs(vs, ShaderStage::VERTEX, attributes, interpolation,
vertexPushConstants);
CodeGenerator::generateSurfaceTypes(vs, ShaderStage::VERTEX);
@@ -546,7 +545,7 @@ std::string ShaderGenerator::createSurfaceFragmentProgram(ShaderModel shaderMode
[](MaterialBuilder::PushConstant const& constant) {
return constant.stage == ShaderStage::FRAGMENT;
});
cg.generateSurfaceShaderInputs(fs, ShaderStage::FRAGMENT, material.requiredAttributes, interpolation,
cg.generateSurfaceInputs(fs, ShaderStage::FRAGMENT, material.requiredAttributes, interpolation,
fragmentPushConstants);
CodeGenerator::generateSurfaceTypes(fs, ShaderStage::FRAGMENT);
+9 -2
View File
@@ -704,12 +704,19 @@ FilamentApp::Window::Window(FilamentApp* filamentApp,
::prepareNativeWindow(mWindow);
void* metalLayer = nullptr;
if (config.backend == filament::Engine::Backend::METAL || config.backend == filament::Engine::Backend::VULKAN) {
if (config.backend == filament::Engine::Backend::METAL) {
metalLayer = setUpMetalLayer(nativeWindow);
// The swap chain on both native Metal and MoltenVK is a CAMetalLayer.
// The swap chain on Metal is a CAMetalLayer.
nativeSwapChain = metalLayer;
}
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
if (config.backend == filament::Engine::Backend::VULKAN) {
// We request a Metal layer for rendering via MoltenVK.
setUpMetalLayer(nativeWindow);
}
#endif
#endif
// Write back the active feature level.
+3 -11
View File
@@ -222,13 +222,8 @@ bool ApiHandler::handleGetApiShader(struct mg_connection* conn,
}
void ApiHandler::addMaterial(MaterialRecord const* material) {
updateMaterial(material->key);
}
void ApiHandler::updateMaterial(uint32_t key) {
std::unique_lock const lock(mStatusMutex);
mCurrentStatus++;
snprintf(statusMaterialId, sizeof(statusMaterialId), "%8.8x", key);
snprintf(statusMaterialId, sizeof(statusMaterialId), "%8.8x", material->key);
mStatusCondition.notify_all();
}
@@ -293,11 +288,8 @@ bool ApiHandler::handlePost(CivetServer* server, struct mg_connection* conn) {
sstream >> std::hex >> matid >> std::dec >> api >> shaderIndex;
std::string const shader = sstream.str().substr(sstream.tellg());
if (!mServer->handleEditCommand(matid, backend::Backend(api), shaderIndex, shader.c_str(),
shader.size())) {
return error(__LINE__, uri);
}
updateMaterial(matid);
mServer->handleEditCommand(matid, backend::Backend(api), shaderIndex, shader.c_str(),
shader.size());
mg_printf(conn, "HTTP/1.1 200 OK\r\nConnection: close");
return true;
+1 -3
View File
@@ -55,8 +55,6 @@ private:
bool handleGetStatus(struct mg_connection* conn, struct mg_request_info const* request);
MaterialRecord const* getMaterialRecord(struct mg_request_info const* request);
void updateMaterial(uint32_t key);
DebugServer* mServer;
std::mutex mStatusMutex;
@@ -66,7 +64,7 @@ private:
// This variable is to implement a *hanging* effect for /api/status. The call to /api/status
// will always block until statusMaterialId is updated again. The client is expected to keep
// calling /api/status (a constant "pull" to simulate a push).
uint64_t mCurrentStatus = 0;
std::atomic<uint64_t> mCurrentStatus = 0;
SourceFormatter mFormatter;
};
+1 -25
View File
@@ -25,7 +25,6 @@
#include <utils/Log.h>
#include <algorithm>
#include <sstream>
#include <GlslangToSpv.h>
@@ -51,30 +50,10 @@ using namespace glslang;
using namespace utils;
using std::ostream;
using std::streampos;
using std::stringstream;
using std::streampos;
using std::vector;
namespace {
// This is to ensure that the edited material package have the same order of shaders as the output
// of the original material. We use the ordering in the front-end to simplify logic.
template<typename RecordType>
void sortRecords(std::vector<RecordType>& records) {
std::sort(records.begin(), records.end(), [](RecordType const& a, RecordType const& b) -> bool {
if (a.shaderModel != b.shaderModel) {
return a.shaderModel < b.shaderModel;
}
if (a.variant.key != b.variant.key) {
return a.variant.key < b.variant.key;
}
return a.stage < b.stage;
});
}
} // anonymous
// Tiny database of shader text that can import / export MaterialTextChunk and DictionaryTextChunk.
class ShaderIndex {
public:
@@ -365,7 +344,6 @@ void ShaderIndex::writeChunks(ostream& stream) {
for (const auto& record : mShaderRecords) {
lines.addText(record.shader);
}
sortRecords(mShaderRecords);
filamat::ChunkContainer cc;
const auto& dchunk = cc.push<DictionaryTextChunk>(std::move(lines), mDictTag);
@@ -428,8 +406,6 @@ void BlobIndex::writeChunks(ostream& stream) {
}
};
sortRecords(mShaderRecords);
// Apply SMOL-V compression and write out the results.
filamat::ChunkContainer cc;
cc.push<MaterialBinaryChunk>(std::move(mShaderRecords), ChunkType::MaterialSpirv);
+1 -1
View File
@@ -34,7 +34,7 @@ std::string SourceFormatter::format(char const* source) {
while (fgets(output, 1024, fp) != NULL) {}
int status = pclose(fp);
if (!fp || WEXITSTATUS(status)) {
if (!fp || !WEXITSTATUS(status)) {
std::call_once(mClangWarningFlag, []() {
utils::slog.w << "[matdbg] unable to run clang-format to format shader file. "
<< "Please make sure it's installed." << utils::io::endl;
+1 -20
View File
@@ -240,25 +240,6 @@ function(add_demo NAME)
endif()
endfunction()
function(add_demo2 NAME)
include_directories(${GENERATION_ROOT})
if (APPLE)
add_executable(${NAME} helper.h helper.mm ${NAME}.cpp)
target_link_libraries(${NAME} PRIVATE sample-resources)
target_compile_options(${NAME} PRIVATE ${COMPILER_FLAGS})
set_target_properties(${NAME} PROPERTIES FOLDER Samples)
# This is needed after XCode 15.3
target_link_libraries(${NAME} PUBLIC "-framework Cocoa -framework QuartzCore" sdl2)
set_target_properties(${NAME} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
set_target_properties(${NAME} PROPERTIES INSTALL_RPATH /usr/local/lib)
else()
add_demo(${NAME})
endif()
target_link_libraries(${NAME} PRIVATE gltfio)
endfunction()
if (NOT ANDROID)
add_demo(animation)
add_demo(depthtesting)
@@ -268,7 +249,7 @@ if (NOT ANDROID)
add_demo(heightfield)
add_demo(hellomorphing)
add_demo(hellopbr)
add_demo2(hellotriangle)
add_demo(hellotriangle)
add_demo(helloskinning)
add_demo(helloskinningbuffer)
add_demo(helloskinningbuffer_morebones)
+167 -166
View File
@@ -1,191 +1,192 @@
#include <fstream>
#include <iostream>
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <filament/Camera.h>
#include <filament/Engine.h>
#include <filament/IndexBuffer.h>
#include <filament/LightManager.h>
#include <filament/Material.h>
#include <filament/MaterialInstance.h>
#include <filament/RenderableManager.h>
#include <filament/Renderer.h>
#include <filament/Scene.h>
#include <filament/Skybox.h>
#include <filament/TransformManager.h>
#include <filament/VertexBuffer.h>
#include <filament/View.h>
#include <filament/Viewport.h>
#include <filamat/MaterialBuilder.h>
#include <utils/EntityManager.h>
#include <utils/Log.h>
#include <math/norm.h>
#include <filamentapp/Config.h>
#include <filamentapp/FilamentApp.h>
#include <gltfio/AssetLoader.h>
#include <gltfio/ResourceLoader.h>
#include <getopt/getopt.h>
#include <SDL.h>
#include <SDL_syswm.h>
#include <SDL_video.h>
#include <cmath>
#include <iostream>
#if defined(__linux__)
void* getNativeWindow(SDL_Window* sdlWindow) {
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version);
SDL_GetWindowWMInfo(sdlWindow, &wmi);
if (wmi.subsystem == SDL_SYSWM_X11) {
Window win = (Window) wmi.info.x11.window;
return (void*) win;
} else {
std::cout << "Unknown SDL subsystem";
}
return nullptr;
}
#elif defined(__APPLE__)
#include "helper.h"
#endif
SDL_Window* createSDLwindow() {
uint32_t windowFlags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
SDL_Window* win = SDL_CreateWindow("Hello World!", 100, 100, 600, 400, 0);
if (win == nullptr) {
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
SDL_Quit();
return nullptr;
}
return win;
}
#include "generated/resources/resources.h"
using namespace filament;
using namespace math;
using namespace utils;
int main() {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
const static uint32_t indices[] = { 0, 1, 2, };
using utils::Entity;
using utils::EntityManager;
const static math::float3 vertices[] = {
{ -10, 0, -10 },
{ -10, 0, 10 },
{ 10, 0, 10 },
struct App {
Config config;
VertexBuffer* vb;
IndexBuffer* ib;
Material* mat;
Camera* cam;
Entity camera;
Skybox* skybox;
Entity renderable;
};
struct Vertex {
filament::math::float2 position;
uint32_t color;
};
static const Vertex TRIANGLE_VERTICES[3] = {
{{1, 0}, 0xffff0000u},
{{cos(M_PI * 2 / 3), sin(M_PI * 2 / 3)}, 0xff00ff00u},
{{cos(M_PI * 4 / 3), sin(M_PI * 4 / 3)}, 0xff0000ffu},
};
static constexpr uint16_t TRIANGLE_INDICES[3] = { 0, 1, 2 };
static void printUsage(char* name) {
std::string exec_name(utils::Path(name).getName());
std::string usage(
"HELLOTRIANGLE renders a spinning colored triangle\n"
"Usage:\n"
" HELLOTRIANGLE [options]\n"
"Options:\n"
" --help, -h\n"
" Prints this message\n\n"
" --api, -a\n"
" Specify the backend API: opengl, vulkan, or metal\n"
);
const std::string from("HELLOTRIANGLE");
for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) {
usage.replace(pos, from.length(), exec_name);
}
std::cout << usage;
}
static int handleCommandLineArguments(int argc, char* argv[], App* app) {
static constexpr const char* OPTSTR = "ha:";
static const struct option OPTIONS[] = {
{ "help", no_argument, nullptr, 'h' },
{ "api", required_argument, nullptr, 'a' },
{ nullptr, 0, nullptr, 0 }
};
int opt;
int option_index = 0;
while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
std::string arg(optarg ? optarg : "");
switch (opt) {
default:
case 'h':
printUsage(argv[0]);
exit(0);
case 'a':
if (arg == "opengl") {
app->config.backend = Engine::Backend::OPENGL;
} else if (arg == "vulkan") {
app->config.backend = Engine::Backend::VULKAN;
} else if (arg == "metal") {
app->config.backend = Engine::Backend::METAL;
} else {
std::cerr << "Unrecognized backend. Must be 'opengl'|'vulkan'|'metal'.\n";
exit(1);
}
break;
}
}
return optind;
}
int main(int argc, char** argv) {
App app{};
app.config.title = "hellotriangle";
app.config.featureLevel = backend::FeatureLevel::FEATURE_LEVEL_0;
handleCommandLineArguments(argc, argv, &app);
auto setup = [&app](Engine* engine, View* view, Scene* scene) {
app.skybox = Skybox::Builder().color({0.1, 0.125, 0.25, 1.0}).build(*engine);
scene->setSkybox(app.skybox);
view->setPostProcessingEnabled(false);
static_assert(sizeof(Vertex) == 12, "Strange vertex size.");
app.vb = VertexBuffer::Builder()
.vertexCount(3)
.bufferCount(1)
.attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT2, 0, 12)
.attribute(VertexAttribute::COLOR, 0, VertexBuffer::AttributeType::UBYTE4, 8, 12)
.normalized(VertexAttribute::COLOR)
.build(*engine);
app.vb->setBufferAt(*engine, 0,
VertexBuffer::BufferDescriptor(TRIANGLE_VERTICES, 36, nullptr));
app.ib = IndexBuffer::Builder()
.indexCount(3)
.bufferType(IndexBuffer::IndexType::USHORT)
.build(*engine);
app.ib->setBuffer(*engine,
IndexBuffer::BufferDescriptor(TRIANGLE_INDICES, 6, nullptr));
app.mat = Material::Builder()
.package(RESOURCES_BAKEDCOLOR_DATA, RESOURCES_BAKEDCOLOR_SIZE)
.build(*engine);
app.renderable = EntityManager::get().create();
RenderableManager::Builder(1)
.boundingBox({{ -1, -1, -1 }, { 1, 1, 1 }})
.material(0, app.mat->getDefaultInstance())
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, app.vb, app.ib, 0, 3)
.culling(false)
.receiveShadows(false)
.castShadows(false)
.build(*engine, app.renderable);
scene->addEntity(app.renderable);
app.camera = utils::EntityManager::get().create();
app.cam = engine->createCamera(app.camera);
view->setCamera(app.cam);
};
short4 tbn = math::packSnorm16(
mat3f::packTangentFrame(
math::mat3f{
float3{ 1.0f, 0.0f, 0.0f },
float3{ 0.0f, 0.0f, 1.0f }, float3{ 0.0f, 1.0f, 0.0f } })
.xyzw);
auto cleanup = [&app](Engine* engine, View*, Scene*) {
engine->destroy(app.skybox);
engine->destroy(app.renderable);
engine->destroy(app.mat);
engine->destroy(app.vb);
engine->destroy(app.ib);
engine->destroyCameraComponent(app.camera);
utils::EntityManager::get().destroy(app.camera);
};
const static math::short4 normals[]{ tbn, tbn, tbn };
SDL_Window* window = createSDLwindow();
if (!window) {
return 1;
}
Engine* engine = Engine::create(filament::backend::Backend::VULKAN);
SwapChain* swapChain = engine->createSwapChain(getNativeWindow(window));
Renderer* renderer = engine->createRenderer();
FilamentApp::get().animate([&app](Engine* engine, View* view, double now) {
constexpr float ZOOM = 1.5f;
const uint32_t w = view->getViewport().width;
const uint32_t h = view->getViewport().height;
const float aspect = (float) w / h;
app.cam->setProjection(Camera::Projection::ORTHO,
-aspect * ZOOM, aspect * ZOOM,
-ZOOM, ZOOM, 0, 1);
auto& tcm = engine->getTransformManager();
tcm.setTransform(tcm.getInstance(app.renderable),
filament::math::mat4f::rotation(now, filament::math::float3{ 0, 0, 1 }));
});
auto cameraEntity = EntityManager::get().create();
Camera* camera = engine->createCamera(cameraEntity);
View* view = engine->createView();
Scene* scene = engine->createScene();
FilamentApp::get().run(app.config, setup, cleanup);
view->setCamera(camera);
// Determine the current size of the window in physical pixels.
uint32_t w, h;
SDL_GL_GetDrawableSize(window, (int*) &w, (int*) &h);
camera->lookAt(float3(0, 50.5f, 0), float3(0, 0, 0), float3(1.f, 0, 0));
camera->setProjection(45.0, double(w) / h, 0.1, 50, Camera::Fov::VERTICAL);
view->setViewport({ 0, 0, w, h });
view->setScene(scene);
view->setPostProcessingEnabled(false);
VertexBuffer* vertexBuffer =
VertexBuffer::Builder()
.vertexCount(3)
.bufferCount(2)
.attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT3)
.attribute(VertexAttribute::TANGENTS, 1, VertexBuffer::AttributeType::SHORT4)
.normalized(VertexAttribute::TANGENTS)
.build(*engine);
vertexBuffer->setBufferAt(*engine, 0,
VertexBuffer::BufferDescriptor(vertices,
vertexBuffer->getVertexCount() * sizeof(vertices[0])));
vertexBuffer->setBufferAt(*engine, 1,
VertexBuffer::BufferDescriptor(normals,
vertexBuffer->getVertexCount() * sizeof(normals[0])));
IndexBuffer* indexBuffer = IndexBuffer::Builder().indexCount(3).build(*engine);
indexBuffer->setBuffer(*engine,
IndexBuffer::BufferDescriptor(indices,
indexBuffer->getIndexCount() * sizeof(uint32_t)));
filamat::MaterialBuilder::init();
filamat::MaterialBuilder builder;
builder.name("Material")
.material(" void material(inout MaterialInputs material) {\n"
" prepareMaterial(material);"
" material.baseColor.rgb = materialParams.baseColor;"
" }")
.parameter("baseColor", filament::backend::UniformType::FLOAT3)
.parameter("metallic", filament::backend::UniformType::FLOAT)
.parameter("roughness", filament::backend::UniformType::FLOAT)
.parameter("reflectance", filament::backend::UniformType::FLOAT)
.optimization(filamat::MaterialBuilder::Optimization::NONE)
.shading(filamat::MaterialBuilder::Shading::UNLIT)
.targetApi(filamat::MaterialBuilder::TargetApi::ALL)
.platform(filamat::MaterialBuilder::Platform::ALL);
filamat::Package package = builder.build(engine->getJobSystem());
Material* material =
Material::Builder().package(package.getData(), package.getSize()).build(*engine);
material->setDefaultParameter("baseColor", RgbType::LINEAR, float3{ 1, 0, 0 });
material->setDefaultParameter("metallic", 0.0f);
material->setDefaultParameter("roughness", 0.4f);
material->setDefaultParameter("reflectance", 0.5f);
MaterialInstance* materialInstance = material->createInstance();
Entity renderable = EntityManager::get().create();
// build a quad
RenderableManager::Builder(1)
.boundingBox({ { -1, -1, -1 }, { 1, 1, 1 } })
.material(0, materialInstance)
.geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vertexBuffer, indexBuffer, 0,
3)
.culling(false)
.build(*engine, renderable);
scene->addEntity(renderable);
int i = 0;
while (i++ < 1) {
// beginFrame() returns false if we need to skip a frame
if (renderer->beginFrame(swapChain)) {
// for each View
renderer->render(view);
renderer->endFrame();
}
}
bool running = true;
SDL_Event event;
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = false;
}
SDL_Delay(16);
}
}
engine->destroy(cameraEntity);
return 0;
}
-10
View File
@@ -1,10 +0,0 @@
#ifndef HELLO_TRIANGLE_H
#define HELLO_TRIANGLE_H
#include <SDL.h>
#include <SDL_syswm.h>
#include <SDL_video.h>
void* getNativeWindow(SDL_Window* sdlWindow);
#endif
-39
View File
@@ -1,39 +0,0 @@
#include "helper.h"
#include <Cocoa/Cocoa.h>
#include <QuartzCore/QuartzCore.h>
#include <utils/Panic.h>
void* getNativeWindow(SDL_Window* sdlWindow) {
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version);
FILAMENT_CHECK_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi))
<< "SDL version unsupported!";
NSWindow* win = wmi.info.cocoa.window;
NSView* view = [win contentView];
[win setColorSpace:[NSColorSpace sRGBColorSpace]];
[view setWantsLayer:YES];
CAMetalLayer* metalLayer = [CAMetalLayer layer];
metalLayer.bounds = view.bounds;
// It's important to set the drawableSize to the actual backing pixels. When rendering
// full-screen, we can skip the macOS compositor if the size matches the display size.
metalLayer.drawableSize = [view convertSizeToBacking:view.bounds.size];
// In its implementation of vkGetPhysicalDeviceSurfaceCapabilitiesKHR, MoltenVK takes into
// consideration both the size (in points) of the bounds, and the contentsScale of the
// CAMetalLayer from which the Vulkan surface was created.
// See also https://github.com/KhronosGroup/MoltenVK/issues/428
metalLayer.contentsScale = view.window.backingScaleFactor;
// This is set to NO by default, but is also important to ensure we can bypass the compositor
// in full-screen mode
// See "Direct to Display" http://metalkit.org/2017/06/30/introducing-metal-2.html.
metalLayer.opaque = YES;
[view setLayer:metalLayer];
return metalLayer;
}
+8 -2
View File
@@ -205,11 +205,17 @@ void setup_window(Window& w, Engine* engine) {
void* nativeSwapChain = nativeWindow;
#if defined(__APPLE__)
void* metalLayer = nullptr;
if (kBackend == filament::Engine::Backend::METAL || kBackend == filament::Engine::Backend::VULKAN) {
if (kBackend == filament::Engine::Backend::METAL) {
metalLayer = setUpMetalLayer(nativeWindow);
// The swap chain on both native Metal and MoltenVK is a CAMetalLayer.
// The swap chain on Metal is a CAMetalLayer.
nativeSwapChain = metalLayer;
}
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
if (kBackend == filament::Engine::Backend::VULKAN) {
// We request a Metal layer for rendering via MoltenVK.
setUpMetalLayer(nativeWindow);
}
#endif
#endif
w.swapChain = engine->createSwapChain(nativeSwapChain);
+1
View File
@@ -21,6 +21,7 @@ set(SHADERS
src/surface_material.fs
src/common_math.glsl
src/common_shading.fs
src/common_varyings.glsl
src/surface_shadowing.glsl
src/surface_types.glsl
src/surface_depth_main.fs
+8 -25
View File
@@ -1,27 +1,3 @@
//------------------------------------------------------------------------------
// Common Helpers
//------------------------------------------------------------------------------
/**
* Index of the eye being rendered, starting at 0.
* @public-api
*/
int getEyeIndex() {
#if defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_INSTANCED)
return instance_index % CONFIG_STEREO_EYE_COUNT;
#elif defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_MULTIVIEW)
# if defined(TARGET_VULKAN_ENVIRONMENT)
return int(gl_ViewIndex);
# else
// gl_ViewID_OVR is of uint type, which needs an explicit conversion.
return int(gl_ViewID_OVR);
# endif // TARGET_VULKAN_ENVIRONMENT
#endif
return 0;
}
//------------------------------------------------------------------------------
// Uniforms access
//------------------------------------------------------------------------------
@@ -48,7 +24,14 @@ highp mat4 getViewFromClipMatrix() {
/** @public-api */
highp mat4 getClipFromWorldMatrix() {
return frameUniforms.clipFromWorldMatrix[getEyeIndex()];
#if defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_INSTANCED)
int eye = instance_index % CONFIG_STEREO_EYE_COUNT;
return frameUniforms.clipFromWorldMatrix[eye];
#elif defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_MULTIVIEW)
return frameUniforms.clipFromWorldMatrix[filament_multiview_data.y];
#else
return frameUniforms.clipFromWorldMatrix[0];
#endif
}
/** @public-api */
+16
View File
@@ -0,0 +1,16 @@
//------------------------------------------------------------------------------
// Common Varyings
//------------------------------------------------------------------------------
// The `filament_multiview_data` variable is to pass the current state of multiview set in the
// vertex shader to the fragment shader. `x` means whether multiview is used, `y` means the current
// view index. Neither the multiview feature nor the `flat` keyword is supported in FL0. So, for
// FL0, declare it as a non-flat and non-varying variable and set it to zeros as a placeholder.
// `MATERIAL_FEATURE_LEVEL > 0` is used as a workaround instead of `defined(VARIANT_HAS_STEREO)` to
// make this line available for post-processing where we cannot use VARIANT_HAS_STEREO. The
// downside of this approach is that `flat VARYING` is used for non-STE shaders as well.
#if MATERIAL_FEATURE_LEVEL > 0 && defined(FILAMENT_STEREO_MULTIVIEW)
LAYOUT_LOCATION(12) flat VARYING ivec2 filament_multiview_data;
#else
ivec2 filament_multiview_data = ivec2(0, 0);
#endif
+14 -1
View File
@@ -235,7 +235,7 @@ vec4 getCustom7() { return mesh_custom7; }
#endif
//------------------------------------------------------------------------------
// Surface Helpers
// Helpers
//------------------------------------------------------------------------------
/**
@@ -275,3 +275,16 @@ vec4 computeWorldPosition() {
#error Unknown Vertex Domain
#endif
}
/**
* Index of the eye being rendered, starting at 0.
* @public-api
*/
int getEyeIndex() {
#if defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_INSTANCED)
return instance_index % CONFIG_STEREO_EYE_COUNT;
#elif defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_MULTIVIEW)
return int(filament_multiview_data.y);
#endif
return 0;
}
+11
View File
@@ -31,6 +31,17 @@ void main() {
logical_instance_index = instance_index / CONFIG_STEREO_EYE_COUNT;
#endif
#if defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_MULTIVIEW)
# if defined(TARGET_VULKAN_ENVIRONMENT)
int multiview_view_index = int(gl_ViewIndex);
# else
int multiview_view_index = int(gl_ViewID_OVR);
# endif // TARGET_VULKAN_ENVIRONMENT
filament_multiview_data = ivec2(1, int(multiview_view_index));
#else
filament_multiview_data = ivec2(0, 0);
#endif
initObjectUniforms();
// Initialize the inputs to sensible default values, see surface_material_inputs.vs
+1 -1
View File
@@ -1,5 +1,5 @@
//------------------------------------------------------------------------------
// Varyings
// Surface Varyings
//------------------------------------------------------------------------------
LAYOUT_LOCATION(4) VARYING highp vec4 vertex_worldPosition;
-109
View File
@@ -1,109 +0,0 @@
add_subdirectory(../ "${CMAKE_CURRENT_BINARY_DIR}/abseil")
# To make Abseil easy for clients to link against, we create a dummy target just for installation
# purposes and combine all of Abseil's libraries into a single, easy to link against static library.
add_library(filament-abseil STATIC dummy.c)
set(ABSEIL_DEPS
# This is a full list of static library targets that Abseil exports, generated with the
# following commands:
# cd out/cmake-debug
# ninja -t targets | grep libabsl | sed 's/^lib//; s/\.a: phony$//'
absl_bad_any_cast_impl
absl_bad_optional_access
absl_bad_variant_access
absl_base
absl_city
absl_civil_time
absl_cord
absl_cord_internal
absl_cordz_functions
absl_cordz_handle
absl_cordz_info
absl_cordz_sample_token
absl_crc32c
absl_crc_cord_state
absl_crc_cpu_detect
absl_crc_internal
absl_debugging_internal
absl_decode_rust_punycode
absl_demangle_internal
absl_demangle_rust
absl_die_if_null
absl_examine_stack
absl_exponential_biased
absl_failure_signal_handler
absl_flags_commandlineflag
absl_flags_commandlineflag_internal
absl_flags_config
absl_flags_internal
absl_flags_marshalling
absl_flags_parse
absl_flags_private_handle_accessor
absl_flags_program_name
absl_flags_reflection
absl_flags_usage
absl_flags_usage_internal
absl_graphcycles_internal
absl_hash
absl_hashtablez_sampler
absl_int128
absl_kernel_timeout_internal
absl_leak_check
absl_log_entry
absl_log_flags
absl_log_globals
absl_log_initialize
absl_log_internal_check_op
absl_log_internal_conditions
absl_log_internal_fnmatch
absl_log_internal_format
absl_log_internal_globals
absl_log_internal_log_sink_set
absl_log_internal_message
absl_log_internal_nullguard
absl_log_internal_proto
absl_log_internal_structured_proto
absl_log_severity
absl_log_sink
absl_low_level_hash
absl_malloc_internal
absl_periodic_sampler
absl_poison
absl_random_distributions
absl_random_internal_distribution_test_util
absl_random_internal_platform
absl_random_internal_pool_urbg
absl_random_internal_randen
absl_random_internal_randen_hwaes
absl_random_internal_randen_hwaes_impl
absl_random_internal_randen_slow
absl_random_internal_seed_material
absl_random_seed_gen_exception
absl_random_seed_sequences
absl_raw_hash_set
absl_raw_logging_internal
absl_scoped_set_env
absl_spinlock_wait
absl_stacktrace
absl_status
absl_statusor
absl_str_format_internal
absl_strerror
absl_string_view
absl_strings
absl_strings_internal
absl_symbolize
absl_synchronization
absl_throw_delegate
absl_time
absl_time_zone
absl_tracing_internal
absl_utf8_for_code_point
absl_vlog_config_internal
)
set(ABSEIL_COMBINED_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libabseil_combined.a")
combine_static_libs(filament-abseil "${ABSEIL_COMBINED_OUTPUT}" "${ABSEIL_DEPS}")
set(ABSEIL_LIB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}abseil${CMAKE_STATIC_LIBRARY_SUFFIX})
install(FILES "${ABSEIL_COMBINED_OUTPUT}" DESTINATION lib/${DIST_DIR} RENAME ${ABSEIL_LIB_NAME})
View File
+1 -8
View File
@@ -661,7 +661,6 @@ class_<View>("View")
.function("getViewport", &View::getViewport)
.function("setVisibleLayers", &View::setVisibleLayers)
.function("setPostProcessingEnabled", &View::setPostProcessingEnabled)
.function("setDithering", &View::setDithering)
.function("_setAmbientOcclusionOptions", &View::setAmbientOcclusionOptions)
.function("_setDepthOfFieldOptions", &View::setDepthOfFieldOptions)
.function("_setMultiSampleAntiAliasingOptions", &View::setMultiSampleAntiAliasingOptions)
@@ -1392,14 +1391,8 @@ class_<MaterialInstance>("MaterialInstance")
.function("isDoubleSided", &MaterialInstance::isDoubleSided)
.function("setTransparencyMode", &MaterialInstance::setTransparencyMode)
.function("getTransparencyMode", &MaterialInstance::getTransparencyMode)
.function("setCullingMode", EMBIND_LAMBDA(void,
(MaterialInstance* self, MaterialInstance::CullingMode mode), {
self->setCullingMode(mode); }), allow_raw_pointers())
.function("setCullingModeSeparate", EMBIND_LAMBDA(void,
(MaterialInstance* self, MaterialInstance::CullingMode color, MaterialInstance::CullingMode shadows), {
self->setCullingMode(color, shadows); }), allow_raw_pointers())
.function("setCullingMode", &MaterialInstance::setCullingMode)
.function("getCullingMode", &MaterialInstance::getCullingMode)
.function("getShadowCullingMode", &MaterialInstance::getShadowCullingMode)
.function("setColorWrite", &MaterialInstance::setColorWrite)
.function("isColorWriteEnabled", &MaterialInstance::isColorWriteEnabled)
.function("setDepthWrite", &MaterialInstance::setDepthWrite)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "filament",
"version": "1.57.0",
"version": "1.56.7",
"description": "Real-time physically based rendering engine",
"main": "filament.js",
"module": "filament.js",