Compare commits

..
43 Commits
Author SHA1 Message Date
Eliza Velasquez 0709f7d59a stuff 2024-03-06 15:02:15 -08:00
Eliza Velasquez 2027c9e237 stuff 2024-02-28 16:05:28 -08:00
Eliza Velasquez 86456c9e34 swizzle! struct indexing! 2024-02-27 17:04:25 -08:00
Eliza Velasquez fad58ba892 insert room for literal operand expressions 2024-02-27 15:39:40 -08:00
Eliza Velasquez 8ae296974c rename bunch of stuff 2024-02-27 14:31:32 -08:00
Eliza Velasquez f9575675d9 more global symbols 2024-02-27 12:54:41 -08:00
Eliza Velasquez 71025cf25a stringify, flesh out global symbols 2024-02-26 16:54:05 -08:00
Eliza Velasquez a067fb02b1 finish get_if 2024-02-26 14:37:14 -08:00
Eliza Velasquez ffde51ee6f continue eradicating get_if 2024-02-26 13:13:25 -08:00
Eliza Velasquez 35f99ed168 templatify 2024-02-23 15:07:18 -08:00
Eliza Velasquez a939ad03f8 stuff 2024-02-22 17:01:54 -08:00
Eliza Velasquez 05e628fff9 more codegen 2024-02-22 15:52:42 -08:00
Eliza Velasquez ad8473760a start literal value support 2024-02-21 17:09:01 -08:00
Eliza Velasquez cb672eb063 more rigorous glsl code gen 2024-02-21 16:04:20 -08:00
Eliza Velasquez 9811b785cb split locals and globals 2024-02-20 16:40:52 -08:00
Eliza Velasquez ff6d4d721e major refactor 2024-02-20 14:08:07 -08:00
Eliza Velasquez c8a5094c41 stuff 2024-02-16 15:03:53 -08:00
Eliza Velasquez 0f34603cfc stringify stuff 2024-02-14 17:11:24 -08:00
Eliza Velasquez 300f80448d test 2024-02-13 16:58:49 -08:00
Eliza Velasquez a41d343a75 wip: komi 2024-02-12 16:59:06 -08:00
Mathias Agopian 02f5903b67 fix external images
It turns out that many drivers require to rebind the external texture
after its content has changed, so we now always do that.

