Compare commits

..
Author SHA1 Message Date
Sungun Park 9f35b6f2f1 Bump version to 1.71.0 2026-04-01 20:08:22 -07:00
27 changed files with 110 additions and 133 deletions
-3
View File
@@ -7,9 +7,6 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
## v1.71.1
## v1.71.0
- matc: better material compression using a Multi-Base Variable-Length Interleaved Token Stream [⚠️ **New Material Version**]
+13 -12
View File
@@ -204,9 +204,10 @@
"license": "Apache-2.0"
},
"node_modules/brace-expansion": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
"integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -234,9 +235,9 @@
"license": "MIT"
},
"node_modules/minimatch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.3.tgz",
"integrity": "sha512-M2GCs7Vk83NxkUyQV1bkABc4yxgz9kILhHImZiBPAZ9ybuvCb0/H7lEl5XvIg3g+9d4eNotkZA5IWwYl0tibaA==",
"dependencies": {
"brace-expansion": "^1.1.7"
},
@@ -409,9 +410,9 @@
"integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="
},
"brace-expansion": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz",
"integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -428,9 +429,9 @@
"integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q=="
},
"minimatch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.3.tgz",
"integrity": "sha512-M2GCs7Vk83NxkUyQV1bkABc4yxgz9kILhHImZiBPAZ9ybuvCb0/H7lEl5XvIg3g+9d4eNotkZA5IWwYl0tibaA==",
"requires": {
"brace-expansion": "^1.1.7"
}
+2 -2
View File
@@ -181,7 +181,7 @@ important for <code>matc</code> (material compiler).</p>
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.70.2'
implementation 'com.google.android.filament:filament-android:1.70.1'
}
</code></pre>
<p>Here are all the libraries available in the group <code>com.google.android.filament</code>:</p>
@@ -195,7 +195,7 @@ dependencies {
</div>
<h3 id="ios"><a class="header" href="#ios">iOS</a></h3>
<p>iOS projects can use CocoaPods to install the latest release:</p>
<pre><code class="language-shell">pod 'Filament', '~&gt; 1.70.2'
<pre><code class="language-shell">pod 'Filament', '~&gt; 1.70.1'
</code></pre>
<h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2>
<ul>
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
+18 -29
View File
@@ -1740,10 +1740,6 @@ void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
assert_invariant(target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment,
GL_RENDERBUFFER, t->gl.id);
// Clear the resolve bit for this particular attachment. Note that other attachment(s)
// might be sampleable, so this does not necessarily prevent the resolve from occurring.
resolveFlags = TargetBufferFlags::NONE;
}
break;
case GL_TEXTURE_3D:
@@ -1883,11 +1879,6 @@ void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
CHECK_GL_ERROR()
}
// We don't need to resolve attachments that match the rendertarget's sample count.
if (rt->gl.samples == t->samples) {
resolveFlags = TargetBufferFlags::NONE;
}
rt->gl.resolve |= resolveFlags;
CHECK_GL_ERROR()
@@ -3777,6 +3768,20 @@ void OpenGLDriver::beginRenderPass(Handle<HwRenderTarget> rth,
// each render-pass starts with a disabled scissor
gl.disable(GL_SCISSOR_TEST);
if (gl.ext.EXT_discard_framebuffer
&& !gl.bugs.disable_invalidate_framebuffer) {
AttachmentArray attachments; // NOLINT
if (GLsizei const attachmentCount = getAttachments(attachments, discardFlags, !fbo)) {
gl.procs.invalidateFramebuffer(GL_FRAMEBUFFER, attachmentCount, attachments.data());
}
CHECK_GL_ERROR()
} else {
// It's important to clear the framebuffer before drawing, as it resets
// the fb to a known state (resets fb compression and possibly other things).
// So we use glClear instead of glInvalidateFramebuffer
clearWithRasterPipe(discardFlags & ~clearFlags, { 0.0f }, 0.0f, 0);
}
if (rt->gl.fbo_read) {
// we have a multi-sample RenderTarget with non multi-sample attachments (i.e. this is the
// EXT_multisampled_render_to_texture emulation).
@@ -3788,26 +3793,9 @@ void OpenGLDriver::beginRenderPass(Handle<HwRenderTarget> rth,
discardFlags |= rt->gl.resolve;
}
// we don't discard attachments that are cleared (because clear is an implicit discard)
TargetBufferFlags const discardOnlyFlags = discardFlags & ~clearFlags;
if (any(discardOnlyFlags)) {
if (gl.ext.EXT_discard_framebuffer && !gl.bugs.disable_invalidate_framebuffer) {
AttachmentArray attachments; // NOLINT
if (GLsizei const attachmentCount = getAttachments(attachments, discardOnlyFlags, !fbo)) {
gl.procs.invalidateFramebuffer(GL_FRAMEBUFFER, attachmentCount, attachments.data());
}
CHECK_GL_ERROR()
} else {
// It's important to clear the framebuffer before drawing, as it resets
// the fb to a known state (resets fb compression and possibly other things).
// So we use glClear instead of glInvalidateFramebuffer
clearWithRasterPipe(discardOnlyFlags, { 0.0f }, 0.0f, 0);
}
}
if (any(clearFlags)) {
clearWithRasterPipe(clearFlags, params.clearColor, GLfloat(params.clearDepth), GLint(params.clearStencil));
clearWithRasterPipe(clearFlags,
params.clearColor, GLfloat(params.clearDepth), GLint(params.clearStencil));
}
// we need to reset those after we call clearWithRasterPipe()
@@ -3824,7 +3812,8 @@ void OpenGLDriver::beginRenderPass(Handle<HwRenderTarget> rth,
#ifndef NDEBUG
// clear the discarded (but not the cleared ones) buffers in debug builds
clearWithRasterPipe(discardOnlyFlags, { 1, 0, 0, 1 }, 1.0, 0);
clearWithRasterPipe(discardFlags & ~clearFlags,
{ 1, 0, 0, 1 }, 1.0, 0);
#endif
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

+35 -5
View File
@@ -31,7 +31,10 @@ using namespace filament;
using namespace filament::backend;
using namespace filament::math;
TEST_F(BackendTest, Autoresolve) {
TEST_F(BackendTest, AutoresolveDifferingSampleCounts) {
SKIP_IF(SkipEnvironment(OperatingSystem::CI, Backend::OPENGL), "see b/486954356");
SKIP_IF(SkipEnvironment(OperatingSystem::CI, Backend::VULKAN), "see b/486954356");
auto& api = getDriverApi();
constexpr int kRenderTargetSize = 512;
@@ -58,18 +61,18 @@ TEST_F(BackendTest, Autoresolve) {
TextureFormat::RGBA8, 1, kRenderTargetSize, kRenderTargetSize, 1,
TextureUsage::COLOR_ATTACHMENT | TextureUsage::SAMPLEABLE));
// render a red triangle to a RenderTarget with 4 samples.
// First render pass: render a red triangle to a RenderTarget with 8 samples.
{
Handle<HwRenderTarget> renderTarget =
addCleanup(api.createRenderTarget(TargetBufferFlags::COLOR, kRenderTargetSize,
kRenderTargetSize, 4, 1, { { texture } }, {}, {}));
kRenderTargetSize, 8, 1, { { texture } }, {}, {}));
shader.uploadUniform(api, ubuffer,
SimpleMaterialParams{
.color = float4(1, 0, 0, 1),
});
RenderPassParams params = getClearColorRenderPass(float4(1));
RenderPassParams params = getClearColorRenderPass(float4(0));
params.viewport = { 0, 0, kRenderTargetSize, kRenderTargetSize };
RenderFrame frame(api);
@@ -81,9 +84,36 @@ TEST_F(BackendTest, Autoresolve) {
api.draw2(0, 3, 1);
api.endRenderPass();
api.commit(swapChain);
}
// Second render pass: render a green triangle to a RenderTarget with 4 samples, attached to
// the same texture.
{
Handle<HwRenderTarget> renderTarget =
addCleanup(api.createRenderTarget(TargetBufferFlags::COLOR, kRenderTargetSize,
kRenderTargetSize, 4, 1, { { texture } }, {}, {}));
shader.uploadUniform(api, ubuffer,
SimpleMaterialParams{
.color = float4(0, 1, 0, 1),
});
RenderPassParams params = getClearColorRenderPass(float4(0));
params.viewport = { 0, 0, kRenderTargetSize, kRenderTargetSize };
RenderFrame frame(api);
api.beginRenderPass(renderTarget, params);
ps.primitiveType = PrimitiveType::TRIANGLES;
ps.vertexBufferInfo = triangle.getVertexBufferInfo();
api.bindPipeline(ps);
api.bindRenderPrimitive(triangle.getRenderPrimitive());
api.draw2(0, 3, 1);
api.endRenderPass();
EXPECT_IMAGE(renderTarget, ScreenshotParams(kRenderTargetSize, kRenderTargetSize,
"Autoresolve", 545665143));
"AutoresolveDifferingSampleCounts", 1048576));
api.commit(swapChain);
}
}
+6 -4
View File
@@ -145,7 +145,7 @@ static void createFaces(DriverApi& dapi, Handle<HwTexture> texture, int baseWidt
}
TEST_F(BlitTest, ColorMagnify) {
// b/453757697: MESA glBlitFramebuffer linear interpolation fallback precision slightly mismatches.
SKIP_IF(SkipEnvironment(OperatingSystem::CI, Backend::OPENGL), "b/453757697");
SKIP_IF(SkipEnvironment(OperatingSystem::CI, Backend::VULKAN), "b/453777397");
SKIP_IF(Backend::WEBGPU, "test cases fail in WebGPU, see b/424157731");
@@ -206,13 +206,15 @@ TEST_F(BlitTest, ColorMagnify) {
{
RenderFrame frame(api);
EXPECT_IMAGE(dstRenderTargets[0],
ScreenshotParams(kDstTexWidth, kDstTexHeight, "ColorMagnify", 0x410bdd31, false, 8000, 5));
ScreenshotParams(kDstTexWidth, kDstTexHeight, "ColorMagnify", 0x410bdd31));
api.commit(swapChain);
}
}
TEST_F(BlitTest, ColorMinify) {
SKIP_IF(Backend::WEBGPU, "test cases fail in WebGPU, see b/424157731");
SKIP_IF(SkipEnvironment(OperatingSystem::CI, Backend::OPENGL), "b/453758045");
SKIP_IF(SkipEnvironment(OperatingSystem::CI, Backend::VULKAN), "b/453776623");
auto& api = getDriverApi();
mCleanup.addPostCall([&]() { executeCommands(); });
@@ -266,7 +268,7 @@ TEST_F(BlitTest, ColorMinify) {
SamplerMagFilter::LINEAR);
EXPECT_IMAGE(dstRenderTargets[0],
ScreenshotParams(kDstTexWidth, kDstTexHeight, "ColorMinify", 0xf3d9c53f, false, 8000, 5));
ScreenshotParams(kDstTexWidth, kDstTexHeight, "ColorMinify", 0xf3d9c53f));
}
TEST_F(BlitTest, ColorResolve) {
@@ -353,7 +355,7 @@ TEST_F(BlitTest, ColorResolve) {
SamplerMagFilter::NEAREST);
EXPECT_IMAGE(dstRenderTarget,
ScreenshotParams(kDstTexWidth, kDstTexHeight, "ColorResolve", 531759687, false, 8000, 5));
ScreenshotParams(kDstTexWidth, kDstTexHeight, "ColorResolve", 531759687));
}
TEST_F(BlitTest, Blit2DTextureArray) {
+2 -1
View File
@@ -391,6 +391,7 @@ TEST_F(LoadImageTest, UpdateImage2D) {
}
TEST_F(LoadImageTest, UpdateImageSRGB) {
SKIP_IF(SkipEnvironment(OperatingSystem::CI, Backend::OPENGL), "see b/453756688");
SKIP_IF(Backend::VULKAN, "b/454040142");
auto& api = getDriverApi();
@@ -467,7 +468,7 @@ TEST_F(LoadImageTest, UpdateImageSRGB) {
api.endRenderPass();
EXPECT_IMAGE(defaultRenderTarget,
ScreenshotParams(kTexSize, kTexSize, "UpdateImageSRGB", 3300305265, false, 8000, 5));
ScreenshotParams(kTexSize, kTexSize, "UpdateImageSRGB", 3300305265));
api.commit(swapChain);
api.endFrame(0);
+3 -1
View File
@@ -177,7 +177,9 @@ TEST_F(BasicStencilBufferTest, DepthAndStencilBuffer) {
TEST_F(BasicStencilBufferTest, StencilBufferMSAA) {
SKIP_IF(Backend::WEBGPU, "test cases fail in WebGPU, see b/424157731");
SKIP_IF(SkipEnvironment(OperatingSystem::APPLE, Backend::VULKAN), "Stencil not preserved");
SKIP_IF(SkipEnvironment(OperatingSystem::APPLE, Backend::OPENGL), "Stencil isn't applied");
SKIP_IF(SkipEnvironment(OperatingSystem::CI, Backend::OPENGL), "see b/453757787");
SKIP_IF(Backend::VULKAN, "b/453777217");
auto& api = getDriverApi();
-18
View File
@@ -442,24 +442,6 @@ public:
* invoking asynchronous methods.
*/
AsynchronousMode asynchronousMode = AsynchronousMode::NONE;
/**
* Capacity of the LRU cache for material definitions.
*
* A value of 0 indicates that definitions will be destroyed immediately when they are no
* longer referenced by any material instances or scenes. A value greater than 0 defines
* the maximum number of unreferenced definitions to keep alive to avoid re-compilation.
*/
uint32_t materialCacheCapacity = 0;
/**
* Capacity of the LRU cache for program specializations.
*
* Similar to materialCacheCapacity, but applies to the underlying shader programs generated
* for materials. A value of 0 means immediate destruction of unreferenced programs. A
* positive value caches up to that number of programs.
*/
uint32_t programCacheCapacity = 0;
};
+3 -3
View File
@@ -39,9 +39,9 @@ bool MaterialCache::MaterialKey::operator==(MaterialKey const& rhs) const noexce
return parser == rhs.parser;
}
MaterialCache::MaterialCache(uint32_t materialCapacity, uint32_t programCapacity)
: mDefinitions("MaterialCache::mDefinitions", materialCapacity),
mPrograms("MaterialCache::mPrograms", programCapacity) {}
MaterialCache::MaterialCache()
: mDefinitions("MaterialCache::mDefinitions", 0),
mPrograms("MaterialCache::mPrograms", 0) {}
MaterialCache::~MaterialCache() {
assert_invariant(mDefinitions.empty());
+1 -1
View File
@@ -56,7 +56,7 @@ public:
using ProgramCache =
utils::RefCountedMap<ProgramSpecialization, backend::Handle<backend::HwProgram>>;
MaterialCache(uint32_t materialCapacity, uint32_t programCapacity);
MaterialCache();
~MaterialCache();
// All reference-counted resources should be freed by the time MaterialCache is destructed, but
-1
View File
@@ -271,7 +271,6 @@ FEngine::FEngine(Builder const& builder) :
mRenderableManager(*this),
mLightManager(*this),
mCameraManager(*this),
mMaterialCache(builder->mConfig.materialCacheCapacity, builder->mConfig.programCacheCapacity),
mCommandBufferQueue(
builder->mConfig.minCommandBufferSizeMB * MiB,
builder->mConfig.commandBufferSizeMB * MiB,
+1 -4
View File
@@ -244,9 +244,6 @@ bool MaterialChunk::getTextShader(Unflattener unflattener,
buf[0] = '_';
auto const [ptr, ec] = std::to_chars(buf + 1, buf + 16, numericLiteral);
size_t const len = ptr - buf;
if (UTILS_UNLIKELY(cursor + len >= shaderSize)) {
return false;
}
memcpy(&shaderContent[cursor], buf, len);
cursor += len;
continue;
@@ -266,7 +263,7 @@ bool MaterialChunk::getTextShader(Unflattener unflattener,
const auto& content = dictionary[globalIndex];
// Ensure string is correctly formed and doesn't exceed reserved shader space.
if (UTILS_UNLIKELY(content.size() == 0 || cursor + content.size() - 1 >= shaderSize)) {
if (UTILS_UNLIKELY(content.size() == 0 || cursor + content.size() - 1 > shaderSize)) {
return false;
}
+4 -18
View File
@@ -90,23 +90,16 @@ TEST_F(FilaflatSecurityTest, DictionaryTextOOBRead) {
// 2. Heap Buffer Overflow writing dictionary arrays to undersized output buffers
TEST_F(FilaflatSecurityTest, MaterialChunkHeapOverflow) {
std::vector<uint8_t> payload;
write16(payload, 0); // mSharedStrings
write16(payload, 0); // mVertexStrings
write16(payload, 0); // mFragmentStrings
write16(payload, 0); // mComputeStrings
write64(payload, 1); // numShaders
payload.push_back(1); // model
payload.push_back(0); // variant
payload.push_back(0); // stage
write32(payload, 23); // offset (4*2 + 8 + 1 + 1 + 1 + 4 = 23)
write32(payload, 15); // offset (8 + 1 + 1 + 1 + 4 = 15)
// Shader content layout
write32(payload, 4); // shaderSize (vulnerable tiny size)
write32(payload, 1); // lineCount = 1
write32(payload, 0); // extLength
write32(payload, 0); // baseLength
write32(payload, 0); // numericLength
payload.push_back(0); // lineIndex = 0
write16(payload, 0); // lineIndex = 0
std::vector<uint8_t> fileData;
write64(fileData, (uint64_t)filamat::ChunkType::MaterialGlsl);
@@ -139,21 +132,14 @@ TEST_F(FilaflatSecurityTest, MaterialChunkHeapOverflow) {
// 3. Out of Bounds Read via index mapping evasion (Text mode)
TEST_F(FilaflatSecurityTest, MaterialChunkOOBReadText) {
std::vector<uint8_t> payload;
write16(payload, 0); // mSharedStrings
write16(payload, 0); // mVertexStrings
write16(payload, 0); // mFragmentStrings
write16(payload, 0); // mComputeStrings
write64(payload, 1); // numShaders
payload.push_back(1); // model
payload.push_back(0); // variant
payload.push_back(0); // stage
write32(payload, 23); // offset
write32(payload, 15); // offset (8 + 1 + 1 + 1 + 4 = 15)
write32(payload, 100); // shaderSize
write32(payload, 1); // lineCount = 1
write32(payload, 0); // extLength
write32(payload, 0); // baseLength
write32(payload, 0); // numericLength
payload.push_back(1); // lineIndex = 1 (OOB for empty dict)
write16(payload, 9999); // lineIndex = 9999 (VULNERABLE ACCESS)
std::vector<uint8_t> fileData;
write64(fileData, (uint64_t)filamat::ChunkType::MaterialGlsl);
+1 -2
View File
@@ -24,8 +24,7 @@ namespace filamat {
// when the container is about to be flattened.
size_t ChunkContainer::getSize() const {
auto flattener = Flattener::getDryRunner();
return flatten(flattener);
return flatten(Flattener::getDryRunner());
}
size_t ChunkContainer::flatten(Flattener& f) const {
+8 -2
View File
@@ -48,8 +48,14 @@ public:
// flattening. If we set mStart = nullptr and mEnd=nullptr, we would hit an error about
// offsetting on null when ubsan is enabled. Instead we point mStart to a fake address, and
// mCursor is offset from that.
static Flattener getDryRunner() {
return Flattener((uint8_t*) FAKE_DRY_RUNNER_START_ADDR);
static Flattener& getDryRunner() {
static Flattener dryRunner = Flattener(nullptr);
dryRunner.mStart = (uint8_t*) FAKE_DRY_RUNNER_START_ADDR;
dryRunner.mCursor = (uint8_t*) FAKE_DRY_RUNNER_START_ADDR;
dryRunner.mOffsetPlaceholders.clear();
dryRunner.mSizePlaceholders.clear();
dryRunner.mValuePlaceholders.clear();
return dryRunner;
}
bool isDryRunner() {
+4 -9
View File
@@ -250,9 +250,7 @@ void ShaderGenerator::generateVertexDomainDefines(io::sstream& out, VertexDomain
}
void ShaderGenerator::generatePostProcessMaterialVariantDefines(io::sstream& out,
ShaderStage const, MaterialBuilder::FeatureLevel const featureLevel,
MaterialInfo const&, PostProcessVariant const variant) noexcept {
CodeGenerator::generateDefine(out, "MATERIAL_FEATURE_LEVEL", uint32_t(featureLevel));
PostProcessVariant const variant) noexcept {
switch (variant) {
case PostProcessVariant::OPAQUE:
CodeGenerator::generateDefine(out, "POST_PROCESS_OPAQUE", 1u);
@@ -739,8 +737,7 @@ std::string ShaderGenerator::createPostProcessVertexProgram(ShaderModel const sm
}
CodeGenerator::generatePostProcessInputs(vs, ShaderStage::VERTEX);
generatePostProcessMaterialVariantDefines(vs, ShaderStage::VERTEX,
featureLevel, material, PostProcessVariant(variantKey));
generatePostProcessMaterialVariantDefines(vs, PostProcessVariant(variantKey));
cg.generateUniforms(vs, ShaderStage::VERTEX,
DescriptorSetBindingPoints::PER_VIEW,
@@ -768,16 +765,14 @@ std::string ShaderGenerator::createPostProcessVertexProgram(ShaderModel const sm
std::string ShaderGenerator::createPostProcessFragmentProgram(ShaderModel const sm,
MaterialBuilder::TargetApi const targetApi, MaterialBuilder::TargetLanguage const targetLanguage,
MaterialBuilder::FeatureLevel const featureLevel,
MaterialInfo const& material, filament::Variant::type_t variantKey,
uint32_t apiLevel) const noexcept {
MaterialInfo const& material, uint8_t variant, uint32_t apiLevel) const noexcept {
const CodeGenerator cg(sm, targetApi, targetLanguage, featureLevel);
io::sstream fs;
cg.generateCommonProlog(fs, ShaderStage::FRAGMENT, material, {}, apiLevel);
generateUserSpecConstants(cg, fs, mConstants);
generatePostProcessMaterialVariantDefines(fs, ShaderStage::FRAGMENT,
featureLevel, material, PostProcessVariant(variantKey));
generatePostProcessMaterialVariantDefines(fs, PostProcessVariant(variant));
// custom material variables
size_t variableIndex = 0;
+2 -5
View File
@@ -102,9 +102,7 @@ private:
MaterialInfo const& material, filament::Variant variant) noexcept;
static void generatePostProcessMaterialVariantDefines(utils::io::sstream& out,
filament::backend::ShaderStage stage,
MaterialBuilder::FeatureLevel featureLevel,
MaterialInfo const& material, filament::PostProcessVariant variant) noexcept;
filament::PostProcessVariant variant) noexcept;
static void generateUserSpecConstants(
const CodeGenerator& cg, utils::io::sstream& fs,
@@ -119,8 +117,7 @@ private:
std::string createPostProcessFragmentProgram(filament::backend::ShaderModel sm,
MaterialBuilder::TargetApi targetApi, MaterialBuilder::TargetLanguage targetLanguage,
MaterialBuilder::FeatureLevel featureLevel,
MaterialInfo const& material, filament::Variant::type_t variantKey,
uint32_t apiLevel) const noexcept;
MaterialInfo const& material, uint8_t variant, uint32_t apiLevel) const noexcept;
static void appendShader(utils::io::sstream& ss,
const utils::CString& shader, size_t lineOffset) noexcept;
-8
View File
@@ -4,14 +4,6 @@ void main() {
// Invoke user code
postProcess(inputs);
#if MATERIAL_FEATURE_LEVEL == 0
if (CONFIG_SRGB_SWAPCHAIN_EMULATION) {
if (frameUniforms.rec709 != 0) {
inputs.FRAG_OUTPUT0.rgb = pow(inputs.FRAG_OUTPUT0.rgb, vec3(0.45454));
}
}
#endif
#if defined(FRAG_OUTPUT0)
FRAG_OUTPUT_AT0 FRAG_OUTPUT_SWIZZLE0 = inputs.FRAG_OUTPUT0;
#endif
+3 -1
View File
@@ -114,7 +114,9 @@ void main() {
#if MATERIAL_FEATURE_LEVEL == 0
if (CONFIG_SRGB_SWAPCHAIN_EMULATION) {
if (frameUniforms.rec709 != 0) {
fragColor.rgb = pow(fragColor.rgb, vec3(0.45454));
fragColor.r = pow(fragColor.r, 0.45454);
fragColor.g = pow(fragColor.g, 0.45454);
fragColor.b = pow(fragColor.b, 0.45454);
}
}
#endif