Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d741fc8d4 | ||
|
|
c20772b458 | ||
|
|
4a6b659098 | ||
|
|
e4cb861817 | ||
|
|
640f080ea6 | ||
|
|
eed4b3b839 | ||
|
|
f48dafe87e | ||
|
|
daff8fea9f | ||
|
|
51b4a38e20 | ||
|
|
2171e372ce | ||
|
|
1a30709121 | ||
|
|
2ed9b11f50 |
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.20.2'
|
||||
implementation 'com.google.android.filament:filament-android:1.20.3'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -52,7 +52,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```
|
||||
pod 'Filament', '~> 1.20.2'
|
||||
pod 'Filament', '~> 1.20.3'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
|
||||
@@ -3,7 +3,12 @@
|
||||
This file contains one line summaries of commits that are worthy of mentioning in release notes.
|
||||
A new header is inserted each time a *tag* is created.
|
||||
|
||||
## v1.20.3 (currently main branch)
|
||||
## v1.20.4 (currently main branch)
|
||||
|
||||
## v1.20.3
|
||||
|
||||
- Java: Fix URI bug in Android Viewer sample when dropping some zips.
|
||||
- Vulkan: Fix "uninitialized texture" warnings from the Vulkan backend.
|
||||
|
||||
## v1.20.2
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.20.2
|
||||
VERSION_NAME=1.20.3
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.RandomAccessFile
|
||||
import java.net.URI
|
||||
import java.nio.Buffer
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.charset.StandardCharsets
|
||||
@@ -118,7 +119,7 @@ class MainActivity : Activity() {
|
||||
}
|
||||
|
||||
// FXAA is pretty cheap and helps a lot
|
||||
view.antiAliasing = View.AntiAliasing.FXAA;
|
||||
view.antiAliasing = View.AntiAliasing.FXAA
|
||||
|
||||
// ambient occlusion is the cheapest effect that adds a lot of quality
|
||||
view.ambientOcclusionOptions = view.ambientOcclusionOptions.apply {
|
||||
@@ -217,13 +218,13 @@ class MainActivity : Activity() {
|
||||
|
||||
val sky = Skybox.Builder().environment(skyboxTexture).build(engine)
|
||||
|
||||
specularFilter.destroy();
|
||||
equirectToCubemap.destroy();
|
||||
context.destroy();
|
||||
specularFilter.destroy()
|
||||
equirectToCubemap.destroy()
|
||||
context.destroy()
|
||||
|
||||
// destroy the previous IBl
|
||||
engine.destroyIndirectLight(modelViewer.scene.indirectLight!!);
|
||||
engine.destroySkybox(modelViewer.scene.skybox!!);
|
||||
engine.destroyIndirectLight(modelViewer.scene.indirectLight!!)
|
||||
engine.destroySkybox(modelViewer.scene.skybox!!)
|
||||
|
||||
modelViewer.scene.skybox = sky
|
||||
modelViewer.scene.indirectLight = ibl
|
||||
@@ -243,7 +244,7 @@ class MainActivity : Activity() {
|
||||
val (zipStream, zipFile) = withContext(Dispatchers.IO) {
|
||||
val file = File.createTempFile("incoming", "zip", cacheDir)
|
||||
val raf = RandomAccessFile(file, "rw")
|
||||
raf.getChannel().write(message.buffer);
|
||||
raf.channel.write(message.buffer)
|
||||
message.buffer = null
|
||||
raf.seek(0)
|
||||
Pair(FileInputStream(file), file)
|
||||
@@ -298,19 +299,16 @@ class MainActivity : Activity() {
|
||||
|
||||
// The gltf is often not at the root level (e.g. if a folder is zipped) so
|
||||
// we need to extract its path in order to resolve the embedded uri strings.
|
||||
var gltfPrefix = gltfPath!!.substringBeforeLast('/', "")
|
||||
if (gltfPrefix.isNotEmpty()) {
|
||||
gltfPrefix += "/"
|
||||
}
|
||||
var prefix = URI(gltfPath!!).resolve("..")
|
||||
|
||||
withContext(Dispatchers.Main) {
|
||||
if (gltfPath!!.endsWith(".glb")) {
|
||||
modelViewer.loadModelGlb(gltfBuffer)
|
||||
} else {
|
||||
modelViewer.loadModelGltf(gltfBuffer) { uri ->
|
||||
val path = gltfPrefix + uri
|
||||
val path = prefix.resolve(uri).toString()
|
||||
if (!pathToBufferMapping.contains(path)) {
|
||||
Log.e(TAG, "Could not find $path in the zip.")
|
||||
Log.e(TAG, "Could not find '$uri' in zip using prefix '$prefix'")
|
||||
setStatusText("Zip is missing $path")
|
||||
}
|
||||
pathToBufferMapping[path]
|
||||
@@ -343,12 +341,10 @@ class MainActivity : Activity() {
|
||||
clearStatusText()
|
||||
titlebarHint.text = message.label
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
if (message.label.endsWith(".zip")) {
|
||||
loadZip(message)
|
||||
} else if (message.label.endsWith(".hdr")) {
|
||||
loadHdr(message)
|
||||
} else {
|
||||
loadGlb(message)
|
||||
when {
|
||||
message.label.endsWith(".zip") -> loadZip(message)
|
||||
message.label.endsWith(".hdr") -> loadHdr(message)
|
||||
else -> loadGlb(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -640,6 +640,10 @@ enum class TextureCubemapFace : uint8_t {
|
||||
NEGATIVE_Z = 5, //!< -z face
|
||||
};
|
||||
|
||||
inline constexpr int operator +(TextureCubemapFace rhs) noexcept {
|
||||
return int(rhs);
|
||||
}
|
||||
|
||||
//! Face offsets for all faces of a cubemap
|
||||
struct FaceOffsets {
|
||||
using size_type = size_t;
|
||||
|
||||
@@ -22,38 +22,19 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace filament {
|
||||
namespace backend {
|
||||
namespace filament::backend {
|
||||
|
||||
//! \privatesection
|
||||
|
||||
class TargetBufferInfo {
|
||||
public:
|
||||
// ctor for 2D textures
|
||||
TargetBufferInfo(Handle<HwTexture> h, uint8_t level = 0) noexcept // NOLINT(google-explicit-constructor)
|
||||
: handle(h), level(level) { }
|
||||
// ctor for cubemaps
|
||||
TargetBufferInfo(Handle<HwTexture> h, uint8_t level, TextureCubemapFace face) noexcept
|
||||
: handle(h), level(level), face(face) { }
|
||||
// ctor for 3D textures
|
||||
TargetBufferInfo(Handle<HwTexture> h, uint8_t level, uint16_t layer) noexcept
|
||||
: handle(h), level(level), layer(layer) { }
|
||||
|
||||
explicit TargetBufferInfo(TextureCubemapFace face) noexcept : face(face) {}
|
||||
|
||||
explicit TargetBufferInfo(uint16_t layer) noexcept : layer(layer) {}
|
||||
|
||||
struct TargetBufferInfo {
|
||||
// texture to be used as render target
|
||||
Handle<HwTexture> handle;
|
||||
|
||||
// level to be used
|
||||
uint8_t level = 0;
|
||||
union {
|
||||
// face if texture is a cubemap
|
||||
TextureCubemapFace face;
|
||||
// for 3D textures
|
||||
uint16_t layer = 0;
|
||||
};
|
||||
TargetBufferInfo() noexcept { }
|
||||
|
||||
// for cubemaps and 3D textures. See TextureCubemapFace for the face->layer mapping
|
||||
uint16_t layer = 0;
|
||||
};
|
||||
|
||||
class MRT {
|
||||
@@ -96,13 +77,12 @@ public:
|
||||
}
|
||||
|
||||
// this is here for backward compatibility
|
||||
MRT(Handle<HwTexture> h, uint8_t level, uint16_t layer) noexcept
|
||||
: mInfos{{ h, level, layer }} {
|
||||
MRT(Handle<HwTexture> handle, uint8_t level, uint16_t layer) noexcept
|
||||
: mInfos{{ handle, level, layer }} {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace backend
|
||||
} // namespace filament
|
||||
} // namespace filament::backend
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::TargetBufferInfo& tbi);
|
||||
|
||||
@@ -293,6 +293,7 @@ DECL_DRIVER_API_SYNCHRONOUS_N(bool, isRenderTargetFormatSupported, backend::Text
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchMultiSampleSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameTimeSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isAutoDepthResolveSupported)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(uint8_t, getMaxDrawBuffers)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(math::float2, getClipSpaceParams)
|
||||
DECL_DRIVER_API_SYNCHRONOUS_0(bool, canGenerateMipmaps)
|
||||
|
||||
@@ -671,6 +671,10 @@ bool MetalDriver::isFrameTimeSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MetalDriver::isAutoDepthResolveSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MetalDriver::isWorkaroundNeeded(Workaround workaround) {
|
||||
switch (workaround) {
|
||||
case Workaround::SPLIT_EASU:
|
||||
|
||||
@@ -168,6 +168,10 @@ bool NoopDriver::isFrameTimeSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NoopDriver::isAutoDepthResolveSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NoopDriver::isWorkaroundNeeded(Workaround workaround) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -168,8 +168,9 @@ constexpr inline GLenum getComponentType(backend::ElementType type) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
constexpr inline GLenum getCubemapTarget(backend::TextureCubemapFace face) noexcept {
|
||||
return GL_TEXTURE_CUBE_MAP_POSITIVE_X + GLenum(face);
|
||||
constexpr inline GLenum getCubemapTarget(uint16_t layer) noexcept {
|
||||
assert_invariant(layer <= 5);
|
||||
return GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer;
|
||||
}
|
||||
|
||||
constexpr inline GLenum getWrapMode(backend::SamplerWrapMode mode) noexcept {
|
||||
|
||||
@@ -785,7 +785,7 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo,
|
||||
// note: multi-sampled textures can't have mipmaps
|
||||
break;
|
||||
case SamplerType::SAMPLER_CUBEMAP:
|
||||
target = getCubemapTarget(binfo.face);
|
||||
target = getCubemapTarget(binfo.layer);
|
||||
// note: cubemaps can't be multi-sampled
|
||||
break;
|
||||
default:
|
||||
@@ -1561,6 +1561,11 @@ bool OpenGLDriver::isFrameTimeSupported() {
|
||||
return mFrameTimeSupported;
|
||||
}
|
||||
|
||||
bool OpenGLDriver::isAutoDepthResolveSupported() {
|
||||
// TODO: this should return true only for GLES3.1+ and EXT_multisampled_render_to_texture2
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLDriver::isWorkaroundNeeded(Workaround workaround) {
|
||||
switch (workaround) {
|
||||
case Workaround::SPLIT_EASU:
|
||||
@@ -1907,9 +1912,9 @@ void OpenGLDriver::setTextureData(GLTexture* t,
|
||||
bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t);
|
||||
gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1);
|
||||
FaceOffsets const& offsets = *faceOffsets;
|
||||
#pragma nounroll
|
||||
UTILS_NOUNROLL
|
||||
for (size_t face = 0; face < 6; face++) {
|
||||
GLenum target = getCubemapTarget(TextureCubemapFace(face));
|
||||
GLenum target = getCubemapTarget(face);
|
||||
glTexSubImage2D(target, GLint(level), 0, 0,
|
||||
width, height, glFormat, glType,
|
||||
static_cast<uint8_t const*>(p.buffer) + offsets[face]);
|
||||
@@ -1992,9 +1997,9 @@ void OpenGLDriver::setCompressedTextureData(GLTexture* t, uint32_t level,
|
||||
bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t);
|
||||
gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1);
|
||||
FaceOffsets const& offsets = *faceOffsets;
|
||||
#pragma nounroll
|
||||
UTILS_NOUNROLL
|
||||
for (size_t face = 0; face < 6; face++) {
|
||||
GLenum target = getCubemapTarget(TextureCubemapFace(face));
|
||||
GLenum target = getCubemapTarget(face);
|
||||
glCompressedTexSubImage2D(target, GLint(level), 0, 0,
|
||||
width, height, t->gl.internalFormat,
|
||||
imageSize, static_cast<uint8_t const*>(p.buffer) + offsets[face]);
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace filament {
|
||||
namespace backend {
|
||||
class OpenGLPlatform;
|
||||
class PixelBufferDescriptor;
|
||||
class TargetBufferInfo;
|
||||
struct TargetBufferInfo;
|
||||
} // namespace backend
|
||||
|
||||
class OpenGLProgram;
|
||||
|
||||
@@ -426,9 +426,9 @@ io::ostream& operator<<(io::ostream& out, const RasterState& rs) {
|
||||
|
||||
io::ostream& operator<<(io::ostream& out, const TargetBufferInfo& tbi) {
|
||||
return out << "TargetBufferInfo{"
|
||||
<< "h=" << tbi.handle
|
||||
<< "handle=" << tbi.handle
|
||||
<< ", level=" << tbi.level
|
||||
<< ", face=" << tbi.face << "}";
|
||||
<< ", layer=" << tbi.layer << "}";
|
||||
}
|
||||
|
||||
io::ostream& operator<<(io::ostream& out, const PolygonOffset& po) {
|
||||
|
||||
@@ -37,6 +37,13 @@
|
||||
// srcDirs = ["${android.ndkDirectory}/sources/third_party/vulkan/src/build-android/jniLibs"]
|
||||
// }
|
||||
//
|
||||
// If gradle claims that your NDK is not installed, try checking what versions you have with
|
||||
// `ls $ANDROID_HOME/ndk` then direct gradle by adding something like this to the "android" section:
|
||||
//
|
||||
// ndkVersion "23.1.7779620"
|
||||
//
|
||||
// Also consider changing the root `gradle.properties` to point to a debug build, although this is
|
||||
// not required for validation if you change the definition of VK_ENABLE_VALIDATION below.
|
||||
#if defined(NDEBUG)
|
||||
#define VK_ENABLE_VALIDATION 0
|
||||
#else
|
||||
|
||||
@@ -839,6 +839,10 @@ bool VulkanDriver::isFrameTimeSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VulkanDriver::isAutoDepthResolveSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VulkanDriver::isWorkaroundNeeded(Workaround workaround) {
|
||||
VkPhysicalDeviceProperties const& deviceProperties = mContext.physicalDeviceProperties;
|
||||
switch (workaround) {
|
||||
@@ -1125,6 +1129,15 @@ void VulkanDriver::beginRenderPass(Handle<HwRenderTarget> rth, const RenderPassP
|
||||
if (depth.texture) {
|
||||
fbkey.depth = depth.getImageView(VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
assert_invariant(fbkey.depth);
|
||||
|
||||
// Vulkan 1.1 does not support multisampled depth resolve, so let's check here
|
||||
// and assert if this is requested. (c.f. isAutoDepthResolveSupported)
|
||||
// Reminder: Filament's backend API works like this:
|
||||
// - If the RT is SS then all attachments must be SS.
|
||||
// - If the RT is MS then all SS attachments are auto resolved if not discarded.
|
||||
assert_invariant(!(rt->getSamples() > 1 &&
|
||||
rt->getDepth().texture->samples == 1 &&
|
||||
!any(rpkey.discardEnd & TargetBufferFlags::DEPTH)));
|
||||
}
|
||||
VkFramebuffer vkfb = mFramebufferCache.getFramebuffer(fbkey);
|
||||
|
||||
|
||||
@@ -309,6 +309,8 @@ private:
|
||||
bool operator()(const DescriptorKey& k1, const DescriptorKey& k2) const;
|
||||
};
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// CACHE ENTRY STRUCTS
|
||||
// -------------------
|
||||
|
||||
@@ -352,8 +354,6 @@ private:
|
||||
std::array<std::vector<VkDescriptorSet>, DESCRIPTOR_TYPE_COUNT> descriptorSetArenas;
|
||||
};
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// CACHE CONTAINERS
|
||||
// ----------------
|
||||
|
||||
|
||||
@@ -185,8 +185,8 @@ TEST_F(BackendTest, CubemapMinify) {
|
||||
const TextureCubemapFace srcFace = TextureCubemapFace::NEGATIVE_Y;
|
||||
const TextureCubemapFace dstFace = TextureCubemapFace::NEGATIVE_Y;
|
||||
|
||||
const TargetBufferInfo srcInfo = { texture, srcLevel, srcFace };
|
||||
const TargetBufferInfo dstInfo = { texture, dstLevel, dstFace };
|
||||
const TargetBufferInfo srcInfo = { texture, srcLevel, +srcFace };
|
||||
const TargetBufferInfo dstInfo = { texture, dstLevel, +dstFace };
|
||||
|
||||
Handle<HwRenderTarget> srcRenderTarget;
|
||||
srcRenderTarget = api.createRenderTarget( TargetBufferFlags::COLOR,
|
||||
@@ -425,14 +425,14 @@ TEST_F(BackendTest, DepthMinify) {
|
||||
Handle<HwRenderTarget> srcRenderTarget = api.createRenderTarget(
|
||||
TargetBufferFlags::COLOR | TargetBufferFlags::DEPTH,
|
||||
kSrcTexWidth >> level, kSrcTexHeight >> level, 1,
|
||||
{ srcColorTexture, level, 0 },
|
||||
{ srcDepthTexture, level, 0 }, {});
|
||||
{{ srcColorTexture, level }},
|
||||
{ srcDepthTexture, level }, {});
|
||||
|
||||
Handle<HwRenderTarget> dstRenderTarget = api.createRenderTarget(
|
||||
TargetBufferFlags::COLOR | TargetBufferFlags::DEPTH,
|
||||
kDstTexWidth >> level, kDstTexHeight >> level, 1,
|
||||
{ dstColorTexture, level, 0 },
|
||||
{ dstDepthTexture, level, 0 }, {});
|
||||
{{ dstColorTexture, level }},
|
||||
{ dstDepthTexture, level }, {});
|
||||
|
||||
// Prep for rendering.
|
||||
RenderPassParams params = {};
|
||||
@@ -555,11 +555,11 @@ TEST_F(BackendTest, ColorResolve) {
|
||||
|
||||
// Create a 4-sample render target with the 4-sample texture.
|
||||
Handle<HwRenderTarget> srcRenderTarget = api.createRenderTarget(
|
||||
TargetBufferFlags::COLOR, kSrcTexWidth, kSrcTexHeight, kSampleCount, { srcColorTexture }, {}, {});
|
||||
TargetBufferFlags::COLOR, kSrcTexWidth, kSrcTexHeight, kSampleCount,{{ srcColorTexture }}, {}, {});
|
||||
|
||||
// Create a 1-sample render target with the 1-sample texture.
|
||||
Handle<HwRenderTarget> dstRenderTarget = api.createRenderTarget(
|
||||
TargetBufferFlags::COLOR, kDstTexWidth, kDstTexHeight, 1, { dstColorTexture }, {}, {});
|
||||
TargetBufferFlags::COLOR, kDstTexWidth, kDstTexHeight, 1, {{ dstColorTexture }}, {}, {});
|
||||
|
||||
// Prep for rendering.
|
||||
RenderPassParams params = {};
|
||||
@@ -672,12 +672,12 @@ TEST_F(BackendTest, DepthResolve) {
|
||||
// Create a 4-sample render target with 4-sample textures.
|
||||
Handle<HwRenderTarget> srcRenderTarget = api.createRenderTarget(
|
||||
TargetBufferFlags::COLOR | TargetBufferFlags::DEPTH, kSrcTexWidth, kSrcTexHeight,
|
||||
kSampleCount, { srcColorTexture }, { srcDepthTexture }, {});
|
||||
kSampleCount, {{ srcColorTexture }}, { srcDepthTexture }, {});
|
||||
|
||||
// Create a 1-sample render target with 1-sample textures.
|
||||
Handle<HwRenderTarget> dstRenderTarget = api.createRenderTarget(
|
||||
TargetBufferFlags::COLOR | TargetBufferFlags::DEPTH, kDstTexWidth, kDstTexHeight,
|
||||
1, { dstColorTexture }, { dstDepthTexture }, {});
|
||||
1, {{ dstColorTexture }}, { dstDepthTexture }, {});
|
||||
|
||||
// Prep for rendering.
|
||||
RenderPassParams params = {};
|
||||
|
||||
@@ -101,7 +101,7 @@ TEST_F(BackendTest, MRT) {
|
||||
512, // width
|
||||
512, // height
|
||||
1, // samples
|
||||
{ textureA, textureB }, // color
|
||||
{{textureA },{textureB }}, // color
|
||||
{}, // depth
|
||||
{}); // stencil
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ TEST_F(ReadPixelsTest, ReadPixels) {
|
||||
// level (at least for OpenGL).
|
||||
Handle<HwRenderTarget> renderTarget = getDriverApi().createRenderTarget(
|
||||
TargetBufferFlags::COLOR, t.getRenderTargetSize(),
|
||||
t.getRenderTargetSize(), t.samples, TargetBufferInfo(texture, t.mipLevel), {},
|
||||
t.getRenderTargetSize(), t.samples, {{ texture, uint8_t(t.mipLevel) }}, {},
|
||||
{});
|
||||
|
||||
TrianglePrimitive triangle(getDriverApi());
|
||||
@@ -290,7 +290,7 @@ TEST_F(ReadPixelsTest, ReadPixels) {
|
||||
RenderPassParams p = params;
|
||||
Handle<HwRenderTarget> mipLevelOneRT = getDriverApi().createRenderTarget(
|
||||
TargetBufferFlags::COLOR, renderTargetBaseSize, renderTargetBaseSize, 1,
|
||||
TargetBufferInfo(texture, 0), {},
|
||||
{{ texture }}, {},
|
||||
{});
|
||||
p.clearColor = {1.f, 0.f, 0.f, 1.f};
|
||||
getDriverApi().beginRenderPass(mipLevelOneRT, p);
|
||||
@@ -378,7 +378,7 @@ TEST_F(ReadPixelsTest, ReadPixelsPerformance) {
|
||||
renderTargetSize, // width
|
||||
renderTargetSize, // height
|
||||
1, // samples
|
||||
TargetBufferInfo(texture, 0), // color
|
||||
{{ texture }}, // color
|
||||
{}, // depth
|
||||
{}); // stencil
|
||||
|
||||
|
||||
@@ -686,7 +686,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::screenSpaceAmbientOcclusion(
|
||||
// create a temporary render target for source, needed for the blit.
|
||||
auto inTarget = driver.createRenderTarget(TargetBufferFlags::DEPTH,
|
||||
desc.width, desc.height, desc.samples, {},
|
||||
resources.getTexture(data.input), {});
|
||||
{ resources.getTexture(data.input) }, {});
|
||||
driver.blit(TargetBufferFlags::DEPTH,
|
||||
out.target, out.params.viewport,
|
||||
inTarget, out.params.viewport,
|
||||
@@ -2965,7 +2965,7 @@ FrameGraphId<FrameGraphTexture> PostProcessManager::resolveBaseLevelNoCheck(Fram
|
||||
if (data.usage == FrameGraphTexture::Usage::COLOR_ATTACHMENT) {
|
||||
inRt = driver.createRenderTarget(data.inFlags,
|
||||
out.params.viewport.width, out.params.viewport.height,
|
||||
inDesc.samples, { in }, {}, {});
|
||||
inDesc.samples, {{ in }}, {}, {});
|
||||
}
|
||||
if (data.usage == FrameGraphTexture::Usage::DEPTH_ATTACHMENT) {
|
||||
inRt = driver.createRenderTarget(data.inFlags,
|
||||
|
||||
@@ -278,6 +278,11 @@ void FEngine::init() {
|
||||
// Create a dummy morph target buffer.
|
||||
mDummyMorphTargetBuffer = createMorphTargetBuffer(FMorphTargetBuffer::EmptyMorphTargetBuilder());
|
||||
|
||||
float3 dummyPositions[1] = {};
|
||||
short4 dummyTangents[1] = {};
|
||||
mDummyMorphTargetBuffer->setPositionsAt(*this, 0, dummyPositions, 1, 0);
|
||||
mDummyMorphTargetBuffer->setTangentsAt(*this, 0, dummyTangents, 1, 0);
|
||||
|
||||
// create dummy textures we need throughout the engine
|
||||
|
||||
mDummyOneTexture = driverApi.createTexture(SamplerType::SAMPLER_2D, 1,
|
||||
|
||||
@@ -133,7 +133,7 @@ FRenderTarget::FRenderTarget(FEngine& engine, const RenderTarget::Builder& build
|
||||
info.handle = t->getHwHandle();
|
||||
info.level = attachment.mipLevel;
|
||||
if (t->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP) {
|
||||
info.face = attachment.face;
|
||||
info.layer = +attachment.face;
|
||||
} else {
|
||||
info.layer = attachment.layer;
|
||||
}
|
||||
@@ -160,4 +160,9 @@ void FRenderTarget::terminate(FEngine& engine) {
|
||||
driver.destroyRenderTarget(mHandle);
|
||||
}
|
||||
|
||||
bool FRenderTarget::hasSampleableDepth() const noexcept {
|
||||
const FTexture* depth = mAttachments[(size_t)AttachmentPoint::DEPTH].texture;
|
||||
return depth && (depth->getUsage() & TextureUsage::SAMPLEABLE) == TextureUsage::SAMPLEABLE;
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -59,6 +59,8 @@ public:
|
||||
return mSupportedColorAttachmentsCount;
|
||||
}
|
||||
|
||||
bool hasSampleableDepth() const noexcept;
|
||||
|
||||
private:
|
||||
friend class RenderTarget;
|
||||
static constexpr size_t ATTACHMENT_COUNT = MAX_SUPPORTED_COLOR_ATTACHMENTS_COUNT + 1u;
|
||||
|
||||
@@ -855,6 +855,9 @@ FrameGraphId<FrameGraphTexture> FRenderer::colorPass(FrameGraph& fg, const char*
|
||||
data.color = builder.createTexture("Color Buffer", colorBufferDesc);
|
||||
}
|
||||
|
||||
DriverApi& driver = mEngine.getDriverApi();
|
||||
const bool canResolveDepth = driver.isAutoDepthResolveSupported();
|
||||
|
||||
if (!data.depth) {
|
||||
// clear newly allocated depth buffers, regardless of given clear flags
|
||||
clearDepthFlags = TargetBufferFlags::DEPTH;
|
||||
@@ -867,7 +870,7 @@ FrameGraphId<FrameGraphTexture> FRenderer::colorPass(FrameGraph& fg, const char*
|
||||
// MS, no need to allocate the depth buffer with MS, if the RT is MS,
|
||||
// the tile depth buffer will be MS, but it'll be resolved to single
|
||||
// sample automatically -- which is what we want.
|
||||
.samples = colorBufferDesc.samples,
|
||||
.samples = canResolveDepth ? colorBufferDesc.samples : uint8_t(config.msaa),
|
||||
.format = TextureFormat::DEPTH32F,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -452,16 +452,18 @@ void FTexture::generateMipmaps(FEngine& engine) const noexcept {
|
||||
|
||||
switch (mTarget) {
|
||||
case SamplerType::SAMPLER_2D:
|
||||
generateMipsForLayer(TargetBufferInfo{ 0 });
|
||||
generateMipsForLayer({});
|
||||
break;
|
||||
case SamplerType::SAMPLER_2D_ARRAY:
|
||||
UTILS_NOUNROLL
|
||||
for (uint16_t layer = 0, c = mDepth; layer < c; ++layer) {
|
||||
generateMipsForLayer(TargetBufferInfo{ layer });
|
||||
generateMipsForLayer({ .layer = layer });
|
||||
}
|
||||
break;
|
||||
case SamplerType::SAMPLER_CUBEMAP:
|
||||
UTILS_NOUNROLL
|
||||
for (uint8_t face = 0; face < 6; ++face) {
|
||||
generateMipsForLayer(TargetBufferInfo{ TextureCubemapFace(face) });
|
||||
generateMipsForLayer({ .layer = face });
|
||||
}
|
||||
break;
|
||||
case SamplerType::SAMPLER_EXTERNAL:
|
||||
|
||||
@@ -935,6 +935,7 @@ void FView::setTemporalAntiAliasingOptions(TemporalAntiAliasingOptions options)
|
||||
void FView::setMultiSampleAntiAliasingOptions(MultiSampleAntiAliasingOptions options) noexcept {
|
||||
options.sampleCount = uint8_t(options.sampleCount < 1u ? 1u : options.sampleCount);
|
||||
mMultiSampleAntiAliasingOptions = options;
|
||||
assert_invariant(!options.enabled || !mRenderTarget || !mRenderTarget->hasSampleableDepth());
|
||||
}
|
||||
|
||||
void FView::setScreenSpaceReflectionsOptions(ScreenSpaceReflectionsOptions options) noexcept {
|
||||
|
||||
@@ -217,6 +217,8 @@ public:
|
||||
}
|
||||
|
||||
void setRenderTarget(FRenderTarget* renderTarget) noexcept {
|
||||
assert_invariant(!renderTarget || !mMultiSampleAntiAliasingOptions.enabled ||
|
||||
!renderTarget->hasSampleableDepth());
|
||||
mRenderTarget = renderTarget;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = "Filament"
|
||||
spec.version = "1.20.2"
|
||||
spec.version = "1.20.3"
|
||||
spec.license = { :type => "Apache 2.0", :file => "LICENSE" }
|
||||
spec.homepage = "https://google.github.io/filament"
|
||||
spec.authors = "Google LLC."
|
||||
spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL."
|
||||
spec.platform = :ios, "11.0"
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.20.2/filament-v1.20.2-ios.tgz" }
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.20.3/filament-v1.20.3-ios.tgz" }
|
||||
|
||||
# Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon.
|
||||
spec.pod_target_xcconfig = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "filament",
|
||||
"version": "1.20.2",
|
||||
"version": "1.20.3",
|
||||
"description": "Real-time physically based rendering engine",
|
||||
"main": "filament.js",
|
||||
"module": "filament.js",
|
||||
|
||||
Reference in New Issue
Block a user