Bug #6188
2024-01-26 14:17:48 -08:00
Mathias Agopian c39a870abc fix mobile debug builds, missing incluldes 2024-01-26 11:14:16 -08:00
Mathias Agopian 09b8008e17 add missing public headers in backend 2024-01-26 10:58:28 -08:00
Mathias Agopian 59b59cf6be add missing includes in libutils public headers 2024-01-26 10:58:00 -08:00
Mathias Agopian 0df6013263 update remote ui 2024-01-26 10:57:37 -08:00
Mathias Agopian d5041fced7 support execinfo.h on Android 33 and above
Note: this currently requires to compile filament with API_LEVEL 33.
2024-01-25 14:50:29 -08:00
Mathias Agopian 9c54b8a777 fix typo that broke FSR upscaling 2024-01-25 10:34:47 -08:00
Mathias Agopian 8a534d0940 Fix missing/extra includes in all public headers 2024-01-24 23:13:14 -08:00
Mathias Agopian 130825422e Shadowmap texture vizualizer
The vizualizer is implemented inside filament itself and activated
using the debug registry. This intended for filament development use.
2024-01-24 11:28:11 -08:00
Powei Feng 984006ee25 geometry: allow additional attributes in TangentSpaceMesh (#7483)
- Add methods for adding attributes to the input mesh
 - Add method in TangentSpaceMesh for when user provides the
   tangents
 - Separate client-side Algorithm enum from implementation algorithm
   (AlgorithmImpl)
 - Fix CMake config for combining static libs
2024-01-23 16:16:35 -08:00
Sungun Park b676002521 Release Filament 1.50.0 2024-01-23 21:10:06 +00:00
Sungun Park 8bdf7bd1e5 Update material version to 50 2024-01-22 15:25:06 -08:00
Mathias Agopian 1262cb286c backend option to disable parallel shader compile 2024-01-22 12:43:27 -08:00
Mathias Agopian ee6f3fb1dc Add sharpening option to TAA
We use the RCAS algorithm from FSR1. This is useful for when TAA
upscaling is enabled and similar to to what FSR2 is doing.
2024-01-19 14:40:04 -08:00
Mathias Agopian b9a9586abb taa: add a 32-sample mode and cleanup
32 sample may be more suited to 2x upsampling, it gives 8 samples per
high-res pixel (instead of 4). This is also what FSR 2.0 is using,
which is useful for comparing.
2024-01-19 14:40:04 -08:00
Mathias Agopian 6ee20a57aa remove all uses of our custom spinlock
This has caused issues and over time we have reduced the use of 
spinlocks, it was only used in few places and we still have evidence
that it's causing ANRs.

We use utils::Mutex instead which is a low overhead mutex implementation
on Linux systems.

FIXES=[321101014]
2024-01-19 12:05:07 -08:00
Mathias Agopian 368fa2bf39 fix IBLPrefilterContext::EquirectangularToCubemap
it was incorrectly mapping the equirect image to a cubemap due to a
typo in our overload of atan2 which was swapping its parameters.

atan2 is now removed, and we use atan(y,x) instead. Also modified the
code slightly so it matches almost exactly cmgen's.

FIXES=[320856413]
2024-01-18 21:10:21 -08:00
Mathias Agopian 8f642892b4 taa: fixes input filtering option=OFF when upscaling is off
when upscaling is off, the confidence value is always 1.
2024-01-18 21:07:13 -08:00
Powei Feng 5435a8ed3b Add missing includes (#7501)
BUG=320668410
2024-01-17 11:04:42 -08:00
Ben Doherty 5fd7a4e153 Don't render in background (#7486) 2024-01-12 10:17:00 -08:00
Sungun Park 20ff230b92 Fix a json parsing bug (#7490)
When parsing a lexeme, we use one less byte than it's intended to be for
comparing the current string.

This results in a success in cases like:
- true and truX
- false and falsX
- null and nulX
where X means an arbitrary character.

Fix this by the full intended length.
2024-01-11 12:47:11 -08:00
Ben Doherty 44ff79ad34 Metal: disable fast math (#7485) 2024-01-10 15:31:23 -08:00
Mathias AgopianandPowei Feng 102d2db008 Bokeh aspect ratio (#7482)
* Bokeh aspect ratio

new DoF option to set the bokeh aspect ratio, this can be used to
simulate anamorphic lenses

* Update android/filament-android/src/main/java/com/google/android/filament/View.java

Co-authored-by: Powei Feng <powei@google.com>

* Update web/filament-js/filament.d.ts

Co-authored-by: Powei Feng <powei@google.com>

---------

Co-authored-by: Powei Feng <powei@google.com>
2024-01-10 15:25:28 -08:00
153 changed files with 6011 additions and 552 deletions
+2 -1
View File
@@ -1,7 +1,8 @@
;;; Directory Local Variables -*- no-byte-compile: t -*-
;;; For more information see (info "(emacs) Directory Variables")
((c++-mode . ((c-file-style . "filament")
((c++-mode . ((eglot-ignored-server-capabilities . (:documentFormattingProvider))
(c-file-style . "filament")
(apheleia-inhibit . t)))
(c-mode . ((c-file-style . "filament")
(apheleia-inhibit . t))))
+6 -3
View File
@@ -634,9 +634,9 @@ function(combine_static_libs TARGET OUTPUT DEPS)
# Loop through the dependent libraries and query their location on disk.
set(DEPS_FILES )
foreach(DEPENDENCY ${DEPS})
if(TARGET ${DEPENDENCY})
if (TARGET ${DEPENDENCY})
get_property(dep_type TARGET ${DEPENDENCY} PROPERTY TYPE)
if(dep_type STREQUAL "STATIC_LIBRARY")
if (dep_type STREQUAL "STATIC_LIBRARY")
list(APPEND DEPS_FILES "$<TARGET_FILE:${DEPENDENCY}>")
endif()
endif()
@@ -721,7 +721,6 @@ add_subdirectory(${LIBRARIES}/filabridge)
add_subdirectory(${LIBRARIES}/filaflat)
add_subdirectory(${LIBRARIES}/filagui)
add_subdirectory(${LIBRARIES}/filameshio)
add_subdirectory(${LIBRARIES}/geometry)
add_subdirectory(${LIBRARIES}/gltfio)
add_subdirectory(${LIBRARIES}/ibl)
add_subdirectory(${LIBRARIES}/iblprefilter)
@@ -749,12 +748,16 @@ add_subdirectory(${EXTERNAL}/jsmn/tnt)
add_subdirectory(${EXTERNAL}/stb/tnt)
add_subdirectory(${EXTERNAL}/getopt)
# Note that this has to be placed after mikktspace in order for combine_static_libs to work.
add_subdirectory(${LIBRARIES}/geometry)
if (FILAMENT_BUILD_FILAMAT OR IS_HOST_PLATFORM)
# spirv-tools must come before filamat, as filamat relies on the presence of the
# spirv-tools_SOURCE_DIR variable.
add_subdirectory(${EXTERNAL}/spirv-tools)
add_subdirectory(${EXTERNAL}/glslang/tnt)
add_subdirectory(${EXTERNAL}/spirv-cross/tnt)
add_subdirectory(${LIBRARIES}/astrict)
add_subdirectory(${LIBRARIES}/filamat)
# the material debugger requires filamat
-2
View File
@@ -7,5 +7,3 @@ for next branch cut* header.
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut
- utils: remove usages of `SpinLock`. Fixes b/321101014.
+6
View File
@@ -7,6 +7,12 @@ 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.50.1
- Metal: fix some shader artifacts by disabling fast math optimizations.
- backend: remove `atan2` overload which had a typo and wasn't useful. Fixes b/320856413.
- utils: remove usages of `SpinLock`. Fixes b/321101014.
## v1.50.0
- engine: TAA now supports 4x upscaling [BETA] [⚠️ **New Material Version**]
@@ -1637,6 +1637,10 @@ public class View {
* circle of confusion scale factor (amount of blur)
*/
public float cocScale = 1.0f;
/**
* width/height aspect ratio of the circle of confusion (simulate anamorphic lenses)
*/
public float cocAspectRatio = 1.0f;
/**
* maximum aperture diameter in meters (zero to disable rotation)
*/
@@ -1921,6 +1925,7 @@ public class View {
UNIFORM_HELIX_X4,
HALTON_23_X8,
HALTON_23_X16,
HALTON_23_X32,
}
/**
@@ -1935,6 +1940,10 @@ public class View {
* texturing lod bias (typically -1 or -2)
*/
public float lodBias = -1.0f;
/**
* post-TAA sharpen, especially useful when upscaling is true.
*/
public float sharpness = 0.0f;
/**
* enables or disables temporal anti-aliasing
*/
File diff suppressed because one or more lines are too long
Binary file not shown.
+1
View File
@@ -238,6 +238,7 @@ set(MATERIAL_SRCS
src/materials/resolveDepth.mat
src/materials/separableGaussianBlur.mat
src/materials/skybox.mat
src/materials/shadowmap.mat
src/materials/ssao/bilateralBlur.mat
src/materials/ssao/bilateralBlurBentNormals.mat
src/materials/ssao/mipmapDepth.mat
@@ -23,7 +23,6 @@
#include <utils/ostream.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -17,8 +17,6 @@
#ifndef TNT_FILAMENT_BACKEND_CALLBACKHANDLER_H
#define TNT_FILAMENT_BACKEND_CALLBACKHANDLER_H
#include <utils/compiler.h>
namespace filament::backend {
/**
@@ -28,7 +28,8 @@
#include <math/vec4.h>
#include <array> // FIXME: STL headers are not allowed in public headers
#include <array> // FIXME: STL headers are not allowed in public headers
#include <type_traits> // FIXME: STL headers are not allowed in public headers
#include <stddef.h>
#include <stdint.h>
+4 -6
View File
@@ -17,16 +17,14 @@
#ifndef TNT_FILAMENT_BACKEND_HANDLE_H
#define TNT_FILAMENT_BACKEND_HANDLE_H
#include <utils/compiler.h>
#if !defined(NDEBUG)
#include <utils/Log.h>
#include <utils/ostream.h>
#endif
#include <utils/debug.h>
#include <stdint.h>
#include <type_traits> // FIXME: STL headers are not allowed in public headers
#include <limits>
#include <type_traits>
#include <stdint.h>
namespace filament::backend {
@@ -54,7 +52,7 @@ struct HwVertexBuffer;
class HandleBase {
public:
using HandleId = uint32_t;
static constexpr const HandleId nullid = HandleId{ std::numeric_limits<HandleId>::max() };
static constexpr const HandleId nullid = HandleId{ UINT32_MAX };
constexpr HandleBase() noexcept: object(nullid) {}
@@ -20,7 +20,7 @@
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <limits>
#include <utils/ostream.h>
#include <stdint.h>
@@ -33,10 +33,7 @@ struct PipelineState {
RasterState rasterState;
StencilState stencilState;
PolygonOffset polygonOffset;
Viewport scissor{ 0, 0,
(uint32_t)std::numeric_limits<int32_t>::max(),
(uint32_t)std::numeric_limits<int32_t>::max()
};
Viewport scissor{ 0, 0, (uint32_t)INT32_MAX, (uint32_t)INT32_MAX };
};
} // namespace filament::backend
@@ -24,6 +24,7 @@
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ostream.h>
#include <stddef.h>
#include <stdint.h>
+12 -6
View File
@@ -19,11 +19,11 @@
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_H
#define TNT_FILAMENT_BACKEND_PLATFORM_H
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <stddef.h>
namespace filament::backend {
class Driver;
@@ -41,18 +41,24 @@ public:
struct Stream {};
struct DriverConfig {
/*
* size of handle arena in bytes. Setting to 0 indicates default value is to be used.
/**
* Size of handle arena in bytes. Setting to 0 indicates default value is to be used.
* Driver clamps to valid values.
*/
size_t handleArenaSize = 0;
/*
* this number of most-recently destroyed textures will be tracked for use-after-free.
/**
* This number of most-recently destroyed textures will be tracked for use-after-free.
* Throws an exception when a texture is freed but still bound to a SamplerGroup and used in
* a draw call. 0 disables completely. Currently only respected by the Metal backend.
*/
size_t textureUseAfterFreePoolSize = 0;
/**
* Set to `true` to forcibly disable parallel shader compilation in the backend.
* Currently only honored by the GL backend.
*/
bool disableParallelShaderCompile = false;
};
Platform() noexcept;
@@ -21,8 +21,7 @@
#include <utils/compiler.h>
namespace filament {
namespace backend {
namespace filament::backend {
/**
* A PresentCallable is a callable object that, when called, schedules a frame for presentation on
@@ -98,7 +97,6 @@ private:
*/
using FrameFinishedCallback UTILS_DEPRECATED = void(*)(PresentCallable callable, void* user);
} // namespace backend
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRESENTCALLABLE
+6 -4
View File
@@ -17,17 +17,19 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_PROGRAM_H
#define TNT_FILAMENT_BACKEND_PRIVATE_PROGRAM_H
#include <utils/compiler.h>
#include <utils/CString.h>
#include <utils/FixedCapacityVector.h>
#include <utils/Invocable.h>
#include <utils/Log.h>
#include <utils/ostream.h>
#include <backend/DriverEnums.h>
#include <array>
#include <variant>
#include <array> // FIXME: STL headers are not allowed in public headers
#include <utility> // FIXME: STL headers are not allowed in public headers
#include <variant> // FIXME: STL headers are not allowed in public headers
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -24,9 +24,6 @@
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
struct UTILS_PUBLIC SamplerDescriptor {
@@ -17,9 +17,11 @@
#ifndef TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H
#define TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <utils/ostream.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -18,8 +18,11 @@
#define TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
#include <backend/AcquiredImage.h>
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#include <stdint.h>
namespace filament::backend {
class Driver;
@@ -17,11 +17,10 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <stdint.h>
namespace filament::backend {
@@ -30,7 +30,7 @@ struct PlatformCocoaTouchGLImpl;
class PlatformCocoaTouchGL : public OpenGLPlatform {
public:
PlatformCocoaTouchGL();
~PlatformCocoaTouchGL() noexcept;
~PlatformCocoaTouchGL() noexcept override;
// --------------------------------------------------------------------------------------------
// Platform Interface
@@ -17,18 +17,21 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <initializer_list>
#include <utility>
#include <vector>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
/**
@@ -17,8 +17,14 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#include <backend/AcquiredImage.h>
#include <backend/Platform.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/platforms/PlatformEGL.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
class ExternalStreamManagerAndroid;
@@ -20,13 +20,18 @@
#include <backend/Platform.h>
#include <bluevk/BlueVK.h>
#include <utils/CString.h>
#include <utils/FixedCapacityVector.h>
#include <utils/PrivateImplementation.h>
#include <string_view>
#include <tuple>
#include <unordered_set>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
using SwapChain = Platform::SwapChain;
@@ -17,10 +17,7 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_CIRCULARBUFFER_H
#define TNT_FILAMENT_BACKEND_PRIVATE_CIRCULARBUFFER_H
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -19,12 +19,14 @@
#include "private/backend/CircularBuffer.h"
#include <utils/compiler.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <vector>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
/*
@@ -32,11 +32,13 @@
#include <backend/TargetBufferInfo.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ThreadUtils.h>
#include <cstddef>
#include <functional>
#include <tuple>
#include <type_traits>
#include <utility>
#ifndef NDEBUG
@@ -152,14 +154,14 @@ struct CommandType<void (Driver::*)(ARGS...)> {
}
// placement new declared as "throw" to avoid the compiler's null-check
inline void* operator new(std::size_t size, void* ptr) {
inline void* operator new(std::size_t, void* ptr) {
assert_invariant(ptr);
return ptr;
}
};
};
// convert an method of "class Driver" into a Command<> type
// convert a method of "class Driver" into a Command<> type
#define COMMAND_TYPE(method) CommandType<decltype(&Driver::method)>::Command<&Driver::method>
// ------------------------------------------------------------------------------------------------
@@ -29,6 +29,7 @@
#include <functional>
#include <stddef.h>
#include <stdint.h>
// Command debugging off. debugging virtuals are not called.
@@ -22,9 +22,18 @@
#include <utils/Allocator.h>
#include <utils/Log.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ostream.h>
#include <tsl/robin_map.h>
#include <exception>
#include <type_traits>
#include <unordered_map>
#include <stddef.h>
#include <stdint.h>
#if !defined(NDEBUG) && UTILS_HAS_RTTI
# define HANDLE_TYPE_SAFETY 1
#else
@@ -222,7 +231,7 @@ private:
explicit Allocator(const utils::AreaPolicy::HeapArea& area);
// this is in fact always called with a constexpr size argument
[[nodiscard]] inline void* alloc(size_t size, size_t alignment, size_t extra) noexcept {
[[nodiscard]] inline void* alloc(size_t size, size_t, size_t extra) noexcept {
void* p = nullptr;
if (size <= mPool0.getSize()) p = mPool0.alloc(size, 16, extra);
else if (size <= mPool1.getSize()) p = mPool1.alloc(size, 16, extra);
@@ -19,9 +19,9 @@
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
#define TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
#include "backend/DriverEnums.h"
#include <backend/DriverEnums.h>
#include "utils/compiler.h"
#include <utils/compiler.h>
namespace filament::backend {
@@ -17,15 +17,13 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_SAMPLERGROUP_H
#define TNT_FILAMENT_BACKEND_PRIVATE_SAMPLERGROUP_H
#include "backend/DriverApiForward.h"
#include <utils/compiler.h>
#include <utils/FixedCapacityVector.h>
#include <backend/DriverApiForward.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <backend/SamplerDescriptor.h>
#include <utils/FixedCapacityVector.h>
#include <utils/ostream.h>
#include <stddef.h>
namespace filament::backend {
+14 -1
View File
@@ -21,7 +21,12 @@
#include <backend/AcquiredImage.h>
#include <backend/BufferDescriptor.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/Log.h>
#include <utils/ostream.h>
#include <utils/Systrace.h>
#include <math/half.h>
@@ -29,6 +34,13 @@
#include <math/vec3.h>
#include <math/vec4.h>
#include <functional>
#include <mutex>
#include <utility>
#include <stddef.h>
#include <stdint.h>
using namespace utils;
using namespace filament::math;
@@ -119,7 +131,8 @@ void DriverBase::purge() noexcept {
// ------------------------------------------------------------------------------------------------
void DriverBase::scheduleDestroySlow(BufferDescriptor&& buffer) noexcept {
scheduleCallback(buffer.getHandler(), [buffer = std::move(buffer)]() {
auto const handler = buffer.getHandler();
scheduleCallback(handler, [buffer = std::move(buffer)]() {
// user callback is called when BufferDescriptor gets destroyed
});
}
@@ -20,6 +20,7 @@
#include "MetalUtils.h"
#include <utils/Panic.h>
#include <utils/Log.h>
namespace filament::backend {
@@ -19,6 +19,7 @@
#include "MetalContext.h"
#include <utils/Panic.h>
#include <utils/Log.h>
#include <utils/trap.h>
#include <thread>
@@ -21,6 +21,7 @@
#include "MetalUtils.h"
#include <utils/Panic.h>
#include <utils/Log.h>
#include <utils/trap.h>
#define NSERROR_CHECK(message) \
@@ -103,10 +103,19 @@ void MetalShaderCompiler::terminate() noexcept {
NSString* objcSource = [[NSString alloc] initWithBytes:source.data()
length:source.size() - 1
encoding:NSUTF8StringEncoding];
// By default, Metal uses the most recent language version.
MTLCompileOptions* options = [MTLCompileOptions new];
// Disable Fast Math optimizations.
// This ensures that operations adhere to IEEE standards for floating-point arithmetic,
// which is crucial for half precision floats in scenarios where fast math optimizations
// lead to inaccuracies, such as in handling special values like NaN or Infinity.
options.fastMathEnabled = NO;
NSError* error = nil;
// When options is nil, Metal uses the most recent language version available.
id<MTLLibrary> library = [device newLibraryWithSource:objcSource
options:nil
options:options
error:&error];
if (library == nil) {
if (error) {
+2
View File
@@ -18,6 +18,8 @@
#include "MetalEnums.h"
#include <utils/Log.h>
namespace filament {
namespace backend {
@@ -427,7 +427,6 @@ void OpenGLContext::initBugs(Bugs* bugs, Extensions const& exts,
if (strstr(renderer, "Mali-T")) {
bugs->disable_glFlush = true;
bugs->disable_shared_context_draws = true;
bugs->texture_external_needs_rebind = true;
// We have not verified that timer queries work on Mali-T, so we disable to be safe.
bugs->dont_use_timer_query = true;
}
+1 -8
View File
@@ -222,10 +222,6 @@ public:
// Some drivers have gl state issues when drawing from shared contexts
bool disable_shared_context_draws;
// Some drivers require the GL_TEXTURE_EXTERNAL_OES target to be bound when
// the texture image changes, even if it's already bound to that texture
bool texture_external_needs_rebind;
// Some web browsers seem to immediately clear the default framebuffer when calling
// glInvalidateFramebuffer with WebGL 2.0
bool disable_invalidate_framebuffer;
@@ -433,9 +429,6 @@ private:
{ bugs.disable_shared_context_draws,
"disable_shared_context_draws",
""},
{ bugs.texture_external_needs_rebind,
"texture_external_needs_rebind",
""},
{ bugs.disable_invalidate_framebuffer,
"disable_invalidate_framebuffer",
""},
@@ -711,7 +704,7 @@ void OpenGLContext::bindTexture(GLuint unit, GLuint target, GLuint texId, size_t
update_state(state.textures.units[unit].targets[targetIndex].texture_id, texId, [&]() {
activeTexture(unit);
glBindTexture(target, texId);
}, (target == GL_TEXTURE_EXTERNAL_OES) && bugs.texture_external_needs_rebind);
}, target == GL_TEXTURE_EXTERNAL_OES);
}
void OpenGLContext::bindTexture(GLuint unit, GLuint target, GLuint texId) noexcept {
+4 -3
View File
@@ -147,9 +147,9 @@ Driver* OpenGLDriver::create(OpenGLPlatform* const platform,
#endif
size_t const defaultSize = FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U;
Platform::DriverConfig validConfig {driverConfig};
Platform::DriverConfig validConfig{ driverConfig };
validConfig.handleArenaSize = std::max(driverConfig.handleArenaSize, defaultSize);
OpenGLDriver* const driver = new OpenGLDriver(ec, validConfig);
OpenGLDriver* const driver = new(std::nothrow) OpenGLDriver(ec, validConfig);
return driver;
}
@@ -171,7 +171,8 @@ OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfi
mContext(),
mShaderCompilerService(*this),
mHandleAllocator("Handles", driverConfig.handleArenaSize),
mSamplerMap(32) {
mSamplerMap(32),
mDriverConfig(driverConfig) {
std::fill(mSamplerBindings.begin(), mSamplerBindings.end(), nullptr);
@@ -400,6 +400,9 @@ private:
// timer query implementation
OpenGLTimerQueryInterface* mTimerQueryImpl = nullptr;
const Platform::DriverConfig mDriverConfig;
Platform::DriverConfig const& getDriverConfig() const noexcept { return mDriverConfig; }
// for ES2 sRGB support
GLSwapChain* mCurrentDrawSwapChain = nullptr;
bool mRec709OutputColorspace = false;
@@ -151,6 +151,12 @@ bool ShaderCompilerService::isParallelShaderCompileSupported() const noexcept {
}
void ShaderCompilerService::init() noexcept {
if (UTILS_UNLIKELY(mDriver.getDriverConfig().disableParallelShaderCompile)) {
// user disabled parallel shader compile
mMode = Mode::SYNCHRONOUS;
return;
}
// Here we decide which mode we'll be using. We always prefer our own thread-pool if
// that mode is available because, we have no control on how the compilation queues are
// handled if done by the driver (so at the very least we'd need to decode this per-driver).
@@ -109,7 +109,7 @@ private:
};
enum class Mode {
UNDEFINED, // init() has not beed called yet.
UNDEFINED, // init() has not been called yet.
SYNCHRONOUS, // synchronous shader compilation
THREAD_POOL, // asynchronous shader compilation using a thread-pool (most common)
ASYNCHRONOUS // asynchronous shader compilation using KHR_parallel_shader_compile
@@ -15,6 +15,7 @@
*/
#include <backend/platforms/VulkanPlatform.h>
#include <backend/DriverEnums.h>
#include "vulkan/VulkanConstants.h"
#include "vulkan/VulkanDriverFactory.h"
@@ -23,6 +24,11 @@
#include <bluevk/BlueVK.h>
#include <tuple>
#include <stdint.h>
#include <stddef.h>
#if defined(__linux__) || defined(__FreeBSD__)
#define LINUX_OR_FREEBSD 1
#endif
+18 -12
View File
@@ -21,10 +21,14 @@
#include <utils/compiler.h>
#include <limits>
#include <math/mat3.h>
#include <math/mat4.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <float.h>
#include <stddef.h>
namespace filament {
@@ -70,7 +74,7 @@ public:
* @return This bounding box
*/
Box& set(const math::float3& min, const math::float3& max) noexcept {
// float3 ctor needed for visual studio
// float3 ctor needed for Visual Studio
center = (max + min) * math::float3(0.5f);
halfExtent = (max - min) * math::float3(0.5f);
return *this;
@@ -130,17 +134,17 @@ public:
struct UTILS_PUBLIC Aabb {
/** min coordinates */
math::float3 min = std::numeric_limits<float>::max();
math::float3 min = FLT_MAX;
/** max coordinates */
math::float3 max = std::numeric_limits<float>::lowest();
math::float3 max = -FLT_MAX;
/**
* Computes the center of the box.
* @return (max + min)/2
*/
math::float3 center() const noexcept {
// float3 ctor needed for visual studio
// float3 ctor needed for Visual Studio
return (max + min) * math::float3(0.5f);
}
@@ -149,7 +153,7 @@ struct UTILS_PUBLIC Aabb {
* @return (max - min)/2
*/
math::float3 extent() const noexcept {
// float3 ctor needed for visual studio
// float3 ctor needed for Visual Studio
return (max - min) * math::float3(0.5f);
}
@@ -198,12 +202,14 @@ struct UTILS_PUBLIC Aabb {
* @return the maximum signed distance to the box. Negative if p is in the box
*/
float contains(math::float3 p) const noexcept {
// we don't use std::max to avoid a dependency on <algorithm>
auto const maximum = [](auto a, auto b) { return a > b ? a : b; };
float d = min.x - p.x;
d = std::max(d, min.y - p.y);
d = std::max(d, min.z - p.z);
d = std::max(d, p.x - max.x);
d = std::max(d, p.y - max.y);
d = std::max(d, p.z - max.z);
d = maximum(d, min.y - p.y);
d = maximum(d, min.z - p.z);
d = maximum(d, p.x - max.x);
d = maximum(d, p.y - max.y);
d = maximum(d, p.z - max.z);
return d;
}
+3 -1
View File
@@ -22,11 +22,13 @@
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/BufferDescriptor.h>
#include <utils/compiler.h>
#include <stdint.h>
#include <stddef.h>
namespace filament {
class FBufferObject;
+7 -2
View File
@@ -28,6 +28,11 @@
#include <math/vec4.h>
#include <math/mat4.h>
#include <math.h>
#include <stdint.h>
#include <stddef.h>
namespace utils {
class Entity;
} // namespace utils
@@ -184,7 +189,7 @@ public:
* @see Fov.
*/
static math::mat4 projection(Fov direction, double fovInDegrees,
double aspect, double near, double far = std::numeric_limits<double>::infinity());
double aspect, double near, double far = INFINITY);
/** Returns the projection matrix from the focal length.
*
@@ -194,7 +199,7 @@ public:
* @param far distance in world units from the camera to the far plane. \p far > \p near.
*/
static math::mat4 projection(double focalLengthInMillimeters,
double aspect, double near, double far = std::numeric_limits<double>::infinity());
double aspect, double near, double far = INFINITY);
/** Sets the projection matrix from a frustum defined by six planes.
+3
View File
@@ -24,6 +24,9 @@
#include <math/vec3.h>
#include <math/vec4.h>
#include <stdint.h>
#include <stddef.h>
namespace filament {
//! RGB color in linear space
+3
View File
@@ -26,6 +26,9 @@
#include <math/mathfwd.h>
#include <stdint.h>
#include <stddef.h>
namespace filament {
class Engine;
-1
View File
@@ -18,7 +18,6 @@
#define TNT_FILAMENT_COLOR_SPACE_H
#include <math/vec2.h>
#include <math/vec3.h>
namespace filament::color {
+1 -1
View File
@@ -25,7 +25,7 @@
#include <math/mathfwd.h>
#include <stdint.h>
#include <stddef.h>
namespace filament {
+5
View File
@@ -19,9 +19,14 @@
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <stdint.h>
#include <stddef.h>
namespace utils {
class Entity;
+2
View File
@@ -25,6 +25,8 @@
#include <utils/compiler.h>
#include <stdint.h>
namespace filament {
/**
+3
View File
@@ -23,9 +23,12 @@
#include <math/mat4.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <utils/unwindows.h> // Because we define NEAR and FAR in the Plane enum.
#include <stdint.h>
namespace filament {
class Box;
+1
View File
@@ -27,6 +27,7 @@
#include <utils/compiler.h>
#include <stdint.h>
#include <stddef.h>
namespace filament {
@@ -25,6 +25,8 @@
#include <math/mathfwd.h>
#include <stdint.h>
namespace filament {
class Engine;
+5 -2
View File
@@ -18,11 +18,14 @@
#define TNT_FILAMENT_INSTANCEBUFFER_H
#include <filament/FilamentAPI.h>
#include <filament/Engine.h>
#include <utils/compiler.h>
#include <math/mathfwd.h>
#include <stddef.h>
namespace filament {
/**
@@ -45,7 +48,7 @@ public:
* >= 1 and <= \c Engine::getMaxAutomaticInstances()
* @see Engine::getMaxAutomaticInstances
*/
Builder(size_t instanceCount) noexcept;
explicit Builder(size_t instanceCount) noexcept;
Builder(Builder const& rhs) noexcept;
Builder(Builder&& rhs) noexcept;
+3
View File
@@ -27,6 +27,9 @@
#include <math/mathfwd.h>
#include <math/quat.h>
#include <stdint.h>
#include <stddef.h>
namespace utils {
class Entity;
} // namespace utils
+5
View File
@@ -30,7 +30,12 @@
#include <math/mathfwd.h>
#include <type_traits>
#include <utility>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
namespace utils {
class CString;
@@ -28,6 +28,12 @@
#include <math/mathfwd.h>
#include <type_traits>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
namespace filament {
class Material;
@@ -21,8 +21,11 @@
#include <filament/Engine.h>
#include <utils/compiler.h>
#include <math/mathfwd.h>
#include <stddef.h>
namespace filament {
+8 -2
View File
@@ -19,10 +19,13 @@
#include <filament/Color.h>
#include <stdint.h>
#include <math/vec2.h>
#include <math/vec3.h>
#include <math.h>
#include <stdint.h>
namespace filament {
class Texture;
@@ -293,6 +296,7 @@ struct DepthOfFieldOptions {
MEDIAN
};
float cocScale = 1.0f; //!< circle of confusion scale factor (amount of blur)
float cocAspectRatio = 1.0f; //!< width/height aspect ratio of the circle of confusion (simulate anamorphic lenses)
float maxApertureDiameter = 0.01f; //!< maximum aperture diameter in meters (zero to disable rotation)
bool enabled = false; //!< enable or disable depth of field effect
Filter filter = Filter::MEDIAN; //!< filter to use for filling gaps in the kernel
@@ -437,6 +441,7 @@ struct TemporalAntiAliasingOptions {
float filterWidth = 1.0f; //!< reconstruction filter width typically between 0.2 (sharper, aliased) and 1.5 (smoother)
float feedback = 0.12f; //!< history feedback, between 0 (maximum temporal AA) and 1 (no temporal AA).
float lodBias = -1.0f; //!< texturing lod bias (typically -1 or -2)
float sharpness = 0.0f; //!< post-TAA sharpen, especially useful when upscaling is true.
bool enabled = false; //!< enables or disables temporal anti-aliasing
bool upscaling = false; //!< 4x TAA upscaling. Disables Dynamic Resolution. [BETA]
@@ -456,7 +461,8 @@ struct TemporalAntiAliasingOptions {
RGSS_X4, //! 4-samples, rotated grid sampling
UNIFORM_HELIX_X4, //! 4-samples, uniform grid in helix sequence
HALTON_23_X8, //! 8-samples of halton 2,3
HALTON_23_X16 //! 16-samples of halton 2,3
HALTON_23_X16, //! 16-samples of halton 2,3
HALTON_23_X32 //! 32-samples of halton 2,3
};
bool filterHistory = true; //!< whether to filter the history buffer
+3
View File
@@ -24,7 +24,10 @@
#include <backend/DriverEnums.h>
#include <backend/TargetBufferInfo.h>
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament {
@@ -29,9 +29,15 @@
#include <utils/FixedCapacityVector.h>
#include <math/mathfwd.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <type_traits>
#include <float.h>
#include <stddef.h>
#include <stdint.h>
namespace utils {
class Entity;
} // namespace utils
@@ -873,8 +879,8 @@ void RenderableManager::setMorphTargetBufferAt(Instance instance, uint8_t level,
template<typename VECTOR, typename INDEX, typename, typename>
Box RenderableManager::computeAABB(VECTOR const* vertices, INDEX const* indices, size_t count,
size_t stride) noexcept {
math::float3 bmin(std::numeric_limits<float>::max());
math::float3 bmax(std::numeric_limits<float>::lowest());
math::float3 bmin(FLT_MAX);
math::float3 bmax(-FLT_MAX);
for (size_t i = 0; i < count; ++i) {
VECTOR const* p = reinterpret_cast<VECTOR const*>(
(char const*)vertices + indices[i] * stride);
-3
View File
@@ -23,9 +23,6 @@
#include <utils/compiler.h>
#include <backend/PresentCallable.h>
#include <backend/DriverEnums.h>
#include <math/vec4.h>
#include <stdint.h>
+2
View File
@@ -24,6 +24,8 @@
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <stddef.h>
namespace utils {
class Entity;
} // namespace utils
+1 -1
View File
@@ -26,7 +26,7 @@
#include <math/mathfwd.h>
#include <stddef.h>
#include <stdint.h>
namespace filament {
+2 -1
View File
@@ -23,9 +23,10 @@
#include <utils/compiler.h>
#include <stdint.h>
#include <math/mathfwd.h>
#include <stdint.h>
namespace filament {
class FSkybox;
+2 -2
View File
@@ -20,12 +20,12 @@
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/PixelBufferDescriptor.h>
#include <backend/CallbackHandler.h>
#include <utils/compiler.h>
#include <stdint.h>
namespace filament {
class FStream;
+2 -1
View File
@@ -21,11 +21,12 @@
#include <backend/CallbackHandler.h>
#include <backend/DriverEnums.h>
#include <backend/PresentCallable.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <stdint.h>
namespace filament {
class Engine;
+4
View File
@@ -20,12 +20,16 @@
#define TNT_FILAMENT_TEXTURE_H
#include <filament/FilamentAPI.h>
#include <backend/DriverEnums.h>
#include <backend/PixelBufferDescriptor.h>
#include <utils/compiler.h>
#include <utility>
#include <stddef.h>
#include <stdint.h>
namespace filament {
@@ -25,6 +25,8 @@
#include <math.h>
#include <stdint.h>
namespace filament {
/**
+2
View File
@@ -21,6 +21,8 @@
#include <math/mathfwd.h>
#include <stdint.h>
namespace filament {
/**
@@ -26,6 +26,7 @@
#include <iterator>
#include <stddef.h>
namespace utils {
class Entity;
+3
View File
@@ -27,6 +27,9 @@
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament {
class FVertexBuffer;
+5 -3
View File
@@ -19,17 +19,19 @@
#ifndef TNT_FILAMENT_VIEW_H
#define TNT_FILAMENT_VIEW_H
#include <filament/Color.h>
#include <filament/FilamentAPI.h>
#include <filament/Options.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/Entity.h>
#include <math/mathfwd.h>
#include <utility>
#include <stddef.h>
#include <stdint.h>
namespace filament {
namespace backend {
-3
View File
@@ -23,9 +23,6 @@
#include <utils/compiler.h>
#include <math/scalar.h>
#include <math/mathfwd.h>
#include <stddef.h>
#include <stdint.h>
+149 -78
View File
@@ -64,6 +64,7 @@
#include <math/mat3.h>
#include <math/mat4.h>
#include <math/scalar.h>
#include <math/vec2.h>
#include <math/vec3.h>
#include <math/vec4.h>
@@ -74,6 +75,7 @@
#include <utils/FixedCapacityVector.h>
#include <algorithm>
#include <array>
#include <cmath>
#include <limits>
#include <string_view>
@@ -113,7 +115,7 @@ PostProcessManager::PostProcessMaterial::PostProcessMaterial() noexcept {
}
PostProcessManager::PostProcessMaterial::PostProcessMaterial(MaterialInfo const& info) noexcept
: PostProcessMaterial() {
: PostProcessMaterial() {
mData = info.data; // aliased to mMaterial
mSize = info.size;
mConstants = info.constants;
@@ -165,7 +167,7 @@ void PostProcessManager::PostProcessMaterial::loadMaterial(FEngine& engine) cons
mHasMaterial = true;
auto builder = Material::Builder();
builder.package(mData, mSize);
for (auto const& constant : mConstants) {
for (auto const& constant: mConstants) {
std::visit([&](auto&& arg) {
builder.constant(constant.name.data(), constant.name.size(), arg);
}, constant.value);
@@ -187,63 +189,60 @@ PipelineState PostProcessManager::PostProcessMaterial::getPipelineState(
FMaterial* const material = getMaterial(engine);
material->prepareProgram(Variant{ variantKey });
return {
.program = material->getProgram(Variant{variantKey}),
.program = material->getProgram(Variant{ variantKey }),
.rasterState = material->getRasterState(),
.scissor = material->getDefaultInstance()->getScissor()
};
}
UTILS_NOINLINE
FMaterialInstance* PostProcessManager::PostProcessMaterial::getMaterialInstance(FEngine& engine) const noexcept {
FMaterialInstance* PostProcessManager::PostProcessMaterial::getMaterialInstance(
FEngine& engine) const noexcept {
FMaterial* const material = getMaterial(engine);
return material->getDefaultInstance();
}
// ------------------------------------------------------------------------------------------------
const PostProcessManager::JitterSequence<4> PostProcessManager::sRGSS4 = {{
const PostProcessManager::JitterSequence<4> PostProcessManager::sRGSS4 = {{{
{ 0.625f, 0.125f },
{ 0.125f, 0.375f },
{ 0.875f, 0.625f },
{ 0.375f, 0.875f }
}};
}}};
const PostProcessManager::JitterSequence<4> PostProcessManager::sUniformHelix4 = {{
const PostProcessManager::JitterSequence<4> PostProcessManager::sUniformHelix4 = {{{
{ 0.25f, 0.25f },
{ 0.75f, 0.75f },
{ 0.25f, 0.75f },
{ 0.75f, 0.25f },
}};
}}};
const PostProcessManager::JitterSequence<16> PostProcessManager::sHaltonSamples = {{
{ filament::halton( 0, 2), filament::halton( 0, 3) },
{ filament::halton( 1, 2), filament::halton( 1, 3) },
{ filament::halton( 2, 2), filament::halton( 2, 3) },
{ filament::halton( 3, 2), filament::halton( 3, 3) },
{ filament::halton( 4, 2), filament::halton( 4, 3) },
{ filament::halton( 5, 2), filament::halton( 5, 3) },
{ filament::halton( 6, 2), filament::halton( 6, 3) },
{ filament::halton( 7, 2), filament::halton( 7, 3) },
{ filament::halton( 8, 2), filament::halton( 8, 3) },
{ filament::halton( 9, 2), filament::halton( 9, 3) },
{ filament::halton(10, 2), filament::halton(10, 3) },
{ filament::halton(11, 2), filament::halton(11, 3) },
{ filament::halton(12, 2), filament::halton(12, 3) },
{ filament::halton(13, 2), filament::halton(13, 3) },
{ filament::halton(14, 2), filament::halton(14, 3) },
{ filament::halton(15, 2), filament::halton(15, 3) }
}};
template<size_t COUNT>
constexpr auto halton() {
std::array<float2, COUNT> h;
for (size_t i = 0; i < COUNT; i++) {
h[i] = {
filament::halton(i, 2),
filament::halton(i, 3) };
}
return h;
}
const PostProcessManager::JitterSequence<32>
PostProcessManager::sHaltonSamples = { halton<32>() };
PostProcessManager::PostProcessManager(FEngine& engine) noexcept
: mEngine(engine),
mWorkaroundSplitEasu(false),
mWorkaroundAllowReadOnlyAncillaryFeedbackLoop(false) {
mWorkaroundSplitEasu(false),
mWorkaroundAllowReadOnlyAncillaryFeedbackLoop(false) {
}
PostProcessManager::~PostProcessManager() noexcept = default;
UTILS_NOINLINE
void PostProcessManager::registerPostProcessMaterial(std::string_view name, MaterialInfo const& info) {
void PostProcessManager::registerPostProcessMaterial(std::string_view name,
MaterialInfo const& info) {
mMaterialRegistry.try_emplace(name, info);
}
@@ -308,6 +307,7 @@ static const PostProcessManager::MaterialInfo sMaterialList[] = {
{ "fsr_rcas", MATERIAL(FSR_RCAS) },
{ "debugShadowCascades", MATERIAL(DEBUGSHADOWCASCADES) },
{ "resolveDepth", MATERIAL(RESOLVEDEPTH) },
{ "shadowmap", MATERIAL(SHADOWMAP) },
};
void PostProcessManager::init() noexcept {
@@ -326,13 +326,13 @@ void PostProcessManager::init() noexcept {
driver.isWorkaroundNeeded(Workaround::ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP);
#pragma nounroll
for (auto const& info : sMaterialListFeatureLevel0) {
for (auto const& info: sMaterialListFeatureLevel0) {
registerPostProcessMaterial(info.name, info);
}
if (mEngine.getActiveFeatureLevel() >= FeatureLevel::FEATURE_LEVEL_1) {
#pragma nounroll
for (auto const& info : sMaterialList) {
for (auto const& info: sMaterialList) {
registerPostProcessMaterial(info.name, info);
}
}
@@ -1428,7 +1428,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> depth,
const CameraInfo& cameraInfo,
bool translucent,
float bokehAspectRatio,
float2 bokehScale,
const DepthOfFieldOptions& dofOptions) noexcept {
assert_invariant(depth);
@@ -1683,8 +1683,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
// we assume the width/height is already multiple of 16
assert_invariant(!(colorDesc.width & 0xF) && !(colorDesc.height & 0xF));
const uint32_t tileBufferWidth = colorDesc.width / dofResolution;
const uint32_t tileBufferHeight = colorDesc.height / dofResolution;
const uint32_t tileBufferWidth = width;
const uint32_t tileBufferHeight = height;
const size_t tileReductionCount = ctz(tileSize / dofResolution);
struct PostProcessDofTiling1 {
@@ -1818,8 +1818,8 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::dof(FrameGraph& fg,
mi->setParameter("tiles", tilesCocMinMax,
{ .filterMin = SamplerMinFilter::NEAREST });
mi->setParameter("cocToTexelScale", float2{
bokehAspectRatio / (inputDesc.width * dofResolution),
1.0 / (inputDesc.height * dofResolution)
bokehScale.x / (inputDesc.width * dofResolution),
bokehScale.y / (inputDesc.height * dofResolution)
});
mi->setParameter("cocToPixelScale", (1.0f / float(dofResolution)));
mi->setParameter("ringCounts", float4{
@@ -2569,6 +2569,8 @@ void PostProcessManager::prepareTaa(FrameGraph& fg,
case JitterPattern::HALTON_23_X8:
return sHaltonSamples(frameIndex % 8);
case JitterPattern::HALTON_23_X16:
return sHaltonSamples(frameIndex % 16);
case JitterPattern::HALTON_23_X32:
return sHaltonSamples(frameIndex);
}
};
@@ -2618,6 +2620,7 @@ void PostProcessManager::configureTemporalAntiAliasingMaterial(
}
};
setConstantParameter(ma, "upscaling", taaOptions.upscaling);
setConstantParameter(ma, "historyReprojection", taaOptions.historyReprojection);
setConstantParameter(ma, "filterHistory", taaOptions.filterHistory);
setConstantParameter(ma, "filterInput", taaOptions.filterInput);
@@ -2767,24 +2770,77 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::taa(FrameGraph& fg,
});
input = colorGradingConfig.asSubpass ? taaPass->tonemappedOutput : taaPass->output;
auto history = input;
// optional sharpen pass from FSR1
if (taaOptions.sharpness > 0.0f) {
input = rcas(fg, taaOptions.sharpness,
input, fg.getDescriptor(input), colorGradingConfig.translucent);
}
struct ExportColorHistoryData {
FrameGraphId<FrameGraphTexture> color;
};
auto& exportHistoryPass = fg.addPass<ExportColorHistoryData>("Export TAA history",
fg.addPass<ExportColorHistoryData>("Export TAA history",
[&](FrameGraph::Builder& builder, auto& data) {
// We need to use sideEffect here to ensure this pass won't be culled.
// The "output" of this pass is going to be used during the next frame as
// an "import".
builder.sideEffect();
data.color = builder.sample(input); // FIXME: an access must be declared for detach(), why?
}, [&current](FrameGraphResources const& resources, auto const& data,
backend::DriverApi&) {
resources.detach(data.color,
&current.color, &current.desc);
data.color = builder.sample(history); // FIXME: an access must be declared for detach(), why?
}, [&current](FrameGraphResources const& resources, auto const& data, auto&) {
resources.detach(data.color, &current.color, &current.desc);
});
return exportHistoryPass->color;
return input;
}
FrameGraphId<FrameGraphTexture> PostProcessManager::rcas(
FrameGraph& fg,
float sharpness,
FrameGraphId<FrameGraphTexture> input,
FrameGraphTexture::Descriptor const& outDesc,
bool translucent) {
struct QuadBlitData {
FrameGraphId<FrameGraphTexture> input;
FrameGraphId<FrameGraphTexture> output;
};
auto& ppFsrRcas = fg.addPass<QuadBlitData>("FidelityFX FSR1 Rcas",
[&](FrameGraph::Builder& builder, auto& data) {
data.input = builder.sample(input);
data.output = builder.createTexture("FFX FSR1 Rcas output", outDesc);
data.output = builder.declareRenderPass(data.output);
},
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
auto input = resources.getTexture(data.input);
auto out = resources.getRenderPassInfo();
auto const& outputDesc = resources.getDescriptor(data.input);
auto& material = getPostProcessMaterial("fsr_rcas");
FMaterialInstance* const mi = material.getMaterialInstance(mEngine);
FSRUniforms uniforms;
FSR_SharpeningSetup(&uniforms, { .sharpness = 2.0f - 2.0f * sharpness });
mi->setParameter("RcasCon", uniforms.RcasCon);
mi->setParameter("color", input, {}); // uses texelFetch
mi->setParameter("resolution", float4{
outputDesc.width, outputDesc.height,
1.0f / outputDesc.width, 1.0f / outputDesc.height });
mi->commit(driver);
mi->use(driver);
const uint8_t variant = uint8_t(
translucent ? PostProcessVariant::TRANSLUCENT : PostProcessVariant::OPAQUE);
PipelineState const pipeline(material.getPipelineState(mEngine, variant));
render(out, pipeline, driver);
});
return ppFsrRcas->output;
}
FrameGraphId<FrameGraphTexture> PostProcessManager::upscale(FrameGraph& fg, bool translucent,
@@ -2947,41 +3003,9 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::upscale(FrameGraph& fg, bool
auto output = ppQuadBlit->output;
// if we had to take the low quality fallback, we still do the "sharpen pass"
if (dsrOptions.sharpness > 0.0f && (dsrOptions.quality != QualityLevel::LOW || lowQualityFallback)) {
auto& ppFsrRcas = fg.addPass<QuadBlitData>("FidelityFX FSR1 Rcas",
[&](FrameGraph::Builder& builder, auto& data) {
data.input = builder.sample(output);
data.output = builder.createTexture("FFX FSR1 Rcas output", outDesc);
data.output = builder.declareRenderPass(data.output);
},
[=](FrameGraphResources const& resources,
auto const& data, DriverApi& driver) {
auto color = resources.getTexture(data.input);
auto out = resources.getRenderPassInfo();
auto const& outputDesc = resources.getDescriptor(data.output);
auto& material = getPostProcessMaterial("fsr_rcas");
FMaterialInstance* const mi = material.getMaterialInstance(mEngine);
FSRUniforms uniforms;
FSR_SharpeningSetup(&uniforms, { .sharpness = 2.0f - 2.0f * dsrOptions.sharpness });
mi->setParameter("RcasCon", uniforms.RcasCon);
mi->setParameter("color", color, { }); // uses texelFetch
mi->setParameter("resolution", float4{
outputDesc.width, outputDesc.height,
1.0f / outputDesc.width, 1.0f / outputDesc.height });
mi->commit(driver);
mi->use(driver);
const uint8_t variant = uint8_t(translucent ?
PostProcessVariant::TRANSLUCENT : PostProcessVariant::OPAQUE);
PipelineState const pipeline(material.getPipelineState(mEngine, variant));
render(out, pipeline, driver);
});
output = ppFsrRcas->output;
if (dsrOptions.sharpness > 0.0f &&
(dsrOptions.quality != QualityLevel::LOW || lowQualityFallback)) {
output = rcas(fg, dsrOptions.sharpness, output, outDesc, translucent);
}
// we rely on automatic culling of unused render passes
@@ -3250,4 +3274,51 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::debugShadowCascades(FrameGra
return debugShadowCascadePass->output;
}
FrameGraphId<FrameGraphTexture> PostProcessManager::debugDisplayShadowTexture(
FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input,
FrameGraphId<FrameGraphTexture> shadowmap, float scale,
uint8_t layer, uint8_t level, uint8_t channel, float power) noexcept {
if (shadowmap) {
struct ShadowMapData {
FrameGraphId<FrameGraphTexture> color;
FrameGraphId<FrameGraphTexture> depth;
};
auto const& desc = fg.getDescriptor(input);
float const ratio = float(desc.height) / float(desc.width);
float const screenScale = float(fg.getDescriptor(shadowmap).height) / float(desc.height);
float2 const s = { screenScale * scale * ratio, screenScale * scale };
auto& shadomapDebugPass = fg.addPass<ShadowMapData>("shadowmap debug pass",
[&](FrameGraph::Builder& builder, auto& data) {
data.color = builder.read(input,
FrameGraphTexture::Usage::COLOR_ATTACHMENT);
data.color = builder.write(data.color,
FrameGraphTexture::Usage::COLOR_ATTACHMENT);
data.depth = builder.sample(shadowmap);
builder.declareRenderPass("color target", {
.attachments = { .color = { data.color }}
});
},
[=](FrameGraphResources const& resources, auto const& data, DriverApi& driver) {
auto out = resources.getRenderPassInfo();
auto in = resources.getTexture(data.depth);
auto const& material = getPostProcessMaterial("shadowmap");
FMaterialInstance* const mi = material.getMaterialInstance(mEngine);
mi->setParameter("shadowmap", in, {
.filterMin = SamplerMinFilter::NEAREST_MIPMAP_NEAREST });
mi->setParameter("scale", s);
mi->setParameter("layer", (uint32_t)layer);
mi->setParameter("level", (uint32_t)level);
mi->setParameter("channel", (uint32_t)channel);
mi->setParameter("power", power);
commitAndRender(out, material, driver);
});
input = shadomapDebugPass->color;
}
return input;
}
} // namespace filament
+16 -3
View File
@@ -36,6 +36,7 @@
#include <tsl/robin_map.h>
#include <array>
#include <random>
#include <string_view>
#include <variant>
@@ -162,7 +163,7 @@ public:
FrameGraphId<FrameGraphTexture> depth,
const CameraInfo& cameraInfo,
bool translucent,
float bokehAspectRatio,
math::float2 bokehScale,
const DepthOfFieldOptions& dofOptions) noexcept;
// Bloom
@@ -241,6 +242,13 @@ public:
filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc,
backend::SamplerMagFilter filter) noexcept;
FrameGraphId<FrameGraphTexture> rcas(
FrameGraph& fg,
float sharpness,
FrameGraphId<FrameGraphTexture> input,
FrameGraphTexture::Descriptor const& outDesc,
bool translucent);
// upscale/downscale blitter using shaders
FrameGraphId<FrameGraphTexture> blit(FrameGraph& fg, bool translucent,
FrameGraphId<FrameGraphTexture> input,
@@ -274,6 +282,11 @@ public:
FrameGraphId<FrameGraphTexture> input,
FrameGraphId<FrameGraphTexture> depth) noexcept;
FrameGraphId<FrameGraphTexture> debugDisplayShadowTexture(FrameGraph& fg,
FrameGraphId<FrameGraphTexture> input,
FrameGraphId<FrameGraphTexture> shadowmap, float scale,
uint8_t layer, uint8_t level, uint8_t channel, float power) noexcept;
backend::Handle<backend::HwTexture> getOneTexture() const;
backend::Handle<backend::HwTexture> getZeroTexture() const;
backend::Handle<backend::HwTexture> getOneTextureArray() const;
@@ -362,12 +375,12 @@ private:
template<size_t SIZE>
struct JitterSequence {
auto operator()(size_t i) const noexcept { return positions[i % SIZE] - 0.5f; }
const math::float2 positions[SIZE];
const std::array<math::float2, SIZE> positions;
};
static const JitterSequence<4> sRGSS4;
static const JitterSequence<4> sUniformHelix4;
static const JitterSequence<16> sHaltonSamples;
static const JitterSequence<32> sHaltonSamples;
bool mWorkaroundSplitEasu : 1;
bool mWorkaroundAllowReadOnlyAncillaryFeedbackLoop : 1;
+6
View File
@@ -294,6 +294,8 @@ FrameGraphId<FrameGraphTexture> ShadowMapManager::render(FEngine& engine, FrameG
// Shadow Passes
// -------------------------------------------------------------------------------------------
fg.getBlackboard()["shadowmap"] = prepareShadowPass->shadows;
struct ShadowPassData {
FrameGraphId<FrameGraphTexture> tempBlurSrc{}; // temporary shadowmap when blurring
FrameGraphId<FrameGraphTexture> output;
@@ -943,6 +945,10 @@ void ShadowMapManager::calculateTextureRequirements(FEngine& engine, FView& view
mipLevels = std::max(1, FTexture::maxLevelCount(maxDimension) - lowMipmapLevel);
}
// publish the debugging data
engine.debug.shadowmap.display_shadow_texture_layer_count = layersNeeded;
engine.debug.shadowmap.display_shadow_texture_level_count = mipLevels;
mTextureAtlasRequirements = {
(uint16_t)maxDimension,
layersNeeded,
+8
View File
@@ -548,12 +548,20 @@ public:
struct {
struct {
bool debug_directional_shadowmap = false;
bool display_shadow_texture = false;
bool far_uses_shadowcasters = true;
bool focus_shadowcasters = true;
bool visualize_cascades = false;
bool tightly_bound_scene = true;
float dzn = -1.0f;
float dzf = 1.0f;
float display_shadow_texture_scale = 0.25f;
int display_shadow_texture_layer = 0;
int display_shadow_texture_level = 0;
int display_shadow_texture_channel = 0;
int display_shadow_texture_layer_count = 0;
int display_shadow_texture_level_count = 0;
float display_shadow_texture_power = 1;
} shadowmap;
struct {
bool camera_at_origin = true;
+33 -4
View File
@@ -70,6 +70,22 @@ FRenderer::FRenderer(FEngine& engine) :
&engine.debug.renderer.doFrameCapture);
debugRegistry.registerProperty("d.renderer.disable_buffer_padding",
&engine.debug.renderer.disable_buffer_padding);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture",
&engine.debug.shadowmap.display_shadow_texture);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_scale",
&engine.debug.shadowmap.display_shadow_texture_scale);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_layer",
&engine.debug.shadowmap.display_shadow_texture_layer);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_level",
&engine.debug.shadowmap.display_shadow_texture_level);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_channel",
&engine.debug.shadowmap.display_shadow_texture_channel);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_layer_count",
&engine.debug.shadowmap.display_shadow_texture_layer_count);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_level_count",
&engine.debug.shadowmap.display_shadow_texture_level_count);
debugRegistry.registerProperty("d.shadowmap.display_shadow_texture_power",
&engine.debug.shadowmap.display_shadow_texture_power);
DriverApi& driver = engine.getDriverApi();
@@ -985,8 +1001,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
auto& history = view.getFrameHistory();
auto& current = history.getCurrent();
current.ssr.projection = projection;
resources.detach(data.history,
&current.ssr.color, &current.ssr.desc);
resources.detach(data.history, &current.ssr.color, &current.ssr.desc);
});
}
@@ -1043,9 +1058,13 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
// The bokeh height is always correct regardless of the dynamic resolution scaling.
// (because the CoC is calculated w.r.t. the height), so we only need to adjust
// the width.
float const bokehAspectRatio = scale.x / scale.y;
float const aspect = (scale.x / scale.y) * dofOptions.cocAspectRatio;
float2 const bokehScale{
aspect < 1.0f ? aspect : 1.0f,
aspect > 1.0f ? 1.0f / aspect : 1.0f
};
input = ppm.dof(fg, input, depth, cameraInfo, needsAlphaChannel,
bokehAspectRatio, dofOptions);
bokehScale, dofOptions);
}
FrameGraphId<FrameGraphTexture> bloom, flare;
@@ -1130,6 +1149,16 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
"SwapChain::CONFIG_HAS_STENCIL_BUFFER flag set.");
}
if (UTILS_UNLIKELY(engine.debug.shadowmap.display_shadow_texture)) {
auto shadowmap = blackboard.get<FrameGraphTexture>("shadowmap");
input = ppm.debugDisplayShadowTexture(fg, input, shadowmap,
engine.debug.shadowmap.display_shadow_texture_scale,
engine.debug.shadowmap.display_shadow_texture_layer,
engine.debug.shadowmap.display_shadow_texture_level,
engine.debug.shadowmap.display_shadow_texture_channel,
engine.debug.shadowmap.display_shadow_texture_power);
}
// auto debug = structure
// fg.forwardResource(fgViewRenderTarget, debug ? debug : input);
+1 -1
View File
@@ -132,7 +132,7 @@ public:
Descriptor descriptor;
SubResourceDescriptor subResourceDescriptor;
// weather the resource was detached
// whether the resource was detached
bool detached = false;
// An Edge with added data from this resource
+97 -47
View File
@@ -34,6 +34,11 @@ material {
}
],
constants : [
{
type : bool,
name : upscaling,
default : false
},
{
type : bool,
name : historyReprojection,
@@ -109,12 +114,41 @@ fragment {
// no clipping (for debugging only)
#define BOX_CLIPPING_NONE 2
float luma(const vec3 color) {
if (materialConstants_useYCoCg) {
return color.x;
} else {
return luminance(color);
}
float rcp(float x) {
return 1.0 / x;
}
float lumaRGB(const vec3 c) {
return luminance(c);
}
float lumaYCoCg(const vec3 c) {
return c.x;
}
float luma(const vec3 c) {
return materialConstants_useYCoCg ? lumaYCoCg(c) : lumaRGB(c);
}
vec3 tonemap(const vec3 c) {
return c * rcp(1.0 + max3(c));
}
vec4 tonemap(const vec4 c) {
return vec4(c.rgb * rcp(1.0 + max3(c.rgb)), c.a);
}
vec3 tonemap(const float w, const vec3 c) {
return c * (w * rcp(1.0 + max3(c)));
}
vec4 tonemap(const float w, const vec4 c) {
return vec4(c.rgb * (w * rcp(1.0 + max3(c.rgb))), c.a);
}
vec3 untonemap(const vec3 c) {
const float epsilon = 1.0 / 65504.0;
return c * rcp(max(epsilon, 1.0 - max3(c)));
}
vec3 RGB_YCoCg(const vec3 c) {
@@ -159,15 +193,16 @@ vec4 clipToBox(const int quality,
// Optimized to 5 taps by removing the corner samples
// And modified for mediump support
vec4 sampleTextureCatmullRom(const sampler2D tex, const highp vec2 uv, const highp vec2 texSize) {
// We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
// down the sample location to get the exact center of our "starting" texel. The starting texel will be at
// location [1, 1] in the grid, where [0, 0] is the top left corner.
// We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate.
// We'll do this by rounding down the sample location to get the exact center of our "starting"
// texel. The starting texel will be at location [1, 1] in the grid, where [0, 0] is the
// top left corner.
highp vec2 samplePos = uv * texSize;
highp vec2 texPos1 = floor(samplePos - 0.5) + 0.5;
// Compute the fractional offset from our starting texel to our original sample location, which we'll
// feed into the Catmull-Rom spline function to get our filter weights.
// Compute the fractional offset from our starting texel to our original sample location,
// which we'll feed into the Catmull-Rom spline function to get our filter weights.
highp vec2 f = samplePos - texPos1;
highp vec2 f2 = f * f;
highp vec2 f3 = f2 * f;
@@ -200,13 +235,20 @@ vec4 sampleTextureCatmullRom(const sampler2D tex, const highp vec2 uv, const hig
float k3 = w3.x * w12.y;
float k4 = w12.x * w3.y;
vec4 result = textureLod(tex, vec2(texPos12.x, texPos0.y), 0.0) * k0
+ textureLod(tex, vec2(texPos0.x, texPos12.y), 0.0) * k1
+ textureLod(tex, vec2(texPos12.x, texPos12.y), 0.0) * k2
+ textureLod(tex, vec2(texPos3.x, texPos12.y), 0.0) * k3
+ textureLod(tex, vec2(texPos12.x, texPos3.y), 0.0) * k4;
vec4 s[5];
s[0] = textureLod(tex, vec2(texPos12.x, texPos0.y), 0.0);
s[1] = textureLod(tex, vec2(texPos0.x, texPos12.y), 0.0);
s[2] = textureLod(tex, vec2(texPos12.x, texPos12.y), 0.0);
s[3] = textureLod(tex, vec2(texPos3.x, texPos12.y), 0.0);
s[4] = textureLod(tex, vec2(texPos12.x, texPos3.y), 0.0);
result *= 1.0 / (k0 + k1 + k2 + k3 + k4);
vec4 result = k0 * s[0]
+ k1 * s[1]
+ k2 * s[2]
+ k3 * s[3]
+ k4 * s[4];
result *= rcp(k0 + k1 + k2 + k3 + k4);
// we could end-up with negative values
result = max(vec4(0), result);
@@ -242,7 +284,7 @@ void postProcess(inout PostProcessInputs postProcess) {
highp vec2 size = vec2(textureSize(materialParams_color, 0));
highp vec2 p = (floor(uv.xy * size) + 0.5) / size;
vec4 color = textureLod(materialParams_color, p, 0.0);
vec4 filtered = textureLod(materialParams_color, p, 0.0);
vec3 s[9];
if (materialConstants_filterInput || materialConstants_boxClipping != BOX_CLIPPING_NONE) {
@@ -250,16 +292,12 @@ void postProcess(inout PostProcessInputs postProcess) {
s[1] = textureLodOffset(materialParams_color, p, 0.0, ivec2( 0, -1)).rgb;
s[2] = textureLodOffset(materialParams_color, p, 0.0, ivec2( 1, -1)).rgb;
s[3] = textureLodOffset(materialParams_color, p, 0.0, ivec2(-1, 0)).rgb;
s[4] = color.rgb;
s[4] = filtered.rgb;
s[5] = textureLodOffset(materialParams_color, p, 0.0, ivec2( 1, 0)).rgb;
s[6] = textureLodOffset(materialParams_color, p, 0.0, ivec2(-1, 1)).rgb;
s[7] = textureLodOffset(materialParams_color, p, 0.0, ivec2( 0, 1)).rgb;
s[8] = textureLodOffset(materialParams_color, p, 0.0, ivec2( 1, 1)).rgb;
}
if (materialConstants_useYCoCg) {
color.rgb = RGB_YCoCg(color.rgb);
if (materialConstants_filterInput || materialConstants_boxClipping != BOX_CLIPPING_NONE) {
if (materialConstants_useYCoCg) {
for (int i = 0; i < 9; i++) {
s[i] = RGB_YCoCg(s[i]);
}
@@ -267,24 +305,35 @@ void postProcess(inout PostProcessInputs postProcess) {
}
vec2 subPixelOffset = p - uv.xy; // +/- [0.25, 0.25]
float confidence = 0.0;
float confidence = materialConstants_upscaling ? 0.0 : 1.0;
vec4 filtered = color;
if (materialConstants_filterInput) {
// unjitter/filter input
// figure out which set of coeficients to use
int jxp = subPixelOffset.y > 0.0 ? 3 : 0;
int jxn = subPixelOffset.y > 0.0 ? 2 : 1;
int j = subPixelOffset.x > 0.0 ? jxp : jxn;
filtered = vec4(0, 0, 0, color.a);
for (int i = 0; i < 9; i++) {
float w = materialParams.filterWeights[i][j];
filtered.rgb += s[i] * w;
confidence = max(confidence, w);
filtered = vec4(0, 0, 0, filtered.a);
if (materialConstants_upscaling) {
int jxp = subPixelOffset.y > 0.0 ? 3 : 0;
int jxn = subPixelOffset.y > 0.0 ? 2 : 1;
int j = subPixelOffset.x > 0.0 ? jxp : jxn;
for (int i = 0; i < 9; i++) {
float w = materialParams.filterWeights[i][j];
filtered.rgb += s[i] * w;
confidence = max(confidence, w);
}
} else {
for (int i = 0; i < 9; i++) {
float w = materialParams.filterWeights[i][0];
filtered.rgb += s[i] * w;
}
}
} else {
confidence = float(materialParams.jitter.x * subPixelOffset.x > 0.0 &&
materialParams.jitter.y * subPixelOffset.y > 0.0);
if (materialConstants_useYCoCg) {
filtered.rgb = RGB_YCoCg(filtered.rgb);
}
if (materialConstants_upscaling) {
confidence = float(materialParams.jitter.x * subPixelOffset.x > 0.0 &&
materialParams.jitter.y * subPixelOffset.y > 0.0);
}
}
// build the history clamping box
@@ -329,29 +378,30 @@ void postProcess(inout PostProcessInputs postProcess) {
history = clipToBox(materialConstants_boxClipping, boxmin, boxmax, filtered, history);
}
float lumaColor = luma(filtered.rgb);
float lumaHistory = luma(history.rgb);
float alpha = materialParams.alpha * confidence;
if (materialConstants_preventFlickering) {
// [Lottes] prevents flickering by modulating the blend weight by the difference in luma
float lumaColor = luma(filtered.rgb);
float lumaHistory = luma(history.rgb);
float diff = 1.0 - abs(lumaColor - lumaHistory) / (0.001 + max(lumaColor, lumaHistory));
alpha *= diff * diff;
}
// tonemapping for handling HDR
filtered.rgb *= 1.0 / (1.0 + lumaColor);
history.rgb *= 1.0 / (1.0 + lumaHistory);
// go back to RGB space before tonemapping
if (materialConstants_useYCoCg) {
filtered.rgb = YCoCg_RGB(filtered.rgb);
history.rgb = YCoCg_RGB(history.rgb);
}
// tonemap before mixing
filtered.rgb = tonemap(filtered.rgb);
history.rgb = tonemap(history.rgb);
// combine history and current frame
vec4 result = mix(history, filtered, alpha);
// untonemap result
result.rgb *= 1.0 / (1.0 - luma(result.rgb));
if (materialConstants_useYCoCg) {
result.rgb = YCoCg_RGB(result.rgb);
}
result.rgb = untonemap(result.rgb);
#if POST_PROCESS_OPAQUE
// kill the work performed above
+5
View File
@@ -43,6 +43,8 @@ fragment {
#define FSR_RCAS_F 1
#if !POST_PROCESS_OPAQUE
# define FSR_RCAS_PASSTHROUGH_ALPHA
// todo: make this a spec constant
# define FSR_RCAS_DENOISE
#endif
#include "ffx_fsr1.h"
@@ -61,6 +63,9 @@ fragment {
#endif
p, materialParams.RcasCon);
// todo: make this an option
postProcess.color.rgb = max(vec3(0), postProcess.color.rgb);
#if POST_PROCESS_OPAQUE
postProcess.color.a = 1.0;
#endif
+59
View File
@@ -0,0 +1,59 @@
material {
name : shadowmap,
parameters : [
{
type : sampler2dArray,
name : shadowmap,
precision : high
},
{
type : float,
name : power,
precision : high
},
{
type : float2,
name : scale,
},
{
type : int,
name : layer
},
{
type : int,
name : level
},
{
type : int,
name : channel
}
],
variables : [
vertex
],
vertexDomain : device,
depthWrite : false,
depthCulling : false,
domain: postprocess
}
vertex {
void postProcessVertex(inout PostProcessVertexInputs postProcess) {
postProcess.vertex.xy = postProcess.normalizedUV;
postProcess.position.xy = 1.0 + (postProcess.position.xy - 1.0) * materialParams.scale;
}
}
fragment {
void dummy(){}
void postProcess(inout PostProcessInputs postProcess) {
highp vec2 uv = uvToRenderTargetUV(variable_vertex.xy);
highp vec3 p = vec3(uv, float(materialParams.layer));
float m = float(materialParams.level);
highp float c = textureLod(materialParams_shadowmap, p, m)[materialParams.channel];
c = pow(abs(c), materialParams.power);
postProcess.color.rgb = vec3(c);
postProcess.color.a = 1.0;
}
}
@@ -47,6 +47,9 @@ const float kToastDelayDuration = 2.0f;
- (void)createRenderables;
- (void)createLights;
- (void)appWillResignActive:(NSNotification*)notification;
- (void)appDidBecomeActive:(NSNotification*)notification;
@end
@implementation FILViewController {
@@ -73,6 +76,16 @@ const float kToastDelayDuration = 2.0f;
self.title = @"https://google.github.io/filament/remote";
// Observe lifecycle notifications to prevent us from rendering in the background.
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(appWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:nil];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(appDidBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
// Arguments:
// --model <path>
// path to glb or gltf file to load from documents directory
@@ -125,6 +138,14 @@ const float kToastDelayDuration = 2.0f;
[self.view addSubview:_toastLabel];
}
- (void)appWillResignActive:(NSNotification*)notification {
[self stopDisplayLink];
}
- (void)appDidBecomeActive:(NSNotification*)notification {
[self startDisplayLink];
}
- (void)viewWillAppear:(BOOL)animated {
[self startDisplayLink];
}
@@ -330,6 +351,7 @@ const float kToastDelayDuration = 2.0f;
}
- (void)dealloc {
[NSNotificationCenter.defaultCenter removeObserver:self];
delete _server;
delete _automation;
self.modelView.engine->destroy(_indirectLight);
+108
View File
@@ -0,0 +1,108 @@
cmake_minimum_required(VERSION 3.19)
project(astrict)
set(TARGET astrict)
set(PUBLIC_HDR_DIR include)
# ==================================================================================================
# Sources and headers
# ==================================================================================================
set(HDRS
include/astrict/CommonTypes.h
include/astrict/DebugCommon.h
include/astrict/DebugGlsl.h
include/astrict/FromGlsl.h
include/astrict/GlslTypes.h
include/astrict/ToGlsl.h)
set(PRIVATE_HDRS)
set(SRCS
src/DebugCommon.cpp
src/DebugGlsl.cpp
src/FromGlsl.cpp
src/ToGlsl.cpp)
# ==================================================================================================
# Include and target definitions
# ==================================================================================================
include_directories(${PUBLIC_HDR_DIR})
include_directories(${CMAKE_BINARY_DIR})
# astrict
add_library(${TARGET} STATIC ${HDRS} ${PRIVATE_HDRS} ${SRCS})
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
set_target_properties(${TARGET} PROPERTIES FOLDER Libs)
target_link_libraries(${TARGET} backend_headers math utils)
# We are being naughty and accessing private headers here
# For spirv-tools, we're just following glslang's example
target_include_directories(${TARGET} PRIVATE ${spirv-tools_SOURCE_DIR}/include)
# glslang libraries have circular dependencies. To make sure the proper object are part of the link
# we need to force archive re-scan on new symbol dependencies via start/end-group.
# Read more about this here https://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking
if (APPLE OR MSVC)
target_link_libraries(${TARGET} glslang SPIRV SPIRV-Tools-opt spirv-cross-glsl)
else()
target_link_libraries(${TARGET}
-Wl,--start-group glslang SPIRV SPIRV-Tools-opt spirv-cross-glsl -Wl,--end-group)
endif()
# ==================================================================================================
# Compiler flags
# ==================================================================================================
# this must match options enabled in glslang's CMakeLists.txt
target_compile_options(${TARGET} PRIVATE -DAMD_EXTENSIONS -DNV_EXTENSIONS )
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0 /Zc:__cplusplus")
endif()
if (FILAMENT_ENABLE_MATDBG)
add_definitions(-DFILAMENT_ENABLE_MATDBG)
endif()
# ==================================================================================================
# Installation
# ==================================================================================================
# Astrict has dependencies on a bunch of SPIRV-related libraries. To make things simpler, we bundle
# them together into a single shared library and copy this into the installation folder. This
# requires us to explicitly list the dependencies below, as CMake doesn't have a way to recursively
# query dependencies.
set(ASTRICT_DEPS
OGLCompiler
OSDependent
SPIRV
SPIRV-Tools
SPIRV-Tools-opt
astrict
glslang
spirv-cross-core
spirv-cross-glsl
spirv-cross-msl
)
set(ASTRICT_COMBINED_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libastrict_combined.a")
combine_static_libs(astrict "${ASTRICT_COMBINED_OUTPUT}" "${ASTRICT_DEPS}")
set(ASTRICT_LIB_NAME ${CMAKE_STATIC_LIBRARY_PREFIX}astrict${CMAKE_STATIC_LIBRARY_SUFFIX})
install(FILES "${ASTRICT_COMBINED_OUTPUT}" DESTINATION lib/${DIST_DIR} RENAME ${ASTRICT_LIB_NAME})
install(DIRECTORY ${PUBLIC_HDR_DIR}/astrict DESTINATION include)
# ==================================================================================================
# Tests
# ==================================================================================================
project(test_astrict)
set(TARGET test_astrict)
set(SRCS
tests/test_FromGlsl.cpp)
add_executable(${TARGET} ${SRCS})
target_include_directories(${TARGET} PRIVATE src)
target_link_libraries(${TARGET} astrict gtest)
set_target_properties(${TARGET} PROPERTIES FOLDER Tests)
@@ -0,0 +1,86 @@
/*
* Copyright (C) 2024 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_ASTRICT_ASTRICT_BUILDER_H
#define TNT_ASTRICT_ASTRICT_BUILDER_H
#include <set>
#include <unordered_map>
#include <astrict/CommonTypes.h>
namespace astrict {
using StringId = Newtype<int, struct StringIdTag>;
using ExpressionId = Newtype<int, struct ExpressionIdTag>;
using GlobalVariableId = Newtype<int, struct GlobalVariableIdTag>;
using StructId = Newtype<int, struct StructIdTag>;
using FunctionId = Newtype<int, struct FunctionIdTag>;
using LocalVariableId = Newtype<int, struct LocalVariableIdTag>;
template<typename Id, typename Value>
class IdStore {
public:
// Inserts if non-existent.
Id insert(Value value, bool* outWasExtant = nullptr) {
auto it = mMap.find(value);
if (it == mMap.end()) {
Id id(mMap.size() + 1);
mMap[value] = id;
if (outWasExtant) {
*outWasExtant = false;
}
return id;
}
if (outWasExtant) {
*outWasExtant = true;
}
return it->second;
}
std::vector<Value> getFinal() {
std::vector<Value> r(mMap.size());
for (const auto& pair : mMap) {
r[pair.second] = pair.first;
}
return r;
}
private:
std::unordered_map<Value, Id> mMap;
};
using ByteVector = std::vector<uint8_t>;
class AstrictBuilder {
public:
std::vector<ByteVector> build();
private:
IdStore<StringId, std::string> mStrings;
IdStore<ExpressionId, ByteVector> mExpressions;
IdStore<StructId, ByteVector> mStructs;
IdStore<GlobalVariableId, ByteVector> mGlobalSymbols;
IdStore<FunctionId, ByteVector> mFunctions;
IdStore<FunctionId, ByteVector> mFunctionBodies;
std::unordered_map<StructId, std::string> mStructNames;
std::unordered_map<GlobalVariableId, std::string> mGlobalVariableNames;
};
} // namespace astrict
#endif // TNT_ASTRICT_ASTRICT_BUILDER_H
+473
View File
@@ -0,0 +1,473 @@
/*
* Copyright (C) 2024 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_ASTRICT_COMMONTYPES_H
#define TNT_ASTRICT_COMMONTYPES_H
#include <variant>
#include <vector>
namespace astrict {
template<typename T, typename Tag>
class Newtype {
public:
Newtype() : mValue() {}
Newtype(const Newtype<T, Tag> &other) : mValue(other.mValue) {}
Newtype(Newtype<T, Tag> &&other) : mValue(other.mValue) {}
explicit Newtype(T& value) : mValue(value) {}
explicit Newtype(T&& value) : mValue(value) {}
Newtype& operator=(const Newtype<T, Tag>& other) {
mValue = other.mValue;
return *this;
}
Newtype& operator=(Newtype<T, Tag>&& other) {
mValue = other.mValue;
return *this;
}
const T& operator*() const {
return mValue;
}
bool operator==(const Newtype<T, Tag>& o) const {
return mValue == o.mValue;
}
bool operator<(const Newtype<T, Tag>& o) const {
return mValue < o.mValue;
}
private:
T mValue;
};
template<class>
inline constexpr bool always_false_v = false;
} // namespace astrict
namespace std {
template<typename Tag>
struct hash<astrict::Newtype<int, Tag>> {
std::size_t operator()(const astrict::Newtype<int, Tag>& o) const {
return *o;
}
};
template<typename Tag>
struct hash<astrict::Newtype<uint16_t, Tag>> {
std::size_t operator()(const astrict::Newtype<uint16_t, Tag>& o) const {
return *o;
}
};
} // namespace std
namespace astrict {
enum class BranchOperator : uint8_t {
Discard, // Fragment only
TerminateInvocation, // Fragment only
Demote, // Fragment only
TerminateRayEXT, // Any-hit only
IgnoreIntersectionEXT, // Any-hit only
Return,
Break,
Continue,
Case,
Default,
};
// Represents an operation whose syntax differs from a function call. For example, addition,
// equality.
enum class ExpressionOperator : uint8_t {
// Unary
Negative,
LogicalNot,
BitwiseNot,
PostIncrement,
PostDecrement,
PreIncrement,
PreDecrement,
ArrayLength,
// Binary
Add,
Sub,
Mul,
Div,
Mod,
RightShift,
LeftShift,
And,
InclusiveOr,
ExclusiveOr,
Equal,
NotEqual,
LessThan,
GreaterThan,
LessThanEqual,
GreaterThanEqual,
LogicalOr,
LogicalXor,
LogicalAnd,
Index,
Assign,
AddAssign,
SubAssign,
MulAssign,
DivAssign,
ModAssign,
AndAssign,
InclusiveOrAssign,
ExclusiveOrAssign,
LeftShiftAssign,
RightShiftAssign,
// Ternary
Ternary,
// Variadic
Comma,
};
using VariableOrExpressionId = std::variant<GlobalVariableId, LocalVariableId, ExpressionId>;
struct StructMember {
StringId qualifier;
StringId type;
bool operator==(const StructMember& o) const {
return qualifier == o.qualifier
&& type == o.type;
}
};
struct Struct {
StringId qualifier;
std::vector<StructMember> members;
std::vector<StringId> memberNames;
bool operator==(const Struct& o) const {
return qualifier == o.qualifier
&& members == o.members
&& memberNames == o.memberNames;
}
};
struct Type {
std::variant<StringId, StructId> name;
std::optional<StringId> qualifiers;
std::vector<std::size_t> arraySizes;
bool operator==(const Type& o) const {
return name == o.name
&& qualifiers == o.qualifiers
&& arraySizes == o.arraySizes;
}
};
struct Variable {
StringId qualifier;
StringId type;
std::optional<StringId> name;
bool operator==(const Variable& o) const {
return qualifier == o.qualifier
&& type == o.type
&& name == o.name;
}
};
struct ExpressionOperandExpression {
std::variant<ExpressionOperator, FunctionId, StructId> op;
std::vector<VariableOrExpressionId> args;
bool operator==(const ExpressionOperandExpression& o) const {
return op == o.op
&& args == o.args;
}
};
struct VectorSwizzleExpression {
VariableOrExpressionId operand;
uint16_t swizzle;
bool operator==(const VectorSwizzleExpression& o) const {
return operand == o.operand
&& swizzle == o.swizzle;
}
};
struct IndexStructExpression {
VariableOrExpressionId operand;
StructId strukt;
uint16_t index;
bool operator==(const IndexStructExpression& o) const {
return operand == o.operand
&& strukt == o.strukt
&& index == o.index;
}
};
struct LiteralExpression {
std::variant<
bool,
int,
double,
unsigned int> value;
bool operator==(const LiteralExpression& o) const {
return value == o.value;
}
};
using Expression = std::variant<
ExpressionOperandExpression,
VectorSwizzleExpression,
IndexStructExpression,
LiteralExpression>;
struct Function {
FunctionId name;
TypeId returnType;
std::vector<LocalVariableId> parameters;
StatementBlockId body;
std::unordered_map<LocalVariableId, Variable> localVariables;
bool operator==(const Function& o) const {
return name == o.name
&& returnType == o.returnType
&& parameters == o.parameters
&& body == o.body
&& localVariables == o.localVariables;
}
};
struct IfStatement {
VariableOrExpressionId condition;
StatementBlockId thenBlock;
std::optional<StatementBlockId> elseBlock;
bool operator==(const IfStatement& o) const {
return condition == o.condition
&& thenBlock == o.thenBlock
&& elseBlock == o.elseBlock;
}
};
struct SwitchStatement {
VariableOrExpressionId condition;
StatementBlockId body;
bool operator==(const SwitchStatement& o) const {
return condition == o.condition
&& body == o.body;
}
};
struct BranchStatement {
BranchOperator op;
std::optional<VariableOrExpressionId> operand;
bool operator==(const BranchStatement& o) const {
return op == o.op
&& operand == o.operand;
}
};
struct LoopStatement {
VariableOrExpressionId condition;
std::optional<ExpressionId> terminal;
bool testFirst;
StatementBlockId body;
bool operator==(const LoopStatement& o) const {
return condition == o.condition
&& terminal == o.terminal
&& testFirst == o.testFirst
&& body == o.body;
}
};
using Statement = std::variant<
ExpressionId,
IfStatement,
SwitchStatement,
BranchStatement,
LoopStatement>;
template <typename T, typename... Rest>
void hashCombine(std::size_t& seed, const T& v, const Rest&... rest) {
seed ^= std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
(hashCombine(seed, rest), ...);
}
} // namespace astrict
namespace std {
template<>
struct hash<astrict::StructMember> {
std::size_t operator()(const astrict::StructMember& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.name, o.type);
return result;
}
};
template<>
struct hash<astrict::Struct> {
std::size_t operator()(const astrict::Struct& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.name, o.members.size());
for (const auto& member : o.members) {
astrict::hashCombine(result, member);
}
return result;
}
};
template<>
struct hash<astrict::Type> {
std::size_t operator()(const astrict::Type& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.name, o.qualifiers, o.arraySizes.size());
for (const auto& size : o.arraySizes) {
astrict::hashCombine(result, size);
}
return result;
}
};
template<>
struct hash<astrict::Variable> {
std::size_t operator()(const astrict::Variable& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.name, o.type);
return result;
}
};
template<>
struct hash<astrict::ExpressionOperandExpression> {
std::size_t operator()(const astrict::ExpressionOperandExpression& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.op, o.args.size());
for (const auto& arg : o.args) {
astrict::hashCombine(result, arg);
}
return result;
}
};
template<>
struct hash<astrict::IndexStructExpression> {
std::size_t operator()(const astrict::IndexStructExpression& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.operand, o.strukt, o.index);
return result;
}
};
template<>
struct hash<astrict::VectorSwizzleExpression> {
std::size_t operator()(const astrict::VectorSwizzleExpression& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.operand, o.swizzle);
return result;
}
};
template<>
struct hash<astrict::LiteralExpression> {
std::size_t operator()(const astrict::LiteralExpression& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.value);
return result;
}
};
template<>
struct hash<astrict::Function> {
std::size_t operator()(const astrict::Function& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.name, o.returnType, o.body,
o.parameters.size(), o.localVariables.size());
for (const auto& argument : o.parameters) {
astrict::hashCombine(result, argument);
}
for (const auto& symbol : o.localVariables) {
astrict::hashCombine(result, symbol.first, symbol.second);
}
return result;
}
};
template<>
struct hash<astrict::IfStatement> {
std::size_t operator()(const astrict::IfStatement& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.condition, o.thenBlock, o.elseBlock);
return result;
}
};
template<>
struct hash<astrict::SwitchStatement> {
std::size_t operator()(const astrict::SwitchStatement& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.condition, o.body);
return result;
}
};
template<>
struct hash<astrict::BranchStatement> {
std::size_t operator()(const astrict::BranchStatement& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.op, o.operand);
return result;
}
};
template<>
struct hash<astrict::LoopStatement> {
std::size_t operator()(const astrict::LoopStatement& o) const {
std::size_t result = 0;
astrict::hashCombine(result, o.condition, o.terminal, o.testFirst, o.body);
return result;
}
};
template<>
struct hash<std::vector<astrict::Statement>> {
std::size_t operator()(const std::vector<astrict::Statement>& o) const {
std::size_t result = o.size();
for (const auto& statement : o) {
astrict::hashCombine(result, statement);
}
return result;
}
};
} // namespace std
#endif // TNT_ASTRICT_COMMONTYPES_H
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2024 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_ASTRICT_DEBUGCOMMON_H
#define TNT_ASTRICT_DEBUGCOMMON_H
#include <astrict/CommonTypes.h>
namespace astrict {
const char* rValueOperatorToString(ExpressionOperator op);
} // namespace astrict
#endif // TNT_ASTRICT_DEBUGCOMMON_H
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2024 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_ASTRICT_DEBUGGLSL_H
#define TNT_ASTRICT_DEBUGGLSL_H
#include "glslang/Include/intermediate.h"
namespace astrict {
const char* glslangOperatorToString(glslang::TOperator op);
std::string glslangNodeToString(const TIntermNode* node);
std::string glslangLocToString(const glslang::TSourceLoc& loc);
std::string glslangNodeToStringWithLoc(const TIntermNode* node);
} // namespace astrict
#endif // TNT_ASTRICT_DEBUGGLSL_H
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2024 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_ASTRICT_FROMGLSL_H
#define TNT_ASTRICT_FROMGLSL_H
#include <astrict/GlslTypes.h>
#include "glslang/Include/intermediate.h"
namespace astrict {
PackFromGlsl fromGlsl(const glslang::TIntermediate& intermediate);
} // namespace astrict
#endif // TNT_ASTRICT_FROMGLSL_H
+46
View File
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2024 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_ASTRICT_GLSLTYPES_H
#define TNT_ASTRICT_GLSLTYPES_H
#include <astrict/CommonTypes.h>
#include <set>
#include <unordered_map>
#include <vector>
namespace astrict {
struct PackFromGlsl {
int version;
std::unordered_map<StringId, std::string> strings;
std::unordered_map<TypeId, Type> types;
std::unordered_map<StructId, Struct> structs;
std::unordered_map<GlobalVariableId, Variable> globalVariables;
std::unordered_map<ExpressionId, Expression> expressions;
std::unordered_map<FunctionId, std::string> functionNames;
std::unordered_map<StatementBlockId, std::vector<Statement>> statementBlocks;
std::unordered_map<FunctionId, Function> functions;
// The below serve as the roots for conversion to glsl.
std::vector<StructId> structsInOrder;
std::set<FunctionId> functionPrototypes;
std::vector<std::pair<GlobalVariableId, VariableOrExpressionId>> globalSymbolsInOrder;
std::vector<FunctionId> functionsInOrder;
};
};
#endif // TNT_ASTRICT_GLSLTYPES_H
+29
View File
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2024 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_ASTRICT_TOGLSL_H
#define TNT_ASTRICT_TOGLSL_H
#include <astrict/GlslTypes.h>
#include <sstream>
namespace astrict {
void toGlsl(const PackFromGlsl& pack, std::ostringstream& out);
};
#endif // TNT_ASTRICT_TOGLSL_H
+36
View File
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2024 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 <astrict/AstrictBuilder.h>
#include <astrict/CommonTypes.h>
#include <astrict/DebugGlsl.h>
#include <utils/Log.h>
#include <utils/Panic.h>
#include <optional>
#include <set>
#include "ConstantUnion.h"
#include "Types.h"
#include "glslang/MachineIndependent/localintermediate.h"
#include "intermediate.h"
#include "utils/ostream.h"
namespace astrict {
} // namespace astrict
+67
View File
@@ -0,0 +1,67 @@
/*
* Copyright (C) 2024 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 <astrict/DebugCommon.h>
namespace astrict {
const char* rValueOperatorToString(ExpressionOperator op) {
switch(op) {
case ExpressionOperator::Negative: return "Negative";
case ExpressionOperator::LogicalNot: return "LogicalNot";
case ExpressionOperator::BitwiseNot: return "BitwiseNot";
case ExpressionOperator::PostIncrement: return "PostIncrement";
case ExpressionOperator::PostDecrement: return "PostDecrement";
case ExpressionOperator::PreIncrement: return "PreIncrement";
case ExpressionOperator::PreDecrement: return "PreDecrement";
case ExpressionOperator::ArrayLength: return "ArrayLength";
case ExpressionOperator::Add: return "Add";
case ExpressionOperator::Sub: return "Sub";
case ExpressionOperator::Mul: return "Mul";
case ExpressionOperator::Div: return "Div";
case ExpressionOperator::Mod: return "Mod";
case ExpressionOperator::RightShift: return "RightShift";
case ExpressionOperator::LeftShift: return "LeftShift";
case ExpressionOperator::And: return "And";
case ExpressionOperator::InclusiveOr: return "InclusiveOr";
case ExpressionOperator::ExclusiveOr: return "ExclusiveOr";
case ExpressionOperator::Equal: return "Equal";
case ExpressionOperator::NotEqual: return "NotEqual";
case ExpressionOperator::LessThan: return "LessThan";
case ExpressionOperator::GreaterThan: return "GreaterThan";
case ExpressionOperator::LessThanEqual: return "LessThanEqual";
case ExpressionOperator::GreaterThanEqual: return "GreaterThanEqual";
case ExpressionOperator::LogicalOr: return "LogicalOr";
case ExpressionOperator::LogicalXor: return "LogicalXor";
case ExpressionOperator::LogicalAnd: return "LogicalAnd";
case ExpressionOperator::Index: return "Index";
case ExpressionOperator::Assign: return "Assign";
case ExpressionOperator::AddAssign: return "AddAssign";
case ExpressionOperator::SubAssign: return "SubAssign";
case ExpressionOperator::MulAssign: return "MulAssign";
case ExpressionOperator::DivAssign: return "DivAssign";
case ExpressionOperator::ModAssign: return "ModAssign";
case ExpressionOperator::AndAssign: return "AndAssign";
case ExpressionOperator::InclusiveOrAssign: return "InclusiveOrAssign";
case ExpressionOperator::ExclusiveOrAssign: return "ExclusiveOrAssign";
case ExpressionOperator::LeftShiftAssign: return "LeftShiftAssign";
case ExpressionOperator::RightShiftAssign: return "RightShiftAssign";
case ExpressionOperator::Ternary: return "Ternary";
case ExpressionOperator::Comma: return "Comma";
}
}
} // namespace astrict
+925
View File
@@ -0,0 +1,925 @@
/*
* Copyright (C) 2024 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 <astrict/DebugGlsl.h>
namespace astrict {
const char* glslangOperatorToString(glslang::TOperator op) {
using namespace glslang;
switch (op) {
case EOpNull: return "EOpNull";
case EOpSequence: return "EOpSequence";
case EOpScope: return "EOpScope";
case EOpLinkerObjects: return "EOpLinkerObjects";
case EOpFunctionCall: return "EOpFunctionCall";
case EOpFunction: return "EOpFunction";
case EOpParameters: return "EOpParameters";
case EOpSpirvInst: return "EOpSpirvInst";
case EOpNegative: return "EOpNegative";
case EOpLogicalNot: return "EOpLogicalNot";
case EOpVectorLogicalNot: return "EOpVectorLogicalNot";
case EOpBitwiseNot: return "EOpBitwiseNot";
case EOpPostIncrement: return "EOpPostIncrement";
case EOpPostDecrement: return "EOpPostDecrement";
case EOpPreIncrement: return "EOpPreIncrement";
case EOpPreDecrement: return "EOpPreDecrement";
case EOpCopyObject: return "EOpCopyObject";
case EOpDeclare: return "EOpDeclare";
case EOpConvInt8ToBool: return "EOpConvInt8ToBool";
case EOpConvUint8ToBool: return "EOpConvUint8ToBool";
case EOpConvInt16ToBool: return "EOpConvInt16ToBool";
case EOpConvUint16ToBool: return "EOpConvUint16ToBool";
case EOpConvIntToBool: return "EOpConvIntToBool";
case EOpConvUintToBool: return "EOpConvUintToBool";
case EOpConvInt64ToBool: return "EOpConvInt64ToBool";
case EOpConvUint64ToBool: return "EOpConvUint64ToBool";
case EOpConvFloat16ToBool: return "EOpConvFloat16ToBool";
case EOpConvFloatToBool: return "EOpConvFloatToBool";
case EOpConvDoubleToBool: return "EOpConvDoubleToBool";
case EOpConvBoolToInt8: return "EOpConvBoolToInt8";
case EOpConvBoolToUint8: return "EOpConvBoolToUint8";
case EOpConvBoolToInt16: return "EOpConvBoolToInt16";
case EOpConvBoolToUint16: return "EOpConvBoolToUint16";
case EOpConvBoolToInt: return "EOpConvBoolToInt";
case EOpConvBoolToUint: return "EOpConvBoolToUint";
case EOpConvBoolToInt64: return "EOpConvBoolToInt64";
case EOpConvBoolToUint64: return "EOpConvBoolToUint64";
case EOpConvBoolToFloat16: return "EOpConvBoolToFloat16";
case EOpConvBoolToFloat: return "EOpConvBoolToFloat";
case EOpConvBoolToDouble: return "EOpConvBoolToDouble";
case EOpConvInt8ToInt16: return "EOpConvInt8ToInt16";
case EOpConvInt8ToInt: return "EOpConvInt8ToInt";
case EOpConvInt8ToInt64: return "EOpConvInt8ToInt64";
case EOpConvInt8ToUint8: return "EOpConvInt8ToUint8";
case EOpConvInt8ToUint16: return "EOpConvInt8ToUint16";
case EOpConvInt8ToUint: return "EOpConvInt8ToUint";
case EOpConvInt8ToUint64: return "EOpConvInt8ToUint64";
case EOpConvUint8ToInt8: return "EOpConvUint8ToInt8";
case EOpConvUint8ToInt16: return "EOpConvUint8ToInt16";
case EOpConvUint8ToInt: return "EOpConvUint8ToInt";
case EOpConvUint8ToInt64: return "EOpConvUint8ToInt64";
case EOpConvUint8ToUint16: return "EOpConvUint8ToUint16";
case EOpConvUint8ToUint: return "EOpConvUint8ToUint";
case EOpConvUint8ToUint64: return "EOpConvUint8ToUint64";
case EOpConvInt8ToFloat16: return "EOpConvInt8ToFloat16";
case EOpConvInt8ToFloat: return "EOpConvInt8ToFloat";
case EOpConvInt8ToDouble: return "EOpConvInt8ToDouble";
case EOpConvUint8ToFloat16: return "EOpConvUint8ToFloat16";
case EOpConvUint8ToFloat: return "EOpConvUint8ToFloat";
case EOpConvUint8ToDouble: return "EOpConvUint8ToDouble";
case EOpConvInt16ToInt8: return "EOpConvInt16ToInt8";
case EOpConvInt16ToInt: return "EOpConvInt16ToInt";
case EOpConvInt16ToInt64: return "EOpConvInt16ToInt64";
case EOpConvInt16ToUint8: return "EOpConvInt16ToUint8";
case EOpConvInt16ToUint16: return "EOpConvInt16ToUint16";
case EOpConvInt16ToUint: return "EOpConvInt16ToUint";
case EOpConvInt16ToUint64: return "EOpConvInt16ToUint64";
case EOpConvUint16ToInt8: return "EOpConvUint16ToInt8";
case EOpConvUint16ToInt16: return "EOpConvUint16ToInt16";
case EOpConvUint16ToInt: return "EOpConvUint16ToInt";
case EOpConvUint16ToInt64: return "EOpConvUint16ToInt64";
case EOpConvUint16ToUint8: return "EOpConvUint16ToUint8";
case EOpConvUint16ToUint: return "EOpConvUint16ToUint";
case EOpConvUint16ToUint64: return "EOpConvUint16ToUint64";
case EOpConvInt16ToFloat16: return "EOpConvInt16ToFloat16";
case EOpConvInt16ToFloat: return "EOpConvInt16ToFloat";
case EOpConvInt16ToDouble: return "EOpConvInt16ToDouble";
case EOpConvUint16ToFloat16: return "EOpConvUint16ToFloat16";
case EOpConvUint16ToFloat: return "EOpConvUint16ToFloat";
case EOpConvUint16ToDouble: return "EOpConvUint16ToDouble";
case EOpConvIntToInt8: return "EOpConvIntToInt8";
case EOpConvIntToInt16: return "EOpConvIntToInt16";
case EOpConvIntToInt64: return "EOpConvIntToInt64";
case EOpConvIntToUint8: return "EOpConvIntToUint8";
case EOpConvIntToUint16: return "EOpConvIntToUint16";
case EOpConvIntToUint: return "EOpConvIntToUint";
case EOpConvIntToUint64: return "EOpConvIntToUint64";
case EOpConvUintToInt8: return "EOpConvUintToInt8";
case EOpConvUintToInt16: return "EOpConvUintToInt16";
case EOpConvUintToInt: return "EOpConvUintToInt";
case EOpConvUintToInt64: return "EOpConvUintToInt64";
case EOpConvUintToUint8: return "EOpConvUintToUint8";
case EOpConvUintToUint16: return "EOpConvUintToUint16";
case EOpConvUintToUint64: return "EOpConvUintToUint64";
case EOpConvIntToFloat16: return "EOpConvIntToFloat16";
case EOpConvIntToFloat: return "EOpConvIntToFloat";
case EOpConvIntToDouble: return "EOpConvIntToDouble";
case EOpConvUintToFloat16: return "EOpConvUintToFloat16";
case EOpConvUintToFloat: return "EOpConvUintToFloat";
case EOpConvUintToDouble: return "EOpConvUintToDouble";
case EOpConvInt64ToInt8: return "EOpConvInt64ToInt8";
case EOpConvInt64ToInt16: return "EOpConvInt64ToInt16";
case EOpConvInt64ToInt: return "EOpConvInt64ToInt";
case EOpConvInt64ToUint8: return "EOpConvInt64ToUint8";
case EOpConvInt64ToUint16: return "EOpConvInt64ToUint16";
case EOpConvInt64ToUint: return "EOpConvInt64ToUint";
case EOpConvInt64ToUint64: return "EOpConvInt64ToUint64";
case EOpConvUint64ToInt8: return "EOpConvUint64ToInt8";
case EOpConvUint64ToInt16: return "EOpConvUint64ToInt16";
case EOpConvUint64ToInt: return "EOpConvUint64ToInt";
case EOpConvUint64ToInt64: return "EOpConvUint64ToInt64";
case EOpConvUint64ToUint8: return "EOpConvUint64ToUint8";
case EOpConvUint64ToUint16: return "EOpConvUint64ToUint16";
case EOpConvUint64ToUint: return "EOpConvUint64ToUint";
case EOpConvInt64ToFloat16: return "EOpConvInt64ToFloat16";
case EOpConvInt64ToFloat: return "EOpConvInt64ToFloat";
case EOpConvInt64ToDouble: return "EOpConvInt64ToDouble";
case EOpConvUint64ToFloat16: return "EOpConvUint64ToFloat16";
case EOpConvUint64ToFloat: return "EOpConvUint64ToFloat";
case EOpConvUint64ToDouble: return "EOpConvUint64ToDouble";
case EOpConvFloat16ToInt8: return "EOpConvFloat16ToInt8";
case EOpConvFloat16ToInt16: return "EOpConvFloat16ToInt16";
case EOpConvFloat16ToInt: return "EOpConvFloat16ToInt";
case EOpConvFloat16ToInt64: return "EOpConvFloat16ToInt64";
case EOpConvFloat16ToUint8: return "EOpConvFloat16ToUint8";
case EOpConvFloat16ToUint16: return "EOpConvFloat16ToUint16";
case EOpConvFloat16ToUint: return "EOpConvFloat16ToUint";
case EOpConvFloat16ToUint64: return "EOpConvFloat16ToUint64";
case EOpConvFloat16ToFloat: return "EOpConvFloat16ToFloat";
case EOpConvFloat16ToDouble: return "EOpConvFloat16ToDouble";
case EOpConvFloatToInt8: return "EOpConvFloatToInt8";
case EOpConvFloatToInt16: return "EOpConvFloatToInt16";
case EOpConvFloatToInt: return "EOpConvFloatToInt";
case EOpConvFloatToInt64: return "EOpConvFloatToInt64";
case EOpConvFloatToUint8: return "EOpConvFloatToUint8";
case EOpConvFloatToUint16: return "EOpConvFloatToUint16";
case EOpConvFloatToUint: return "EOpConvFloatToUint";
case EOpConvFloatToUint64: return "EOpConvFloatToUint64";
case EOpConvFloatToFloat16: return "EOpConvFloatToFloat16";
case EOpConvFloatToDouble: return "EOpConvFloatToDouble";
case EOpConvDoubleToInt8: return "EOpConvDoubleToInt8";
case EOpConvDoubleToInt16: return "EOpConvDoubleToInt16";
case EOpConvDoubleToInt: return "EOpConvDoubleToInt";
case EOpConvDoubleToInt64: return "EOpConvDoubleToInt64";
case EOpConvDoubleToUint8: return "EOpConvDoubleToUint8";
case EOpConvDoubleToUint16: return "EOpConvDoubleToUint16";
case EOpConvDoubleToUint: return "EOpConvDoubleToUint";
case EOpConvDoubleToUint64: return "EOpConvDoubleToUint64";
case EOpConvDoubleToFloat16: return "EOpConvDoubleToFloat16";
case EOpConvDoubleToFloat: return "EOpConvDoubleToFloat";
case EOpConvUint64ToPtr: return "EOpConvUint64ToPtr";
case EOpConvPtrToUint64: return "EOpConvPtrToUint64";
case EOpConvUvec2ToPtr: return "EOpConvUvec2ToPtr";
case EOpConvPtrToUvec2: return "EOpConvPtrToUvec2";
case EOpConvUint64ToAccStruct: return "EOpConvUint64ToAccStruct";
case EOpConvUvec2ToAccStruct: return "EOpConvUvec2ToAccStruct";
case EOpAdd: return "EOpAdd";
case EOpSub: return "EOpSub";
case EOpMul: return "EOpMul";
case EOpDiv: return "EOpDiv";
case EOpMod: return "EOpMod";
case EOpRightShift: return "EOpRightShift";
case EOpLeftShift: return "EOpLeftShift";
case EOpAnd: return "EOpAnd";
case EOpInclusiveOr: return "EOpInclusiveOr";
case EOpExclusiveOr: return "EOpExclusiveOr";
case EOpEqual: return "EOpEqual";
case EOpNotEqual: return "EOpNotEqual";
case EOpVectorEqual: return "EOpVectorEqual";
case EOpVectorNotEqual: return "EOpVectorNotEqual";
case EOpLessThan: return "EOpLessThan";
case EOpGreaterThan: return "EOpGreaterThan";
case EOpLessThanEqual: return "EOpLessThanEqual";
case EOpGreaterThanEqual: return "EOpGreaterThanEqual";
case EOpComma: return "EOpComma";
case EOpVectorTimesScalar: return "EOpVectorTimesScalar";
case EOpVectorTimesMatrix: return "EOpVectorTimesMatrix";
case EOpMatrixTimesVector: return "EOpMatrixTimesVector";
case EOpMatrixTimesScalar: return "EOpMatrixTimesScalar";
case EOpLogicalOr: return "EOpLogicalOr";
case EOpLogicalXor: return "EOpLogicalXor";
case EOpLogicalAnd: return "EOpLogicalAnd";
case EOpIndexDirect: return "EOpIndexDirect";
case EOpIndexIndirect: return "EOpIndexIndirect";
case EOpIndexDirectStruct: return "EOpIndexDirectStruct";
case EOpVectorSwizzle: return "EOpVectorSwizzle";
case EOpMethod: return "EOpMethod";
case EOpScoping: return "EOpScoping";
case EOpRadians: return "EOpRadians";
case EOpDegrees: return "EOpDegrees";
case EOpSin: return "EOpSin";
case EOpCos: return "EOpCos";
case EOpTan: return "EOpTan";
case EOpAsin: return "EOpAsin";
case EOpAcos: return "EOpAcos";
case EOpAtan: return "EOpAtan";
case EOpSinh: return "EOpSinh";
case EOpCosh: return "EOpCosh";
case EOpTanh: return "EOpTanh";
case EOpAsinh: return "EOpAsinh";
case EOpAcosh: return "EOpAcosh";
case EOpAtanh: return "EOpAtanh";
case EOpPow: return "EOpPow";
case EOpExp: return "EOpExp";
case EOpLog: return "EOpLog";
case EOpExp2: return "EOpExp2";
case EOpLog2: return "EOpLog2";
case EOpSqrt: return "EOpSqrt";
case EOpInverseSqrt: return "EOpInverseSqrt";
case EOpAbs: return "EOpAbs";
case EOpSign: return "EOpSign";
case EOpFloor: return "EOpFloor";
case EOpTrunc: return "EOpTrunc";
case EOpRound: return "EOpRound";
case EOpRoundEven: return "EOpRoundEven";
case EOpCeil: return "EOpCeil";
case EOpFract: return "EOpFract";
case EOpModf: return "EOpModf";
case EOpMin: return "EOpMin";
case EOpMax: return "EOpMax";
case EOpClamp: return "EOpClamp";
case EOpMix: return "EOpMix";
case EOpStep: return "EOpStep";
case EOpSmoothStep: return "EOpSmoothStep";
case EOpIsNan: return "EOpIsNan";
case EOpIsInf: return "EOpIsInf";
case EOpFma: return "EOpFma";
case EOpFrexp: return "EOpFrexp";
case EOpLdexp: return "EOpLdexp";
case EOpFloatBitsToInt: return "EOpFloatBitsToInt";
case EOpFloatBitsToUint: return "EOpFloatBitsToUint";
case EOpIntBitsToFloat: return "EOpIntBitsToFloat";
case EOpUintBitsToFloat: return "EOpUintBitsToFloat";
case EOpDoubleBitsToInt64: return "EOpDoubleBitsToInt64";
case EOpDoubleBitsToUint64: return "EOpDoubleBitsToUint64";
case EOpInt64BitsToDouble: return "EOpInt64BitsToDouble";
case EOpUint64BitsToDouble: return "EOpUint64BitsToDouble";
case EOpFloat16BitsToInt16: return "EOpFloat16BitsToInt16";
case EOpFloat16BitsToUint16: return "EOpFloat16BitsToUint16";
case EOpInt16BitsToFloat16: return "EOpInt16BitsToFloat16";
case EOpUint16BitsToFloat16: return "EOpUint16BitsToFloat16";
case EOpPackSnorm2x16: return "EOpPackSnorm2x16";
case EOpUnpackSnorm2x16: return "EOpUnpackSnorm2x16";
case EOpPackUnorm2x16: return "EOpPackUnorm2x16";
case EOpUnpackUnorm2x16: return "EOpUnpackUnorm2x16";
case EOpPackSnorm4x8: return "EOpPackSnorm4x8";
case EOpUnpackSnorm4x8: return "EOpUnpackSnorm4x8";
case EOpPackUnorm4x8: return "EOpPackUnorm4x8";
case EOpUnpackUnorm4x8: return "EOpUnpackUnorm4x8";
case EOpPackHalf2x16: return "EOpPackHalf2x16";
case EOpUnpackHalf2x16: return "EOpUnpackHalf2x16";
case EOpPackDouble2x32: return "EOpPackDouble2x32";
case EOpUnpackDouble2x32: return "EOpUnpackDouble2x32";
case EOpPackInt2x32: return "EOpPackInt2x32";
case EOpUnpackInt2x32: return "EOpUnpackInt2x32";
case EOpPackUint2x32: return "EOpPackUint2x32";
case EOpUnpackUint2x32: return "EOpUnpackUint2x32";
case EOpPackFloat2x16: return "EOpPackFloat2x16";
case EOpUnpackFloat2x16: return "EOpUnpackFloat2x16";
case EOpPackInt2x16: return "EOpPackInt2x16";
case EOpUnpackInt2x16: return "EOpUnpackInt2x16";
case EOpPackUint2x16: return "EOpPackUint2x16";
case EOpUnpackUint2x16: return "EOpUnpackUint2x16";
case EOpPackInt4x16: return "EOpPackInt4x16";
case EOpUnpackInt4x16: return "EOpUnpackInt4x16";
case EOpPackUint4x16: return "EOpPackUint4x16";
case EOpUnpackUint4x16: return "EOpUnpackUint4x16";
case EOpPack16: return "EOpPack16";
case EOpPack32: return "EOpPack32";
case EOpPack64: return "EOpPack64";
case EOpUnpack32: return "EOpUnpack32";
case EOpUnpack16: return "EOpUnpack16";
case EOpUnpack8: return "EOpUnpack8";
case EOpLength: return "EOpLength";
case EOpDistance: return "EOpDistance";
case EOpDot: return "EOpDot";
case EOpCross: return "EOpCross";
case EOpNormalize: return "EOpNormalize";
case EOpFaceForward: return "EOpFaceForward";
case EOpReflect: return "EOpReflect";
case EOpRefract: return "EOpRefract";
case EOpMin3: return "EOpMin3";
case EOpMax3: return "EOpMax3";
case EOpMid3: return "EOpMid3";
case EOpDPdx: return "EOpDPdx";
case EOpDPdy: return "EOpDPdy";
case EOpFwidth: return "EOpFwidth";
case EOpDPdxFine: return "EOpDPdxFine";
case EOpDPdyFine: return "EOpDPdyFine";
case EOpFwidthFine: return "EOpFwidthFine";
case EOpDPdxCoarse: return "EOpDPdxCoarse";
case EOpDPdyCoarse: return "EOpDPdyCoarse";
case EOpFwidthCoarse: return "EOpFwidthCoarse";
case EOpInterpolateAtCentroid: return "EOpInterpolateAtCentroid";
case EOpInterpolateAtSample: return "EOpInterpolateAtSample";
case EOpInterpolateAtOffset: return "EOpInterpolateAtOffset";
case EOpInterpolateAtVertex: return "EOpInterpolateAtVertex";
case EOpMatrixTimesMatrix: return "EOpMatrixTimesMatrix";
case EOpOuterProduct: return "EOpOuterProduct";
case EOpDeterminant: return "EOpDeterminant";
case EOpMatrixInverse: return "EOpMatrixInverse";
case EOpTranspose: return "EOpTranspose";
case EOpFtransform: return "EOpFtransform";
case EOpNoise: return "EOpNoise";
case EOpEmitVertex: return "EOpEmitVertex";
case EOpEndPrimitive: return "EOpEndPrimitive";
case EOpEmitStreamVertex: return "EOpEmitStreamVertex";
case EOpEndStreamPrimitive: return "EOpEndStreamPrimitive";
case EOpBarrier: return "EOpBarrier";
case EOpMemoryBarrier: return "EOpMemoryBarrier";
case EOpMemoryBarrierAtomicCounter: return "EOpMemoryBarrierAtomicCounter";
case EOpMemoryBarrierBuffer: return "EOpMemoryBarrierBuffer";
case EOpMemoryBarrierImage: return "EOpMemoryBarrierImage";
case EOpMemoryBarrierShared: return "EOpMemoryBarrierShared";
case EOpGroupMemoryBarrier: return "EOpGroupMemoryBarrier";
case EOpBallot: return "EOpBallot";
case EOpReadInvocation: return "EOpReadInvocation";
case EOpReadFirstInvocation: return "EOpReadFirstInvocation";
case EOpAnyInvocation: return "EOpAnyInvocation";
case EOpAllInvocations: return "EOpAllInvocations";
case EOpAllInvocationsEqual: return "EOpAllInvocationsEqual";
case EOpSubgroupGuardStart: return "EOpSubgroupGuardStart";
case EOpSubgroupBarrier: return "EOpSubgroupBarrier";
case EOpSubgroupMemoryBarrier: return "EOpSubgroupMemoryBarrier";
case EOpSubgroupMemoryBarrierBuffer: return "EOpSubgroupMemoryBarrierBuffer";
case EOpSubgroupMemoryBarrierImage: return "EOpSubgroupMemoryBarrierImage";
case EOpSubgroupMemoryBarrierShared: return "EOpSubgroupMemoryBarrierShared";
case EOpSubgroupElect: return "EOpSubgroupElect";
case EOpSubgroupAll: return "EOpSubgroupAll";
case EOpSubgroupAny: return "EOpSubgroupAny";
case EOpSubgroupAllEqual: return "EOpSubgroupAllEqual";
case EOpSubgroupBroadcast: return "EOpSubgroupBroadcast";
case EOpSubgroupBroadcastFirst: return "EOpSubgroupBroadcastFirst";
case EOpSubgroupBallot: return "EOpSubgroupBallot";
case EOpSubgroupInverseBallot: return "EOpSubgroupInverseBallot";
case EOpSubgroupBallotBitExtract: return "EOpSubgroupBallotBitExtract";
case EOpSubgroupBallotBitCount: return "EOpSubgroupBallotBitCount";
case EOpSubgroupBallotInclusiveBitCount: return "EOpSubgroupBallotInclusiveBitCount";
case EOpSubgroupBallotExclusiveBitCount: return "EOpSubgroupBallotExclusiveBitCount";
case EOpSubgroupBallotFindLSB: return "EOpSubgroupBallotFindLSB";
case EOpSubgroupBallotFindMSB: return "EOpSubgroupBallotFindMSB";
case EOpSubgroupShuffle: return "EOpSubgroupShuffle";
case EOpSubgroupShuffleXor: return "EOpSubgroupShuffleXor";
case EOpSubgroupShuffleUp: return "EOpSubgroupShuffleUp";
case EOpSubgroupShuffleDown: return "EOpSubgroupShuffleDown";
case EOpSubgroupAdd: return "EOpSubgroupAdd";
case EOpSubgroupMul: return "EOpSubgroupMul";
case EOpSubgroupMin: return "EOpSubgroupMin";
case EOpSubgroupMax: return "EOpSubgroupMax";
case EOpSubgroupAnd: return "EOpSubgroupAnd";
case EOpSubgroupOr: return "EOpSubgroupOr";
case EOpSubgroupXor: return "EOpSubgroupXor";
case EOpSubgroupInclusiveAdd: return "EOpSubgroupInclusiveAdd";
case EOpSubgroupInclusiveMul: return "EOpSubgroupInclusiveMul";
case EOpSubgroupInclusiveMin: return "EOpSubgroupInclusiveMin";
case EOpSubgroupInclusiveMax: return "EOpSubgroupInclusiveMax";
case EOpSubgroupInclusiveAnd: return "EOpSubgroupInclusiveAnd";
case EOpSubgroupInclusiveOr: return "EOpSubgroupInclusiveOr";
case EOpSubgroupInclusiveXor: return "EOpSubgroupInclusiveXor";
case EOpSubgroupExclusiveAdd: return "EOpSubgroupExclusiveAdd";
case EOpSubgroupExclusiveMul: return "EOpSubgroupExclusiveMul";
case EOpSubgroupExclusiveMin: return "EOpSubgroupExclusiveMin";
case EOpSubgroupExclusiveMax: return "EOpSubgroupExclusiveMax";
case EOpSubgroupExclusiveAnd: return "EOpSubgroupExclusiveAnd";
case EOpSubgroupExclusiveOr: return "EOpSubgroupExclusiveOr";
case EOpSubgroupExclusiveXor: return "EOpSubgroupExclusiveXor";
case EOpSubgroupClusteredAdd: return "EOpSubgroupClusteredAdd";
case EOpSubgroupClusteredMul: return "EOpSubgroupClusteredMul";
case EOpSubgroupClusteredMin: return "EOpSubgroupClusteredMin";
case EOpSubgroupClusteredMax: return "EOpSubgroupClusteredMax";
case EOpSubgroupClusteredAnd: return "EOpSubgroupClusteredAnd";
case EOpSubgroupClusteredOr: return "EOpSubgroupClusteredOr";
case EOpSubgroupClusteredXor: return "EOpSubgroupClusteredXor";
case EOpSubgroupQuadBroadcast: return "EOpSubgroupQuadBroadcast";
case EOpSubgroupQuadSwapHorizontal: return "EOpSubgroupQuadSwapHorizontal";
case EOpSubgroupQuadSwapVertical: return "EOpSubgroupQuadSwapVertical";
case EOpSubgroupQuadSwapDiagonal: return "EOpSubgroupQuadSwapDiagonal";
case EOpSubgroupPartition: return "EOpSubgroupPartition";
case EOpSubgroupPartitionedAdd: return "EOpSubgroupPartitionedAdd";
case EOpSubgroupPartitionedMul: return "EOpSubgroupPartitionedMul";
case EOpSubgroupPartitionedMin: return "EOpSubgroupPartitionedMin";
case EOpSubgroupPartitionedMax: return "EOpSubgroupPartitionedMax";
case EOpSubgroupPartitionedAnd: return "EOpSubgroupPartitionedAnd";
case EOpSubgroupPartitionedOr: return "EOpSubgroupPartitionedOr";
case EOpSubgroupPartitionedXor: return "EOpSubgroupPartitionedXor";
case EOpSubgroupPartitionedInclusiveAdd: return "EOpSubgroupPartitionedInclusiveAdd";
case EOpSubgroupPartitionedInclusiveMul: return "EOpSubgroupPartitionedInclusiveMul";
case EOpSubgroupPartitionedInclusiveMin: return "EOpSubgroupPartitionedInclusiveMin";
case EOpSubgroupPartitionedInclusiveMax: return "EOpSubgroupPartitionedInclusiveMax";
case EOpSubgroupPartitionedInclusiveAnd: return "EOpSubgroupPartitionedInclusiveAnd";
case EOpSubgroupPartitionedInclusiveOr: return "EOpSubgroupPartitionedInclusiveOr";
case EOpSubgroupPartitionedInclusiveXor: return "EOpSubgroupPartitionedInclusiveXor";
case EOpSubgroupPartitionedExclusiveAdd: return "EOpSubgroupPartitionedExclusiveAdd";
case EOpSubgroupPartitionedExclusiveMul: return "EOpSubgroupPartitionedExclusiveMul";
case EOpSubgroupPartitionedExclusiveMin: return "EOpSubgroupPartitionedExclusiveMin";
case EOpSubgroupPartitionedExclusiveMax: return "EOpSubgroupPartitionedExclusiveMax";
case EOpSubgroupPartitionedExclusiveAnd: return "EOpSubgroupPartitionedExclusiveAnd";
case EOpSubgroupPartitionedExclusiveOr: return "EOpSubgroupPartitionedExclusiveOr";
case EOpSubgroupPartitionedExclusiveXor: return "EOpSubgroupPartitionedExclusiveXor";
case EOpSubgroupGuardStop: return "EOpSubgroupGuardStop";
case EOpMinInvocations: return "EOpMinInvocations";
case EOpMaxInvocations: return "EOpMaxInvocations";
case EOpAddInvocations: return "EOpAddInvocations";
case EOpMinInvocationsNonUniform: return "EOpMinInvocationsNonUniform";
case EOpMaxInvocationsNonUniform: return "EOpMaxInvocationsNonUniform";
case EOpAddInvocationsNonUniform: return "EOpAddInvocationsNonUniform";
case EOpMinInvocationsInclusiveScan: return "EOpMinInvocationsInclusiveScan";
case EOpMaxInvocationsInclusiveScan: return "EOpMaxInvocationsInclusiveScan";
case EOpAddInvocationsInclusiveScan: return "EOpAddInvocationsInclusiveScan";
case EOpMinInvocationsInclusiveScanNonUniform: return "EOpMinInvocationsInclusiveScanNonUniform";
case EOpMaxInvocationsInclusiveScanNonUniform: return "EOpMaxInvocationsInclusiveScanNonUniform";
case EOpAddInvocationsInclusiveScanNonUniform: return "EOpAddInvocationsInclusiveScanNonUniform";
case EOpMinInvocationsExclusiveScan: return "EOpMinInvocationsExclusiveScan";
case EOpMaxInvocationsExclusiveScan: return "EOpMaxInvocationsExclusiveScan";
case EOpAddInvocationsExclusiveScan: return "EOpAddInvocationsExclusiveScan";
case EOpMinInvocationsExclusiveScanNonUniform: return "EOpMinInvocationsExclusiveScanNonUniform";
case EOpMaxInvocationsExclusiveScanNonUniform: return "EOpMaxInvocationsExclusiveScanNonUniform";
case EOpAddInvocationsExclusiveScanNonUniform: return "EOpAddInvocationsExclusiveScanNonUniform";
case EOpSwizzleInvocations: return "EOpSwizzleInvocations";
case EOpSwizzleInvocationsMasked: return "EOpSwizzleInvocationsMasked";
case EOpWriteInvocation: return "EOpWriteInvocation";
case EOpMbcnt: return "EOpMbcnt";
case EOpCubeFaceIndex: return "EOpCubeFaceIndex";
case EOpCubeFaceCoord: return "EOpCubeFaceCoord";
case EOpTime: return "EOpTime";
case EOpAtomicAdd: return "EOpAtomicAdd";
case EOpAtomicSubtract: return "EOpAtomicSubtract";
case EOpAtomicMin: return "EOpAtomicMin";
case EOpAtomicMax: return "EOpAtomicMax";
case EOpAtomicAnd: return "EOpAtomicAnd";
case EOpAtomicOr: return "EOpAtomicOr";
case EOpAtomicXor: return "EOpAtomicXor";
case EOpAtomicExchange: return "EOpAtomicExchange";
case EOpAtomicCompSwap: return "EOpAtomicCompSwap";
case EOpAtomicLoad: return "EOpAtomicLoad";
case EOpAtomicStore: return "EOpAtomicStore";
case EOpAtomicCounterIncrement: return "EOpAtomicCounterIncrement";
case EOpAtomicCounterDecrement: return "EOpAtomicCounterDecrement";
case EOpAtomicCounter: return "EOpAtomicCounter";
case EOpAtomicCounterAdd: return "EOpAtomicCounterAdd";
case EOpAtomicCounterSubtract: return "EOpAtomicCounterSubtract";
case EOpAtomicCounterMin: return "EOpAtomicCounterMin";
case EOpAtomicCounterMax: return "EOpAtomicCounterMax";
case EOpAtomicCounterAnd: return "EOpAtomicCounterAnd";
case EOpAtomicCounterOr: return "EOpAtomicCounterOr";
case EOpAtomicCounterXor: return "EOpAtomicCounterXor";
case EOpAtomicCounterExchange: return "EOpAtomicCounterExchange";
case EOpAtomicCounterCompSwap: return "EOpAtomicCounterCompSwap";
case EOpAny: return "EOpAny";
case EOpAll: return "EOpAll";
case EOpCooperativeMatrixLoad: return "EOpCooperativeMatrixLoad";
case EOpCooperativeMatrixStore: return "EOpCooperativeMatrixStore";
case EOpCooperativeMatrixMulAdd: return "EOpCooperativeMatrixMulAdd";
case EOpCooperativeMatrixLoadNV: return "EOpCooperativeMatrixLoadNV";
case EOpCooperativeMatrixStoreNV: return "EOpCooperativeMatrixStoreNV";
case EOpCooperativeMatrixMulAddNV: return "EOpCooperativeMatrixMulAddNV";
case EOpBeginInvocationInterlock: return "EOpBeginInvocationInterlock";
case EOpEndInvocationInterlock: return "EOpEndInvocationInterlock";
case EOpIsHelperInvocation: return "EOpIsHelperInvocation";
case EOpDebugPrintf: return "EOpDebugPrintf";
case EOpKill: return "EOpKill";
case EOpTerminateInvocation: return "EOpTerminateInvocation";
case EOpDemote: return "EOpDemote";
case EOpTerminateRayKHR: return "EOpTerminateRayKHR";
case EOpIgnoreIntersectionKHR: return "EOpIgnoreIntersectionKHR";
case EOpReturn: return "EOpReturn";
case EOpBreak: return "EOpBreak";
case EOpContinue: return "EOpContinue";
case EOpCase: return "EOpCase";
case EOpDefault: return "EOpDefault";
case EOpConstructGuardStart: return "EOpConstructGuardStart";
case EOpConstructInt: return "EOpConstructInt";
case EOpConstructUint: return "EOpConstructUint";
case EOpConstructInt8: return "EOpConstructInt8";
case EOpConstructUint8: return "EOpConstructUint8";
case EOpConstructInt16: return "EOpConstructInt16";
case EOpConstructUint16: return "EOpConstructUint16";
case EOpConstructInt64: return "EOpConstructInt64";
case EOpConstructUint64: return "EOpConstructUint64";
case EOpConstructBool: return "EOpConstructBool";
case EOpConstructFloat: return "EOpConstructFloat";
case EOpConstructDouble: return "EOpConstructDouble";
case EOpConstructVec2: return "EOpConstructVec2";
case EOpConstructVec3: return "EOpConstructVec3";
case EOpConstructVec4: return "EOpConstructVec4";
case EOpConstructMat2x2: return "EOpConstructMat2x2";
case EOpConstructMat2x3: return "EOpConstructMat2x3";
case EOpConstructMat2x4: return "EOpConstructMat2x4";
case EOpConstructMat3x2: return "EOpConstructMat3x2";
case EOpConstructMat3x3: return "EOpConstructMat3x3";
case EOpConstructMat3x4: return "EOpConstructMat3x4";
case EOpConstructMat4x2: return "EOpConstructMat4x2";
case EOpConstructMat4x3: return "EOpConstructMat4x3";
case EOpConstructMat4x4: return "EOpConstructMat4x4";
case EOpConstructDVec2: return "EOpConstructDVec2";
case EOpConstructDVec3: return "EOpConstructDVec3";
case EOpConstructDVec4: return "EOpConstructDVec4";
case EOpConstructBVec2: return "EOpConstructBVec2";
case EOpConstructBVec3: return "EOpConstructBVec3";
case EOpConstructBVec4: return "EOpConstructBVec4";
case EOpConstructI8Vec2: return "EOpConstructI8Vec2";
case EOpConstructI8Vec3: return "EOpConstructI8Vec3";
case EOpConstructI8Vec4: return "EOpConstructI8Vec4";
case EOpConstructU8Vec2: return "EOpConstructU8Vec2";
case EOpConstructU8Vec3: return "EOpConstructU8Vec3";
case EOpConstructU8Vec4: return "EOpConstructU8Vec4";
case EOpConstructI16Vec2: return "EOpConstructI16Vec2";
case EOpConstructI16Vec3: return "EOpConstructI16Vec3";
case EOpConstructI16Vec4: return "EOpConstructI16Vec4";
case EOpConstructU16Vec2: return "EOpConstructU16Vec2";
case EOpConstructU16Vec3: return "EOpConstructU16Vec3";
case EOpConstructU16Vec4: return "EOpConstructU16Vec4";
case EOpConstructIVec2: return "EOpConstructIVec2";
case EOpConstructIVec3: return "EOpConstructIVec3";
case EOpConstructIVec4: return "EOpConstructIVec4";
case EOpConstructUVec2: return "EOpConstructUVec2";
case EOpConstructUVec3: return "EOpConstructUVec3";
case EOpConstructUVec4: return "EOpConstructUVec4";
case EOpConstructI64Vec2: return "EOpConstructI64Vec2";
case EOpConstructI64Vec3: return "EOpConstructI64Vec3";
case EOpConstructI64Vec4: return "EOpConstructI64Vec4";
case EOpConstructU64Vec2: return "EOpConstructU64Vec2";
case EOpConstructU64Vec3: return "EOpConstructU64Vec3";
case EOpConstructU64Vec4: return "EOpConstructU64Vec4";
case EOpConstructDMat2x2: return "EOpConstructDMat2x2";
case EOpConstructDMat2x3: return "EOpConstructDMat2x3";
case EOpConstructDMat2x4: return "EOpConstructDMat2x4";
case EOpConstructDMat3x2: return "EOpConstructDMat3x2";
case EOpConstructDMat3x3: return "EOpConstructDMat3x3";
case EOpConstructDMat3x4: return "EOpConstructDMat3x4";
case EOpConstructDMat4x2: return "EOpConstructDMat4x2";
case EOpConstructDMat4x3: return "EOpConstructDMat4x3";
case EOpConstructDMat4x4: return "EOpConstructDMat4x4";
case EOpConstructIMat2x2: return "EOpConstructIMat2x2";
case EOpConstructIMat2x3: return "EOpConstructIMat2x3";
case EOpConstructIMat2x4: return "EOpConstructIMat2x4";
case EOpConstructIMat3x2: return "EOpConstructIMat3x2";
case EOpConstructIMat3x3: return "EOpConstructIMat3x3";
case EOpConstructIMat3x4: return "EOpConstructIMat3x4";
case EOpConstructIMat4x2: return "EOpConstructIMat4x2";
case EOpConstructIMat4x3: return "EOpConstructIMat4x3";
case EOpConstructIMat4x4: return "EOpConstructIMat4x4";
case EOpConstructUMat2x2: return "EOpConstructUMat2x2";
case EOpConstructUMat2x3: return "EOpConstructUMat2x3";
case EOpConstructUMat2x4: return "EOpConstructUMat2x4";
case EOpConstructUMat3x2: return "EOpConstructUMat3x2";
case EOpConstructUMat3x3: return "EOpConstructUMat3x3";
case EOpConstructUMat3x4: return "EOpConstructUMat3x4";
case EOpConstructUMat4x2: return "EOpConstructUMat4x2";
case EOpConstructUMat4x3: return "EOpConstructUMat4x3";
case EOpConstructUMat4x4: return "EOpConstructUMat4x4";
case EOpConstructBMat2x2: return "EOpConstructBMat2x2";
case EOpConstructBMat2x3: return "EOpConstructBMat2x3";
case EOpConstructBMat2x4: return "EOpConstructBMat2x4";
case EOpConstructBMat3x2: return "EOpConstructBMat3x2";
case EOpConstructBMat3x3: return "EOpConstructBMat3x3";
case EOpConstructBMat3x4: return "EOpConstructBMat3x4";
case EOpConstructBMat4x2: return "EOpConstructBMat4x2";
case EOpConstructBMat4x3: return "EOpConstructBMat4x3";
case EOpConstructBMat4x4: return "EOpConstructBMat4x4";
case EOpConstructFloat16: return "EOpConstructFloat16";
case EOpConstructF16Vec2: return "EOpConstructF16Vec2";
case EOpConstructF16Vec3: return "EOpConstructF16Vec3";
case EOpConstructF16Vec4: return "EOpConstructF16Vec4";
case EOpConstructF16Mat2x2: return "EOpConstructF16Mat2x2";
case EOpConstructF16Mat2x3: return "EOpConstructF16Mat2x3";
case EOpConstructF16Mat2x4: return "EOpConstructF16Mat2x4";
case EOpConstructF16Mat3x2: return "EOpConstructF16Mat3x2";
case EOpConstructF16Mat3x3: return "EOpConstructF16Mat3x3";
case EOpConstructF16Mat3x4: return "EOpConstructF16Mat3x4";
case EOpConstructF16Mat4x2: return "EOpConstructF16Mat4x2";
case EOpConstructF16Mat4x3: return "EOpConstructF16Mat4x3";
case EOpConstructF16Mat4x4: return "EOpConstructF16Mat4x4";
case EOpConstructStruct: return "EOpConstructStruct";
case EOpConstructTextureSampler: return "EOpConstructTextureSampler";
case EOpConstructNonuniform: return "EOpConstructNonuniform";
case EOpConstructReference: return "EOpConstructReference";
case EOpConstructCooperativeMatrixNV: return "EOpConstructCooperativeMatrixNV";
case EOpConstructCooperativeMatrixKHR: return "EOpConstructCooperativeMatrixKHR";
case EOpConstructAccStruct: return "EOpConstructAccStruct";
case EOpConstructGuardEnd: return "EOpConstructGuardEnd";
case EOpAssign: return "EOpAssign";
case EOpAddAssign: return "EOpAddAssign";
case EOpSubAssign: return "EOpSubAssign";
case EOpMulAssign: return "EOpMulAssign";
case EOpVectorTimesMatrixAssign: return "EOpVectorTimesMatrixAssign";
case EOpVectorTimesScalarAssign: return "EOpVectorTimesScalarAssign";
case EOpMatrixTimesScalarAssign: return "EOpMatrixTimesScalarAssign";
case EOpMatrixTimesMatrixAssign: return "EOpMatrixTimesMatrixAssign";
case EOpDivAssign: return "EOpDivAssign";
case EOpModAssign: return "EOpModAssign";
case EOpAndAssign: return "EOpAndAssign";
case EOpInclusiveOrAssign: return "EOpInclusiveOrAssign";
case EOpExclusiveOrAssign: return "EOpExclusiveOrAssign";
case EOpLeftShiftAssign: return "EOpLeftShiftAssign";
case EOpRightShiftAssign: return "EOpRightShiftAssign";
case EOpArrayLength: return "EOpArrayLength";
case EOpImageGuardBegin: return "EOpImageGuardBegin";
case EOpImageQuerySize: return "EOpImageQuerySize";
case EOpImageQuerySamples: return "EOpImageQuerySamples";
case EOpImageLoad: return "EOpImageLoad";
case EOpImageStore: return "EOpImageStore";
case EOpImageLoadLod: return "EOpImageLoadLod";
case EOpImageStoreLod: return "EOpImageStoreLod";
case EOpImageAtomicAdd: return "EOpImageAtomicAdd";
case EOpImageAtomicMin: return "EOpImageAtomicMin";
case EOpImageAtomicMax: return "EOpImageAtomicMax";
case EOpImageAtomicAnd: return "EOpImageAtomicAnd";
case EOpImageAtomicOr: return "EOpImageAtomicOr";
case EOpImageAtomicXor: return "EOpImageAtomicXor";
case EOpImageAtomicExchange: return "EOpImageAtomicExchange";
case EOpImageAtomicCompSwap: return "EOpImageAtomicCompSwap";
case EOpImageAtomicLoad: return "EOpImageAtomicLoad";
case EOpImageAtomicStore: return "EOpImageAtomicStore";
case EOpSubpassLoad: return "EOpSubpassLoad";
case EOpSubpassLoadMS: return "EOpSubpassLoadMS";
case EOpSparseImageLoad: return "EOpSparseImageLoad";
case EOpSparseImageLoadLod: return "EOpSparseImageLoadLod";
case EOpColorAttachmentReadEXT: return "EOpColorAttachmentReadEXT";
case EOpImageGuardEnd: return "EOpImageGuardEnd";
case EOpTextureGuardBegin: return "EOpTextureGuardBegin";
case EOpTextureQuerySize: return "EOpTextureQuerySize";
case EOpTextureQueryLod: return "EOpTextureQueryLod";
case EOpTextureQueryLevels: return "EOpTextureQueryLevels";
case EOpTextureQuerySamples: return "EOpTextureQuerySamples";
case EOpSamplingGuardBegin: return "EOpSamplingGuardBegin";
case EOpTexture: return "EOpTexture";
case EOpTextureProj: return "EOpTextureProj";
case EOpTextureLod: return "EOpTextureLod";
case EOpTextureOffset: return "EOpTextureOffset";
case EOpTextureFetch: return "EOpTextureFetch";
case EOpTextureFetchOffset: return "EOpTextureFetchOffset";
case EOpTextureProjOffset: return "EOpTextureProjOffset";
case EOpTextureLodOffset: return "EOpTextureLodOffset";
case EOpTextureProjLod: return "EOpTextureProjLod";
case EOpTextureProjLodOffset: return "EOpTextureProjLodOffset";
case EOpTextureGrad: return "EOpTextureGrad";
case EOpTextureGradOffset: return "EOpTextureGradOffset";
case EOpTextureProjGrad: return "EOpTextureProjGrad";
case EOpTextureProjGradOffset: return "EOpTextureProjGradOffset";
case EOpTextureGather: return "EOpTextureGather";
case EOpTextureGatherOffset: return "EOpTextureGatherOffset";
case EOpTextureGatherOffsets: return "EOpTextureGatherOffsets";
case EOpTextureClamp: return "EOpTextureClamp";
case EOpTextureOffsetClamp: return "EOpTextureOffsetClamp";
case EOpTextureGradClamp: return "EOpTextureGradClamp";
case EOpTextureGradOffsetClamp: return "EOpTextureGradOffsetClamp";
case EOpTextureGatherLod: return "EOpTextureGatherLod";
case EOpTextureGatherLodOffset: return "EOpTextureGatherLodOffset";
case EOpTextureGatherLodOffsets: return "EOpTextureGatherLodOffsets";
case EOpFragmentMaskFetch: return "EOpFragmentMaskFetch";
case EOpFragmentFetch: return "EOpFragmentFetch";
case EOpSparseTextureGuardBegin: return "EOpSparseTextureGuardBegin";
case EOpSparseTexture: return "EOpSparseTexture";
case EOpSparseTextureLod: return "EOpSparseTextureLod";
case EOpSparseTextureOffset: return "EOpSparseTextureOffset";
case EOpSparseTextureFetch: return "EOpSparseTextureFetch";
case EOpSparseTextureFetchOffset: return "EOpSparseTextureFetchOffset";
case EOpSparseTextureLodOffset: return "EOpSparseTextureLodOffset";
case EOpSparseTextureGrad: return "EOpSparseTextureGrad";
case EOpSparseTextureGradOffset: return "EOpSparseTextureGradOffset";
case EOpSparseTextureGather: return "EOpSparseTextureGather";
case EOpSparseTextureGatherOffset: return "EOpSparseTextureGatherOffset";
case EOpSparseTextureGatherOffsets: return "EOpSparseTextureGatherOffsets";
case EOpSparseTexelsResident: return "EOpSparseTexelsResident";
case EOpSparseTextureClamp: return "EOpSparseTextureClamp";
case EOpSparseTextureOffsetClamp: return "EOpSparseTextureOffsetClamp";
case EOpSparseTextureGradClamp: return "EOpSparseTextureGradClamp";
case EOpSparseTextureGradOffsetClamp: return "EOpSparseTextureGradOffsetClamp";
case EOpSparseTextureGatherLod: return "EOpSparseTextureGatherLod";
case EOpSparseTextureGatherLodOffset: return "EOpSparseTextureGatherLodOffset";
case EOpSparseTextureGatherLodOffsets: return "EOpSparseTextureGatherLodOffsets";
case EOpSparseTextureGuardEnd: return "EOpSparseTextureGuardEnd";
case EOpImageFootprintGuardBegin: return "EOpImageFootprintGuardBegin";
case EOpImageSampleFootprintNV: return "EOpImageSampleFootprintNV";
case EOpImageSampleFootprintClampNV: return "EOpImageSampleFootprintClampNV";
case EOpImageSampleFootprintLodNV: return "EOpImageSampleFootprintLodNV";
case EOpImageSampleFootprintGradNV: return "EOpImageSampleFootprintGradNV";
case EOpImageSampleFootprintGradClampNV: return "EOpImageSampleFootprintGradClampNV";
case EOpImageFootprintGuardEnd: return "EOpImageFootprintGuardEnd";
case EOpSamplingGuardEnd: return "EOpSamplingGuardEnd";
case EOpTextureGuardEnd: return "EOpTextureGuardEnd";
case EOpAddCarry: return "EOpAddCarry";
case EOpSubBorrow: return "EOpSubBorrow";
case EOpUMulExtended: return "EOpUMulExtended";
case EOpIMulExtended: return "EOpIMulExtended";
case EOpBitfieldExtract: return "EOpBitfieldExtract";
case EOpBitfieldInsert: return "EOpBitfieldInsert";
case EOpBitFieldReverse: return "EOpBitFieldReverse";
case EOpBitCount: return "EOpBitCount";
case EOpFindLSB: return "EOpFindLSB";
case EOpFindMSB: return "EOpFindMSB";
case EOpCountLeadingZeros: return "EOpCountLeadingZeros";
case EOpCountTrailingZeros: return "EOpCountTrailingZeros";
case EOpAbsDifference: return "EOpAbsDifference";
case EOpAddSaturate: return "EOpAddSaturate";
case EOpSubSaturate: return "EOpSubSaturate";
case EOpAverage: return "EOpAverage";
case EOpAverageRounded: return "EOpAverageRounded";
case EOpMul32x16: return "EOpMul32x16";
case EOpTraceNV: return "EOpTraceNV";
case EOpTraceRayMotionNV: return "EOpTraceRayMotionNV";
case EOpTraceKHR: return "EOpTraceKHR";
case EOpReportIntersection: return "EOpReportIntersection";
case EOpIgnoreIntersectionNV: return "EOpIgnoreIntersectionNV";
case EOpTerminateRayNV: return "EOpTerminateRayNV";
case EOpExecuteCallableNV: return "EOpExecuteCallableNV";
case EOpExecuteCallableKHR: return "EOpExecuteCallableKHR";
case EOpWritePackedPrimitiveIndices4x8NV: return "EOpWritePackedPrimitiveIndices4x8NV";
case EOpEmitMeshTasksEXT: return "EOpEmitMeshTasksEXT";
case EOpSetMeshOutputsEXT: return "EOpSetMeshOutputsEXT";
case EOpRayQueryInitialize: return "EOpRayQueryInitialize";
case EOpRayQueryTerminate: return "EOpRayQueryTerminate";
case EOpRayQueryGenerateIntersection: return "EOpRayQueryGenerateIntersection";
case EOpRayQueryConfirmIntersection: return "EOpRayQueryConfirmIntersection";
case EOpRayQueryProceed: return "EOpRayQueryProceed";
case EOpRayQueryGetIntersectionType: return "EOpRayQueryGetIntersectionType";
case EOpRayQueryGetRayTMin: return "EOpRayQueryGetRayTMin";
case EOpRayQueryGetRayFlags: return "EOpRayQueryGetRayFlags";
case EOpRayQueryGetIntersectionT: return "EOpRayQueryGetIntersectionT";
case EOpRayQueryGetIntersectionInstanceCustomIndex: return "EOpRayQueryGetIntersectionInstanceCustomIndex";
case EOpRayQueryGetIntersectionInstanceId: return "EOpRayQueryGetIntersectionInstanceId";
case EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset: return "EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset";
case EOpRayQueryGetIntersectionGeometryIndex: return "EOpRayQueryGetIntersectionGeometryIndex";
case EOpRayQueryGetIntersectionPrimitiveIndex: return "EOpRayQueryGetIntersectionPrimitiveIndex";
case EOpRayQueryGetIntersectionBarycentrics: return "EOpRayQueryGetIntersectionBarycentrics";
case EOpRayQueryGetIntersectionFrontFace: return "EOpRayQueryGetIntersectionFrontFace";
case EOpRayQueryGetIntersectionCandidateAABBOpaque: return "EOpRayQueryGetIntersectionCandidateAABBOpaque";
case EOpRayQueryGetIntersectionObjectRayDirection: return "EOpRayQueryGetIntersectionObjectRayDirection";
case EOpRayQueryGetIntersectionObjectRayOrigin: return "EOpRayQueryGetIntersectionObjectRayOrigin";
case EOpRayQueryGetWorldRayDirection: return "EOpRayQueryGetWorldRayDirection";
case EOpRayQueryGetWorldRayOrigin: return "EOpRayQueryGetWorldRayOrigin";
case EOpRayQueryGetIntersectionObjectToWorld: return "EOpRayQueryGetIntersectionObjectToWorld";
case EOpRayQueryGetIntersectionWorldToObject: return "EOpRayQueryGetIntersectionWorldToObject";
case EOpHitObjectTraceRayNV: return "EOpHitObjectTraceRayNV";
case EOpHitObjectTraceRayMotionNV: return "EOpHitObjectTraceRayMotionNV";
case EOpHitObjectRecordHitNV: return "EOpHitObjectRecordHitNV";
case EOpHitObjectRecordHitMotionNV: return "EOpHitObjectRecordHitMotionNV";
case EOpHitObjectRecordHitWithIndexNV: return "EOpHitObjectRecordHitWithIndexNV";
case EOpHitObjectRecordHitWithIndexMotionNV: return "EOpHitObjectRecordHitWithIndexMotionNV";
case EOpHitObjectRecordMissNV: return "EOpHitObjectRecordMissNV";
case EOpHitObjectRecordMissMotionNV: return "EOpHitObjectRecordMissMotionNV";
case EOpHitObjectRecordEmptyNV: return "EOpHitObjectRecordEmptyNV";
case EOpHitObjectExecuteShaderNV: return "EOpHitObjectExecuteShaderNV";
case EOpHitObjectIsEmptyNV: return "EOpHitObjectIsEmptyNV";
case EOpHitObjectIsMissNV: return "EOpHitObjectIsMissNV";
case EOpHitObjectIsHitNV: return "EOpHitObjectIsHitNV";
case EOpHitObjectGetRayTMinNV: return "EOpHitObjectGetRayTMinNV";
case EOpHitObjectGetRayTMaxNV: return "EOpHitObjectGetRayTMaxNV";
case EOpHitObjectGetObjectRayOriginNV: return "EOpHitObjectGetObjectRayOriginNV";
case EOpHitObjectGetObjectRayDirectionNV: return "EOpHitObjectGetObjectRayDirectionNV";
case EOpHitObjectGetWorldRayOriginNV: return "EOpHitObjectGetWorldRayOriginNV";
case EOpHitObjectGetWorldRayDirectionNV: return "EOpHitObjectGetWorldRayDirectionNV";
case EOpHitObjectGetWorldToObjectNV: return "EOpHitObjectGetWorldToObjectNV";
case EOpHitObjectGetObjectToWorldNV: return "EOpHitObjectGetObjectToWorldNV";
case EOpHitObjectGetInstanceCustomIndexNV: return "EOpHitObjectGetInstanceCustomIndexNV";
case EOpHitObjectGetInstanceIdNV: return "EOpHitObjectGetInstanceIdNV";
case EOpHitObjectGetGeometryIndexNV: return "EOpHitObjectGetGeometryIndexNV";
case EOpHitObjectGetPrimitiveIndexNV: return "EOpHitObjectGetPrimitiveIndexNV";
case EOpHitObjectGetHitKindNV: return "EOpHitObjectGetHitKindNV";
case EOpHitObjectGetShaderBindingTableRecordIndexNV: return "EOpHitObjectGetShaderBindingTableRecordIndexNV";
case EOpHitObjectGetShaderRecordBufferHandleNV: return "EOpHitObjectGetShaderRecordBufferHandleNV";
case EOpHitObjectGetAttributesNV: return "EOpHitObjectGetAttributesNV";
case EOpHitObjectGetCurrentTimeNV: return "EOpHitObjectGetCurrentTimeNV";
case EOpReorderThreadNV: return "EOpReorderThreadNV";
case EOpFetchMicroTriangleVertexPositionNV: return "EOpFetchMicroTriangleVertexPositionNV";
case EOpFetchMicroTriangleVertexBarycentricNV: return "EOpFetchMicroTriangleVertexBarycentricNV";
case EOpClip: return "EOpClip";
case EOpIsFinite: return "EOpIsFinite";
case EOpLog10: return "EOpLog10";
case EOpRcp: return "EOpRcp";
case EOpSaturate: return "EOpSaturate";
case EOpSinCos: return "EOpSinCos";
case EOpGenMul: return "EOpGenMul";
case EOpDst: return "EOpDst";
case EOpInterlockedAdd: return "EOpInterlockedAdd";
case EOpInterlockedAnd: return "EOpInterlockedAnd";
case EOpInterlockedCompareExchange: return "EOpInterlockedCompareExchange";
case EOpInterlockedCompareStore: return "EOpInterlockedCompareStore";
case EOpInterlockedExchange: return "EOpInterlockedExchange";
case EOpInterlockedMax: return "EOpInterlockedMax";
case EOpInterlockedMin: return "EOpInterlockedMin";
case EOpInterlockedOr: return "EOpInterlockedOr";
case EOpInterlockedXor: return "EOpInterlockedXor";
case EOpAllMemoryBarrierWithGroupSync: return "EOpAllMemoryBarrierWithGroupSync";
case EOpDeviceMemoryBarrier: return "EOpDeviceMemoryBarrier";
case EOpDeviceMemoryBarrierWithGroupSync: return "EOpDeviceMemoryBarrierWithGroupSync";
case EOpWorkgroupMemoryBarrier: return "EOpWorkgroupMemoryBarrier";
case EOpWorkgroupMemoryBarrierWithGroupSync: return "EOpWorkgroupMemoryBarrierWithGroupSync";
case EOpEvaluateAttributeSnapped: return "EOpEvaluateAttributeSnapped";
case EOpF32tof16: return "EOpF32tof16";
case EOpF16tof32: return "EOpF16tof32";
case EOpLit: return "EOpLit";
case EOpTextureBias: return "EOpTextureBias";
case EOpAsDouble: return "EOpAsDouble";
case EOpD3DCOLORtoUBYTE4: return "EOpD3DCOLORtoUBYTE4";
case EOpMethodSample: return "EOpMethodSample";
case EOpMethodSampleBias: return "EOpMethodSampleBias";
case EOpMethodSampleCmp: return "EOpMethodSampleCmp";
case EOpMethodSampleCmpLevelZero: return "EOpMethodSampleCmpLevelZero";
case EOpMethodSampleGrad: return "EOpMethodSampleGrad";
case EOpMethodSampleLevel: return "EOpMethodSampleLevel";
case EOpMethodLoad: return "EOpMethodLoad";
case EOpMethodGetDimensions: return "EOpMethodGetDimensions";
case EOpMethodGetSamplePosition: return "EOpMethodGetSamplePosition";
case EOpMethodGather: return "EOpMethodGather";
case EOpMethodCalculateLevelOfDetail: return "EOpMethodCalculateLevelOfDetail";
case EOpMethodCalculateLevelOfDetailUnclamped: return "EOpMethodCalculateLevelOfDetailUnclamped";
case EOpMethodLoad2: return "EOpMethodLoad2";
case EOpMethodLoad3: return "EOpMethodLoad3";
case EOpMethodLoad4: return "EOpMethodLoad4";
case EOpMethodStore: return "EOpMethodStore";
case EOpMethodStore2: return "EOpMethodStore2";
case EOpMethodStore3: return "EOpMethodStore3";
case EOpMethodStore4: return "EOpMethodStore4";
case EOpMethodIncrementCounter: return "EOpMethodIncrementCounter";
case EOpMethodDecrementCounter: return "EOpMethodDecrementCounter";
case EOpMethodConsume: return "EOpMethodConsume";
case EOpMethodGatherRed: return "EOpMethodGatherRed";
case EOpMethodGatherGreen: return "EOpMethodGatherGreen";
case EOpMethodGatherBlue: return "EOpMethodGatherBlue";
case EOpMethodGatherAlpha: return "EOpMethodGatherAlpha";
case EOpMethodGatherCmp: return "EOpMethodGatherCmp";
case EOpMethodGatherCmpRed: return "EOpMethodGatherCmpRed";
case EOpMethodGatherCmpGreen: return "EOpMethodGatherCmpGreen";
case EOpMethodGatherCmpBlue: return "EOpMethodGatherCmpBlue";
case EOpMethodGatherCmpAlpha: return "EOpMethodGatherCmpAlpha";
case EOpMethodAppend: return "EOpMethodAppend";
case EOpMethodRestartStrip: return "EOpMethodRestartStrip";
case EOpMatrixSwizzle: return "EOpMatrixSwizzle";
case EOpWaveGetLaneCount: return "EOpWaveGetLaneCount";
case EOpWaveGetLaneIndex: return "EOpWaveGetLaneIndex";
case EOpWaveActiveCountBits: return "EOpWaveActiveCountBits";
case EOpWavePrefixCountBits: return "EOpWavePrefixCountBits";
case EOpReadClockSubgroupKHR: return "EOpReadClockSubgroupKHR";
case EOpReadClockDeviceKHR: return "EOpReadClockDeviceKHR";
case EOpRayQueryGetIntersectionTriangleVertexPositionsEXT: return "EOpRayQueryGetIntersectionTriangleVertexPositionsEXT";
case EOpStencilAttachmentReadEXT: return "EOpStencilAttachmentReadEXT";
case EOpDepthAttachmentReadEXT: return "EOpDepthAttachmentReadEXT";
case EOpImageSampleWeightedQCOM: return "EOpImageSampleWeightedQCOM";
case EOpImageBoxFilterQCOM: return "EOpImageBoxFilterQCOM";
case EOpImageBlockMatchSADQCOM: return "EOpImageBlockMatchSADQCOM";
case EOpImageBlockMatchSSDQCOM: return "EOpImageBlockMatchSSDQCOM";
}
}
std::string glslangNodeToString(const TIntermNode* node) {
if (auto nodeAsOperator = node->getAsOperator()) {
std::string result;
if (node->getAsAggregate()) {
result = "Aggregate(";
} else if (node->getAsUnaryNode()) {
result = "Unary(";
} else if (node->getAsBinaryNode()) {
result = "Binary(";
} else {
result = "Operator(";
}
result += glslangOperatorToString(nodeAsOperator->getOp());
result += ')';
return result;
}
if (node->getAsLoopNode()) {
return "Loop";
}
if (auto nodeAsBranch = node->getAsBranchNode()) {
return std::string("Branch(") + glslangOperatorToString(nodeAsBranch->getFlowOp()) + ")";
}
if (auto nodeAsSymbol = node->getAsSymbolNode()) {
return std::string("Symbol(") + std::string(nodeAsSymbol->getAccessName()) + ")";
}
if (node->getAsMethodNode()) {
return "Method";
}
if (node->getAsSwitchNode()) {
return "Switch";
}
if (node->getAsSelectionNode()) {
return "Selection";
}
if (auto nodeAsConstantUnion = node->getAsConstantUnion()) {
return "ConstantUnion(size = "
+ std::to_string(nodeAsConstantUnion->getConstArray().size())
+ ", type = "
+ std::string(nodeAsConstantUnion->getType().getCompleteString())
+ ")";
}
if (node->getAsTyped()) {
return "Typed";
}
return "Node";
}
std::string glslangLocToString(const glslang::TSourceLoc& loc) {
return loc.getStringNameOrNum() + ":" + std::to_string(loc.line) + ":" + std::to_string(loc.column);
}
std::string glslangNodeToStringWithLoc(const TIntermNode* node) {
return glslangLocToString(node->getLoc()) + ":" + glslangNodeToString(node);
}
} // namespace astrict
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More