Skip to content

Commit

Permalink
Merge branch 'rc/1.9.8' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
bejado committed Nov 9, 2020
2 parents bcdad76 + 75af254 commit 06d9183
Show file tree
Hide file tree
Showing 41 changed files with 608 additions and 275 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.9.7'
implementation 'com.google.android.filament:filament-android:1.9.8'
}
```

Expand Down Expand Up @@ -63,7 +63,7 @@ A much smaller alternative to `filamat-android` that can only generate OpenGL sh
iOS projects can use CocoaPods to install the latest release:

```
pod 'Filament', '~> 1.9.7'
pod 'Filament', '~> 1.9.8'
```

### Snapshots
Expand Down
12 changes: 12 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ A new header is inserted each time a *tag* is created.

## Next release (main branch)

## v1.9.8

- Fix a few Fence-related bugs
- gltfio: add createInstance() to AssetLoader.
- gltfio: fix ASAN issue when consuming invalid animation.
- gltfio: do not segfault on invalid primitives.
- gltfio: add safety checks to getAnimator.
- gltfio: fix segfault when consuming invalid file.
- Vulkan: various internal refactoring and improvements
- mathio: add ostream operator for quaternions.
- Fix color grading not applied when dithering is off.

## v1.9.7

- Vulkan: improvements to the ReadPixels implementation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,32 @@ public FilamentAsset createInstancedAsset(@NonNull Buffer buffer,
return new FilamentAsset(mEngine, nativeAsset);
}

/**
* Adds a new instance to an instanced asset.
*
* Use this with caution. It is more efficient to pre-allocate a max number of instances, and
* gradually add them to the scene as needed. Instances can also be "recycled" by removing and
* re-adding them to the scene.
*
* NOTE: destroyInstance() does not exist because gltfio favors flat arrays for storage of
* entity lists and instance lists, which would be slow to shift. We also wish to discourage
* create/destroy churn, as noted above.
*
* This cannot be called after FilamentAsset#releaseSourceData().
* This cannot be called on a non-instanced asset.
* Animation is not supported in new instances.
* See also AssetLoader#createInstancedAsset().
*/
@Nullable
@SuppressWarnings("unused")
public FilamentInstance createInstance(@NonNull FilamentAsset asset) {
long nativeInstance = nCreateInstance(mNativeObject, asset.getNativeObject());
if (nativeInstance == 0) {
return null;
}
return new FilamentInstance(nativeInstance);
}

/**
* Allows clients to enable diagnostic shading on newly-loaded assets.
*/
Expand All @@ -175,6 +201,7 @@ private static native long nCreateAssetLoader(long nativeEngine, long nativeGene
private static native long nCreateAssetFromJson(long nativeLoader, Buffer buffer, int remaining);
private static native long nCreateInstancedAsset(long nativeLoader, Buffer buffer, int remaining,
long[] nativeInstances);
private static native long nCreateInstance(long nativeLoader, long nativeAsset);
private static native void nEnableDiagnostics(long nativeLoader, boolean enable);
private static native void nDestroyAsset(long nativeLoader, long nativeAsset);
}
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,11 @@ public String getName(@Entity int entity) {
if (mAnimator != null) {
return mAnimator;
}
mAnimator = new Animator(nGetAnimator(getNativeObject()));
long nativeAnimator = nGetAnimator(getNativeObject());
if (nativeAnimator == 0) {
throw new IllegalStateException("Unable to create animator");
}
mAnimator = new Animator(nativeAnimator);
return mAnimator;
}

Expand All @@ -215,6 +219,7 @@ public String getName(@Entity int entity) {
*
* This should only be called after ResourceLoader#loadResources().
* If using Animator, this should be called after getAnimator().
* If this is an instanced asset, this prevents creation of new instances.
*/
public void releaseSourceData() {
nReleaseSourceData(mNativeObject);
Expand Down
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.9.7
VERSION_NAME=1.9.8

POM_DESCRIPTION=Real-time physically based rendering engine for Android.

Expand Down
1 change: 1 addition & 0 deletions filament/backend/src/metal/MetalHandles.mm
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ static MTLPixelFormat decidePixelFormat(id<MTLDevice> device, TextureFormat form
FenceStatus MetalFence::wait(uint64_t timeoutNs) {
if (@available(macOS 10.14, iOS 12, *)) {
std::unique_lock<std::mutex> guard(state->mutex);
timeoutNs = std::min(timeoutNs, (uint64_t) std::chrono::nanoseconds::max().count());
while (state->status == FenceStatus::TIMEOUT_EXPIRED) {
if (timeoutNs == 0 ||
state->cv.wait_for(guard, std::chrono::nanoseconds(timeoutNs)) ==
Expand Down
4 changes: 2 additions & 2 deletions filament/backend/src/vulkan/VulkanBinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ bool VulkanBinder::getOrCreatePipeline(VkPipeline* pipeline) noexcept {
pipelineCreateInfo.pDynamicState = &dynamicState;

// Filament assumes consistent blend state across all color attachments.
mColorBlendState.attachmentCount = mPipelineKey.rasterState.getColorTargetCount;
mColorBlendState.attachmentCount = mPipelineKey.rasterState.colorTargetCount;
for (auto& target : mColorBlendAttachments) {
target = mPipelineKey.rasterState.blending;
}
Expand Down Expand Up @@ -333,7 +333,7 @@ void VulkanBinder::bindRasterState(const RasterState& rasterState) noexcept {
VkPipelineMultisampleStateCreateInfo& ms0 = mPipelineKey.rasterState.multisampling;
const VkPipelineMultisampleStateCreateInfo& ms1 = rasterState.multisampling;
if (
mPipelineKey.rasterState.getColorTargetCount != rasterState.getColorTargetCount ||
mPipelineKey.rasterState.colorTargetCount != rasterState.colorTargetCount ||
raster0.polygonMode != raster1.polygonMode ||
raster0.cullMode != raster1.cullMode ||
raster0.frontFace != raster1.frontFace ||
Expand Down
2 changes: 1 addition & 1 deletion filament/backend/src/vulkan/VulkanBinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class VulkanBinder {
VkPipelineColorBlendAttachmentState blending;
VkPipelineDepthStencilStateCreateInfo depthStencil;
VkPipelineMultisampleStateCreateInfo multisampling;
uint32_t getColorTargetCount;
uint32_t colorTargetCount;
};
static_assert(std::is_pod<RasterState>::value, "RasterState must be a POD for fast hashing.");

Expand Down
118 changes: 118 additions & 0 deletions filament/backend/src/vulkan/VulkanContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@
#pragma clang diagnostic pop

#include "VulkanContext.h"
#include "VulkanHandles.h"
#include "VulkanUtility.h"

#include <utils/Panic.h>

#define FILAMENT_VULKAN_CHECK_BLIT_FORMAT 0

namespace filament {
namespace backend {

Expand Down Expand Up @@ -831,5 +834,120 @@ VkImageLayout getTextureLayout(TextureUsage usage) {
return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
}

static void blit(VkImageAspectFlags aspect, VkFilter filter, VulkanContext* context,
const VulkanRenderTarget* srcTarget, VulkanAttachment src, VulkanAttachment dst,
const VkOffset3D srcRect[2], const VkOffset3D dstRect[2], VkCommandBuffer cmdbuffer) {
const VkImageBlit blitRegions[1] = {{
.srcSubresource = { aspect, src.level, src.layer, 1 },
.srcOffsets = { srcRect[0], srcRect[1] },
.dstSubresource = { aspect, dst.level, dst.layer, 1 },
.dstOffsets = { dstRect[0], dstRect[1] }
}};

const VkExtent2D srcExtent = srcTarget->getExtent();

const VkImageResolve resolveRegions[1] = {{
.srcSubresource = { aspect, src.level, src.layer, 1 },
.srcOffset = srcRect[0],
.dstSubresource = { aspect, dst.level, dst.layer, 1 },
.dstOffset = dstRect[0],
.extent = { srcExtent.width, srcExtent.height, 1 }
}};

VulkanTexture::transitionImageLayout(cmdbuffer, src.image, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, src.level, 1, 1, aspect);

VulkanTexture::transitionImageLayout(cmdbuffer, dst.image, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst.level, 1, 1, aspect);

if (src.texture && src.texture->samples > 1 && dst.texture && dst.texture->samples == 1) {
vkCmdResolveImage(cmdbuffer, src.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst.image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, resolveRegions);
} else {
vkCmdBlitImage(cmdbuffer, src.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst.image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, blitRegions, filter);
}

if (src.texture) {
VulkanTexture::transitionImageLayout(cmdbuffer, src.image, VK_IMAGE_LAYOUT_UNDEFINED,
getTextureLayout(src.texture->usage), src.level, 1, 1, aspect);
} else if (!context->currentSurface->headlessQueue) {
VulkanTexture::transitionImageLayout(cmdbuffer, src.image, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, src.level, 1, 1, aspect);
}

// Determine the desired texture layout for the destination while ensuring that the default
// render target is supported, which has no associated texture.
const VkImageLayout desiredLayout = dst.texture ? getTextureLayout(dst.texture->usage) :
getSwapContext(*context).attachment.layout;

VulkanTexture::transitionImageLayout(cmdbuffer, dst.image, VK_IMAGE_LAYOUT_UNDEFINED,
desiredLayout, dst.level, 1, 1, aspect);
}

void blitDepth(VulkanContext* context, const VulkanRenderTarget* dstTarget,
const VkOffset3D dstRect[2], const VulkanRenderTarget* srcTarget,
const VkOffset3D srcRect[2]) {
const VulkanAttachment src = srcTarget->getDepth();
const VulkanAttachment dst = dstTarget->getDepth();
const VkImageAspectFlags aspect = VK_IMAGE_ASPECT_DEPTH_BIT;

#if FILAMENT_VULKAN_CHECK_BLIT_FORMAT
const VkPhysicalDevice gpu = context->physicalDevice;
VkFormatProperties info;
vkGetPhysicalDeviceFormatProperties(gpu, src.format, &info);
if (!ASSERT_POSTCONDITION_NON_FATAL(info.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT,
"Depth format is not blittable")) {
return;
}
vkGetPhysicalDeviceFormatProperties(gpu, dst.format, &info);
if (!ASSERT_POSTCONDITION_NON_FATAL(info.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT,
"Depth format is not blittable")) {
return;
}
#endif

if (!context->currentCommands) {
VkCommandBuffer cmdbuf = acquireWorkCommandBuffer(*context);
blit(aspect, VK_FILTER_NEAREST, context, srcTarget, src, dst, srcRect, dstRect, cmdbuf);
flushWorkCommandBuffer(*context);
} else {
VkCommandBuffer cmdbuf = context->currentCommands->cmdbuffer;
blit(aspect, VK_FILTER_NEAREST, context, srcTarget, src, dst, srcRect, dstRect, cmdbuf);
}
}

void blitColor(VulkanContext* context, const VulkanRenderTarget* dstTarget,
const VkOffset3D dstRect[2], const VulkanRenderTarget* srcTarget,
const VkOffset3D srcRect[2], VkFilter filter, int targetIndex) {
const VulkanAttachment src = srcTarget->getColor(targetIndex);
const VulkanAttachment dst = dstTarget->getColor(0);
const VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;

#if FILAMENT_VULKAN_CHECK_BLIT_FORMAT
const VkPhysicalDevice gpu = context->physicalDevice;
VkFormatProperties info;
vkGetPhysicalDeviceFormatProperties(gpu, src.format, &info);
if (!ASSERT_POSTCONDITION_NON_FATAL(info.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT,
"Source format is not blittable")) {
return;
}
vkGetPhysicalDeviceFormatProperties(gpu, dst.format, &info);
if (!ASSERT_POSTCONDITION_NON_FATAL(info.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT,
"Destination format is not blittable")) {
return;
}
#endif

if (!context->currentCommands) {
VkCommandBuffer cmdbuf = acquireWorkCommandBuffer(*context);
blit(aspect, filter, context, srcTarget, src, dst, srcRect, dstRect, cmdbuf);
flushWorkCommandBuffer(*context);
} else {
VkCommandBuffer cmdbuf = context->currentCommands->cmdbuffer;
blit(aspect, filter, context, srcTarget, src, dst, srcRect, dstRect, cmdbuf);
}
}

} // namespace filament
} // namespace backend
9 changes: 9 additions & 0 deletions filament/backend/src/vulkan/VulkanContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ constexpr VkAllocationCallbacks* VKALLOC = nullptr;
constexpr static const int VK_REQUIRED_VERSION_MAJOR = 1;
constexpr static const int VK_REQUIRED_VERSION_MINOR = 0;

struct VulkanRenderTarget;
struct VulkanSurfaceContext;
struct VulkanTexture;

Expand Down Expand Up @@ -176,6 +177,14 @@ void flushWorkCommandBuffer(VulkanContext& context);
void createFinalDepthBuffer(VulkanContext& context, VulkanSurfaceContext& sc, VkFormat depthFormat);
VkImageLayout getTextureLayout(TextureUsage usage);

void blitDepth(VulkanContext* context, const VulkanRenderTarget* dstTarget,
const VkOffset3D dstRect[2], const VulkanRenderTarget* srcTarget,
const VkOffset3D srcRect[2]);

void blitColor(VulkanContext* context, const VulkanRenderTarget* dstTarget,
const VkOffset3D dstRect[2], const VulkanRenderTarget* srcTarget,
const VkOffset3D srcRect[2], VkFilter filter, int index);

} // namespace filament
} // namespace backend

Expand Down
Loading

0 comments on commit 06d9183

Please sign in to comment.