From cf91e42847d3772555aa5fd95073caa97a86de31 Mon Sep 17 00:00:00 2001 From: Ben Doherty Date: Fri, 24 May 2024 13:46:34 -0700 Subject: [PATCH] Switch ASSERT macros to new stream API (#7881) --- filament/backend/src/Callable.cpp | 4 +- filament/backend/src/metal/MetalBlitter.mm | 11 +- filament/backend/src/metal/MetalBuffer.mm | 11 +- filament/backend/src/metal/MetalBufferPool.mm | 3 +- filament/backend/src/metal/MetalContext.mm | 3 +- filament/backend/src/metal/MetalDriver.mm | 213 +++++++++--------- filament/backend/src/metal/MetalEnums.h | 7 +- .../backend/src/metal/MetalExternalImage.mm | 26 +-- filament/backend/src/metal/MetalHandles.mm | 49 ++-- filament/backend/src/metal/MetalState.mm | 2 +- filament/backend/src/opengl/OpenGLDriver.cpp | 31 ++- .../opengl/platforms/CocoaExternalImage.mm | 4 +- .../platforms/CocoaTouchExternalImage.mm | 11 +- .../src/opengl/platforms/PlatformCocoaGL.mm | 2 +- .../opengl/platforms/PlatformCocoaTouchGL.mm | 7 +- .../src/opengl/platforms/PlatformGLX.cpp | 2 +- .../src/opengl/platforms/PlatformWGL.cpp | 2 +- filament/backend/src/vulkan/VulkanContext.cpp | 6 +- filament/backend/src/vulkan/VulkanDriver.cpp | 79 +++---- .../backend/src/vulkan/VulkanFboCache.cpp | 8 +- filament/backend/src/vulkan/VulkanHandles.cpp | 2 +- .../backend/src/vulkan/VulkanReadPixels.cpp | 8 +- .../backend/src/vulkan/VulkanSamplerCache.cpp | 2 +- .../backend/src/vulkan/VulkanSwapChain.cpp | 17 +- filament/backend/src/vulkan/VulkanTexture.cpp | 10 +- filament/backend/src/vulkan/VulkanUtility.cpp | 2 +- filament/backend/src/vulkan/VulkanUtility.h | 14 +- .../caching/VulkanDescriptorSetManager.cpp | 6 +- .../src/vulkan/platform/VulkanPlatform.cpp | 44 ++-- .../VulkanPlatformAndroidLinuxWindows.cpp | 24 +- .../vulkan/platform/VulkanPlatformApple.mm | 12 +- .../platform/VulkanPlatformSwapChainImpl.cpp | 24 +- filament/include/filament/SwapChain.h | 2 +- filament/src/Engine.cpp | 9 +- filament/src/RenderPass.cpp | 3 +- filament/src/RendererUtils.cpp | 17 +- filament/src/components/RenderableManager.cpp | 148 ++++++------ filament/src/components/RenderableManager.h | 18 +- filament/src/details/Camera.cpp | 30 +-- filament/src/details/Engine.cpp | 30 +-- filament/src/details/Fence.cpp | 3 +- filament/src/details/IndirectLight.cpp | 12 +- filament/src/details/InstanceBuffer.cpp | 21 +- filament/src/details/Material.cpp | 64 +++--- filament/src/details/MorphTargetBuffer.cpp | 33 ++- filament/src/details/RenderTarget.cpp | 18 +- filament/src/details/Renderer.cpp | 14 +- filament/src/details/SkinningBuffer.cpp | 16 +- filament/src/details/Skybox.cpp | 4 +- filament/src/details/Texture.cpp | 152 +++++++------ filament/src/details/VertexBuffer.cpp | 52 +++-- filament/src/details/View.cpp | 6 +- filament/src/fg/FrameGraph.cpp | 12 +- filament/src/fg/FrameGraphResources.cpp | 15 +- filament/src/fg/Resource.cpp | 6 +- filament/src/fg/details/Resource.h | 7 +- libs/bluevk/src/BlueVKDarwin.cpp | 7 +- libs/filabridge/src/BufferInterfaceBlock.cpp | 15 +- libs/filabridge/src/SamplerInterfaceBlock.cpp | 3 +- libs/filamat/src/MaterialBuilder.cpp | 70 +++--- libs/filamentapp/src/FilamentApp.cpp | 2 +- .../src/NativeWindowHelperCocoa.mm | 6 +- .../src/NativeWindowHelperLinux.cpp | 3 +- .../src/NativeWindowHelperWindows.cpp | 3 +- libs/geometry/src/TangentSpaceMesh.cpp | 32 +-- libs/gltfio/src/AssetLoader.cpp | 4 +- libs/gltfio/src/FilamentInstance.cpp | 11 +- libs/iblprefilter/src/IBLPrefilterContext.cpp | 52 +++-- libs/image/src/ImageOps.cpp | 38 ++-- libs/image/src/ImageSampler.cpp | 13 +- libs/image/src/Ktx1Bundle.cpp | 8 +- libs/image/tests/test_image.cpp | 5 +- libs/imageio/src/ImageDiffer.cpp | 4 +- .../utils/include/utils/FixedCapacityVector.h | 6 +- libs/utils/include/utils/RangeMap.h | 3 +- libs/utils/src/JobSystem.cpp | 30 +-- samples/multiple_windows.cpp | 2 +- 77 files changed, 855 insertions(+), 800 deletions(-) diff --git a/filament/backend/src/Callable.cpp b/filament/backend/src/Callable.cpp index 524d06a75dc9..2c19e2a78630 100644 --- a/filament/backend/src/Callable.cpp +++ b/filament/backend/src/Callable.cpp @@ -27,8 +27,8 @@ PresentCallable::PresentCallable(PresentFn fn, void* user) noexcept } void PresentCallable::operator()(bool presentFrame) noexcept { - ASSERT_PRECONDITION(mPresentFn, "This PresentCallable was already called. " \ - "PresentCallables should be called exactly once."); + FILAMENT_CHECK_PRECONDITION(mPresentFn) << "This PresentCallable was already called. " + "PresentCallables should be called exactly once."; mPresentFn(presentFrame, mUser); // Set mPresentFn to nullptr to denote that the callable has been called. mPresentFn = nullptr; diff --git a/filament/backend/src/metal/MetalBlitter.mm b/filament/backend/src/metal/MetalBlitter.mm index 51e1fc3b88d5..6675434bce8a 100644 --- a/filament/backend/src/metal/MetalBlitter.mm +++ b/filament/backend/src/metal/MetalBlitter.mm @@ -109,9 +109,8 @@ inline bool MTLSizeEqual(T a, T b) noexcept { MetalBlitter::MetalBlitter(MetalContext& context) noexcept : mContext(context) { } void MetalBlitter::blit(id cmdBuffer, const BlitArgs& args, const char* label) { - - ASSERT_PRECONDITION(args.source.region.size.depth == args.destination.region.size.depth, - "Blitting requires the source and destination regions to have the same depth."); + FILAMENT_CHECK_PRECONDITION(args.source.region.size.depth == args.destination.region.size.depth) + << "Blitting requires the source and destination regions to have the same depth."; // Determine if the blit for color or depth are eligible to use a MTLBlitCommandEncoder. // blitFastPath returns true upon success. @@ -327,7 +326,8 @@ inline bool MTLSizeEqual(T a, T b) noexcept { utils::slog.e << description << utils::io::endl; } } - ASSERT_POSTCONDITION(library && function, "Unable to compile fragment shader for MetalBlitter."); + FILAMENT_CHECK_POSTCONDITION(library && function) + << "Unable to compile fragment shader for MetalBlitter."; return function; } @@ -352,7 +352,8 @@ inline bool MTLSizeEqual(T a, T b) noexcept { utils::slog.e << description << utils::io::endl; } } - ASSERT_POSTCONDITION(library && function, "Unable to compile vertex shader for MetalBlitter."); + FILAMENT_CHECK_POSTCONDITION(library && function) + << "Unable to compile vertex shader for MetalBlitter."; mVertexFunction = function; diff --git a/filament/backend/src/metal/MetalBuffer.mm b/filament/backend/src/metal/MetalBuffer.mm index 5f09a290781b..83fe25d59835 100644 --- a/filament/backend/src/metal/MetalBuffer.mm +++ b/filament/backend/src/metal/MetalBuffer.mm @@ -44,7 +44,8 @@ mBuffer = { [context.device newBufferWithLength:size options:MTLResourceStorageModePrivate], TrackedMetalBuffer::Type::GENERIC }; } - ASSERT_POSTCONDITION(mBuffer, "Could not allocate Metal buffer of size %zu.", size); + FILAMENT_CHECK_POSTCONDITION(mBuffer) + << "Could not allocate Metal buffer of size " << size << "."; } MetalBuffer::~MetalBuffer() { @@ -57,9 +58,9 @@ if (size <= 0) { return; } - ASSERT_PRECONDITION(size + byteOffset <= mBufferSize, - "Attempting to copy %zu bytes into a buffer of size %zu at offset %zu", - size, mBufferSize, byteOffset); + FILAMENT_CHECK_PRECONDITION(size + byteOffset <= mBufferSize) + << "Attempting to copy " << size << " bytes into a buffer of size " << mBufferSize + << " at offset " << byteOffset; // Either copy into the Metal buffer or into our cpu buffer. if (mCpuBuffer) { @@ -73,7 +74,7 @@ memcpy(staging->buffer.get().contents, src, size); // The blit below requires that byteOffset be a multiple of 4. - ASSERT_PRECONDITION(!(byteOffset & 0x3u), "byteOffset must be a multiple of 4"); + FILAMENT_CHECK_PRECONDITION(!(byteOffset & 0x3u)) << "byteOffset must be a multiple of 4"; // Encode a blit from the staging buffer into the private GPU buffer. id cmdBuffer = getPendingCommandBuffer(&mContext); diff --git a/filament/backend/src/metal/MetalBufferPool.mm b/filament/backend/src/metal/MetalBufferPool.mm index a1e54a462391..c9a80e83520f 100644 --- a/filament/backend/src/metal/MetalBufferPool.mm +++ b/filament/backend/src/metal/MetalBufferPool.mm @@ -48,7 +48,8 @@ buffer = [mContext.device newBufferWithLength:numBytes options:MTLResourceStorageModeShared]; } - ASSERT_POSTCONDITION(buffer, "Could not allocate Metal staging buffer of size %zu.", numBytes); + FILAMENT_CHECK_POSTCONDITION(buffer) + << "Could not allocate Metal staging buffer of size " << numBytes << "."; MetalBufferPoolEntry* stage = new MetalBufferPoolEntry { .buffer = { buffer, TrackedMetalBuffer::Type::STAGING }, .capacity = numBytes, diff --git a/filament/backend/src/metal/MetalContext.mm b/filament/backend/src/metal/MetalContext.mm index 3997944521cc..6eb7518d31c2 100644 --- a/filament/backend/src/metal/MetalContext.mm +++ b/filament/backend/src/metal/MetalContext.mm @@ -113,7 +113,8 @@ void initializeSupportedGpuFamilies(MetalContext* context) { } } }]; - ASSERT_POSTCONDITION(context->pendingCommandBuffer, "Could not obtain command buffer."); + FILAMENT_CHECK_POSTCONDITION(context->pendingCommandBuffer) + << "Could not obtain command buffer."; return context->pendingCommandBuffer; } diff --git a/filament/backend/src/metal/MetalDriver.mm b/filament/backend/src/metal/MetalDriver.mm index a9d963e784f6..58852a671437 100644 --- a/filament/backend/src/metal/MetalDriver.mm +++ b/filament/backend/src/metal/MetalDriver.mm @@ -181,7 +181,8 @@ CVReturn success = CVMetalTextureCacheCreate(kCFAllocatorDefault, nullptr, mContext->device, nullptr, &mContext->textureCache); - ASSERT_POSTCONDITION(success == kCVReturnSuccess, "Could not create Metal texture cache."); + FILAMENT_CHECK_POSTCONDITION(success == kCVReturnSuccess) + << "Could not create Metal texture cache."; if (@available(iOS 12, *)) { dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0); @@ -289,14 +290,14 @@ } void MetalDriver::flush(int) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "flush must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "flush must be called outside of a render pass."; submitPendingCommands(mContext); } void MetalDriver::finish(int) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "finish must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "finish must be called outside of a render pass."; // Wait for all frames to finish by submitting and waiting on a dummy command buffer. submitPendingCommands(mContext); id oneOffBuffer = [mContext->commandQueue commandBuffer]; @@ -357,19 +358,19 @@ TextureFormat format, uint8_t samples, uint32_t width, uint32_t height, uint32_t depth, TextureUsage usage) { id metalTexture = (id) CFBridgingRelease((void*) i); - ASSERT_PRECONDITION(metalTexture.width == width, - "Imported id width (%d) != Filament texture width (%d)", - metalTexture.width, width); - ASSERT_PRECONDITION(metalTexture.height == height, - "Imported id height (%d) != Filament texture height (%d)", - metalTexture.height, height); - ASSERT_PRECONDITION(metalTexture.mipmapLevelCount == levels, - "Imported id levels (%d) != Filament texture levels (%d)", - metalTexture.mipmapLevelCount, levels); + FILAMENT_CHECK_PRECONDITION(metalTexture.width == width) + << "Imported id width (" << metalTexture.width + << ") != Filament texture width (" << width << ")"; + FILAMENT_CHECK_PRECONDITION(metalTexture.height == height) + << "Imported id height (" << metalTexture.height + << ") != Filament texture height (" << height << ")"; + FILAMENT_CHECK_PRECONDITION(metalTexture.mipmapLevelCount == levels) + << "Imported id levels (" << metalTexture.mipmapLevelCount + << ") != Filament texture levels (" << levels << ")"; MTLTextureType filamentMetalType = getMetalType(target); - ASSERT_PRECONDITION(metalTexture.textureType == filamentMetalType, - "Imported id type (%d) != Filament texture type (%d)", - metalTexture.textureType, filamentMetalType); + FILAMENT_CHECK_PRECONDITION(metalTexture.textureType == filamentMetalType) + << "Imported id type (" << metalTexture.textureType + << ") != Filament texture type (" << filamentMetalType << ")"; mContext->textures.insert(construct_handle(th, *mContext, target, levels, format, samples, width, height, depth, usage, metalTexture)); } @@ -398,8 +399,8 @@ TargetBufferFlags targetBufferFlags, uint32_t width, uint32_t height, uint8_t samples, uint8_t layerCount, MRT color, TargetBufferInfo depth, TargetBufferInfo stencil) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "createRenderTarget must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "createRenderTarget must be called outside of a render pass."; // Clamp sample count to what the device supports. auto& sc = mContext->sampleCountLookup; samples = sc[std::min(MAX_SAMPLE_COUNT, samples)]; @@ -410,33 +411,33 @@ continue; } const auto& buffer = color[i]; - ASSERT_PRECONDITION(buffer.handle, - "The COLOR%u flag was specified, but invalid color handle provided.", i); + FILAMENT_CHECK_PRECONDITION(buffer.handle) + << "The COLOR" << i << " flag was specified, but invalid color handle provided."; auto colorTexture = handle_cast(buffer.handle); - ASSERT_PRECONDITION(colorTexture->getMtlTextureForWrite(), - "Color texture passed to render target has no texture allocation"); + FILAMENT_CHECK_PRECONDITION(colorTexture->getMtlTextureForWrite()) + << "Color texture passed to render target has no texture allocation"; colorTexture->extendLodRangeTo(buffer.level); colorAttachments[i] = { colorTexture, color[i].level, color[i].layer }; } MetalRenderTarget::Attachment depthAttachment = {}; if (any(targetBufferFlags & TargetBufferFlags::DEPTH)) { - ASSERT_PRECONDITION(depth.handle, - "The DEPTH flag was specified, but invalid depth handle provided."); + FILAMENT_CHECK_PRECONDITION(depth.handle) + << "The DEPTH flag was specified, but invalid depth handle provided."; auto depthTexture = handle_cast(depth.handle); - ASSERT_PRECONDITION(depthTexture->getMtlTextureForWrite(), - "Depth texture passed to render target has no texture allocation."); + FILAMENT_CHECK_PRECONDITION(depthTexture->getMtlTextureForWrite()) + << "Depth texture passed to render target has no texture allocation."; depthTexture->extendLodRangeTo(depth.level); depthAttachment = { depthTexture, depth.level, depth.layer }; } MetalRenderTarget::Attachment stencilAttachment = {}; if (any(targetBufferFlags & TargetBufferFlags::STENCIL)) { - ASSERT_PRECONDITION(stencil.handle, - "The STENCIL flag was specified, but invalid stencil handle provided."); + FILAMENT_CHECK_PRECONDITION(stencil.handle) + << "The STENCIL flag was specified, but invalid stencil handle provided."; auto stencilTexture = handle_cast(stencil.handle); - ASSERT_PRECONDITION(stencilTexture->getMtlTextureForWrite(), - "Stencil texture passed to render target has no texture allocation."); + FILAMENT_CHECK_PRECONDITION(stencilTexture->getMtlTextureForWrite()) + << "Stencil texture passed to render target has no texture allocation."; stencilTexture->extendLodRangeTo(stencil.level); stencilAttachment = { stencilTexture, stencil.level, stencil.layer }; } @@ -881,8 +882,8 @@ void MetalDriver::updateBufferObject(Handle boh, BufferDescriptor&& data, uint32_t byteOffset) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "updateBufferObject must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "updateBufferObject must be called outside of a render pass."; auto* bo = handle_cast(boh); bo->updateBuffer(data.buffer, data.size, byteOffset); scheduleDestroy(std::move(data)); @@ -921,8 +922,8 @@ uint32_t xoffset, uint32_t yoffset, uint32_t zoffset, uint32_t width, uint32_t height, uint32_t depth, PixelBufferDescriptor&& data) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "update3DImage must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "update3DImage must be called outside of a render pass."; auto tex = handle_cast(th); tex->loadImage(level, MTLRegionMake3D(xoffset, yoffset, zoffset, width, height, depth), data); scheduleDestroy(std::move(data)); @@ -938,15 +939,15 @@ } void MetalDriver::setExternalImage(Handle th, void* image) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "setExternalImage must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "setExternalImage must be called outside of a render pass."; auto texture = handle_cast(th); texture->externalImage.set((CVPixelBufferRef) image); } void MetalDriver::setExternalImagePlane(Handle th, void* image, uint32_t plane) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "setExternalImagePlane must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "setExternalImagePlane must be called outside of a render pass."; auto texture = handle_cast(th); texture->externalImage.set((CVPixelBufferRef) image, plane); } @@ -961,15 +962,15 @@ } void MetalDriver::generateMipmaps(Handle th) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "generateMipmaps must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "generateMipmaps must be called outside of a render pass."; auto tex = handle_cast(th); tex->generateMipmaps(); } void MetalDriver::updateSamplerGroup(Handle sbh, BufferDescriptor&& data) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "updateSamplerGroup must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "updateSamplerGroup must be called outside of a render pass."; auto sb = handle_cast(sbh); assert_invariant(sb->size == data.size / sizeof(SamplerDescriptor)); @@ -1261,8 +1262,8 @@ void MetalDriver::setPushConstant(backend::ShaderStage stage, uint8_t index, backend::PushConstantVariant value) { - ASSERT_PRECONDITION( - isInRenderPass(mContext), "setPushConstant must be called inside a render pass."); + FILAMENT_CHECK_PRECONDITION(isInRenderPass(mContext)) + << "setPushConstant must be called inside a render pass."; assert_invariant(static_cast(stage) < mContext->currentPushConstants.size()); MetalPushConstantBuffer& pushConstants = mContext->currentPushConstants[static_cast(stage)]; @@ -1319,8 +1320,8 @@ void MetalDriver::readPixels(Handle src, uint32_t x, uint32_t y, uint32_t width, uint32_t height, PixelBufferDescriptor&& data) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "readPixels must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "readPixels must be called outside of a render pass."; auto srcTarget = handle_cast(src); // We always readPixels from the COLOR0 attachment. @@ -1334,17 +1335,19 @@ width = std::min(static_cast(srcTextureSize.width), width); const MTLPixelFormat format = getMetalFormat(data.format, data.type); - ASSERT_PRECONDITION(format != MTLPixelFormatInvalid, - "The chosen combination of PixelDataFormat (%d) and PixelDataType (%d) is not supported for " - "readPixels.", (int) data.format, (int) data.type); + FILAMENT_CHECK_PRECONDITION(format != MTLPixelFormatInvalid) + << "The chosen combination of PixelDataFormat (" << (int)data.format + << ") and PixelDataType (" << (int)data.type + << ") is not supported for " + "readPixels."; const bool formatConversionNecessary = srcTexture.pixelFormat != format; // TODO: MetalBlitter does not currently support format conversions to integer types. // The format and type must match the source pixel format exactly. - ASSERT_PRECONDITION(!formatConversionNecessary || !isMetalFormatInteger(format), - "readPixels does not support integer format conversions from MTLPixelFormat (%d) to (%d).", - (int) srcTexture.pixelFormat, (int) format); + FILAMENT_CHECK_PRECONDITION(!formatConversionNecessary || !isMetalFormatInteger(format)) + << "readPixels does not support integer format conversions from MTLPixelFormat (" + << (int)srcTexture.pixelFormat << ") to (" << (int)format << ")."; MTLTextureDescriptor* textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format @@ -1410,31 +1413,31 @@ assert_invariant(srcTexture); assert_invariant(dstTexture); - ASSERT_PRECONDITION(mContext->currentRenderPassEncoder == nil, - "resolve() cannot be invoked inside a render pass."); + FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder == nil) + << "resolve() cannot be invoked inside a render pass."; - ASSERT_PRECONDITION( - dstTexture->width == srcTexture->width && dstTexture->height == srcTexture->height, - "invalid resolve: src and dst sizes don't match"); + FILAMENT_CHECK_PRECONDITION( + dstTexture->width == srcTexture->width && dstTexture->height == srcTexture->height) + << "invalid resolve: src and dst sizes don't match"; - ASSERT_PRECONDITION(srcTexture->samples > 1 && dstTexture->samples == 1, - "invalid resolve: src.samples=%u, dst.samples=%u", - +srcTexture->samples, +dstTexture->samples); + FILAMENT_CHECK_PRECONDITION(srcTexture->samples > 1 && dstTexture->samples == 1) + << "invalid resolve: src.samples=" << +srcTexture->samples + << ", dst.samples=" << +dstTexture->samples; - ASSERT_PRECONDITION(srcTexture->format == dstTexture->format, - "src and dst texture format don't match"); + FILAMENT_CHECK_PRECONDITION(srcTexture->format == dstTexture->format) + << "src and dst texture format don't match"; - ASSERT_PRECONDITION(!isDepthFormat(srcTexture->format), - "can't resolve depth formats"); + FILAMENT_CHECK_PRECONDITION(!isDepthFormat(srcTexture->format)) + << "can't resolve depth formats"; - ASSERT_PRECONDITION(!isStencilFormat(srcTexture->format), - "can't resolve stencil formats"); + FILAMENT_CHECK_PRECONDITION(!isStencilFormat(srcTexture->format)) + << "can't resolve stencil formats"; - ASSERT_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST), - "texture doesn't have BLIT_DST"); + FILAMENT_CHECK_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST)) + << "texture doesn't have BLIT_DST"; - ASSERT_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC), - "texture doesn't have BLIT_SRC"); + FILAMENT_CHECK_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC)) + << "texture doesn't have BLIT_SRC"; // FIXME: on metal the blit() call below always take the slow path (using a shader) @@ -1459,21 +1462,22 @@ assert_invariant(srcTexture); assert_invariant(dstTexture); - ASSERT_PRECONDITION(mContext->currentRenderPassEncoder == nil, - "blit() cannot be invoked inside a render pass."); + FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder == nil) + << "blit() cannot be invoked inside a render pass."; - ASSERT_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST), - "texture doesn't have BLIT_DST"); + FILAMENT_CHECK_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST)) + << "texture doesn't have BLIT_DST"; - ASSERT_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC), - "texture doesn't have BLIT_SRC"); + FILAMENT_CHECK_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC)) + << "texture doesn't have BLIT_SRC"; - ASSERT_PRECONDITION(srcTexture->format == dstTexture->format, - "src and dst texture format don't match"); + FILAMENT_CHECK_PRECONDITION(srcTexture->format == dstTexture->format) + << "src and dst texture format don't match"; - ASSERT_PRECONDITION(isBlitableTextureType(srcTexture->getMtlTextureForRead().textureType) && - isBlitableTextureType(dstTexture->getMtlTextureForWrite().textureType), - "Metal does not support blitting to/from non-2D textures."); + FILAMENT_CHECK_PRECONDITION( + isBlitableTextureType(srcTexture->getMtlTextureForRead().textureType) && + isBlitableTextureType(dstTexture->getMtlTextureForWrite().textureType)) + << "Metal does not support blitting to/from non-2D textures."; MetalBlitter::BlitArgs args{}; args.filter = SamplerMagFilter::NEAREST; @@ -1511,18 +1515,18 @@ // It is called between beginFrame and endFrame, but should never be called in the middle of // a render pass. - ASSERT_PRECONDITION(mContext->currentRenderPassEncoder == nil, - "blitDEPRECATED() cannot be invoked inside a render pass."); + FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder == nil) + << "blitDEPRECATED() cannot be invoked inside a render pass."; auto srcTarget = handle_cast(src); auto dstTarget = handle_cast(dst); - ASSERT_PRECONDITION(buffers == TargetBufferFlags::COLOR0, - "blitDEPRECATED only supports COLOR0"); + FILAMENT_CHECK_PRECONDITION(buffers == TargetBufferFlags::COLOR0) + << "blitDEPRECATED only supports COLOR0"; - ASSERT_PRECONDITION(srcRect.left >= 0 && srcRect.bottom >= 0 && - dstRect.left >= 0 && dstRect.bottom >= 0, - "Source and destination rects must be positive."); + FILAMENT_CHECK_PRECONDITION( + srcRect.left >= 0 && srcRect.bottom >= 0 && dstRect.left >= 0 && dstRect.bottom >= 0) + << "Source and destination rects must be positive."; auto isBlitableTextureType = [](MTLTextureType t) { return t == MTLTextureType2D || t == MTLTextureType2DMultisample || @@ -1534,9 +1538,10 @@ MetalRenderTarget::Attachment const dstColorAttachment = dstTarget->getDrawColorAttachment(0); if (srcColorAttachment && dstColorAttachment) { - ASSERT_PRECONDITION(isBlitableTextureType(srcColorAttachment.getTexture().textureType) && - isBlitableTextureType(dstColorAttachment.getTexture().textureType), - "Metal does not support blitting to/from non-2D textures."); + FILAMENT_CHECK_PRECONDITION( + isBlitableTextureType(srcColorAttachment.getTexture().textureType) && + isBlitableTextureType(dstColorAttachment.getTexture().textureType)) + << "Metal does not support blitting to/from non-2D textures."; MetalBlitter::BlitArgs args{}; args.filter = filter; @@ -1648,8 +1653,8 @@ } void MetalDriver::bindPipeline(PipelineState const& ps) { - ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr, - "bindPipeline() without a valid command encoder."); + FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder != nullptr) + << "bindPipeline() without a valid command encoder."; MetalVertexBufferInfo const* const vbi = handle_cast(ps.vertexBufferInfo); @@ -1821,8 +1826,8 @@ } void MetalDriver::bindRenderPrimitive(Handle rph) { - ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr, - "bindRenderPrimitive() without a valid command encoder."); + FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder != nullptr) + << "bindRenderPrimitive() without a valid command encoder."; // Bind the user vertex buffers. MetalBuffer* vertexBuffers[MAX_VERTEX_BUFFER_COUNT] = {}; @@ -1858,8 +1863,8 @@ } void MetalDriver::draw2(uint32_t indexOffset, uint32_t indexCount, uint32_t instanceCount) { - ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr, - "draw() without a valid command encoder."); + FILAMENT_CHECK_PRECONDITION(mContext->currentRenderPassEncoder != nullptr) + << "draw() without a valid command encoder."; // Bind uniform buffers. MetalBuffer* uniformsToBind[Program::UNIFORM_BINDING_COUNT] = { nil }; @@ -1908,8 +1913,8 @@ } void MetalDriver::dispatchCompute(Handle program, math::uint3 workGroupCount) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "dispatchCompute must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "dispatchCompute must be called outside of a render pass."; auto mtlProgram = handle_cast(program); @@ -2009,15 +2014,15 @@ } void MetalDriver::beginTimerQuery(Handle tqh) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "beginTimerQuery must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "beginTimerQuery must be called outside of a render pass."; auto* tq = handle_cast(tqh); mContext->timerQueryImpl->beginTimeElapsedQuery(tq); } void MetalDriver::endTimerQuery(Handle tqh) { - ASSERT_PRECONDITION(!isInRenderPass(mContext), - "endTimerQuery must be called outside of a render pass."); + FILAMENT_CHECK_PRECONDITION(!isInRenderPass(mContext)) + << "endTimerQuery must be called outside of a render pass."; auto* tq = handle_cast(tqh); mContext->timerQueryImpl->endTimeElapsedQuery(tq); } diff --git a/filament/backend/src/metal/MetalEnums.h b/filament/backend/src/metal/MetalEnums.h index c166a34bf5d2..2c622ed833f2 100644 --- a/filament/backend/src/metal/MetalEnums.h +++ b/filament/backend/src/metal/MetalEnums.h @@ -71,7 +71,7 @@ constexpr inline MTLIndexType getIndexType(size_t elementSize) noexcept { } else if (elementSize == 4) { return MTLIndexTypeUInt32; } - ASSERT_POSTCONDITION(false, "Index element size not supported."); + FILAMENT_CHECK_POSTCONDITION(false) << "Index element size not supported."; } constexpr inline MTLVertexFormat getMetalFormat(ElementType type, bool normalized) noexcept { @@ -100,7 +100,7 @@ constexpr inline MTLVertexFormat getMetalFormat(ElementType type, bool normalize case ElementType::SHORT4: return MTLVertexFormatShort4Normalized; case ElementType::USHORT4: return MTLVertexFormatUShort4Normalized; default: - ASSERT_POSTCONDITION(false, "Normalized format does not exist."); + FILAMENT_CHECK_POSTCONDITION(false) << "Normalized format does not exist."; return MTLVertexFormatInvalid; } } @@ -326,7 +326,8 @@ constexpr inline MTLCullMode getMetalCullMode(CullingMode cullMode) noexcept { case CullingMode::FRONT: return MTLCullModeFront; case CullingMode::BACK: return MTLCullModeBack; case CullingMode::FRONT_AND_BACK: - ASSERT_POSTCONDITION(false, "FRONT_AND_BACK culling is not supported in Metal."); + FILAMENT_CHECK_POSTCONDITION(false) + << "FRONT_AND_BACK culling is not supported in Metal."; } } diff --git a/filament/backend/src/metal/MetalExternalImage.mm b/filament/backend/src/metal/MetalExternalImage.mm index a5481cc74567..518cbbe76dfe 100644 --- a/filament/backend/src/metal/MetalExternalImage.mm +++ b/filament/backend/src/metal/MetalExternalImage.mm @@ -29,7 +29,7 @@ auto description = [error.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding]; \ utils::slog.e << description << utils::io::endl; \ } \ - ASSERT_POSTCONDITION(error == nil, message); + FILAMENT_CHECK_POSTCONDITION(error == nil) << message; namespace filament { namespace backend { @@ -86,14 +86,14 @@ } OSType formatType = CVPixelBufferGetPixelFormatType(image); - ASSERT_POSTCONDITION(formatType == kCVPixelFormatType_32BGRA || - formatType == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, - "Metal external images must be in either 32BGRA or 420f format."); + FILAMENT_CHECK_POSTCONDITION(formatType == kCVPixelFormatType_32BGRA || + formatType == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) + << "Metal external images must be in either 32BGRA or 420f format."; size_t planeCount = CVPixelBufferGetPlaneCount(image); - ASSERT_POSTCONDITION(planeCount == 0 || planeCount == 2, - "The Metal backend does not support images with plane counts of %d.", planeCount); - + FILAMENT_CHECK_POSTCONDITION(planeCount == 0 || planeCount == 2) + << "The Metal backend does not support images with plane counts of " << planeCount + << "."; if (planeCount == 0) { mImage = image; @@ -138,8 +138,8 @@ } const OSType formatType = CVPixelBufferGetPixelFormatType(image); - ASSERT_POSTCONDITION(formatType == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, - "Metal planar external images must be in the 420f format."); + FILAMENT_CHECK_POSTCONDITION(formatType == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) + << "Metal planar external images must be in the 420f format."; mImage = image; @@ -191,8 +191,8 @@ CVMetalTextureRef texture; CVReturn result = CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, mContext.textureCache, image, nullptr, format, width, height, plane, &texture); - ASSERT_POSTCONDITION(result == kCVReturnSuccess, - "Could not create a CVMetalTexture from CVPixelBuffer."); + FILAMENT_CHECK_POSTCONDITION(result == kCVReturnSuccess) + << "Could not create a CVMetalTexture from CVPixelBuffer."; return texture; } @@ -203,8 +203,8 @@ void MetalExternalImage::assertWritableImage(CVPixelBufferRef image) { OSType formatType = CVPixelBufferGetPixelFormatType(image); - ASSERT_PRECONDITION(formatType == kCVPixelFormatType_32BGRA, - "Metal SwapChain images must be in the 32BGRA format."); + FILAMENT_CHECK_PRECONDITION(formatType == kCVPixelFormatType_32BGRA) + << "Metal SwapChain images must be in the 32BGRA format."; } void MetalExternalImage::unset() { diff --git a/filament/backend/src/metal/MetalHandles.mm b/filament/backend/src/metal/MetalHandles.mm index dcf22137fb0c..7ebe639786f5 100644 --- a/filament/backend/src/metal/MetalHandles.mm +++ b/filament/backend/src/metal/MetalHandles.mm @@ -176,7 +176,7 @@ static inline MTLTextureUsage getMetalTextureUsage(TextureUsage usage) { assert_invariant(isCaMetalLayer()); drawable = [layer nextDrawable]; - ASSERT_POSTCONDITION(drawable != nil, "Could not obtain drawable."); + FILAMENT_CHECK_POSTCONDITION(drawable != nil) << "Could not obtain drawable."; return drawable.texture; } @@ -493,15 +493,16 @@ static void func(void* user) { externalImage(context, r, g, b, a) { devicePixelFormat = decidePixelFormat(&context, format); - ASSERT_POSTCONDITION(devicePixelFormat != MTLPixelFormatInvalid, "Texture format not supported."); + FILAMENT_CHECK_POSTCONDITION(devicePixelFormat != MTLPixelFormatInvalid) + << "Texture format not supported."; const BOOL mipmapped = levels > 1; const BOOL multisampled = samples > 1; #if defined(IOS) const BOOL textureArray = target == SamplerType::SAMPLER_2D_ARRAY; - ASSERT_PRECONDITION(!textureArray || !multisampled, - "iOS does not support multisampled texture arrays."); + FILAMENT_CHECK_PRECONDITION(!textureArray || !multisampled) + << "iOS does not support multisampled texture arrays."; #endif const auto get2DTextureType = [](SamplerType target, bool isMultisampled) { @@ -536,12 +537,14 @@ static void func(void* user) { descriptor.usage = getMetalTextureUsage(usage); descriptor.storageMode = MTLStorageModePrivate; texture = [context.device newTextureWithDescriptor:descriptor]; - ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?"); + FILAMENT_CHECK_POSTCONDITION(texture != nil) + << "Could not create Metal texture. Out of memory?"; break; case SamplerType::SAMPLER_CUBEMAP: case SamplerType::SAMPLER_CUBEMAP_ARRAY: - ASSERT_POSTCONDITION(!multisampled, "Multisampled cubemap faces not supported."); - ASSERT_POSTCONDITION(width == height, "Cubemap faces must be square."); + FILAMENT_CHECK_POSTCONDITION(!multisampled) + << "Multisampled cubemap faces not supported."; + FILAMENT_CHECK_POSTCONDITION(width == height) << "Cubemap faces must be square."; descriptor = [MTLTextureDescriptor textureCubeDescriptorWithPixelFormat:devicePixelFormat size:width mipmapped:mipmapped]; @@ -550,7 +553,8 @@ static void func(void* user) { descriptor.usage = getMetalTextureUsage(usage); descriptor.storageMode = MTLStorageModePrivate; texture = [context.device newTextureWithDescriptor:descriptor]; - ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?"); + FILAMENT_CHECK_POSTCONDITION(texture != nil) + << "Could not create Metal texture. Out of memory?"; break; case SamplerType::SAMPLER_3D: descriptor = [MTLTextureDescriptor new]; @@ -563,7 +567,8 @@ static void func(void* user) { descriptor.usage = getMetalTextureUsage(usage); descriptor.storageMode = MTLStorageModePrivate; texture = [context.device newTextureWithDescriptor:descriptor]; - ASSERT_POSTCONDITION(texture != nil, "Could not create Metal texture. Out of memory?"); + FILAMENT_CHECK_POSTCONDITION(texture != nil) + << "Could not create Metal texture. Out of memory?"; break; case SamplerType::SAMPLER_EXTERNAL: // If we're using external textures (CVPixelBufferRefs), we don't need to make any @@ -765,9 +770,9 @@ static void func(void* user) { PixelBufferDescriptor const& data) noexcept { const PixelBufferShape shape = PixelBufferShape::compute(data, format, region.size, byteOffset); - ASSERT_PRECONDITION(data.size >= shape.totalBytes, - "Expected buffer size of at least %d but " - "received PixelBufferDescriptor with size %d.", shape.totalBytes, data.size); + FILAMENT_CHECK_PRECONDITION(data.size >= shape.totalBytes) + << "Expected buffer size of at least " << shape.totalBytes + << " but received PixelBufferDescriptor with size " << data.size << "."; // Earlier versions of iOS don't have the maxBufferLength query, but 256 MB is a safe bet. NSUInteger deviceMaxBufferLength = 256 * 1024 * 1024; // 256 MB @@ -988,9 +993,9 @@ static void func(void* user) { } color[i] = colorAttachments[i]; - ASSERT_PRECONDITION(color[i].getSampleCount() <= samples, - "MetalRenderTarget was initialized with a MSAA COLOR%d texture, but sample count is %d.", - i, samples); + FILAMENT_CHECK_PRECONDITION(color[i].getSampleCount() <= samples) + << "MetalRenderTarget was initialized with a MSAA COLOR" << i + << " texture, but sample count is " << samples << "."; auto t = color[i].metalTexture; const auto twidth = std::max(1u, t->width >> color[i].level); @@ -1013,9 +1018,10 @@ static void func(void* user) { if (depthAttachment) { depth = depthAttachment; - ASSERT_PRECONDITION(depth.getSampleCount() <= samples, - "MetalRenderTarget was initialized with a MSAA DEPTH texture, but sample count is %d.", - samples); + FILAMENT_CHECK_PRECONDITION(depth.getSampleCount() <= samples) + << "MetalRenderTarget was initialized with a MSAA DEPTH texture, but sample count " + "is " + << samples << "."; auto t = depth.metalTexture; const auto twidth = std::max(1u, t->width >> depth.level); @@ -1038,9 +1044,10 @@ static void func(void* user) { if (stencilAttachment) { stencil = stencilAttachment; - ASSERT_PRECONDITION(stencil.getSampleCount() <= samples, - "MetalRenderTarget was initialized with a MSAA STENCIL texture, but sample count is %d.", - samples); + FILAMENT_CHECK_PRECONDITION(stencil.getSampleCount() <= samples) + << "MetalRenderTarget was initialized with a MSAA STENCIL texture, but sample " + "count is " + << samples << "."; auto t = stencil.metalTexture; const auto twidth = std::max(1u, t->width >> stencil.level); diff --git a/filament/backend/src/metal/MetalState.mm b/filament/backend/src/metal/MetalState.mm index bf288c9751fb..58be435a5bb7 100644 --- a/filament/backend/src/metal/MetalState.mm +++ b/filament/backend/src/metal/MetalState.mm @@ -100,7 +100,7 @@ reason:errorMessage userInfo:nil] raise]; } - ASSERT_POSTCONDITION(error == nil, "Could not create Metal pipeline state."); + FILAMENT_CHECK_POSTCONDITION(error == nil) << "Could not create Metal pipeline state."; return pipeline; } diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index 884db62459e8..414d0c8aa211 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -1494,9 +1494,8 @@ void OpenGLDriver::createSwapChainR(Handle sch, void* nativeWindow, #if !defined(__EMSCRIPTEN__) // note: in practice this should never happen on Android - ASSERT_POSTCONDITION(sc->swapChain, - "createSwapChain(%p, 0x%lx) failed. See logs for details.", - nativeWindow, flags); + FILAMENT_CHECK_POSTCONDITION(sc->swapChain) << "createSwapChain(" << nativeWindow << ", " + << flags << ") failed. See logs for details."; #endif // See if we need the emulated rec709 output conversion @@ -1515,9 +1514,9 @@ void OpenGLDriver::createSwapChainHeadlessR(Handle sch, #if !defined(__EMSCRIPTEN__) // note: in practice this should never happen on Android - ASSERT_POSTCONDITION(sc->swapChain, - "createSwapChainHeadless(%u, %u, 0x%lx) failed. See logs for details.", - width, height, flags); + FILAMENT_CHECK_POSTCONDITION(sc->swapChain) + << "createSwapChainHeadless(" << width << ", " << height << ", " << flags + << ") failed. See logs for details."; #endif // See if we need the emulated rec709 output conversion @@ -3606,13 +3605,11 @@ void OpenGLDriver::resolve( assert_invariant(s); assert_invariant(d); - ASSERT_PRECONDITION( - d->width == s->width && d->height == s->height, - "invalid resolve: src and dst sizes don't match"); + FILAMENT_CHECK_PRECONDITION(d->width == s->width && d->height == s->height) + << "invalid resolve: src and dst sizes don't match"; - ASSERT_PRECONDITION(s->samples > 1 && d->samples == 1, - "invalid resolve: src.samples=%u, dst.samples=%u", - +s->samples, +d->samples); + FILAMENT_CHECK_PRECONDITION(s->samples > 1 && d->samples == 1) + << "invalid resolve: src.samples=" << +s->samples << ", dst.samples=" << +d->samples; blit( dst, dstLevel, dstLayer, {}, src, srcLevel, srcLayer, {}, @@ -3768,12 +3765,12 @@ void OpenGLDriver::blitDEPRECATED(TargetBufferFlags buffers, UTILS_UNUSED_IN_RELEASE auto& gl = mContext; assert_invariant(!gl.isES2()); - ASSERT_PRECONDITION(buffers == TargetBufferFlags::COLOR0, - "blitDEPRECATED only supports COLOR0"); + FILAMENT_CHECK_PRECONDITION(buffers == TargetBufferFlags::COLOR0) + << "blitDEPRECATED only supports COLOR0"; - ASSERT_PRECONDITION(srcRect.left >= 0 && srcRect.bottom >= 0 && - dstRect.left >= 0 && dstRect.bottom >= 0, - "Source and destination rects must be positive."); + FILAMENT_CHECK_PRECONDITION( + srcRect.left >= 0 && srcRect.bottom >= 0 && dstRect.left >= 0 && dstRect.bottom >= 0) + << "Source and destination rects must be positive."; #ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2 diff --git a/filament/backend/src/opengl/platforms/CocoaExternalImage.mm b/filament/backend/src/opengl/platforms/CocoaExternalImage.mm index 4d8e08b9dc5a..913dc29e66d9 100644 --- a/filament/backend/src/opengl/platforms/CocoaExternalImage.mm +++ b/filament/backend/src/opengl/platforms/CocoaExternalImage.mm @@ -111,8 +111,8 @@ void main() { } OSType formatType = CVPixelBufferGetPixelFormatType(image); - ASSERT_POSTCONDITION(formatType == kCVPixelFormatType_32BGRA, - "macOS external images must be 32BGRA format."); + FILAMENT_CHECK_POSTCONDITION(formatType == kCVPixelFormatType_32BGRA) + << "macOS external images must be 32BGRA format."; // The pixel buffer must be locked whenever we do rendering with it. We'll unlock it before // releasing. diff --git a/filament/backend/src/opengl/platforms/CocoaTouchExternalImage.mm b/filament/backend/src/opengl/platforms/CocoaTouchExternalImage.mm index 64b0478360ca..23ee69e46461 100644 --- a/filament/backend/src/opengl/platforms/CocoaTouchExternalImage.mm +++ b/filament/backend/src/opengl/platforms/CocoaTouchExternalImage.mm @@ -135,13 +135,14 @@ void main() { } OSType formatType = CVPixelBufferGetPixelFormatType(image); - ASSERT_POSTCONDITION(formatType == kCVPixelFormatType_32BGRA || - formatType == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange, - "iOS external images must be in either 32BGRA or 420f format."); + FILAMENT_CHECK_POSTCONDITION(formatType == kCVPixelFormatType_32BGRA || + formatType == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) + << "iOS external images must be in either 32BGRA or 420f format."; size_t planeCount = CVPixelBufferGetPlaneCount(image); - ASSERT_POSTCONDITION(planeCount == 0 || planeCount == 2, - "The OpenGL backend does not support images with plane counts of %d.", planeCount); + FILAMENT_CHECK_POSTCONDITION(planeCount == 0 || planeCount == 2) + << "The OpenGL backend does not support images with plane counts of " << planeCount + << "."; // The pixel buffer must be locked whenever we do rendering with it. We'll unlock it before // releasing. diff --git a/filament/backend/src/opengl/platforms/PlatformCocoaGL.mm b/filament/backend/src/opengl/platforms/PlatformCocoaGL.mm index 95645f02b519..b62783c1dc0f 100644 --- a/filament/backend/src/opengl/platforms/PlatformCocoaGL.mm +++ b/filament/backend/src/opengl/platforms/PlatformCocoaGL.mm @@ -162,7 +162,7 @@ pImpl->mGLContext = nsOpenGLContext; int result = bluegl::bind(); - ASSERT_POSTCONDITION(!result, "Unable to load OpenGL entry points."); + FILAMENT_CHECK_POSTCONDITION(!result) << "Unable to load OpenGL entry points."; UTILS_UNUSED_IN_RELEASE CVReturn success = CVOpenGLTextureCacheCreate(kCFAllocatorDefault, nullptr, [pImpl->mGLContext CGLContextObj], [pImpl->mGLContext.pixelFormat CGLPixelFormatObj], nullptr, diff --git a/filament/backend/src/opengl/platforms/PlatformCocoaTouchGL.mm b/filament/backend/src/opengl/platforms/PlatformCocoaTouchGL.mm index 91fb5cb88a22..326f55f06d2b 100644 --- a/filament/backend/src/opengl/platforms/PlatformCocoaTouchGL.mm +++ b/filament/backend/src/opengl/platforms/PlatformCocoaTouchGL.mm @@ -61,7 +61,7 @@ EAGLSharegroup* sharegroup = (__bridge EAGLSharegroup*) sharedGLContext; EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3 sharegroup:sharegroup]; - ASSERT_POSTCONDITION(context, "Unable to create OpenGL ES context."); + FILAMENT_CHECK_POSTCONDITION(context) << "Unable to create OpenGL ES context."; [EAGLContext setCurrentContext:context]; @@ -103,7 +103,7 @@ EAGLContext* const context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3 sharegroup:sharegroup]; - ASSERT_POSTCONDITION(context, "Unable to create extra OpenGL ES context."); + FILAMENT_CHECK_POSTCONDITION(context) << "Unable to create extra OpenGL ES context."; [EAGLContext setCurrentContext:context]; pImpl->mAdditionalContexts.push_back(context); } @@ -180,7 +180,8 @@ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, pImpl->mDefaultFramebuffer); GLenum const status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - ASSERT_POSTCONDITION(status == GL_FRAMEBUFFER_COMPLETE, "Incomplete framebuffer."); + FILAMENT_CHECK_POSTCONDITION(status == GL_FRAMEBUFFER_COMPLETE) + << "Incomplete framebuffer."; glBindFramebuffer(GL_FRAMEBUFFER, oldFramebuffer); } return true; diff --git a/filament/backend/src/opengl/platforms/PlatformGLX.cpp b/filament/backend/src/opengl/platforms/PlatformGLX.cpp index b2f7ba3432bd..f7a64bda6223 100644 --- a/filament/backend/src/opengl/platforms/PlatformGLX.cpp +++ b/filament/backend/src/opengl/platforms/PlatformGLX.cpp @@ -226,7 +226,7 @@ Driver* PlatformGLX::createDriver(void* const sharedGLContext, g_glx.setCurrentContext(mGLXDisplay, mDummySurface, mDummySurface, mGLXContext); int result = bluegl::bind(); - ASSERT_POSTCONDITION(!result, "Unable to load OpenGL entry points."); + FILAMENT_CHECK_POSTCONDITION(!result) << "Unable to load OpenGL entry points."; return OpenGLPlatform::createDefaultDriver(this, sharedGLContext, driverConfig); } diff --git a/filament/backend/src/opengl/platforms/PlatformWGL.cpp b/filament/backend/src/opengl/platforms/PlatformWGL.cpp index 26746b708e68..b8fee3e1210b 100644 --- a/filament/backend/src/opengl/platforms/PlatformWGL.cpp +++ b/filament/backend/src/opengl/platforms/PlatformWGL.cpp @@ -154,7 +154,7 @@ Driver* PlatformWGL::createDriver(void* const sharedGLContext, } result = bluegl::bind(); - ASSERT_POSTCONDITION(!result, "Unable to load OpenGL entry points."); + FILAMENT_CHECK_POSTCONDITION(!result) << "Unable to load OpenGL entry points."; return OpenGLPlatform::createDefaultDriver(this, sharedGLContext, driverConfig); diff --git a/filament/backend/src/vulkan/VulkanContext.cpp b/filament/backend/src/vulkan/VulkanContext.cpp index c590977af2a0..447351c1ba6b 100644 --- a/filament/backend/src/vulkan/VulkanContext.cpp +++ b/filament/backend/src/vulkan/VulkanContext.cpp @@ -86,7 +86,7 @@ VulkanTimestamps::VulkanTimestamps(VkDevice device) : mDevice(device) { std::unique_lock lock(mMutex); tqpCreateInfo.queryCount = mUsed.size() * 2; VkResult result = vkCreateQueryPool(mDevice, &tqpCreateInfo, VKALLOC, &mPool); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateQueryPool error."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "vkCreateQueryPool error."; mUsed.reset(); } @@ -134,8 +134,8 @@ VulkanTimestamps::QueryResult VulkanTimestamps::getResult(VulkanTimerQuery const VkResult vkresult = vkGetQueryPoolResults(mDevice, mPool, index, 2, dataSize, (void*) result.data(), stride, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT); - ASSERT_POSTCONDITION(vkresult == VK_SUCCESS || vkresult == VK_NOT_READY, - "vkGetQueryPoolResults error: %d", static_cast(vkresult)); + FILAMENT_CHECK_POSTCONDITION(vkresult == VK_SUCCESS || vkresult == VK_NOT_READY) + << "vkGetQueryPoolResults error: " << static_cast(vkresult); if (vkresult == VK_NOT_READY) { return {0, 0, 0, 0}; } diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 0e62a75e1daa..577196861e3b 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -173,7 +173,8 @@ DebugUtils::DebugUtils(VkInstance instance, VkDevice device, VulkanContext const }; VkResult result = vkCreateDebugUtilsMessengerEXT(instance, &createInfo, VKALLOC, &mDebugMessenger); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "Unable to create Vulkan debug messenger."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) + << "Unable to create Vulkan debug messenger."; } #endif // FVK_EANBLED(FVK_DEBUG_VALIDATION) } @@ -247,7 +248,8 @@ VulkanDriver::VulkanDriver(VulkanPlatform* platform, VulkanContext const& contex }; VkResult result = createDebugReportCallback(mPlatform->getInstance(), &cbinfo, VKALLOC, &mDebugCallback); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "Unable to create Vulkan debug callback."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) + << "Unable to create Vulkan debug callback."; } #endif @@ -1090,7 +1092,8 @@ TimerQueryResult VulkanDriver::getTimerQueryValue(Handle tqh, uint return TimerQueryResult::NOT_READY; } - ASSERT_POSTCONDITION(timestamp1 >= timestamp0, "Timestamps are not monotonically increasing."); + FILAMENT_CHECK_POSTCONDITION(timestamp1 >= timestamp0) + << "Timestamps are not monotonically increasing."; // NOTE: MoltenVK currently writes system time so the following delta will always be zero. // However there are plans for implementing this properly. See the following GitHub ticket. @@ -1495,8 +1498,8 @@ void VulkanDriver::endRenderPass(int) { } void VulkanDriver::nextSubpass(int) { - ASSERT_PRECONDITION(mCurrentRenderPass.currentSubpass == 0, - "Only two subpasses are currently supported."); + FILAMENT_CHECK_PRECONDITION(mCurrentRenderPass.currentSubpass == 0) + << "Only two subpasses are currently supported."; VulkanRenderTarget* renderTarget = mCurrentRenderPass.renderTarget; assert_invariant(renderTarget); @@ -1636,36 +1639,36 @@ void VulkanDriver::resolve( FVK_SYSTRACE_CONTEXT(); FVK_SYSTRACE_START("resolve"); - ASSERT_PRECONDITION(mCurrentRenderPass.renderPass == VK_NULL_HANDLE, - "resolve() cannot be invoked inside a render pass."); + FILAMENT_CHECK_PRECONDITION(mCurrentRenderPass.renderPass == VK_NULL_HANDLE) + << "resolve() cannot be invoked inside a render pass."; auto* const srcTexture = mResourceAllocator.handle_cast(src); auto* const dstTexture = mResourceAllocator.handle_cast(dst); assert_invariant(srcTexture); assert_invariant(dstTexture); - ASSERT_PRECONDITION( - dstTexture->width == srcTexture->width && dstTexture->height == srcTexture->height, - "invalid resolve: src and dst sizes don't match"); + FILAMENT_CHECK_PRECONDITION( + dstTexture->width == srcTexture->width && dstTexture->height == srcTexture->height) + << "invalid resolve: src and dst sizes don't match"; - ASSERT_PRECONDITION(srcTexture->samples > 1 && dstTexture->samples == 1, - "invalid resolve: src.samples=%u, dst.samples=%u", - +srcTexture->samples, +dstTexture->samples); + FILAMENT_CHECK_PRECONDITION(srcTexture->samples > 1 && dstTexture->samples == 1) + << "invalid resolve: src.samples=" << +srcTexture->samples + << ", dst.samples=" << +dstTexture->samples; - ASSERT_PRECONDITION(srcTexture->format == dstTexture->format, - "src and dst texture format don't match"); + FILAMENT_CHECK_PRECONDITION(srcTexture->format == dstTexture->format) + << "src and dst texture format don't match"; - ASSERT_PRECONDITION(!isDepthFormat(srcTexture->format), - "can't resolve depth formats"); + FILAMENT_CHECK_PRECONDITION(!isDepthFormat(srcTexture->format)) + << "can't resolve depth formats"; - ASSERT_PRECONDITION(!isStencilFormat(srcTexture->format), - "can't resolve stencil formats"); + FILAMENT_CHECK_PRECONDITION(!isStencilFormat(srcTexture->format)) + << "can't resolve stencil formats"; - ASSERT_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST), - "texture doesn't have BLIT_DST"); + FILAMENT_CHECK_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST)) + << "texture doesn't have BLIT_DST"; - ASSERT_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC), - "texture doesn't have BLIT_SRC"); + FILAMENT_CHECK_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC)) + << "texture doesn't have BLIT_SRC"; mBlitter.resolve( { .texture = dstTexture, .level = dstLevel, .layer = dstLayer }, @@ -1681,20 +1684,20 @@ void VulkanDriver::blit( FVK_SYSTRACE_CONTEXT(); FVK_SYSTRACE_START("blit"); - ASSERT_PRECONDITION(mCurrentRenderPass.renderPass == VK_NULL_HANDLE, - "blit() cannot be invoked inside a render pass."); + FILAMENT_CHECK_PRECONDITION(mCurrentRenderPass.renderPass == VK_NULL_HANDLE) + << "blit() cannot be invoked inside a render pass."; auto* const srcTexture = mResourceAllocator.handle_cast(src); auto* const dstTexture = mResourceAllocator.handle_cast(dst); - ASSERT_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST), - "texture doesn't have BLIT_DST"); + FILAMENT_CHECK_PRECONDITION(any(dstTexture->usage & TextureUsage::BLIT_DST)) + << "texture doesn't have BLIT_DST"; - ASSERT_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC), - "texture doesn't have BLIT_SRC"); + FILAMENT_CHECK_PRECONDITION(any(srcTexture->usage & TextureUsage::BLIT_SRC)) + << "texture doesn't have BLIT_SRC"; - ASSERT_PRECONDITION(srcTexture->format == dstTexture->format, - "src and dst texture format don't match"); + FILAMENT_CHECK_PRECONDITION(srcTexture->format == dstTexture->format) + << "src and dst texture format don't match"; // The Y inversion below makes it so that Vk matches GL and Metal. @@ -1726,15 +1729,15 @@ void VulkanDriver::blitDEPRECATED(TargetBufferFlags buffers, // Note: blitDEPRECATED is only used for Renderer::copyFrame() - ASSERT_PRECONDITION(mCurrentRenderPass.renderPass == VK_NULL_HANDLE, - "blitDEPRECATED() cannot be invoked inside a render pass."); + FILAMENT_CHECK_PRECONDITION(mCurrentRenderPass.renderPass == VK_NULL_HANDLE) + << "blitDEPRECATED() cannot be invoked inside a render pass."; - ASSERT_PRECONDITION(buffers == TargetBufferFlags::COLOR0, - "blitDEPRECATED only supports COLOR0"); + FILAMENT_CHECK_PRECONDITION(buffers == TargetBufferFlags::COLOR0) + << "blitDEPRECATED only supports COLOR0"; - ASSERT_PRECONDITION(srcRect.left >= 0 && srcRect.bottom >= 0 && - dstRect.left >= 0 && dstRect.bottom >= 0, - "Source and destination rects must be positive."); + FILAMENT_CHECK_PRECONDITION( + srcRect.left >= 0 && srcRect.bottom >= 0 && dstRect.left >= 0 && dstRect.bottom >= 0) + << "Source and destination rects must be positive."; VulkanRenderTarget* dstTarget = mResourceAllocator.handle_cast(dst); VulkanRenderTarget* srcTarget = mResourceAllocator.handle_cast(src); diff --git a/filament/backend/src/vulkan/VulkanFboCache.cpp b/filament/backend/src/vulkan/VulkanFboCache.cpp index c754fe57e70c..9da721e90275 100644 --- a/filament/backend/src/vulkan/VulkanFboCache.cpp +++ b/filament/backend/src/vulkan/VulkanFboCache.cpp @@ -64,8 +64,8 @@ VulkanFboCache::VulkanFboCache(VkDevice device) : mDevice(device) {} VulkanFboCache::~VulkanFboCache() { - ASSERT_POSTCONDITION(mFramebufferCache.empty() && mRenderPassCache.empty(), - "Please explicitly call terminate() while the VkDevice is still alive."); + FILAMENT_CHECK_POSTCONDITION(mFramebufferCache.empty() && mRenderPassCache.empty()) + << "Please explicitly call terminate() while the VkDevice is still alive."; } VkFramebuffer VulkanFboCache::getFramebuffer(FboKey config) noexcept { @@ -115,7 +115,7 @@ VkFramebuffer VulkanFboCache::getFramebuffer(FboKey config) noexcept { mRenderPassRefCount[info.renderPass]++; VkFramebuffer framebuffer; VkResult error = vkCreateFramebuffer(mDevice, &info, VKALLOC, &framebuffer); - ASSERT_POSTCONDITION(!error, "Unable to create framebuffer."); + FILAMENT_CHECK_POSTCONDITION(!error) << "Unable to create framebuffer."; mFramebufferCache[config] = {framebuffer, mCurrentTime}; return framebuffer; } @@ -306,7 +306,7 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey config) noexcept { // Finally, create the VkRenderPass. VkRenderPass renderPass; VkResult error = vkCreateRenderPass(mDevice, &renderPassInfo, VKALLOC, &renderPass); - ASSERT_POSTCONDITION(!error, "Unable to create render pass."); + FILAMENT_CHECK_POSTCONDITION(!error) << "Unable to create render pass."; mRenderPassCache[config] = {renderPass, mCurrentTime}; #if FVK_ENABLED(FVK_DEBUG_FBO_CACHE) diff --git a/filament/backend/src/vulkan/VulkanHandles.cpp b/filament/backend/src/vulkan/VulkanHandles.cpp index 40157753b8e7..351762a758c2 100644 --- a/filament/backend/src/vulkan/VulkanHandles.cpp +++ b/filament/backend/src/vulkan/VulkanHandles.cpp @@ -237,7 +237,7 @@ VulkanProgram::VulkanProgram(VkDevice device, Program const& builder) noexcept .pCode = data, }; VkResult result = vkCreateShaderModule(mDevice, &moduleInfo, VKALLOC, &module); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "Unable to create shader module."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "Unable to create shader module."; #if FVK_ENABLED(FVK_DEBUG_DEBUG_UTILS) std::string name{ builder.getName().c_str(), builder.getName().size() }; diff --git a/filament/backend/src/vulkan/VulkanReadPixels.cpp b/filament/backend/src/vulkan/VulkanReadPixels.cpp index 2fc7ee2e0907..c03ccb68236c 100644 --- a/filament/backend/src/vulkan/VulkanReadPixels.cpp +++ b/filament/backend/src/vulkan/VulkanReadPixels.cpp @@ -71,8 +71,8 @@ void TaskHandler::shutdown() { } mHasTaskCondition.notify_one(); mThread.join(); - ASSERT_POSTCONDITION(mTaskQueue.empty(), - "ReadPixels handler has tasks in the queue after shutdown"); + FILAMENT_CHECK_POSTCONDITION(mTaskQueue.empty()) + << "ReadPixels handler has tasks in the queue after shutdown"; } void TaskHandler::loop() { @@ -190,8 +190,8 @@ void VulkanReadPixels::run(VulkanRenderTarget* srcTarget, uint32_t const x, uint << utils::io::endl; } - ASSERT_POSTCONDITION(memoryTypeIndex < VK_MAX_MEMORY_TYPES, - "VulkanReadPixels: unable to find a memory type that meets requirements."); + FILAMENT_CHECK_POSTCONDITION(memoryTypeIndex < VK_MAX_MEMORY_TYPES) + << "VulkanReadPixels: unable to find a memory type that meets requirements."; VkMemoryAllocateInfo const allocInfo = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, diff --git a/filament/backend/src/vulkan/VulkanSamplerCache.cpp b/filament/backend/src/vulkan/VulkanSamplerCache.cpp index 79f8bfbd5353..38ba5bb3ab89 100644 --- a/filament/backend/src/vulkan/VulkanSamplerCache.cpp +++ b/filament/backend/src/vulkan/VulkanSamplerCache.cpp @@ -122,7 +122,7 @@ VkSampler VulkanSamplerCache::getSampler(SamplerParams params) noexcept { }; VkSampler sampler; VkResult error = vkCreateSampler(mDevice, &samplerInfo, VKALLOC, &sampler); - ASSERT_POSTCONDITION(!error, "Unable to create sampler."); + FILAMENT_CHECK_POSTCONDITION(!error) << "Unable to create sampler."; mCache.insert({params, sampler}); return sampler; } diff --git a/filament/backend/src/vulkan/VulkanSwapChain.cpp b/filament/backend/src/vulkan/VulkanSwapChain.cpp index 108cceca5c28..961876306504 100644 --- a/filament/backend/src/vulkan/VulkanSwapChain.cpp +++ b/filament/backend/src/vulkan/VulkanSwapChain.cpp @@ -39,7 +39,7 @@ VulkanSwapChain::VulkanSwapChain(VulkanPlatform* platform, VulkanContext const& mAcquired(false), mIsFirstRenderPass(true) { swapChain = mPlatform->createSwapChain(nativeWindow, flags, extent); - ASSERT_POSTCONDITION(swapChain, "Unable to create swapchain"); + FILAMENT_CHECK_POSTCONDITION(swapChain) << "Unable to create swapchain"; VkSemaphoreCreateInfo const createInfo = { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, @@ -53,8 +53,9 @@ VulkanSwapChain::VulkanSwapChain(VulkanPlatform* platform, VulkanContext const& for (uint32_t i = 0; i < IMAGE_READY_SEMAPHORE_COUNT; ++i) { VkResult result = vkCreateSemaphore(mPlatform->getDevice(), &createInfo, nullptr, mImageReady + i); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "Failed to create semaphore"); - } + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) + << "Failed to create semaphore"; + } } update(); @@ -112,9 +113,9 @@ void VulkanSwapChain::present() { if (!mHeadless) { VkSemaphore const finishedDrawing = mCommands->acquireFinishedSignal(); VkResult const result = mPlatform->present(swapChain, mCurrentSwapIndex, finishedDrawing); - ASSERT_POSTCONDITION(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR || - result == VK_ERROR_OUT_OF_DATE_KHR, - "Cannot present in swapchain."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR || + result == VK_ERROR_OUT_OF_DATE_KHR) + << "Cannot present in swapchain."; } // We presented the last acquired buffer. @@ -141,8 +142,8 @@ void VulkanSwapChain::acquire(bool& resized) { mCurrentImageReadyIndex = (mCurrentImageReadyIndex + 1) % IMAGE_READY_SEMAPHORE_COUNT; const VkSemaphore imageReady = mImageReady[mCurrentImageReadyIndex]; VkResult const result = mPlatform->acquire(swapChain, imageReady, &mCurrentSwapIndex); - ASSERT_POSTCONDITION(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR, - "Cannot acquire in swapchain."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR) + << "Cannot acquire in swapchain."; if (imageReady != VK_NULL_HANDLE) { mCommands->injectDependency(imageReady); } diff --git a/filament/backend/src/vulkan/VulkanTexture.cpp b/filament/backend/src/vulkan/VulkanTexture.cpp index 7819c00cedc7..eb8cfcf3bb0d 100644 --- a/filament/backend/src/vulkan/VulkanTexture.cpp +++ b/filament/backend/src/vulkan/VulkanTexture.cpp @@ -177,7 +177,7 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice, << "target = " << static_cast(target) <<", " << "format = " << mVkFormat << utils::io::endl; } - ASSERT_POSTCONDITION(!error, "Unable to create image."); + FILAMENT_CHECK_POSTCONDITION(!error) << "Unable to create image."; // Allocate memory for the VkImage and bind it. VkMemoryRequirements memReqs = {}; @@ -186,8 +186,8 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice, uint32_t memoryTypeIndex = context.selectMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - ASSERT_POSTCONDITION(memoryTypeIndex < VK_MAX_MEMORY_TYPES, - "VulkanTexture: unable to find a memory type that meets requirements."); + FILAMENT_CHECK_POSTCONDITION(memoryTypeIndex < VK_MAX_MEMORY_TYPES) + << "VulkanTexture: unable to find a memory type that meets requirements."; VkMemoryAllocateInfo allocInfo = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, @@ -195,9 +195,9 @@ VulkanTexture::VulkanTexture(VkDevice device, VkPhysicalDevice physicalDevice, .memoryTypeIndex = memoryTypeIndex, }; error = vkAllocateMemory(mDevice, &allocInfo, nullptr, &mTextureImageMemory); - ASSERT_POSTCONDITION(!error, "Unable to allocate image memory."); + FILAMENT_CHECK_POSTCONDITION(!error) << "Unable to allocate image memory."; error = vkBindImageMemory(mDevice, mTextureImage, mTextureImageMemory, 0); - ASSERT_POSTCONDITION(!error, "Unable to bind image."); + FILAMENT_CHECK_POSTCONDITION(!error) << "Unable to bind image."; uint32_t layerCount = 0; if (target == SamplerType::SAMPLER_CUBEMAP) { diff --git a/filament/backend/src/vulkan/VulkanUtility.cpp b/filament/backend/src/vulkan/VulkanUtility.cpp index 612acb20e5db..3b8e5f851a24 100644 --- a/filament/backend/src/vulkan/VulkanUtility.cpp +++ b/filament/backend/src/vulkan/VulkanUtility.cpp @@ -51,7 +51,7 @@ VkFormat getVkFormat(ElementType type, bool normalized, bool integer) { case ElementType::SHORT4: return VK_FORMAT_R16G16B16A16_SNORM; case ElementType::USHORT4: return VK_FORMAT_R16G16B16A16_UNORM; default: - ASSERT_POSTCONDITION(false, "Normalized format does not exist."); + FILAMENT_CHECK_POSTCONDITION(false) << "Normalized format does not exist."; return VK_FORMAT_UNDEFINED; } } diff --git a/filament/backend/src/vulkan/VulkanUtility.h b/filament/backend/src/vulkan/VulkanUtility.h index 4dd403591108..cb780cf88576 100644 --- a/filament/backend/src/vulkan/VulkanUtility.h +++ b/filament/backend/src/vulkan/VulkanUtility.h @@ -56,13 +56,13 @@ uint8_t reduceSampleCount(uint8_t sampleCount, VkSampleCountFlags mask); // considered, but because the "variadic" part of the vk methods (i.e. the inputs) are before the // non-variadic parts, this breaks the template type matching logic. Hence, we use a macro approach // here. -#define EXPAND_ENUM(...)\ - uint32_t size = 0;\ - VkResult result = func(__VA_ARGS__, nullptr);\ - ASSERT_POSTCONDITION(result == VK_SUCCESS, "enumerate size error");\ - utils::FixedCapacityVector ret(size);\ - result = func(__VA_ARGS__, ret.data());\ - ASSERT_POSTCONDITION(result == VK_SUCCESS, "enumerate error");\ +#define EXPAND_ENUM(...) \ + uint32_t size = 0; \ + VkResult result = func(__VA_ARGS__, nullptr); \ + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "enumerate size error"; \ + utils::FixedCapacityVector ret(size); \ + result = func(__VA_ARGS__, ret.data()); \ + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "enumerate error"; \ return std::move(ret); #define EXPAND_ENUM_NO_ARGS() EXPAND_ENUM(&size) diff --git a/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.cpp b/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.cpp index 8c27d0e11def..16b53b115669 100644 --- a/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.cpp +++ b/filament/backend/src/vulkan/caching/VulkanDescriptorSetManager.cpp @@ -170,9 +170,9 @@ class DescriptorPool { }; VkDescriptorSet vkSet; UTILS_UNUSED VkResult result = vkAllocateDescriptorSets(mDevice, &allocInfo, &vkSet); - ASSERT_POSTCONDITION(result == VK_SUCCESS, - "Failed to allocate descriptor set code=%d size=%d capacity=%d count=%s", result, - mSize, mCapacity); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) + << "Failed to allocate descriptor set code=" << result << " size=" << mSize + << " capacity=" << mCapacity << " count=" << "%s"; mSize++; return createSet(layout->bitmask, vkSet); } diff --git a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp index c84035721618..aaa8c7d00e27 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatform.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatform.cpp @@ -281,8 +281,8 @@ VkInstance createInstance(ExtensionSet const& requiredExts) { } VkResult result = vkCreateInstance(&instanceCreateInfo, VKALLOC, &instance); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "Unable to create Vulkan instance. Result=%d", - result); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) + << "Unable to create Vulkan instance. Result=" << result; return instance; } @@ -333,7 +333,7 @@ VkDevice createLogicalDevice(VkPhysicalDevice physicalDevice, } VkResult result = vkCreateDevice(physicalDevice, &deviceCreateInfo, VKALLOC, &device); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateDevice error=%d.", result); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "vkCreateDevice error=" << result << "."; return device; } @@ -467,9 +467,9 @@ VkPhysicalDevice selectPhysicalDevice(VkInstance instance, deviceList[deviceInd].name = targetDeviceProperties.deviceName; } - ASSERT_PRECONDITION(gpuPreference.index < static_cast(deviceList.size()), - "Provided GPU index=%d >= the number of GPUs=%d", gpuPreference.index, - static_cast(deviceList.size())); + FILAMENT_CHECK_PRECONDITION(gpuPreference.index < static_cast(deviceList.size())) + << "Provided GPU index=" << gpuPreference.index + << " >= the number of GPUs=" << static_cast(deviceList.size()); // Sort the found devices std::sort(deviceList.begin(), deviceList.end(), @@ -497,7 +497,7 @@ VkPhysicalDevice selectPhysicalDevice(VkInstance instance, return deviceTypeOrder(a.deviceType) < deviceTypeOrder(b.deviceType); }); auto device = deviceList.back().device; - ASSERT_POSTCONDITION(device != VK_NULL_HANDLE, "Unable to find suitable device."); + FILAMENT_CHECK_POSTCONDITION(device != VK_NULL_HANDLE) << "Unable to find suitable device."; return device; } @@ -586,21 +586,21 @@ void VulkanPlatform::terminate() { Driver* VulkanPlatform::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept { // Load Vulkan entry points. - ASSERT_POSTCONDITION(bluevk::initialize(), "BlueVK is unable to load entry points."); + FILAMENT_CHECK_POSTCONDITION(bluevk::initialize()) << "BlueVK is unable to load entry points."; if (sharedContext) { VulkanSharedContext const* scontext = (VulkanSharedContext const*) sharedContext; // All fields of VulkanSharedContext should be present. - ASSERT_PRECONDITION(scontext->instance != VK_NULL_HANDLE, - "Client needs to provide VkInstance"); - ASSERT_PRECONDITION(scontext->physicalDevice != VK_NULL_HANDLE, - "Client needs to provide VkPhysicalDevice"); - ASSERT_PRECONDITION(scontext->logicalDevice != VK_NULL_HANDLE, - "Client needs to provide VkDevice"); - ASSERT_PRECONDITION(scontext->graphicsQueueFamilyIndex != INVALID_VK_INDEX, - "Client needs to provide graphics queue family index"); - ASSERT_PRECONDITION(scontext->graphicsQueueIndex != INVALID_VK_INDEX, - "Client needs to provide graphics queue index"); + FILAMENT_CHECK_PRECONDITION(scontext->instance != VK_NULL_HANDLE) + << "Client needs to provide VkInstance"; + FILAMENT_CHECK_PRECONDITION(scontext->physicalDevice != VK_NULL_HANDLE) + << "Client needs to provide VkPhysicalDevice"; + FILAMENT_CHECK_PRECONDITION(scontext->logicalDevice != VK_NULL_HANDLE) + << "Client needs to provide VkDevice"; + FILAMENT_CHECK_PRECONDITION(scontext->graphicsQueueFamilyIndex != INVALID_VK_INDEX) + << "Client needs to provide graphics queue family index"; + FILAMENT_CHECK_PRECONDITION(scontext->graphicsQueueIndex != INVALID_VK_INDEX) + << "Client needs to provide graphics queue index"; mImpl->mInstance = scontext->instance; mImpl->mPhysicalDevice = scontext->physicalDevice; @@ -646,8 +646,8 @@ Driver* VulkanPlatform::createDriver(void* sharedContext, VulkanPlatform::Customization::GPUPreference const pref = getCustomization().gpu; bool const hasGPUPreference = pref.index >= 0 || !pref.deviceName.empty(); - ASSERT_PRECONDITION(!(hasGPUPreference && sharedContext), - "Cannot both share context and indicate GPU preference"); + FILAMENT_CHECK_PRECONDITION(!(hasGPUPreference && sharedContext)) + << "Cannot both share context and indicate GPU preference"; mImpl->mPhysicalDevice = mImpl->mPhysicalDevice == VK_NULL_HANDLE ? selectPhysicalDevice(mImpl->mInstance, pref) @@ -707,8 +707,8 @@ Driver* VulkanPlatform::createDriver(void* sharedContext, #ifdef NDEBUG // If we are in release build, we should not have turned on debug extensions - ASSERT_POSTCONDITION(!context.mDebugUtilsSupported && !context.mDebugMarkersSupported, - "Debug utils should not be enabled in release build."); + FILAMENT_CHECK_POSTCONDITION(!context.mDebugUtilsSupported && !context.mDebugMarkersSupported) + << "Debug utils should not be enabled in release build."; #endif context.mDepthStencilFormats = findAttachmentDepthStencilFormats(mImpl->mPhysicalDevice); diff --git a/filament/backend/src/vulkan/platform/VulkanPlatformAndroidLinuxWindows.cpp b/filament/backend/src/vulkan/platform/VulkanPlatformAndroidLinuxWindows.cpp index 67a63b7279f4..f12d9e793142 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatformAndroidLinuxWindows.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatformAndroidLinuxWindows.cpp @@ -123,7 +123,7 @@ VulkanPlatform::SurfaceBundle VulkanPlatform::createVkSurfaceKHR(void* nativeWin }; VkResult const result = vkCreateAndroidSurfaceKHR(instance, &createInfo, VKALLOC, (VkSurfaceKHR*) &surface); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateAndroidSurfaceKHR error."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "vkCreateAndroidSurfaceKHR error."; #elif defined(__linux__) && defined(FILAMENT_SUPPORTS_WAYLAND) wl* ptrval = reinterpret_cast(nativeWindow); extent.width = ptrval->width; @@ -138,11 +138,11 @@ VulkanPlatform::SurfaceBundle VulkanPlatform::createVkSurfaceKHR(void* nativeWin }; VkResult const result = vkCreateWaylandSurfaceKHR(instance, &createInfo, VKALLOC, (VkSurfaceKHR*) &surface); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateWaylandSurfaceKHR error."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "vkCreateWaylandSurfaceKHR error."; #elif defined(LINUX_OR_FREEBSD) && defined(FILAMENT_SUPPORTS_X11) if (g_x11_vk.library == nullptr) { g_x11_vk.library = dlopen(LIBRARY_X11, RTLD_LOCAL | RTLD_NOW); - ASSERT_PRECONDITION(g_x11_vk.library, "Unable to open X11 library."); + FILAMENT_CHECK_PRECONDITION(g_x11_vk.library) << "Unable to open X11 library."; #if defined(FILAMENT_SUPPORTS_XCB) g_x11_vk.xcbConnect = (XCB_CONNECT) dlsym(g_x11_vk.library, "xcb_connect"); int screen; @@ -151,7 +151,7 @@ VulkanPlatform::SurfaceBundle VulkanPlatform::createVkSurfaceKHR(void* nativeWin #if defined(FILAMENT_SUPPORTS_XLIB) g_x11_vk.openDisplay = (X11_OPEN_DISPLAY) dlsym(g_x11_vk.library, "XOpenDisplay"); g_x11_vk.display = g_x11_vk.openDisplay(NULL); - ASSERT_PRECONDITION(g_x11_vk.display, "Unable to open X11 display."); + FILAMENT_CHECK_PRECONDITION(g_x11_vk.display) << "Unable to open X11 display."; #endif } #if defined(FILAMENT_SUPPORTS_XCB) || defined(FILAMENT_SUPPORTS_XLIB) @@ -164,8 +164,8 @@ VulkanPlatform::SurfaceBundle VulkanPlatform::createVkSurfaceKHR(void* nativeWin useXcb = true; #endif if (useXcb) { - ASSERT_POSTCONDITION(vkCreateXcbSurfaceKHR, - "Unable to load vkCreateXcbSurfaceKHR function."); + FILAMENT_CHECK_POSTCONDITION(vkCreateXcbSurfaceKHR) + << "Unable to load vkCreateXcbSurfaceKHR function."; VkXcbSurfaceCreateInfoKHR const createInfo = { .sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, @@ -174,13 +174,14 @@ VulkanPlatform::SurfaceBundle VulkanPlatform::createVkSurfaceKHR(void* nativeWin }; VkResult const result = vkCreateXcbSurfaceKHR(instance, &createInfo, VKALLOC, (VkSurfaceKHR*) &surface); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateXcbSurfaceKHR error."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) + << "vkCreateXcbSurfaceKHR error."; } #endif #if defined(FILAMENT_SUPPORTS_XLIB) if (!useXcb) { - ASSERT_POSTCONDITION(vkCreateXlibSurfaceKHR, - "Unable to load vkCreateXlibSurfaceKHR function."); + FILAMENT_CHECK_POSTCONDITION(vkCreateXlibSurfaceKHR) + << "Unable to load vkCreateXlibSurfaceKHR function."; VkXlibSurfaceCreateInfoKHR const createInfo = { .sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, @@ -189,7 +190,8 @@ VulkanPlatform::SurfaceBundle VulkanPlatform::createVkSurfaceKHR(void* nativeWin }; VkResult const result = vkCreateXlibSurfaceKHR(instance, &createInfo, VKALLOC, (VkSurfaceKHR*) &surface); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateXlibSurfaceKHR error."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) + << "vkCreateXlibSurfaceKHR error."; } #endif #elif defined(WIN32) @@ -200,7 +202,7 @@ VulkanPlatform::SurfaceBundle VulkanPlatform::createVkSurfaceKHR(void* nativeWin }; VkResult const result = vkCreateWin32SurfaceKHR(instance, &createInfo, nullptr, (VkSurfaceKHR*) &surface); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateWin32SurfaceKHR error."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "vkCreateWin32SurfaceKHR error."; #endif return std::make_tuple(surface, extent); } diff --git a/filament/backend/src/vulkan/platform/VulkanPlatformApple.mm b/filament/backend/src/vulkan/platform/VulkanPlatformApple.mm index a24e9ca3dcb5..a540f2f7d751 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatformApple.mm +++ b/filament/backend/src/vulkan/platform/VulkanPlatformApple.mm @@ -68,20 +68,22 @@ VkSurfaceKHR surface; #if defined(__APPLE__) NSView* nsview = (__bridge NSView*) nativeWindow; - ASSERT_POSTCONDITION(nsview, "Unable to obtain Metal-backed NSView."); + FILAMENT_CHECK_POSTCONDITION(nsview) << "Unable to obtain Metal-backed NSView."; // Create the VkSurface. - ASSERT_POSTCONDITION(vkCreateMacOSSurfaceMVK, "Unable to load vkCreateMacOSSurfaceMVK."); + FILAMENT_CHECK_POSTCONDITION(vkCreateMacOSSurfaceMVK) + << "Unable to load vkCreateMacOSSurfaceMVK."; VkMacOSSurfaceCreateInfoMVK createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; createInfo.pView = (__bridge void*) nsview; VkResult result = vkCreateMacOSSurfaceMVK((VkInstance) instance, &createInfo, VKALLOC, (VkSurfaceKHR*) &surface); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateMacOSSurfaceMVK error."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "vkCreateMacOSSurfaceMVK error."; #elif defined(IOS) && defined(METAL_AVAILABLE) CAMetalLayer* metalLayer = (CAMetalLayer*) nativeWindow; // Create the VkSurface. - ASSERT_POSTCONDITION(vkCreateIOSSurfaceMVK, "Unable to load vkCreateIOSSurfaceMVK function."); + FILAMENT_CHECK_POSTCONDITION(vkCreateIOSSurfaceMVK) + << "Unable to load vkCreateIOSSurfaceMVK function."; VkIOSSurfaceCreateInfoMVK createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK; createInfo.pNext = NULL; @@ -89,7 +91,7 @@ createInfo.pView = metalLayer; VkResult result = vkCreateIOSSurfaceMVK((VkInstance) instance, &createInfo, VKALLOC, (VkSurfaceKHR*) &surface); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkCreateIOSSurfaceMVK error."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "vkCreateIOSSurfaceMVK error."; #endif return std::make_tuple(surface, VkExtent2D {}); } diff --git a/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp b/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp index 5627e2610c2e..6e12de1500a8 100644 --- a/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp +++ b/filament/backend/src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp @@ -50,8 +50,8 @@ std::tuple createImageAndMemory(VulkanContext const& co }; VkImage image; VkResult result = vkCreateImage(device, &imageInfo, VKALLOC, &image); - ASSERT_POSTCONDITION(result == VK_SUCCESS, - "Unable to create image: ", static_cast(result)); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) + << "Unable to create image: " << static_cast(result); // Allocate memory for the VkImage and bind it. VkDeviceMemory imageMemory; @@ -61,8 +61,8 @@ std::tuple createImageAndMemory(VulkanContext const& co uint32_t memoryTypeIndex = context.selectMemoryType(memReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - ASSERT_POSTCONDITION(memoryTypeIndex < VK_MAX_MEMORY_TYPES, - "VulkanPlatformSwapChainImpl: unable to find a memory type that meets requirements."); + FILAMENT_CHECK_POSTCONDITION(memoryTypeIndex < VK_MAX_MEMORY_TYPES) + << "VulkanPlatformSwapChainImpl: unable to find a memory type that meets requirements."; VkMemoryAllocateInfo allocInfo = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, @@ -70,9 +70,9 @@ std::tuple createImageAndMemory(VulkanContext const& co .memoryTypeIndex = memoryTypeIndex, }; result = vkAllocateMemory(device, &allocInfo, nullptr, &imageMemory); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "Unable to allocate image memory."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "Unable to allocate image memory."; result = vkBindImageMemory(device, image, imageMemory, 0); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "Unable to bind image."); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) << "Unable to bind image."; return std::tuple(image, imageMemory); } @@ -178,8 +178,8 @@ VkResult VulkanPlatformSurfaceSwapChain::create() { break; } } - ASSERT_POSTCONDITION(surfaceFormat.format != VK_FORMAT_UNDEFINED, - "Cannot find suitable swapchain format"); + FILAMENT_CHECK_POSTCONDITION(surfaceFormat.format != VK_FORMAT_UNDEFINED) + << "Cannot find suitable swapchain format"; // Verify that our chosen present mode is supported. In practice all devices support the FIFO // mode, but we check for it anyway for completeness. (and to avoid validation warnings) @@ -193,8 +193,8 @@ VkResult VulkanPlatformSurfaceSwapChain::create() { break; } } - ASSERT_POSTCONDITION(foundSuitablePresentMode, - "Desired present mode is not supported by this device."); + FILAMENT_CHECK_POSTCONDITION(foundSuitablePresentMode) + << "Desired present mode is not supported by this device."; // Create the low-level swap chain. if (caps.currentExtent.width == VULKAN_UNDEFINED_EXTENT @@ -237,8 +237,8 @@ VkResult VulkanPlatformSurfaceSwapChain::create() { .oldSwapchain = mSwapchain, }; VkResult result = vkCreateSwapchainKHR(mDevice, &createInfo, VKALLOC, &mSwapchain); - ASSERT_POSTCONDITION(result == VK_SUCCESS, "vkGetPhysicalDeviceSurfaceFormatsKHR error: %d", - static_cast(result)); + FILAMENT_CHECK_POSTCONDITION(result == VK_SUCCESS) + << "vkGetPhysicalDeviceSurfaceFormatsKHR error: " << static_cast(result); mSwapChainBundle.colors = enumerate(vkGetSwapchainImagesKHR, mDevice, mSwapchain); mSwapChainBundle.colorFormat = surfaceFormat.format; diff --git a/filament/include/filament/SwapChain.h b/filament/include/filament/SwapChain.h index 585e016eec09..6917507a5d66 100644 --- a/filament/include/filament/SwapChain.h +++ b/filament/include/filament/SwapChain.h @@ -116,7 +116,7 @@ class Engine; * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SDL_SysWMinfo wmi; * SDL_VERSION(&wmi.version); - * ASSERT_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi), "SDL version unsupported!"); + * FILAMENT_CHECK_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi)) << "SDL version unsupported!"; * HDC nativeWindow = (HDC) wmi.info.win.hdc; * * using namespace filament; diff --git a/filament/src/Engine.cpp b/filament/src/Engine.cpp index 75e16b109b39..ae37b3cea1e2 100644 --- a/filament/src/Engine.cpp +++ b/filament/src/Engine.cpp @@ -299,7 +299,8 @@ void* Engine::streamAlloc(size_t size, size_t alignment) noexcept { // The external-facing execute does a flush, and is meant only for single-threaded environments. // It also discards the boolean return value, which would otherwise indicate a thread exit. void Engine::execute() { - ASSERT_PRECONDITION(!UTILS_HAS_THREADING, "Execute is meant for single-threaded platforms."); + FILAMENT_CHECK_PRECONDITION(!UTILS_HAS_THREADING) + << "Execute is meant for single-threaded platforms."; downcast(this)->flush(); downcast(this)->execute(); } @@ -309,12 +310,14 @@ utils::JobSystem& Engine::getJobSystem() noexcept { } bool Engine::isPaused() const noexcept { - ASSERT_PRECONDITION(UTILS_HAS_THREADING, "Pause is meant for multi-threaded platforms."); + FILAMENT_CHECK_PRECONDITION(UTILS_HAS_THREADING) + << "Pause is meant for multi-threaded platforms."; return downcast(this)->isPaused(); } void Engine::setPaused(bool paused) { - ASSERT_PRECONDITION(UTILS_HAS_THREADING, "Pause is meant for multi-threaded platforms."); + FILAMENT_CHECK_PRECONDITION(UTILS_HAS_THREADING) + << "Pause is meant for multi-threaded platforms."; downcast(this)->setPaused(paused); } diff --git a/filament/src/RenderPass.cpp b/filament/src/RenderPass.cpp index e13b5da30555..ee5092370d00 100644 --- a/filament/src/RenderPass.cpp +++ b/filament/src/RenderPass.cpp @@ -80,7 +80,8 @@ RenderPassBuilder& RenderPassBuilder::customCommand( } RenderPass RenderPassBuilder::build(FEngine& engine) { - ASSERT_POSTCONDITION(mRenderableSoa, "RenderPassBuilder::geometry() hasn't been called"); + FILAMENT_CHECK_POSTCONDITION(mRenderableSoa) + << "RenderPassBuilder::geometry() hasn't been called"; assert_invariant(mScissorViewport.width <= std::numeric_limits::max()); assert_invariant(mScissorViewport.height <= std::numeric_limits::max()); return RenderPass{ engine, *this }; diff --git a/filament/src/RendererUtils.cpp b/filament/src/RendererUtils.cpp index e5b29567fe43..2e252633c476 100644 --- a/filament/src/RendererUtils.cpp +++ b/filament/src/RendererUtils.cpp @@ -353,14 +353,12 @@ UTILS_NOINLINE void RendererUtils::readPixels(backend::DriverApi& driver, Handle renderTargetHandle, uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height, backend::PixelBufferDescriptor&& buffer) { - ASSERT_PRECONDITION( - buffer.type != PixelDataType::COMPRESSED, - "buffer.format cannot be COMPRESSED"); + FILAMENT_CHECK_PRECONDITION(buffer.type != PixelDataType::COMPRESSED) + << "buffer.format cannot be COMPRESSED"; - ASSERT_PRECONDITION( - buffer.alignment > 0 && buffer.alignment <= 8 && - !(buffer.alignment & (buffer.alignment - 1u)), - "buffer.alignment must be 1, 2, 4 or 8"); + FILAMENT_CHECK_PRECONDITION(buffer.alignment > 0 && buffer.alignment <= 8 && + !(buffer.alignment & (buffer.alignment - 1u))) + << "buffer.alignment must be 1, 2, 4 or 8"; // It's not really possible to know here which formats will be supported because // it can vary depending on the RenderTarget, in GL the following are ALWAYS supported though: @@ -373,8 +371,9 @@ void RendererUtils::readPixels(backend::DriverApi& driver, Handle= sizeNeeded, - "Pixel buffer too small: has %u bytes, needs %u bytes", buffer.size, sizeNeeded); + FILAMENT_CHECK_PRECONDITION(buffer.size >= sizeNeeded) + << "Pixel buffer too small: has " << buffer.size << " bytes, needs " << sizeNeeded + << " bytes"; driver.readPixels(renderTargetHandle, xoffset, yoffset, width, height, std::move(buffer)); } diff --git a/filament/src/components/RenderableManager.cpp b/filament/src/components/RenderableManager.cpp index 8a09e0b34f0c..596cd8e7fe74 100644 --- a/filament/src/components/RenderableManager.cpp +++ b/filament/src/components/RenderableManager.cpp @@ -322,19 +322,21 @@ void RenderableManager::BuilderDetails::processBoneIndicesAndWights(Engine& engi for (auto& bonePair: mBonePairs) { auto primitiveIndex = bonePair.first; auto entries = mEntries; - ASSERT_PRECONDITION(primitiveIndex < entries.size() && primitiveIndex >= 0, - "[primitive @ %u] primitiveindex is out of size (%u)", primitiveIndex, entries.size()); + FILAMENT_CHECK_PRECONDITION(primitiveIndex < entries.size() && primitiveIndex >= 0) + << "[primitive @ " << primitiveIndex << "] primitiveindex is out of size (" + << entries.size() << ")"; auto entry = mEntries[primitiveIndex]; auto bonePairsForPrimitive = bonePair.second; auto vertexCount = entry.vertices->getVertexCount(); - ASSERT_PRECONDITION(bonePairsForPrimitive.size() == vertexCount, - "[primitive @ %u] bone indices and weights pairs count (%u) must be equal to vertex count (%u)", - primitiveIndex, bonePairsForPrimitive.size(), vertexCount); + FILAMENT_CHECK_PRECONDITION(bonePairsForPrimitive.size() == vertexCount) + << "[primitive @ " << primitiveIndex << "] bone indices and weights pairs count (" + << bonePairsForPrimitive.size() << ") must be equal to vertex count (" + << vertexCount << ")"; auto const& declaredAttributes = downcast(entry.vertices)->getDeclaredAttributes(); - ASSERT_PRECONDITION(declaredAttributes[VertexAttribute::BONE_INDICES] - || declaredAttributes[VertexAttribute::BONE_WEIGHTS], - "[entity=%u, primitive @ %u] for advanced skinning set VertexBuffer::Builder::advancedSkinning()", - entity.getId(), primitiveIndex); + FILAMENT_CHECK_PRECONDITION(declaredAttributes[VertexAttribute::BONE_INDICES] || + declaredAttributes[VertexAttribute::BONE_WEIGHTS]) + << "[entity=" << entity.getId() << ", primitive @ " << primitiveIndex + << "] for advanced skinning set VertexBuffer::Builder::advancedSkinning()"; for (size_t iVertex = 0; iVertex < vertexCount; iVertex++) { size_t const bonesPerVertex = bonePairsForPrimitive[iVertex].size(); maxPairsCount += bonesPerVertex; @@ -365,16 +367,20 @@ void RenderableManager::BuilderDetails::processBoneIndicesAndWights(Engine& engi for (size_t k = 0; k < bonePairsForPrimitive[iVertex].size(); k++) { auto boneWeight = bonePairsForPrimitive[iVertex][k][1]; auto boneIndex = bonePairsForPrimitive[iVertex][k][0]; - ASSERT_PRECONDITION(boneWeight >= 0, - "[entity=%u, primitive @ %u] bone weight (%f) of vertex=%u is negative ", - entity.getId(), primitiveIndex, boneWeight, iVertex); + FILAMENT_CHECK_PRECONDITION(boneWeight >= 0) + << "[entity=" << entity.getId() << ", primitive @ " << primitiveIndex + << "] bone weight (" << boneWeight << ") of vertex=" << iVertex + << " is negative"; if (boneWeight > 0.0f) { - ASSERT_PRECONDITION(boneIndex >= 0, - "[entity=%u, primitive @ %u] bone index (%i) of vertex=%u is negative ", - entity.getId(), primitiveIndex, (int) boneIndex, iVertex); - ASSERT_PRECONDITION(boneIndex < mSkinningBoneCount, - "[entity=%u, primitive @ %u] bone index (%i) of vertex=%u is bigger then bone count (%u) ", - entity.getId(), primitiveIndex, (int) boneIndex, iVertex, mSkinningBoneCount); + FILAMENT_CHECK_PRECONDITION(boneIndex >= 0) + << "[entity=" << entity.getId() << ", primitive @ " + << primitiveIndex << "] bone index (" << (int)boneIndex + << ") of vertex=" << iVertex << " is negative"; + FILAMENT_CHECK_PRECONDITION(boneIndex < mSkinningBoneCount) + << "[entity=" << entity.getId() << ", primitive @ " + << primitiveIndex << "] bone index (" << (int)boneIndex + << ") of vertex=" << iVertex << " is bigger then bone count (" + << mSkinningBoneCount << ")"; boneWeightsSum += boneWeight; tempPairs[tempPairCount][0] = boneIndex; tempPairs[tempPairCount][1] = boneWeight; @@ -382,9 +388,10 @@ void RenderableManager::BuilderDetails::processBoneIndicesAndWights(Engine& engi } } - ASSERT_PRECONDITION(boneWeightsSum > 0, - "[entity=%u, primitive @ %u] sum of bone weights of vertex=%u is %f, it should be positive.", - entity.getId(), primitiveIndex, iVertex, boneWeightsSum); + FILAMENT_CHECK_PRECONDITION(boneWeightsSum > 0) + << "[entity=" << entity.getId() << ", primitive @ " << primitiveIndex + << "] sum of bone weights of vertex=" << iVertex << " is " << boneWeightsSum + << ", it should be positive."; // see https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes double const epsilon = 2e-7 * double(tempPairCount); @@ -432,30 +439,29 @@ void RenderableManager::BuilderDetails::processBoneIndicesAndWights(Engine& engi RenderableManager::Builder::Result RenderableManager::Builder::build(Engine& engine, Entity entity) { bool isEmpty = true; - ASSERT_PRECONDITION(mImpl->mSkinningBoneCount <= CONFIG_MAX_BONE_COUNT, - "bone count > %u", CONFIG_MAX_BONE_COUNT); + FILAMENT_CHECK_PRECONDITION(mImpl->mSkinningBoneCount <= CONFIG_MAX_BONE_COUNT) + << "bone count > " << CONFIG_MAX_BONE_COUNT; - ASSERT_PRECONDITION(mImpl->mInstanceCount <= CONFIG_MAX_INSTANCES || !mImpl->mInstanceBuffer, - "instance count is %zu, but instance count is limited to CONFIG_MAX_INSTANCES (%zu) " - "instances when supplying transforms via an InstanceBuffer.", - mImpl->mInstanceCount, - CONFIG_MAX_INSTANCES); + FILAMENT_CHECK_PRECONDITION( + mImpl->mInstanceCount <= CONFIG_MAX_INSTANCES || !mImpl->mInstanceBuffer) + << "instance count is " << mImpl->mInstanceCount + << ", but instance count is limited to CONFIG_MAX_INSTANCES (" << CONFIG_MAX_INSTANCES + << ") instances when supplying transforms via an InstanceBuffer."; if (mImpl->mGeometryType == GeometryType::STATIC) { - ASSERT_PRECONDITION(mImpl->mSkinningBoneCount > 0, - "Skinning can't be used with STATIC geometry"); + FILAMENT_CHECK_PRECONDITION(mImpl->mSkinningBoneCount > 0) + << "Skinning can't be used with STATIC geometry"; - ASSERT_PRECONDITION(mImpl->mMorphTargetCount > 0, - "Morphing can't be used with STATIC geometry"); + FILAMENT_CHECK_PRECONDITION(mImpl->mMorphTargetCount > 0) + << "Morphing can't be used with STATIC geometry"; } if (mImpl->mInstanceBuffer) { size_t const bufferInstanceCount = mImpl->mInstanceBuffer->mInstanceCount; - ASSERT_PRECONDITION(mImpl->mInstanceCount <= bufferInstanceCount, - "instance count (%zu) must be less than or equal to the InstanceBuffer's instance " - "count " - "(%zu).", - mImpl->mInstanceCount, bufferInstanceCount); + FILAMENT_CHECK_PRECONDITION(mImpl->mInstanceCount <= bufferInstanceCount) + << "instance count (" << mImpl->mInstanceCount + << ") must be less than or equal to the InstanceBuffer's instance " + "count (" << bufferInstanceCount << ")."; } if (UTILS_LIKELY(mImpl->mSkinningBoneCount || mImpl->mSkinningBufferMode)) { @@ -480,15 +486,15 @@ RenderableManager::Builder::Result RenderableManager::Builder::build(Engine& eng } // we want a feature level violation to be a hard error (exception if enabled, or crash) - ASSERT_PRECONDITION(downcast(engine).hasFeatureLevel(material->getFeatureLevel()), - "Material \"%s\" has feature level %u which is not supported by this Engine", - material->getName().c_str_safe(), (uint8_t)material->getFeatureLevel()); + FILAMENT_CHECK_PRECONDITION(downcast(engine).hasFeatureLevel(material->getFeatureLevel())) + << "Material \"" << material->getName().c_str_safe() << "\" has feature level " + << (uint8_t)material->getFeatureLevel() << " which is not supported by this Engine"; // reject invalid geometry parameters - ASSERT_PRECONDITION(entry.offset + entry.count <= entry.indices->getIndexCount(), - "[entity=%u, primitive @ %u] offset (%u) + count (%u) > indexCount (%u)", - entity.getId(), i, - entry.offset, entry.count, entry.indices->getIndexCount()); + FILAMENT_CHECK_PRECONDITION(entry.offset + entry.count <= entry.indices->getIndexCount()) + << "[entity=" << entity.getId() << ", primitive @ " << i << "] offset (" + << entry.offset << ") + count (" << entry.count << ") > indexCount (" + << entry.indices->getIndexCount() << ")"; // this can't be an error because (1) those values are not immutable, so the caller // could fix later, and (2) the material's shader will work (i.e. compile), and @@ -505,12 +511,11 @@ RenderableManager::Builder::Result RenderableManager::Builder::build(Engine& eng isEmpty = false; } - ASSERT_PRECONDITION( - !mImpl->mAABB.isEmpty() || - (!mImpl->mCulling && (!(mImpl->mReceiveShadows || mImpl->mCastShadows)) || - isEmpty), - "[entity=%u] AABB can't be empty, unless culling is disabled and " - "the object is not a shadow caster/receiver", entity.getId()); + FILAMENT_CHECK_PRECONDITION(!mImpl->mAABB.isEmpty() || + (!mImpl->mCulling && (!(mImpl->mReceiveShadows || mImpl->mCastShadows)) || isEmpty)) + << "[entity=" << entity.getId() + << "] AABB can't be empty, unless culling is disabled and " + "the object is not a shadow caster/receiver"; downcast(engine).createRenderable(*this, entity); return Success; @@ -804,9 +809,10 @@ void FRenderableManager::setMaterialInstanceAt(Instance instance, uint8_t level, FMaterial const* material = mi->getMaterial(); // we want a feature level violation to be a hard error (exception if enabled, or crash) - ASSERT_PRECONDITION(mEngine.hasFeatureLevel(material->getFeatureLevel()), - "Material \"%s\" has feature level %u which is not supported by this Engine", - material->getName().c_str_safe(), (uint8_t)material->getFeatureLevel()); + FILAMENT_CHECK_PRECONDITION(mEngine.hasFeatureLevel(material->getFeatureLevel())) + << "Material \"" << material->getName().c_str_safe() << "\" has feature level " + << (uint8_t)material->getFeatureLevel() + << " which is not supported by this Engine"; primitives[primitiveIndex].setMaterialInstance(mi); AttributeBitset const required = material->getRequiredAttributes(); @@ -881,8 +887,8 @@ void FRenderableManager::setBones(Instance ci, if (ci) { Bones const& bones = mManager[ci].bones; - ASSERT_PRECONDITION(!bones.skinningBufferMode, - "Disable skinning buffer mode to use this API"); + FILAMENT_CHECK_PRECONDITION(!bones.skinningBufferMode) + << "Disable skinning buffer mode to use this API"; assert_invariant(bones.handle && offset + boneCount <= bones.count); if (bones.handle) { @@ -897,8 +903,8 @@ void FRenderableManager::setBones(Instance ci, if (ci) { Bones const& bones = mManager[ci].bones; - ASSERT_PRECONDITION(!bones.skinningBufferMode, - "Disable skinning buffer mode to use this API"); + FILAMENT_CHECK_PRECONDITION(!bones.skinningBufferMode) + << "Disable skinning buffer mode to use this API"; assert_invariant(bones.handle && offset + boneCount <= bones.count); if (bones.handle) { @@ -913,12 +919,11 @@ void FRenderableManager::setSkinningBuffer(FRenderableManager::Instance ci, Bones& bones = mManager[ci].bones; - ASSERT_PRECONDITION(bones.skinningBufferMode, - "Enable skinning buffer mode to use this API"); + FILAMENT_CHECK_PRECONDITION(bones.skinningBufferMode) + << "Enable skinning buffer mode to use this API"; - ASSERT_PRECONDITION( - count <= CONFIG_MAX_BONE_COUNT, - "SkinningBuffer larger than 256 (count=%u)", count); + FILAMENT_CHECK_PRECONDITION(count <= CONFIG_MAX_BONE_COUNT) + << "SkinningBuffer larger than 256 (count=" << count << ")"; // According to the OpenGL ES 3.2 specification in 7.6.3 Uniform // Buffer Object Bindings: @@ -930,10 +935,9 @@ void FRenderableManager::setSkinningBuffer(FRenderableManager::Instance ci, count = CONFIG_MAX_BONE_COUNT; - ASSERT_PRECONDITION( - count + offset <= skinningBuffer->getBoneCount(), - "SkinningBuffer overflow (size=%u, count=%u, offset=%u)", - skinningBuffer->getBoneCount(), count, offset); + FILAMENT_CHECK_PRECONDITION(count + offset <= skinningBuffer->getBoneCount()) + << "SkinningBuffer overflow (size=" << skinningBuffer->getBoneCount() + << ", count=" << count << ", offset=" << offset << ")"; bones.handle = skinningBuffer->getHwHandle(); bones.count = uint16_t(count); @@ -953,9 +957,9 @@ static void updateMorphWeights(FEngine& engine, backend::Handle& morphTargets = getMorphTargets(instance, level); if (primitiveIndex < morphTargets.size()) { diff --git a/filament/src/components/RenderableManager.h b/filament/src/components/RenderableManager.h index 6135ba2d7338..0fa44c83e771 100644 --- a/filament/src/components/RenderableManager.h +++ b/filament/src/components/RenderableManager.h @@ -310,10 +310,10 @@ FILAMENT_DOWNCAST(RenderableManager) void FRenderableManager::setAxisAlignedBoundingBox(Instance instance, const Box& aabb) { if (instance) { - ASSERT_PRECONDITION( - static_cast( - mManager[instance].visibility).geometryType == GeometryType::DYNAMIC, - "This renderable has staticBounds enabled; its AABB cannot change."); + FILAMENT_CHECK_PRECONDITION( + static_cast(mManager[instance].visibility).geometryType == + GeometryType::DYNAMIC) + << "This renderable has staticBounds enabled; its AABB cannot change."; mManager[instance].aabb = aabb; } } @@ -389,9 +389,8 @@ void FRenderableManager::setSkinning(Instance instance, bool enable) { if (instance) { Visibility& visibility = mManager[instance].visibility; - ASSERT_PRECONDITION( - visibility.geometryType != GeometryType::STATIC || !enable, - "Skinning can't be used with STATIC geometry"); + FILAMENT_CHECK_PRECONDITION(visibility.geometryType != GeometryType::STATIC || !enable) + << "Skinning can't be used with STATIC geometry"; visibility.skinning = enable; } @@ -401,9 +400,8 @@ void FRenderableManager::setMorphing(Instance instance, bool enable) { if (instance) { Visibility& visibility = mManager[instance].visibility; - ASSERT_PRECONDITION( - visibility.geometryType != GeometryType::STATIC || !enable, - "Morphing can't be used with STATIC geometry"); + FILAMENT_CHECK_PRECONDITION(visibility.geometryType != GeometryType::STATIC || !enable) + << "Morphing can't be used with STATIC geometry"; visibility.morphing = enable; } diff --git a/filament/src/details/Camera.cpp b/filament/src/details/Camera.cpp index d57035863789..1c333d4b632d 100644 --- a/filament/src/details/Camera.cpp +++ b/filament/src/details/Camera.cpp @@ -97,9 +97,10 @@ void UTILS_NOINLINE FCamera::setCustomProjection(mat4 const& p, void UTILS_NOINLINE FCamera::setCustomEyeProjection(math::mat4 const* projection, size_t count, math::mat4 const& projectionForCulling, double near, double far) { const Engine::Config& config = mEngine.getConfig(); - ASSERT_PRECONDITION(count >= config.stereoscopicEyeCount, - "All eye projections must be supplied together, count must be >= " - "config.stereoscopicEyeCount (%d)", config.stereoscopicEyeCount); + FILAMENT_CHECK_PRECONDITION(count >= config.stereoscopicEyeCount) + << "All eye projections must be supplied together, count must be >= " + "config.stereoscopicEyeCount (" + << config.stereoscopicEyeCount << ")"; for (int i = 0; i < config.stereoscopicEyeCount; i++) { mEyeProjection[i] = projection[i]; } @@ -113,14 +114,13 @@ void UTILS_NOINLINE FCamera::setProjection(Camera::Projection projection, double bottom, double top, double near, double far) { - ASSERT_PRECONDITION(!( - left == right || - bottom == top || + FILAMENT_CHECK_PRECONDITION(!(left == right || bottom == top || (projection == Projection::PERSPECTIVE && (near <= 0 || far <= near)) || - (projection == Projection::ORTHO && (near == far))), - "Camera preconditions not met in setProjection(%s, %f, %f, %f, %f, %f, %f)", - projection == Camera::Projection::PERSPECTIVE ? "PERSPECTIVE" : "ORTHO", - left, right, bottom, top, near, far); + (projection == Projection::ORTHO && (near == far)))) + << "Camera preconditions not met in setProjection(" + << (projection == Camera::Projection::PERSPECTIVE ? "PERSPECTIVE" : "ORTHO") << ", " + << left << ", " << right << ", " << bottom << ", " << top << ", " << near << ", " << far + << ")"; mat4 c, p; switch (projection) { @@ -193,8 +193,9 @@ math::mat4 FCamera::getCullingProjectionMatrix() const noexcept { const math::mat4& FCamera::getUserProjectionMatrix(uint8_t eyeId) const { const Engine::Config& config = mEngine.getConfig(); - ASSERT_PRECONDITION(eyeId < config.stereoscopicEyeCount, - "eyeId must be < config.stereoscopicEyeCount (%d)", config.stereoscopicEyeCount); + FILAMENT_CHECK_PRECONDITION(eyeId < config.stereoscopicEyeCount) + << "eyeId must be < config.stereoscopicEyeCount (" << config.stereoscopicEyeCount + << ")"; return mEyeProjection[eyeId]; } @@ -210,8 +211,9 @@ void UTILS_NOINLINE FCamera::setModelMatrix(const mat4& modelMatrix) noexcept { void UTILS_NOINLINE FCamera::setEyeModelMatrix(uint8_t eyeId, math::mat4 const& model) { const Engine::Config& config = mEngine.getConfig(); - ASSERT_PRECONDITION(eyeId < config.stereoscopicEyeCount, - "eyeId must be < config.stereoscopicEyeCount (%d)", config.stereoscopicEyeCount); + FILAMENT_CHECK_PRECONDITION(eyeId < config.stereoscopicEyeCount) + << "eyeId must be < config.stereoscopicEyeCount (" << config.stereoscopicEyeCount + << ")"; mEyeFromView[eyeId] = inverse(model); } diff --git a/filament/src/details/Engine.cpp b/filament/src/details/Engine.cpp index a4469d97d9fb..54e16bb69c55 100644 --- a/filament/src/details/Engine.cpp +++ b/filament/src/details/Engine.cpp @@ -159,8 +159,8 @@ FEngine* FEngine::getEngine(void* token) { FEngine* instance = static_cast(token); - ASSERT_PRECONDITION(ThreadUtils::isThisThread(instance->mMainThreadId), - "Engine::createAsync() and Engine::getEngine() must be called on the same thread."); + FILAMENT_CHECK_PRECONDITION(ThreadUtils::isThisThread(instance->mMainThreadId)) + << "Engine::createAsync() and Engine::getEngine() must be called on the same thread."; // we use mResourceAllocator as a proxy for "am I already initialized" if (!instance->mResourceAllocator) { @@ -441,8 +441,8 @@ void FEngine::shutdown() { // by construction this should never be nullptr assert_invariant(mResourceAllocator); - ASSERT_PRECONDITION(ThreadUtils::isThisThread(mMainThreadId), - "Engine::shutdown() called from the wrong thread!"); + FILAMENT_CHECK_PRECONDITION(ThreadUtils::isThisThread(mMainThreadId)) + << "Engine::shutdown() called from the wrong thread!"; #ifndef NDEBUG // print out some statistics about this run @@ -585,14 +585,14 @@ void FEngine::flush() { } void FEngine::flushAndWait() { - ASSERT_PRECONDITION(!mCommandBufferQueue.isPaused(), - "Cannot call flushAndWait() when rendering thread is paused!"); + FILAMENT_CHECK_PRECONDITION(!mCommandBufferQueue.isPaused()) + << "Cannot call flushAndWait() when rendering thread is paused!"; #if defined(__ANDROID__) // first make sure we've not terminated filament - ASSERT_PRECONDITION(!mCommandBufferQueue.isExitRequested(), - "calling Engine::flushAndWait() after Engine::shutdown()!"); + FILAMENT_CHECK_PRECONDITION(!mCommandBufferQueue.isExitRequested()) + << "calling Engine::flushAndWait() after Engine::shutdown()!"; #endif @@ -610,10 +610,10 @@ void FEngine::flushAndWait() { // if the fence didn't trigger after 250ms, check that the command queue thread is still // running (otherwise indicating a precondition violation). if (UTILS_UNLIKELY(status == FenceStatus::TIMEOUT_EXPIRED)) { - ASSERT_PRECONDITION(!mCommandBufferQueue.isExitRequested(), - "called Engine::shutdown() WHILE in Engine::flushAndWait()!"); + FILAMENT_CHECK_PRECONDITION(!mCommandBufferQueue.isExitRequested()) + << "called Engine::shutdown() WHILE in Engine::flushAndWait()!"; tryCount--; - ASSERT_POSTCONDITION(tryCount, "flushAndWait() failed inexplicably after 2s"); + FILAMENT_CHECK_POSTCONDITION(tryCount) << "flushAndWait() failed inexplicably after 2s"; // if the thread is still running, maybe we just need to give it more time continue; } @@ -1240,10 +1240,10 @@ Engine::FeatureLevel FEngine::getSupportedFeatureLevel() const noexcept { } Engine::FeatureLevel FEngine::setActiveFeatureLevel(FeatureLevel featureLevel) { - ASSERT_PRECONDITION(featureLevel <= getSupportedFeatureLevel(), - "Feature level %u not supported", (unsigned)featureLevel); - ASSERT_PRECONDITION(mActiveFeatureLevel >= FeatureLevel::FEATURE_LEVEL_1, - "Cannot adjust feature level beyond 0 at runtime"); + FILAMENT_CHECK_PRECONDITION(featureLevel <= getSupportedFeatureLevel()) + << "Feature level " << (unsigned)featureLevel << " not supported"; + FILAMENT_CHECK_PRECONDITION(mActiveFeatureLevel >= FeatureLevel::FEATURE_LEVEL_1) + << "Cannot adjust feature level beyond 0 at runtime"; return (mActiveFeatureLevel = std::max(mActiveFeatureLevel, featureLevel)); } diff --git a/filament/src/details/Fence.cpp b/filament/src/details/Fence.cpp index 354c11936c35..b05cab44f7be 100644 --- a/filament/src/details/Fence.cpp +++ b/filament/src/details/Fence.cpp @@ -61,7 +61,8 @@ FenceStatus FFence::waitAndDestroy(FFence* fence, Mode mode) noexcept { UTILS_NOINLINE FenceStatus FFence::wait(Mode mode, uint64_t timeout) noexcept { - ASSERT_PRECONDITION(UTILS_HAS_THREADING || timeout == 0, "Non-zero timeout requires threads."); + FILAMENT_CHECK_PRECONDITION(UTILS_HAS_THREADING || timeout == 0) + << "Non-zero timeout requires threads."; FEngine& engine = mEngine; diff --git a/filament/src/details/IndirectLight.cpp b/filament/src/details/IndirectLight.cpp index b3eb1c4ce550..2822266c72b8 100644 --- a/filament/src/details/IndirectLight.cpp +++ b/filament/src/details/IndirectLight.cpp @@ -150,9 +150,9 @@ IndirectLight::Builder& IndirectLight::Builder::rotation(mat3f const& rotation) IndirectLight* IndirectLight::Builder::build(Engine& engine) { if (mImpl->mReflectionsMap) { - ASSERT_PRECONDITION( - mImpl->mReflectionsMap->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP, - "reflection map must a cubemap"); + FILAMENT_CHECK_PRECONDITION( + mImpl->mReflectionsMap->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP) + << "reflection map must a cubemap"; if constexpr (IBL_INTEGRATION == IBL_INTEGRATION_IMPORTANCE_SAMPLING) { mImpl->mReflectionsMap->generateMipmaps(engine); @@ -160,9 +160,9 @@ IndirectLight* IndirectLight::Builder::build(Engine& engine) { } if (mImpl->mIrradianceMap) { - ASSERT_PRECONDITION( - mImpl->mIrradianceMap->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP, - "irradiance map must a cubemap"); + FILAMENT_CHECK_PRECONDITION( + mImpl->mIrradianceMap->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP) + << "irradiance map must a cubemap"; } return downcast(engine).createIndirectLight(*this); diff --git a/filament/src/details/InstanceBuffer.cpp b/filament/src/details/InstanceBuffer.cpp index eba97fa539df..af22554d0f2e 100644 --- a/filament/src/details/InstanceBuffer.cpp +++ b/filament/src/details/InstanceBuffer.cpp @@ -51,12 +51,11 @@ InstanceBuffer::Builder& InstanceBuffer::Builder::localTransforms( } InstanceBuffer* InstanceBuffer::Builder::build(Engine& engine) { - ASSERT_PRECONDITION(mImpl->mInstanceCount >= 1, "instanceCount must be >= 1."); - ASSERT_PRECONDITION(mImpl->mInstanceCount <= engine.getMaxAutomaticInstances(), - "instanceCount is %zu, but instance count is limited to " - "Engine::getMaxAutomaticInstances() (%zu) instances when supplying transforms.", - mImpl->mInstanceCount, - engine.getMaxAutomaticInstances()); + FILAMENT_CHECK_PRECONDITION(mImpl->mInstanceCount >= 1) << "instanceCount must be >= 1."; + FILAMENT_CHECK_PRECONDITION(mImpl->mInstanceCount <= engine.getMaxAutomaticInstances()) + << "instanceCount is " << mImpl->mInstanceCount + << ", but instance count is limited to Engine::getMaxAutomaticInstances() (" + << engine.getMaxAutomaticInstances() << ") instances when supplying transforms."; return downcast(engine).createInstanceBuffer(*this); } @@ -76,12 +75,10 @@ FInstanceBuffer::FInstanceBuffer(FEngine& engine, const Builder& builder) { void FInstanceBuffer::setLocalTransforms( math::mat4f const* localTransforms, size_t count, size_t offset) { - ASSERT_PRECONDITION(offset + count <= mInstanceCount, - "setLocalTransforms overflow. InstanceBuffer has only %zu instances, but trying to set " - "%zu transforms at offset %zu.", - mInstanceCount, - count, - offset); + FILAMENT_CHECK_PRECONDITION(offset + count <= mInstanceCount) + << "setLocalTransforms overflow. InstanceBuffer has only " << mInstanceCount + << " instances, but trying to set " << count + << " transforms at offset " << offset << "."; memcpy(mLocalTransforms.data() + offset, localTransforms, sizeof(math::mat4f) * count); } diff --git a/filament/src/details/Material.cpp b/filament/src/details/Material.cpp index e0d2f86984f4..790c3874c7ce 100644 --- a/filament/src/details/Material.cpp +++ b/filament/src/details/Material.cpp @@ -91,23 +91,24 @@ static std::unique_ptr createParser(Backend backend, } } - ASSERT_PRECONDITION(materialResult != MaterialParser::ParseResult::ERROR_MISSING_BACKEND, - "the material was not built for any of the %s backend's supported shader " - "languages (%s)\n", - backendToString(backend), languageNames.c_str()); + FILAMENT_CHECK_PRECONDITION( + materialResult != MaterialParser::ParseResult::ERROR_MISSING_BACKEND) + << "the material was not built for any of the " << backendToString(backend) + << " backend's supported shader languages (" << languageNames.c_str() << ")\n"; } if (backend == Backend::NOOP) { return materialParser; } - ASSERT_PRECONDITION(materialResult == MaterialParser::ParseResult::SUCCESS, - "could not parse the material package"); + FILAMENT_CHECK_PRECONDITION(materialResult == MaterialParser::ParseResult::SUCCESS) + << "could not parse the material package"; uint32_t version = 0; materialParser->getMaterialVersion(&version); - ASSERT_PRECONDITION(version == MATERIAL_VERSION, - "Material version mismatch. Expected %d but received %d.", MATERIAL_VERSION, version); + FILAMENT_CHECK_PRECONDITION(version == MATERIAL_VERSION) + << "Material version mismatch. Expected " << MATERIAL_VERSION << " but received " + << version << "."; assert_invariant(backend != Backend::DEFAULT && "Default backend has not been resolved."); @@ -144,7 +145,7 @@ Material::Builder& Material::Builder::package(const void* payload, size_t size) template Material::Builder& Material::Builder::constant(const char* name, size_t nameLength, T value) { - ASSERT_PRECONDITION(name != nullptr, "name cannot be null"); + FILAMENT_CHECK_PRECONDITION(name != nullptr) << "name cannot be null"; mImpl->mConstantSpecializations[{name, nameLength}] = value; return *this; } @@ -522,10 +523,11 @@ Program FMaterial::getProgramWithVariants( UTILS_UNUSED_IN_RELEASE bool const vsOK = mMaterialParser->getShader(vsBuilder, sm, vertexVariant, ShaderStage::VERTEX); - ASSERT_POSTCONDITION(isNoop || (vsOK && !vsBuilder.empty()), - "The material '%s' has not been compiled to include the required " - "GLSL or SPIR-V chunks for the vertex shader (variant=0x%x, filtered=0x%x).", - mName.c_str(), variant.key, vertexVariant.key); + FILAMENT_CHECK_POSTCONDITION(isNoop || (vsOK && !vsBuilder.empty())) + << "The material '" << mName.c_str() + << "' has not been compiled to include the required GLSL or SPIR-V chunks for the " + "vertex shader (variant=" + << variant.key << ", filtered=" << vertexVariant.key << ")."; /* * Fragment shader @@ -536,10 +538,11 @@ Program FMaterial::getProgramWithVariants( UTILS_UNUSED_IN_RELEASE bool const fsOK = mMaterialParser->getShader(fsBuilder, sm, fragmentVariant, ShaderStage::FRAGMENT); - ASSERT_POSTCONDITION(isNoop || (fsOK && !fsBuilder.empty()), - "The material '%s' has not been compiled to include the required " - "GLSL or SPIR-V chunks for the fragment shader (variant=0x%x, filtered=0x%x).", - mName.c_str(), variant.key, fragmentVariant.key); + FILAMENT_CHECK_POSTCONDITION(isNoop || (fsOK && !fsBuilder.empty())) + << "The material '" << mName.c_str() + << "' has not been compiled to include the required GLSL or SPIR-V chunks for the " + "fragment shader (variant=" + << variant.key << ", filtered=" << ")."; Program program; program.shader(ShaderStage::VERTEX, vsBuilder.data(), vsBuilder.size()) @@ -904,26 +907,29 @@ void FMaterial::processSpecializationConstants(FEngine& engine, Material::Builde for (auto const& [name, value] : builder->mConstantSpecializations) { std::string_view const key{ name.data(), name.size() }; auto pos = mSpecializationConstantsNameToIndex.find(key); - ASSERT_PRECONDITION(pos != mSpecializationConstantsNameToIndex.end(), - "The material %s does not have a constant parameter named %s.", - mName.c_str_safe(), name.c_str()); + FILAMENT_CHECK_PRECONDITION(pos != mSpecializationConstantsNameToIndex.end()) + << "The material " << mName.c_str_safe() + << " does not have a constant parameter named " << name.c_str() << "."; const char* const types[3] = {"an int", "a float", "a bool"}; - const char* const errorMessage = - "The constant parameter %s on material %s is of type %s, but %s was " - "provided."; auto& constant = mMaterialConstants[pos->second]; switch (constant.type) { case ConstantType::INT: - ASSERT_PRECONDITION(std::holds_alternative(value), errorMessage, - name.c_str(), mName.c_str_safe(), "int", types[value.index()]); + FILAMENT_CHECK_PRECONDITION(std::holds_alternative(value)) + << "The constant parameter " << name.c_str() << " on material " + << mName.c_str_safe() << " is of type int, but " << types[value.index()] + << " was provided."; break; case ConstantType::FLOAT: - ASSERT_PRECONDITION(std::holds_alternative(value), errorMessage, - name.c_str(), mName.c_str_safe(), "float", types[value.index()]); + FILAMENT_CHECK_PRECONDITION(std::holds_alternative(value)) + << "The constant parameter " << name.c_str() << " on material " + << mName.c_str_safe() << " is of type float, but " << types[value.index()] + << " was provided."; break; case ConstantType::BOOL: - ASSERT_PRECONDITION(std::holds_alternative(value), errorMessage, - name.c_str(), mName.c_str_safe(), "bool", types[value.index()]); + FILAMENT_CHECK_PRECONDITION(std::holds_alternative(value)) + << "The constant parameter " << name.c_str() << " on material " + << mName.c_str_safe() << " is of type bool, but " << types[value.index()] + << " was provided."; break; } uint32_t const index = pos->second + CONFIG_MAX_RESERVED_SPEC_CONSTANTS; diff --git a/filament/src/details/MorphTargetBuffer.cpp b/filament/src/details/MorphTargetBuffer.cpp index c2f3d9a13846..d4124fb2a6b2 100644 --- a/filament/src/details/MorphTargetBuffer.cpp +++ b/filament/src/details/MorphTargetBuffer.cpp @@ -148,15 +148,14 @@ void FMorphTargetBuffer::terminate(FEngine& engine) { void FMorphTargetBuffer::setPositionsAt(FEngine& engine, size_t targetIndex, math::float3 const* positions, size_t count, size_t offset) { - - ASSERT_PRECONDITION(offset + count <= mVertexCount, - "MorphTargetBuffer (size=%lu) overflow (count=%u, offset=%u)", - (unsigned)mVertexCount, (unsigned)count, (unsigned)offset); + FILAMENT_CHECK_PRECONDITION(offset + count <= mVertexCount) + << "MorphTargetBuffer (size=" << (unsigned)mVertexCount + << ") overflow (count=" << (unsigned)count << ", offset=" << (unsigned)offset << ")"; auto size = getSize(count); - ASSERT_PRECONDITION(targetIndex < mCount, - "%d target index must be < %d", targetIndex, mCount); + FILAMENT_CHECK_PRECONDITION(targetIndex < mCount) + << targetIndex << " target index must be < " << mCount; // We could use a pool instead of malloc() directly. auto* out = (float4*) malloc(size); @@ -172,15 +171,14 @@ void FMorphTargetBuffer::setPositionsAt(FEngine& engine, size_t targetIndex, void FMorphTargetBuffer::setPositionsAt(FEngine& engine, size_t targetIndex, math::float4 const* positions, size_t count, size_t offset) { - - ASSERT_PRECONDITION(offset + count <= mVertexCount, - "MorphTargetBuffer (size=%lu) overflow (count=%u, offset=%u)", - (unsigned)mVertexCount, (unsigned)count, (unsigned)offset); + FILAMENT_CHECK_PRECONDITION(offset + count <= mVertexCount) + << "MorphTargetBuffer (size=" << (unsigned)mVertexCount + << ") overflow (count=" << (unsigned)count << ", offset=" << (unsigned)offset << ")"; auto size = getSize(count); - ASSERT_PRECONDITION(targetIndex < mCount, - "%d target index must be < %d", targetIndex, mCount); + FILAMENT_CHECK_PRECONDITION(targetIndex < mCount) + << targetIndex << " target index must be < " << mCount; // We could use a pool instead of malloc() directly. auto* out = (float4*) malloc(size); @@ -195,15 +193,14 @@ void FMorphTargetBuffer::setPositionsAt(FEngine& engine, size_t targetIndex, void FMorphTargetBuffer::setTangentsAt(FEngine& engine, size_t targetIndex, math::short4 const* tangents, size_t count, size_t offset) { - - ASSERT_PRECONDITION(offset + count <= mVertexCount, - "MorphTargetBuffer (size=%lu) overflow (count=%u, offset=%u)", - (unsigned)mVertexCount, (unsigned)count, (unsigned)offset); + FILAMENT_CHECK_PRECONDITION(offset + count <= mVertexCount) + << "MorphTargetBuffer (size=" << (unsigned)mVertexCount + << ") overflow (count=" << (unsigned)count << ", offset=" << (unsigned)offset << ")"; const auto size = getSize(count); - ASSERT_PRECONDITION(targetIndex < mCount, - "%d target index must be < %d", targetIndex, mCount); + FILAMENT_CHECK_PRECONDITION(targetIndex < mCount) + << targetIndex << " target index must be < " << mCount; // We could use a pool instead of malloc() directly. auto* out = (short4*) malloc(size); diff --git a/filament/src/details/RenderTarget.cpp b/filament/src/details/RenderTarget.cpp index 4965f3c96415..dad0af4d633d 100644 --- a/filament/src/details/RenderTarget.cpp +++ b/filament/src/details/RenderTarget.cpp @@ -71,20 +71,20 @@ RenderTarget* RenderTarget::Builder::build(Engine& engine) { const FRenderTarget::Attachment& depth = mImpl->mAttachments[(size_t)AttachmentPoint::DEPTH]; if (color.texture) { - ASSERT_PRECONDITION(color.texture->getUsage() & TextureUsage::COLOR_ATTACHMENT, - "Texture usage must contain COLOR_ATTACHMENT"); + FILAMENT_CHECK_PRECONDITION(color.texture->getUsage() & TextureUsage::COLOR_ATTACHMENT) + << "Texture usage must contain COLOR_ATTACHMENT"; } if (depth.texture) { - ASSERT_PRECONDITION(depth.texture->getUsage() & TextureUsage::DEPTH_ATTACHMENT, - "Texture usage must contain DEPTH_ATTACHMENT"); + FILAMENT_CHECK_PRECONDITION(depth.texture->getUsage() & TextureUsage::DEPTH_ATTACHMENT) + << "Texture usage must contain DEPTH_ATTACHMENT"; } const size_t maxDrawBuffers = downcast(engine).getDriverApi().getMaxDrawBuffers(); for (size_t i = maxDrawBuffers; i < MAX_SUPPORTED_COLOR_ATTACHMENTS_COUNT; i++) { - ASSERT_PRECONDITION(!mImpl->mAttachments[i].texture, - "Only %u color attachments are supported, but COLOR%u attachment is set", - maxDrawBuffers, i); + FILAMENT_CHECK_PRECONDITION(!mImpl->mAttachments[i].texture) + << "Only " << maxDrawBuffers << " color attachments are supported, but COLOR" << i + << " attachment is set"; } uint32_t minWidth = std::numeric_limits::max(); @@ -102,8 +102,8 @@ RenderTarget* RenderTarget::Builder::build(Engine& engine) { } } - ASSERT_PRECONDITION(minWidth == maxWidth && minHeight == maxHeight, - "All attachments dimensions must match"); + FILAMENT_CHECK_PRECONDITION(minWidth == maxWidth && minHeight == maxHeight) + << "All attachments dimensions must match"; mImpl->mWidth = minWidth; mImpl->mHeight = minHeight; diff --git a/filament/src/details/Renderer.cpp b/filament/src/details/Renderer.cpp index e10947ae3733..9066f6ed958f 100644 --- a/filament/src/details/Renderer.cpp +++ b/filament/src/details/Renderer.cpp @@ -387,8 +387,8 @@ void FRenderer::readPixels(uint32_t xoffset, uint32_t yoffset, uint32_t width, u PixelBufferDescriptor&& buffer) { #ifndef NDEBUG const bool withinFrame = mSwapChain != nullptr; - ASSERT_PRECONDITION(withinFrame, "readPixels() on a SwapChain must be called after" - " beginFrame() and before endFrame()."); + FILAMENT_CHECK_PRECONDITION(withinFrame) << "readPixels() on a SwapChain must be called after" + " beginFrame() and before endFrame()."; #endif RendererUtils::readPixels(mEngine.getDriverApi(), mRenderTargetHandle, xoffset, yoffset, width, height, std::move(buffer)); @@ -454,8 +454,8 @@ void FRenderer::renderStandaloneView(FView const* view) { using namespace std::chrono; - ASSERT_PRECONDITION(view->getRenderTarget(), - "View \"%s\" must have a RenderTarget associated", view->getName()); + FILAMENT_CHECK_PRECONDITION(view->getRenderTarget()) + << "View \"" << view->getName() << "\" must have a RenderTarget associated"; if (UTILS_LIKELY(view->getScene())) { mPreviousRenderTargets.clear(); @@ -1230,9 +1230,9 @@ void FRenderer::renderJob(RootArenaScope& rootArenaScope, FView& view) { if (UTILS_UNLIKELY(outputIsSwapChain && view.isStencilBufferEnabled())) { assert_invariant(mSwapChain); - ASSERT_PRECONDITION(mSwapChain->hasStencilBuffer(), - "View has stencil buffer enabled, but SwapChain does not have " - "SwapChain::CONFIG_HAS_STENCIL_BUFFER flag set."); + FILAMENT_CHECK_PRECONDITION(mSwapChain->hasStencilBuffer()) + << "View has stencil buffer enabled, but SwapChain does not have " + "SwapChain::CONFIG_HAS_STENCIL_BUFFER flag set."; } if (UTILS_UNLIKELY(engine.debug.shadowmap.display_shadow_texture)) { diff --git a/filament/src/details/SkinningBuffer.cpp b/filament/src/details/SkinningBuffer.cpp index 74de88f713b4..d35fe1c70dde 100644 --- a/filament/src/details/SkinningBuffer.cpp +++ b/filament/src/details/SkinningBuffer.cpp @@ -96,20 +96,20 @@ void FSkinningBuffer::terminate(FEngine& engine) { void FSkinningBuffer::setBones(FEngine& engine, RenderableManager::Bone const* transforms, size_t count, size_t offset) { - - ASSERT_PRECONDITION((offset + count) <= mBoneCount, - "SkinningBuffer (size=%lu) overflow (boneCount=%u, offset=%u)", - (unsigned)mBoneCount, (unsigned)count, (unsigned)offset); + FILAMENT_CHECK_PRECONDITION((offset + count) <= mBoneCount) + << "SkinningBuffer (size=" << (unsigned)mBoneCount + << ") overflow (boneCount=" << (unsigned)count << ", offset=" << (unsigned)offset + << ")"; setBones(engine, mHandle, transforms, count, offset); } void FSkinningBuffer::setBones(FEngine& engine, math::mat4f const* transforms, size_t count, size_t offset) { - - ASSERT_PRECONDITION((offset + count) <= mBoneCount, - "SkinningBuffer (size=%lu) overflow (boneCount=%u, offset=%u)", - (unsigned)mBoneCount, (unsigned)count, (unsigned)offset); + FILAMENT_CHECK_PRECONDITION((offset + count) <= mBoneCount) + << "SkinningBuffer (size=" << (unsigned)mBoneCount + << ") overflow (boneCount=" << (unsigned)count << ", offset=" << (unsigned)offset + << ")"; setBones(engine, mHandle, transforms, count, offset); } diff --git a/filament/src/details/Skybox.cpp b/filament/src/details/Skybox.cpp index 07da6280514e..6526c5a29704 100644 --- a/filament/src/details/Skybox.cpp +++ b/filament/src/details/Skybox.cpp @@ -85,8 +85,8 @@ Skybox::Builder& Skybox::Builder::showSun(bool show) noexcept { Skybox* Skybox::Builder::build(Engine& engine) { FTexture* cubemap = downcast(mImpl->mEnvironmentMap); - ASSERT_PRECONDITION(!cubemap || cubemap->isCubemap(), - "environment maps must be a cubemap"); + FILAMENT_CHECK_PRECONDITION(!cubemap || cubemap->isCubemap()) + << "environment maps must be a cubemap"; return downcast(engine).createSkybox(*this); } diff --git a/filament/src/details/Texture.cpp b/filament/src/details/Texture.cpp index e47f7251b23f..3734df4b6d9a 100644 --- a/filament/src/details/Texture.cpp +++ b/filament/src/details/Texture.cpp @@ -141,15 +141,16 @@ Texture::Builder& Texture::Builder::swizzle(Swizzle r, Swizzle g, Swizzle b, Swi } Texture* Texture::Builder::build(Engine& engine) { - ASSERT_PRECONDITION(Texture::isTextureFormatSupported(engine, mImpl->mFormat), - "Texture format %u not supported on this platform", mImpl->mFormat); + FILAMENT_CHECK_PRECONDITION(Texture::isTextureFormatSupported(engine, mImpl->mFormat)) + << "Texture format " << uint16_t(mImpl->mFormat) << " not supported on this platform"; const bool isProtectedTexturesSupported = downcast(engine).getDriverApi().isProtectedTexturesSupported(); const bool useProtectedMemory = bool(mImpl->mUsage & TextureUsage::PROTECTED); - ASSERT_PRECONDITION((isProtectedTexturesSupported && useProtectedMemory) || !useProtectedMemory, - "Texture is PROTECTED but protected textures are not supported"); + FILAMENT_CHECK_PRECONDITION( + (isProtectedTexturesSupported && useProtectedMemory) || !useProtectedMemory) + << "Texture is PROTECTED but protected textures are not supported"; uint8_t maxLevelCount; switch (mImpl->mTarget) { @@ -186,7 +187,7 @@ Texture* Texture::Builder::build(Engine& engine) { const bool imported = mImpl->mImportedId; #if defined(__EMSCRIPTEN__) - ASSERT_PRECONDITION(!swizzled, "WebGL does not support texture swizzling."); + FILAMENT_CHECK_PRECONDITION(!swizzled) << "WebGL does not support texture swizzling."; #endif auto validateSamplerType = [&engine = downcast(engine)](SamplerType sampler) -> bool { @@ -203,15 +204,15 @@ Texture* Texture::Builder::build(Engine& engine) { } }; - ASSERT_PRECONDITION(validateSamplerType(mImpl->mTarget), - "SamplerType %u not support at feature level %u", - mImpl->mTarget, engine.getActiveFeatureLevel()); + FILAMENT_CHECK_PRECONDITION(validateSamplerType(mImpl->mTarget)) + << "SamplerType " << uint8_t(mImpl->mTarget) << " not support at feature level " + << uint8_t(engine.getActiveFeatureLevel()); - ASSERT_PRECONDITION((swizzled && sampleable) || !swizzled, - "Swizzled texture must be SAMPLEABLE"); + FILAMENT_CHECK_PRECONDITION((swizzled && sampleable) || !swizzled) + << "Swizzled texture must be SAMPLEABLE"; - ASSERT_PRECONDITION((imported && sampleable) || !imported, - "Imported texture must be SAMPLEABLE"); + FILAMENT_CHECK_PRECONDITION((imported && sampleable) || !imported) + << "Imported texture must be SAMPLEABLE"; return downcast(engine).createTexture(*this); } @@ -268,41 +269,42 @@ void FTexture::setImage(FEngine& engine, size_t level, FTexture::PixelBufferDescriptor&& p) const { if (UTILS_UNLIKELY(!engine.hasFeatureLevel(FeatureLevel::FEATURE_LEVEL_1))) { - ASSERT_PRECONDITION(p.stride == 0 || p.stride == width, - "PixelBufferDescriptor stride must be 0 (or width) at FEATURE_LEVEL_0"); + FILAMENT_CHECK_PRECONDITION(p.stride == 0 || p.stride == width) + << "PixelBufferDescriptor stride must be 0 (or width) at FEATURE_LEVEL_0"; } // this should have been validated already assert_invariant(isTextureFormatSupported(engine, mFormat)); - ASSERT_PRECONDITION(p.type == PixelDataType::COMPRESSED || - validatePixelFormatAndType(mFormat, p.format, p.type), - "The combination of internal format=%u and {format=%u, type=%u} is not supported.", - unsigned(mFormat), unsigned(p.format), unsigned(p.type)); + FILAMENT_CHECK_PRECONDITION(p.type == PixelDataType::COMPRESSED || + validatePixelFormatAndType(mFormat, p.format, p.type)) + << "The combination of internal format=" << unsigned(mFormat) + << " and {format=" << unsigned(p.format) << ", type=" << unsigned(p.type) + << "} is not supported."; - ASSERT_PRECONDITION(!mStream, "setImage() called on a Stream texture."); + FILAMENT_CHECK_PRECONDITION(!mStream) << "setImage() called on a Stream texture."; - ASSERT_PRECONDITION(level < mLevelCount, - "level=%u is >= to levelCount=%u.", unsigned(level), unsigned(mLevelCount)); + FILAMENT_CHECK_PRECONDITION(level < mLevelCount) + << "level=" << unsigned(level) << " is >= to levelCount=" << unsigned(mLevelCount) + << "."; - ASSERT_PRECONDITION(mTarget != SamplerType::SAMPLER_EXTERNAL, - "Texture SamplerType::SAMPLER_EXTERNAL not supported for this operation.", - unsigned(mTarget)); + FILAMENT_CHECK_PRECONDITION(mTarget != SamplerType::SAMPLER_EXTERNAL) + << "Texture SamplerType::SAMPLER_EXTERNAL not supported for this operation."; - ASSERT_PRECONDITION(mSampleCount <= 1, - "Operation not supported with multisample (%u) texture.", unsigned(mSampleCount)); + FILAMENT_CHECK_PRECONDITION(mSampleCount <= 1) << "Operation not supported with multisample (" + << unsigned(mSampleCount) << ") texture."; - ASSERT_PRECONDITION(xoffset + width <= valueForLevel(level, mWidth), - "xoffset (%u) + width (%u) > texture width (%u) at level (%u)", - unsigned(xoffset), unsigned(width), unsigned(valueForLevel(level, mWidth)), - unsigned(level)); + FILAMENT_CHECK_PRECONDITION(xoffset + width <= valueForLevel(level, mWidth)) + << "xoffset (" << unsigned(xoffset) << ") + width (" << unsigned(width) + << ") > texture width (" << valueForLevel(level, mWidth) << ") at level (" + << unsigned(level) << ")"; - ASSERT_PRECONDITION(yoffset + height <= valueForLevel(level, mHeight), - "yoffset (%u) + height (%u) > texture height (%u) at level (%u)", - unsigned(yoffset), unsigned(height), unsigned(valueForLevel(level, mHeight)), - unsigned(level)); + FILAMENT_CHECK_PRECONDITION(yoffset + height <= valueForLevel(level, mHeight)) + << "yoffset (" << unsigned(yoffset) << ") + height (" << unsigned(height) + << ") > texture height (" << valueForLevel(level, mHeight) << ") at level (" + << unsigned(level) << ")"; - ASSERT_PRECONDITION(p.buffer, "Data buffer is nullptr."); + FILAMENT_CHECK_PRECONDITION(p.buffer) << "Data buffer is nullptr."; uint32_t effectiveTextureDepthOrLayers; switch (mTarget) { @@ -326,9 +328,10 @@ void FTexture::setImage(FEngine& engine, size_t level, break; } - ASSERT_PRECONDITION(zoffset + depth <= effectiveTextureDepthOrLayers, - "zoffset (%u) + depth (%u) > texture depth (%u) at level (%u)", - unsigned(zoffset), unsigned(depth), effectiveTextureDepthOrLayers, unsigned(level)); + FILAMENT_CHECK_PRECONDITION(zoffset + depth <= effectiveTextureDepthOrLayers) + << "zoffset (" << unsigned(zoffset) << ") + depth (" << unsigned(depth) + << ") > texture depth (" << effectiveTextureDepthOrLayers << ") at level (" + << unsigned(level) << ")"; using PBD = PixelBufferDescriptor; size_t const stride = p.stride ? p.stride : width; @@ -336,12 +339,13 @@ void FTexture::setImage(FEngine& engine, size_t level, size_t const bpr = PBD::computeDataSize(p.format, p.type, stride, 1, p.alignment); size_t const bpl = bpr * height; // TODO: PBD should have a "layer stride" // TODO: PBD should have a p.depth (# layers to skip) - ASSERT_PRECONDITION(bpp * p.left + bpr * p.top + bpl * (0 + depth) <= p.size, - "buffer overflow: (size=%lu, stride=%lu, left=%u, top=%u) smaller than specified region " - "{{%u,%u,%u},{%u,%u,%u)}}", - size_t(p.size), size_t(p.stride), unsigned(p.left), unsigned(p.top), - unsigned(xoffset), unsigned(yoffset), unsigned(zoffset), - unsigned(width), unsigned(height), unsigned(depth)); + FILAMENT_CHECK_PRECONDITION(bpp * p.left + bpr * p.top + bpl * (0 + depth) <= p.size) + << "buffer overflow: (size=" << size_t(p.size) << ", stride=" << size_t(p.stride) + << ", left=" << unsigned(p.left) << ", top=" << unsigned(p.top) + << ") smaller than specified region " + "{{" + << unsigned(xoffset) << "," << unsigned(yoffset) << "," << unsigned(zoffset) << "},{" + << unsigned(width) << "," << unsigned(height) << "," << unsigned(depth) << ")}}"; engine.getDriverApi().update3DImage(mHandle, uint8_t(level), xoffset, yoffset, zoffset, width, height, depth, std::move(p)); @@ -367,20 +371,23 @@ void FTexture::setImage(FEngine& engine, size_t level, // this should have been validated already assert_invariant(isTextureFormatSupported(engine, mFormat)); - ASSERT_PRECONDITION(buffer.type == PixelDataType::COMPRESSED || - validatePixelFormatAndType(mFormat, buffer.format, buffer.type), - "The combination of internal format=%u and {format=%u, type=%u} is not supported.", - unsigned(mFormat), unsigned(buffer.format), unsigned(buffer.type)); + FILAMENT_CHECK_PRECONDITION(buffer.type == PixelDataType::COMPRESSED || + validatePixelFormatAndType(mFormat, buffer.format, buffer.type)) + << "The combination of internal format=" << unsigned(mFormat) + << " and {format=" << unsigned(buffer.format) << ", type=" << unsigned(buffer.type) + << "} is not supported."; - ASSERT_PRECONDITION(!mStream, "setImage() called on a Stream texture."); + FILAMENT_CHECK_PRECONDITION(!mStream) << "setImage() called on a Stream texture."; - ASSERT_PRECONDITION(level < mLevelCount, - "level=%u is >= to levelCount=%u.", unsigned(level), unsigned(mLevelCount)); + FILAMENT_CHECK_PRECONDITION(level < mLevelCount) + << "level=" << unsigned(level) << " is >= to levelCount=" << unsigned(mLevelCount) + << "."; - ASSERT_PRECONDITION(validateTarget(mTarget), - "Texture Sampler type (%u) not supported for this operation.", unsigned(mTarget)); + FILAMENT_CHECK_PRECONDITION(validateTarget(mTarget)) + << "Texture Sampler type (" << unsigned(mTarget) + << ") not supported for this operation."; - ASSERT_PRECONDITION(buffer.buffer, "Data buffer is nullptr."); + FILAMENT_CHECK_PRECONDITION(buffer.buffer) << "Data buffer is nullptr."; auto w = std::max(1u, mWidth >> level); auto h = std::max(1u, mHeight >> level); @@ -430,8 +437,8 @@ void FTexture::setExternalImage(FEngine& engine, void* image, size_t plane) noex void FTexture::setExternalStream(FEngine& engine, FStream* stream) noexcept { if (stream) { - ASSERT_PRECONDITION(mTarget == Sampler::SAMPLER_EXTERNAL, - "Texture target must be SAMPLER_EXTERNAL"); + FILAMENT_CHECK_PRECONDITION(mTarget == Sampler::SAMPLER_EXTERNAL) + << "Texture target must be SAMPLER_EXTERNAL"; mStream = stream; engine.getDriverApi().setExternalStream(mHandle, stream->getHandle()); @@ -442,15 +449,15 @@ void FTexture::setExternalStream(FEngine& engine, FStream* stream) noexcept { } void FTexture::generateMipmaps(FEngine& engine) const noexcept { - ASSERT_PRECONDITION(mTarget != SamplerType::SAMPLER_EXTERNAL, - "External Textures are not mipmappable."); + FILAMENT_CHECK_PRECONDITION(mTarget != SamplerType::SAMPLER_EXTERNAL) + << "External Textures are not mipmappable."; - ASSERT_PRECONDITION(mTarget != SamplerType::SAMPLER_3D, - "3D Textures are not mipmappable."); + FILAMENT_CHECK_PRECONDITION(mTarget != SamplerType::SAMPLER_3D) + << "3D Textures are not mipmappable."; const bool formatMipmappable = engine.getDriverApi().isTextureFormatMipmappable(mFormat); - ASSERT_PRECONDITION(formatMipmappable, - "Texture format %u is not mipmappable.", (unsigned)mFormat); + FILAMENT_CHECK_PRECONDITION(formatMipmappable) + << "Texture format " << (unsigned)mFormat << " is not mipmappable."; if (mLevelCount < 2 || (mWidth == 1 && mHeight == 1)) { return; @@ -493,24 +500,21 @@ void FTexture::generatePrefilterMipmap(FEngine& engine, /* validate input data */ - ASSERT_PRECONDITION(buffer.format == PixelDataFormat::RGB || - buffer.format == PixelDataFormat::RGBA, - "input data format must be RGB or RGBA"); + FILAMENT_CHECK_PRECONDITION( + buffer.format == PixelDataFormat::RGB || buffer.format == PixelDataFormat::RGBA) + << "input data format must be RGB or RGBA"; - ASSERT_PRECONDITION( - buffer.type == PixelDataType::FLOAT || + FILAMENT_CHECK_PRECONDITION(buffer.type == PixelDataType::FLOAT || buffer.type == PixelDataType::HALF || - buffer.type == PixelDataType::UINT_10F_11F_11F_REV, - "input data type must be FLOAT, HALF or UINT_10F_11F_11F_REV"); + buffer.type == PixelDataType::UINT_10F_11F_11F_REV) + << "input data type must be FLOAT, HALF or UINT_10F_11F_11F_REV"; /* validate texture */ - ASSERT_PRECONDITION(!(size & (size-1)), - "input data cubemap dimensions must be a power-of-two"); - - ASSERT_PRECONDITION(!isCompressed(), - "reflections texture cannot be compressed"); + FILAMENT_CHECK_PRECONDITION(!(size & (size - 1))) + << "input data cubemap dimensions must be a power-of-two"; + FILAMENT_CHECK_PRECONDITION(!isCompressed()) << "reflections texture cannot be compressed"; PrefilterOptions const defaultOptions; options = options ? options : &defaultOptions; diff --git a/filament/src/details/VertexBuffer.cpp b/filament/src/details/VertexBuffer.cpp index 2edf62d85550..6269bc5ed7bf 100644 --- a/filament/src/details/VertexBuffer.cpp +++ b/filament/src/details/VertexBuffer.cpp @@ -148,10 +148,10 @@ VertexBuffer::Builder& VertexBuffer::Builder::advancedSkinning(bool enabled) noe } VertexBuffer* VertexBuffer::Builder::build(Engine& engine) { - ASSERT_PRECONDITION(mImpl->mVertexCount > 0, "vertexCount cannot be 0"); - ASSERT_PRECONDITION(mImpl->mBufferCount > 0, "bufferCount cannot be 0"); - ASSERT_PRECONDITION(mImpl->mBufferCount <= MAX_VERTEX_BUFFER_COUNT, - "bufferCount cannot be more than %d", MAX_VERTEX_BUFFER_COUNT); + FILAMENT_CHECK_PRECONDITION(mImpl->mVertexCount > 0) << "vertexCount cannot be 0"; + FILAMENT_CHECK_PRECONDITION(mImpl->mBufferCount > 0) << "bufferCount cannot be 0"; + FILAMENT_CHECK_PRECONDITION(mImpl->mBufferCount <= MAX_VERTEX_BUFFER_COUNT) + << "bufferCount cannot be more than " << MAX_VERTEX_BUFFER_COUNT; // Next we check if any unused buffer slots have been allocated. This helps prevent errors // because uploading to an unused slot can trigger undefined behavior in the backend. @@ -164,8 +164,8 @@ VertexBuffer* VertexBuffer::Builder::build(Engine& engine) { attributedBuffers.set(attributes[j].buffer); if (engine.getActiveFeatureLevel() == backend::FeatureLevel::FEATURE_LEVEL_0) { - ASSERT_PRECONDITION(!(attributes[j].flags & Attribute::FLAG_INTEGER_TARGET), - "Attribute::FLAG_INTEGER_TARGET not supported at FEATURE_LEVEL_0"); + FILAMENT_CHECK_PRECONDITION(!(attributes[j].flags & Attribute::FLAG_INTEGER_TARGET)) + << "Attribute::FLAG_INTEGER_TARGET not supported at FEATURE_LEVEL_0"; } // also checks that we don't use an invalid type with integer attributes @@ -180,23 +180,23 @@ VertexBuffer* VertexBuffer::Builder::build(Engine& engine) { (1 << (int)ET::HALF2) | (1 << (int)ET::HALF3) | (1 << (int)ET::HALF4); - ASSERT_PRECONDITION(!(invalidIntegerTypes & (1 << (int)attributes[j].type)), - "invalid integer vertex attribute type %d", attributes[j].type); + FILAMENT_CHECK_PRECONDITION(!(invalidIntegerTypes & (1 << (int)attributes[j].type))) + << "invalid integer vertex attribute type " << int(attributes[j].type); } }); - ASSERT_PRECONDITION(attributedBuffers.count() == mImpl->mBufferCount, - "At least one buffer slot was never assigned to an attribute."); + FILAMENT_CHECK_PRECONDITION(attributedBuffers.count() == mImpl->mBufferCount) + << "At least one buffer slot was never assigned to an attribute."; if (mImpl->mAdvancedSkinningEnabled) { - ASSERT_PRECONDITION(!mImpl->mDeclaredAttributes[VertexAttribute::BONE_INDICES], - "Vertex buffer attribute BONE_INDICES is already defined, " - "no advanced skinning is allowed"); - ASSERT_PRECONDITION(!mImpl->mDeclaredAttributes[VertexAttribute::BONE_WEIGHTS], - "Vertex buffer attribute BONE_WEIGHTS is already defined, " - "no advanced skinning is allowed"); - ASSERT_PRECONDITION(mImpl->mBufferCount < (MAX_VERTEX_BUFFER_COUNT - 2), - "Vertex buffer uses to many buffers (%u)", mImpl->mBufferCount); + FILAMENT_CHECK_PRECONDITION(!mImpl->mDeclaredAttributes[VertexAttribute::BONE_INDICES]) + << "Vertex buffer attribute BONE_INDICES is already defined, " + "no advanced skinning is allowed"; + FILAMENT_CHECK_PRECONDITION(!mImpl->mDeclaredAttributes[VertexAttribute::BONE_WEIGHTS]) + << "Vertex buffer attribute BONE_WEIGHTS is already defined, " + "no advanced skinning is allowed"; + FILAMENT_CHECK_PRECONDITION(mImpl->mBufferCount < (MAX_VERTEX_BUFFER_COUNT - 2)) + << "Vertex buffer uses to many buffers (" << mImpl->mBufferCount << ")"; } return downcast(engine).createVertexBuffer(*this); @@ -328,21 +328,22 @@ size_t FVertexBuffer::getVertexCount() const noexcept { void FVertexBuffer::setBufferAt(FEngine& engine, uint8_t bufferIndex, backend::BufferDescriptor&& buffer, uint32_t byteOffset) { - ASSERT_PRECONDITION(!mBufferObjectsEnabled, "Please use setBufferObjectAt()"); + FILAMENT_CHECK_PRECONDITION(!mBufferObjectsEnabled) << "Please use setBufferObjectAt()"; if (bufferIndex < mBufferCount) { assert_invariant(mBufferObjects[bufferIndex]); engine.getDriverApi().updateBufferObject(mBufferObjects[bufferIndex], std::move(buffer), byteOffset); } else { - ASSERT_PRECONDITION(bufferIndex < mBufferCount, "bufferIndex must be < bufferCount"); + FILAMENT_CHECK_PRECONDITION(bufferIndex < mBufferCount) + << "bufferIndex must be < bufferCount"; } } void FVertexBuffer::setBufferObjectAt(FEngine& engine, uint8_t bufferIndex, FBufferObject const * bufferObject) { - ASSERT_PRECONDITION(mBufferObjectsEnabled, "Please use setBufferAt()"); - ASSERT_PRECONDITION(bufferObject->getBindingType() == BufferObject::BindingType::VERTEX, - "Binding type must be VERTEX."); + FILAMENT_CHECK_PRECONDITION(mBufferObjectsEnabled) << "Please use setBufferAt()"; + FILAMENT_CHECK_PRECONDITION(bufferObject->getBindingType() == BufferObject::BindingType::VERTEX) + << "Binding type must be VERTEX."; if (bufferIndex < mBufferCount) { auto hwBufferObject = bufferObject->getHwHandle(); engine.getDriverApi().setVertexBufferObject(mHandle, bufferIndex, hwBufferObject); @@ -350,14 +351,15 @@ void FVertexBuffer::setBufferObjectAt(FEngine& engine, uint8_t bufferIndex, // used only in buffer object mode mBufferObjects[bufferIndex] = hwBufferObject; } else { - ASSERT_PRECONDITION(bufferIndex < mBufferCount, "bufferIndex must be < bufferCount"); + FILAMENT_CHECK_PRECONDITION(bufferIndex < mBufferCount) + << "bufferIndex must be < bufferCount"; } } void FVertexBuffer::updateBoneIndicesAndWeights(FEngine& engine, std::unique_ptr skinJoints, std::unique_ptr skinWeights) { - ASSERT_PRECONDITION(mAdvancedSkinningEnabled, "No advanced skinning enabled"); + FILAMENT_CHECK_PRECONDITION(mAdvancedSkinningEnabled) << "No advanced skinning enabled"; auto jointsData = skinJoints.release(); uint8_t const indicesIndex = mAttributes[VertexAttribute::BONE_INDICES].buffer; engine.getDriverApi().updateBufferObject(mBufferObjects[indicesIndex], diff --git a/filament/src/details/View.cpp b/filament/src/details/View.cpp index 7b7d160cb4d4..ed9daeb4b062 100644 --- a/filament/src/details/View.cpp +++ b/filament/src/details/View.cpp @@ -1175,12 +1175,14 @@ void FView::setStereoscopicOptions(const StereoscopicOptions& options) noexcept } void FView::setMaterialGlobal(uint32_t index, float4 const& value) { - ASSERT_PRECONDITION(index < 4, "material global variable index (%u) out of range", +index); + FILAMENT_CHECK_PRECONDITION(index < 4) + << "material global variable index (" << +index << ") out of range"; mMaterialGlobals[index] = value; } math::float4 FView::getMaterialGlobal(uint32_t index) const { - ASSERT_PRECONDITION(index < 4, "material global variable index (%u) out of range", +index); + FILAMENT_CHECK_PRECONDITION(index < 4) + << "material global variable index (" << +index << ") out of range"; return mMaterialGlobals[index]; } diff --git a/filament/src/fg/FrameGraph.cpp b/filament/src/fg/FrameGraph.cpp index 00deb7dc7b88..e52cdef5c4f0 100644 --- a/filament/src/fg/FrameGraph.cpp +++ b/filament/src/fg/FrameGraph.cpp @@ -302,9 +302,9 @@ FrameGraphHandle FrameGraph::readInternal(FrameGraphHandle handle, PassNode* pas // Check preconditions bool const passAlreadyAWriter = node->hasWriteFrom(passNode); - ASSERT_PRECONDITION(!passAlreadyAWriter, - "Pass \"%s\" already writes to \"%s\"", - passNode->getName(), node->getName()); + FILAMENT_CHECK_PRECONDITION(!passAlreadyAWriter) + << "Pass \"" << passNode->getName() << "\" already writes to \"" << node->getName() + << "\""; if (!node->hasWriterPass() && !resource->isImported()) { // TODO: we're attempting to read from a resource that was never written and is not @@ -464,9 +464,9 @@ bool FrameGraph::isValid(FrameGraphHandle handle) const { } void FrameGraph::assertValid(FrameGraphHandle handle) const { - ASSERT_PRECONDITION(isValid(handle), - "Resource handle is invalid or uninitialized {id=%u, version=%u}", - (int)handle.index, (int)handle.version); + FILAMENT_CHECK_PRECONDITION(isValid(handle)) + << "Resource handle is invalid or uninitialized {id=" << (int)handle.index + << ", version=" << (int)handle.version << "}"; } bool FrameGraph::isCulled(FrameGraphPassBase const& pass) const noexcept { diff --git a/filament/src/fg/FrameGraphResources.cpp b/filament/src/fg/FrameGraphResources.cpp index 578d914f64c2..a3b04c3f74c1 100644 --- a/filament/src/fg/FrameGraphResources.cpp +++ b/filament/src/fg/FrameGraphResources.cpp @@ -32,18 +32,18 @@ const char* FrameGraphResources::getPassName() const noexcept { // this perhaps weirdly returns a reference, this is to express the fact that if this method // fails, it has to assert (or throw), it can't return for e.g. a nullptr, because the public // API doesn't return pointers. -// We still use ASSERT_PRECONDITION() because these failures are due to post conditions not met. +// We still use FILAMENT_CHECK_PRECONDITION() because these failures are due to post conditions not met. VirtualResource& FrameGraphResources::getResource(FrameGraphHandle handle) const { - ASSERT_PRECONDITION(handle, "Uninitialized handle when using FrameGraphResources."); + FILAMENT_CHECK_PRECONDITION(handle) << "Uninitialized handle when using FrameGraphResources."; VirtualResource* const resource = mFrameGraph.getResource(handle); auto& declaredHandles = mPassNode.mDeclaredHandles; const bool hasReadOrWrite = declaredHandles.find(handle.index) != declaredHandles.cend(); - ASSERT_PRECONDITION(hasReadOrWrite, - "Pass \"%s\" didn't declare any access to resource \"%s\"", - mPassNode.getName(), resource->name); + FILAMENT_CHECK_PRECONDITION(hasReadOrWrite) + << "Pass \"" << mPassNode.getName() << "\" didn't declare any access to resource \"" + << resource->name << "\""; assert_invariant(resource->refcount); @@ -55,9 +55,8 @@ FrameGraphResources::RenderPassInfo FrameGraphResources::getRenderPassInfo(uint3 RenderPassNode const& renderPassNode = static_cast(mPassNode); RenderPassNode::RenderPassData const* pRenderPassData = renderPassNode.getRenderPassData(id); - ASSERT_PRECONDITION(pRenderPassData, - "using invalid RenderPass index %u in Pass \"%s\"", - id, mPassNode.getName()); + FILAMENT_CHECK_PRECONDITION(pRenderPassData) << "using invalid RenderPass index " << id + << " in Pass \"" << mPassNode.getName() << "\""; return { pRenderPassData->backend.target, pRenderPassData->backend.params }; } diff --git a/filament/src/fg/Resource.cpp b/filament/src/fg/Resource.cpp index 5bbeb80549cc..df3401142466 100644 --- a/filament/src/fg/Resource.cpp +++ b/filament/src/fg/Resource.cpp @@ -100,9 +100,9 @@ void ImportedRenderTarget::assertConnect(FrameGraphTexture::Usage u) { FrameGraphTexture::Usage::DEPTH_ATTACHMENT | FrameGraphTexture::Usage::STENCIL_ATTACHMENT; - ASSERT_PRECONDITION(none(u & ~ANY_ATTACHMENT), - "Imported render target resource \"%s\" can only be used as an attachment (usage=%s)", - name, utils::to_string(u).c_str()); + FILAMENT_CHECK_PRECONDITION(none(u & ~ANY_ATTACHMENT)) + << "Imported render target resource \"" << name + << "\" can only be used as an attachment (usage=" << utils::to_string(u).c_str() << ')'; } bool ImportedRenderTarget::connect(DependencyGraph& graph, PassNode* passNode, diff --git a/filament/src/fg/details/Resource.h b/filament/src/fg/details/Resource.h index 0b9a89954de8..d2207dd96d46 100644 --- a/filament/src/fg/details/Resource.h +++ b/filament/src/fg/details/Resource.h @@ -296,9 +296,10 @@ class ImportedResource : public Resource { private: UTILS_NOINLINE void assertConnect(FrameGraphTexture::Usage u) { - ASSERT_PRECONDITION((u & this->usage) == u, - "Requested usage %s not available on imported resource \"%s\" with usage %s", - utils::to_string(u).c_str(), this->name, utils::to_string(this->usage).c_str()); + FILAMENT_CHECK_PRECONDITION((u & this->usage) == u) + << "Requested usage " << utils::to_string(u).c_str() + << " not available on imported resource \"" << this->name << "\" with usage " + << utils::to_string(this->usage).c_str(); } }; diff --git a/libs/bluevk/src/BlueVKDarwin.cpp b/libs/bluevk/src/BlueVKDarwin.cpp index 69c446f78e81..c070bf00c045 100644 --- a/libs/bluevk/src/BlueVKDarwin.cpp +++ b/libs/bluevk/src/BlueVKDarwin.cpp @@ -31,10 +31,9 @@ bool loadLibrary() { #endif module = dlopen(dylibPath, RTLD_NOW | RTLD_LOCAL); - ASSERT_POSTCONDITION(module != nullptr, - "BlueVK is unable to load entry points: %s.\n" - "Install the LunarG SDK with 'System Global Installation' and reboot.\n", - dlerror()); + FILAMENT_CHECK_POSTCONDITION(module != nullptr) + << "BlueVK is unable to load entry points: " << dlerror() << ".\n" + "Install the LunarG SDK with 'System Global Installation' and reboot.\n"; return module != nullptr; } diff --git a/libs/filabridge/src/BufferInterfaceBlock.cpp b/libs/filabridge/src/BufferInterfaceBlock.cpp index 6c6cf9efc5c9..409cf55f32b2 100644 --- a/libs/filabridge/src/BufferInterfaceBlock.cpp +++ b/libs/filabridge/src/BufferInterfaceBlock.cpp @@ -86,16 +86,16 @@ BufferInterfaceBlock BufferInterfaceBlock::Builder::build() { }); // if there is one, check it's the last entry - ASSERT_PRECONDITION(pos == mEntries.end() || pos == mEntries.end() - 1, - "the variable-size array must be the last entry"); + FILAMENT_CHECK_PRECONDITION(pos == mEntries.end() || pos == mEntries.end() - 1) + << "the variable-size array must be the last entry"; // if we have a variable size array, we can't be a UBO - ASSERT_PRECONDITION(pos == mEntries.end() || mTarget == Target::SSBO, - "variable size arrays not supported for UBOs"); + FILAMENT_CHECK_PRECONDITION(pos == mEntries.end() || mTarget == Target::SSBO) + << "variable size arrays not supported for UBOs"; // std430 not available for UBOs - ASSERT_PRECONDITION(mAlignment == Alignment::std140 || mTarget == Target::SSBO, - "UBOs must use std140"); + FILAMENT_CHECK_PRECONDITION(mAlignment == Alignment::std140 || mTarget == Target::SSBO) + << "UBOs must use std140"; return BufferInterfaceBlock(*this); } @@ -166,8 +166,7 @@ ssize_t BufferInterfaceBlock::getFieldOffset(std::string_view name, size_t index BufferInterfaceBlock::FieldInfo const* BufferInterfaceBlock::getFieldInfo( std::string_view name) const { auto pos = mInfoMap.find(name); - ASSERT_PRECONDITION(pos != mInfoMap.end(), - "uniform named \"%.*s\" not found", name.size(), name.data()); + FILAMENT_CHECK_PRECONDITION(pos != mInfoMap.end()) << "uniform named \"%.*s\" not found"; return &mFieldInfoList[pos->second]; } diff --git a/libs/filabridge/src/SamplerInterfaceBlock.cpp b/libs/filabridge/src/SamplerInterfaceBlock.cpp index 09c70a240b5e..43ad966ea485 100644 --- a/libs/filabridge/src/SamplerInterfaceBlock.cpp +++ b/libs/filabridge/src/SamplerInterfaceBlock.cpp @@ -93,8 +93,7 @@ SamplerInterfaceBlock::SamplerInterfaceBlock(Builder const& builder) noexcept const SamplerInterfaceBlock::SamplerInfo* SamplerInterfaceBlock::getSamplerInfo( std::string_view name) const { auto pos = mInfoMap.find(name); - ASSERT_PRECONDITION(pos != mInfoMap.end(), "sampler named \"%.*s\" not found", - name.size(), name.data()); + FILAMENT_CHECK_PRECONDITION(pos != mInfoMap.end()) << "sampler named \"" << name << "\" not found"; return &mSamplersInfoList[pos->second]; } diff --git a/libs/filamat/src/MaterialBuilder.cpp b/libs/filamat/src/MaterialBuilder.cpp index ee897754f66f..11d539870a8f 100644 --- a/libs/filamat/src/MaterialBuilder.cpp +++ b/libs/filamat/src/MaterialBuilder.cpp @@ -242,7 +242,7 @@ MaterialBuilder& MaterialBuilder::variable(Variable v, const char* name) noexcep MaterialBuilder& MaterialBuilder::parameter(const char* name, size_t size, UniformType type, ParameterPrecision precision) noexcept { - ASSERT_POSTCONDITION(mParameterCount < MAX_PARAMETERS_COUNT, "Too many parameters"); + FILAMENT_CHECK_POSTCONDITION(mParameterCount < MAX_PARAMETERS_COUNT) << "Too many parameters"; mParameters[mParameterCount++] = { name, type, size, precision }; return *this; } @@ -255,15 +255,14 @@ MaterialBuilder& MaterialBuilder::parameter(const char* name, UniformType type, MaterialBuilder& MaterialBuilder::parameter(const char* name, SamplerType samplerType, SamplerFormat format, ParameterPrecision precision, bool multisample) noexcept { - - ASSERT_PRECONDITION( - !multisample || (format != SamplerFormat::SHADOW && ( - samplerType == SamplerType::SAMPLER_2D - || samplerType == SamplerType::SAMPLER_2D_ARRAY)), - "multisample samplers only possible with SAMPLER_2D or SAMPLER_2D_ARRAY," - " as long as type is not SHADOW"); - - ASSERT_POSTCONDITION(mParameterCount < MAX_PARAMETERS_COUNT, "Too many parameters"); + FILAMENT_CHECK_PRECONDITION(!multisample || + (format != SamplerFormat::SHADOW && + (samplerType == SamplerType::SAMPLER_2D || + samplerType == SamplerType::SAMPLER_2D_ARRAY))) + << "multisample samplers only possible with SAMPLER_2D or SAMPLER_2D_ARRAY," + " as long as type is not SHADOW"; + + FILAMENT_CHECK_POSTCONDITION(mParameterCount < MAX_PARAMETERS_COUNT) << "Too many parameters"; mParameters[mParameterCount++] = { name, samplerType, format, precision, multisample }; return *this; } @@ -273,8 +272,8 @@ MaterialBuilder& MaterialBuilder::constant(const char* name, ConstantType type, auto result = std::find_if(mConstants.begin(), mConstants.end(), [name](const Constant& c) { return c.name == utils::CString(name); }); - ASSERT_POSTCONDITION(result == mConstants.end(), - "There is already a constant parameter present with the name %s.", name); + FILAMENT_CHECK_POSTCONDITION(result == mConstants.end()) + << "There is already a constant parameter present with the name " << name << "."; Constant constant { .name = CString(name), .type = type, @@ -287,19 +286,20 @@ MaterialBuilder& MaterialBuilder::constant(const char* name, ConstantType type, } }; - const char* const errMessage = - "Constant %s was declared with type %s but given %s default value."; if constexpr (std::is_same_v) { - ASSERT_POSTCONDITION( - type == ConstantType::INT, errMessage, name, toString(type), "an int"); + FILAMENT_CHECK_POSTCONDITION(type == ConstantType::INT) + << "Constant " << name << " was declared with type " << toString(type) + << " but given an int default value."; constant.defaultValue.i = defaultValue; } else if constexpr (std::is_same_v) { - ASSERT_POSTCONDITION( - type == ConstantType::FLOAT, errMessage, name, toString(type), "a float"); + FILAMENT_CHECK_POSTCONDITION(type == ConstantType::FLOAT) + << "Constant " << name << " was declared with type " << toString(type) + << " but given a float default value."; constant.defaultValue.f = defaultValue; } else if constexpr (std::is_same_v) { - ASSERT_POSTCONDITION( - type == ConstantType::BOOL, errMessage, name, toString(type), "a bool"); + FILAMENT_CHECK_POSTCONDITION(type == ConstantType::BOOL) + << "Constant " << name << " was declared with type " << toString(type) + << " but given a bool default value."; constant.defaultValue.b = defaultValue; } else { assert_invariant(false); @@ -316,17 +316,17 @@ template MaterialBuilder& MaterialBuilder::constant( const char* name, ConstantType type, bool defaultValue); MaterialBuilder& MaterialBuilder::buffer(BufferInterfaceBlock bib) noexcept { - ASSERT_POSTCONDITION(mBuffers.size() < MAX_BUFFERS_COUNT, "Too many buffers"); + FILAMENT_CHECK_POSTCONDITION(mBuffers.size() < MAX_BUFFERS_COUNT) << "Too many buffers"; mBuffers.emplace_back(std::make_unique(std::move(bib))); return *this; } MaterialBuilder& MaterialBuilder::subpass(SubpassType subpassType, SamplerFormat format, ParameterPrecision precision, const char* name) noexcept { - ASSERT_PRECONDITION(format == SamplerFormat::FLOAT, - "Subpass parameters must have FLOAT format."); + FILAMENT_CHECK_PRECONDITION(format == SamplerFormat::FLOAT) + << "Subpass parameters must have FLOAT format."; - ASSERT_POSTCONDITION(mSubpassCount < MAX_SUBPASS_COUNT, "Too many subpasses"); + FILAMENT_CHECK_POSTCONDITION(mSubpassCount < MAX_SUBPASS_COUNT) << "Too many subpasses"; mSubpasses[mSubpassCount++] = { name, subpassType, format, precision }; return *this; } @@ -1079,14 +1079,14 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector= -1, - "Output location must be >= 0 (or use -1 for default location)."); + FILAMENT_CHECK_PRECONDITION(location >= -1) + << "Output location must be >= 0 (or use -1 for default location)."; // A location value of -1 signals using the default location. We'll simply take the previous // output's location and add 1. @@ -1108,10 +1108,10 @@ MaterialBuilder& MaterialBuilder::output(VariableQualifier qualifier, OutputTarg } } - ASSERT_PRECONDITION(colorOutputCount <= MAX_COLOR_OUTPUT, - "A maximum of %d COLOR outputs is allowed.", MAX_COLOR_OUTPUT); - ASSERT_PRECONDITION(depthOutputCount <= MAX_DEPTH_OUTPUT, - "A maximum of %d DEPTH output is allowed.", MAX_DEPTH_OUTPUT); + FILAMENT_CHECK_PRECONDITION(colorOutputCount <= MAX_COLOR_OUTPUT) + << "A maximum of " << MAX_COLOR_OUTPUT << " COLOR outputs is allowed."; + FILAMENT_CHECK_PRECONDITION(depthOutputCount <= MAX_DEPTH_OUTPUT) + << "A maximum of " << MAX_DEPTH_OUTPUT << " DEPTH output is allowed."; assert(mOutputs.size() <= MAX_COLOR_OUTPUT + MAX_DEPTH_OUTPUT); diff --git a/libs/filamentapp/src/FilamentApp.cpp b/libs/filamentapp/src/FilamentApp.cpp index 635f482ccfea..980f3bdcfc81 100644 --- a/libs/filamentapp/src/FilamentApp.cpp +++ b/libs/filamentapp/src/FilamentApp.cpp @@ -578,7 +578,7 @@ void FilamentApp::loadDirt(const Config& config) { } void FilamentApp::initSDL() { - ASSERT_POSTCONDITION(SDL_Init(SDL_INIT_EVENTS) == 0, "SDL_Init Failure"); + FILAMENT_CHECK_POSTCONDITION(SDL_Init(SDL_INIT_EVENTS) == 0) << "SDL_Init Failure"; } // ------------------------------------------------------------------------------------------------ diff --git a/libs/filamentapp/src/NativeWindowHelperCocoa.mm b/libs/filamentapp/src/NativeWindowHelperCocoa.mm index e0603e8e48cd..26eabe7071eb 100644 --- a/libs/filamentapp/src/NativeWindowHelperCocoa.mm +++ b/libs/filamentapp/src/NativeWindowHelperCocoa.mm @@ -26,7 +26,8 @@ void* getNativeWindow(SDL_Window* sdlWindow) { SDL_SysWMinfo wmi; SDL_VERSION(&wmi.version); - ASSERT_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi), "SDL version unsupported!"); + FILAMENT_CHECK_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi)) + << "SDL version unsupported!"; NSWindow* win = wmi.info.cocoa.window; NSView* view = [win contentView]; return view; @@ -35,7 +36,8 @@ void prepareNativeWindow(SDL_Window* sdlWindow) { SDL_SysWMinfo wmi; SDL_VERSION(&wmi.version); - ASSERT_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi), "SDL version unsupported!"); + FILAMENT_CHECK_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi)) + << "SDL version unsupported!"; NSWindow* win = wmi.info.cocoa.window; [win setColorSpace:[NSColorSpace sRGBColorSpace]]; } diff --git a/libs/filamentapp/src/NativeWindowHelperLinux.cpp b/libs/filamentapp/src/NativeWindowHelperLinux.cpp index 979c495ce722..a9348e660d89 100644 --- a/libs/filamentapp/src/NativeWindowHelperLinux.cpp +++ b/libs/filamentapp/src/NativeWindowHelperLinux.cpp @@ -23,7 +23,8 @@ void* getNativeWindow(SDL_Window* sdlWindow) { SDL_SysWMinfo wmi; SDL_VERSION(&wmi.version); - ASSERT_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi), "SDL version unsupported!"); + FILAMENT_CHECK_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi)) + << "SDL version unsupported!"; if (wmi.subsystem == SDL_SYSWM_X11) { #if defined(FILAMENT_SUPPORTS_X11) Window win = (Window) wmi.info.x11.window; diff --git a/libs/filamentapp/src/NativeWindowHelperWindows.cpp b/libs/filamentapp/src/NativeWindowHelperWindows.cpp index 38d53bd9ca7f..47dac9a32819 100644 --- a/libs/filamentapp/src/NativeWindowHelperWindows.cpp +++ b/libs/filamentapp/src/NativeWindowHelperWindows.cpp @@ -23,7 +23,8 @@ void* getNativeWindow(SDL_Window* sdlWindow) { SDL_SysWMinfo wmi; SDL_VERSION(&wmi.version); - ASSERT_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi), "SDL version unsupported!"); + FILAMENT_CHECK_POSTCONDITION(SDL_GetWindowWMInfo(sdlWindow, &wmi)) + << "SDL version unsupported!"; HWND win = (HWND) wmi.info.win.window; return (void*) win; } diff --git a/libs/geometry/src/TangentSpaceMesh.cpp b/libs/geometry/src/TangentSpaceMesh.cpp index bb4a74ab1053..385189add231 100644 --- a/libs/geometry/src/TangentSpaceMesh.cpp +++ b/libs/geometry/src/TangentSpaceMesh.cpp @@ -100,8 +100,8 @@ inline AlgorithmImpl selectBestDefaultAlgorithm(uint8_t const inputType) { } else if (isInputType(inputType, POSITIONS_INDICES)) { return AlgorithmImpl::FLAT_SHADING; } else { - ASSERT_PRECONDITION(inputType & NORMALS, - "Must at least have normals or (positions + indices) as input"); + FILAMENT_CHECK_PRECONDITION(inputType & NORMALS) + << "Must at least have normals or (positions + indices) as input"; return AlgorithmImpl::FRISVAD; } } @@ -580,14 +580,14 @@ Builder& Builder::algorithm(Algorithm algo) noexcept { } TangentSpaceMesh* Builder::build() { - ASSERT_PRECONDITION(!mMesh->mInput->triangles32 || !mMesh->mInput->triangles16, - "Cannot provide both uint32 triangles and uint16 triangles"); + FILAMENT_CHECK_PRECONDITION(!mMesh->mInput->triangles32 || !mMesh->mInput->triangles16) + << "Cannot provide both uint32 triangles and uint16 triangles"; // Validate whether the provided data for an attribute is of the right data type. for (auto attribute: mMesh->mInput->getAuxAttributes()) { - ASSERT_PRECONDITION( - TangentSpaceMeshInput::isDataTypeCorrect(attribute, mMesh->mInput->data(attribute)), - "Incorrect attribute data type"); + FILAMENT_CHECK_PRECONDITION( + TangentSpaceMeshInput::isDataTypeCorrect(attribute, mMesh->mInput->data(attribute))) + << "Incorrect attribute data type"; } mMesh->mOutput->algorithm = selectAlgorithm(mMesh->mInput); @@ -654,7 +654,7 @@ size_t TangentSpaceMesh::getVertexCount() const noexcept { void TangentSpaceMesh::getPositions(float3* positions, size_t stride) const { auto inPositions = mInput->positions(); - ASSERT_PRECONDITION(inPositions, "Must provide input positions"); + FILAMENT_CHECK_PRECONDITION(inPositions) << "Must provide input positions"; stride = stride ? stride : sizeof(decltype(*positions)); auto const& outPositions = mOutput->positions(); for (size_t i = 0; i < mOutput->vertexCount; ++i) { @@ -665,7 +665,7 @@ void TangentSpaceMesh::getPositions(float3* positions, size_t stride) const { void TangentSpaceMesh::getUVs(float2* uvs, size_t stride) const { auto inUVs = mInput->uvs(); - ASSERT_PRECONDITION(inUVs, "Must provide input positions"); + FILAMENT_CHECK_PRECONDITION(inUVs) << "Must provide input positions"; stride = stride ? stride : sizeof(decltype(*uvs)); auto const& outUvs = mOutput->uvs(); for (size_t i = 0; i < mOutput->vertexCount; ++i) { @@ -679,7 +679,8 @@ size_t TangentSpaceMesh::getTriangleCount() const noexcept { } void TangentSpaceMesh::getTriangles(uint3* out) const { - ASSERT_PRECONDITION(mInput->triangles16 || mInput->triangles32, "Must provide input triangles"); + FILAMENT_CHECK_PRECONDITION(mInput->triangles16 || mInput->triangles32) + << "Must provide input triangles"; bool const is16 = (bool) mOutput->triangles16; auto const& triangles16 = mOutput->triangles16; @@ -692,7 +693,8 @@ void TangentSpaceMesh::getTriangles(uint3* out) const { } void TangentSpaceMesh::getTriangles(ushort3* out) const { - ASSERT_PRECONDITION(mInput->triangles16 || mInput->triangles32, "Must provide input triangles"); + FILAMENT_CHECK_PRECONDITION(mInput->triangles16 || mInput->triangles32) + << "Must provide input triangles"; const bool is16 = (bool) mOutput->triangles16; auto const& triangles16 = mOutput->triangles16; @@ -703,9 +705,9 @@ void TangentSpaceMesh::getTriangles(ushort3* out) const { *out = triangles16[i]; } else { uint3 const& tri = triangles32[i]; - ASSERT_PRECONDITION(tri.x <= USHRT_MAX && - tri.y <= USHRT_MAX && - tri.z <= USHRT_MAX, "Overflow when casting uint3 to ushort3"); + FILAMENT_CHECK_PRECONDITION( + tri.x <= USHRT_MAX && tri.y <= USHRT_MAX && tri.z <= USHRT_MAX) + << "Overflow when casting uint3 to ushort3"; *out = ushort3{static_cast(tri.x), static_cast(tri.y), static_cast(tri.z)}; @@ -763,7 +765,7 @@ template void TangentSpaceMesh::getAux(AuxAttribute attribute, T* out, size_t stride) const noexcept { AttributeImpl attrib = static_cast(attribute); auto inAux = mInput->data(attrib); - ASSERT_PRECONDITION(inAux, "Must provide input auxilliary attribute"); + FILAMENT_CHECK_PRECONDITION(inAux) << "Must provide input auxilliary attribute"; stride = stride ? stride : sizeof(decltype(*out)); auto const& outAux = mOutput->data(attrib); for (size_t i = 0; i < mOutput->vertexCount; ++i) { diff --git a/libs/gltfio/src/AssetLoader.cpp b/libs/gltfio/src/AssetLoader.cpp index 61a2c6ed589c..b212e09a0958 100644 --- a/libs/gltfio/src/AssetLoader.cpp +++ b/libs/gltfio/src/AssetLoader.cpp @@ -214,8 +214,8 @@ struct FAssetLoader : public AssetLoader { mEngine(*config.engine), mDefaultNodeName(config.defaultNodeName) { if (config.ext) { - ASSERT_PRECONDITION(AssetConfigurationExtended::isSupported(), - "Extend asset loading is not supported on this platform"); + FILAMENT_CHECK_PRECONDITION(AssetConfigurationExtended::isSupported()) + << "Extend asset loading is not supported on this platform"; mLoaderExtended = std::make_unique( *config.ext, config.engine, mMaterials); } diff --git a/libs/gltfio/src/FilamentInstance.cpp b/libs/gltfio/src/FilamentInstance.cpp index bee3118b1aa3..0437ffc53fe7 100644 --- a/libs/gltfio/src/FilamentInstance.cpp +++ b/libs/gltfio/src/FilamentInstance.cpp @@ -92,16 +92,17 @@ void FFilamentInstance::detachSkin(size_t skinIndex, Entity target) noexcept { mat4f const* FFilamentInstance::getInverseBindMatricesAt(size_t skinIndex) const { assert_invariant(mOwner); - ASSERT_PRECONDITION(skinIndex < mOwner->mSkins.size(), "skinIndex must be less than the number of skins in this instance."); + FILAMENT_CHECK_PRECONDITION(skinIndex < mOwner->mSkins.size()) + << "skinIndex must be less than the number of skins in this instance."; return mOwner->mSkins[skinIndex].inverseBindMatrices.data(); } void FFilamentInstance::recomputeBoundingBoxes() { - ASSERT_PRECONDITION(mOwner->mSourceAsset, - "Do not call releaseSourceData before recomputeBoundingBoxes"); + FILAMENT_CHECK_PRECONDITION(mOwner->mSourceAsset) + << "Do not call releaseSourceData before recomputeBoundingBoxes"; - ASSERT_PRECONDITION(mOwner->mResourcesLoaded, - "Do not call recomputeBoundingBoxes before loadResources or asyncBeginLoad"); + FILAMENT_CHECK_PRECONDITION(mOwner->mResourcesLoaded) + << "Do not call recomputeBoundingBoxes before loadResources or asyncBeginLoad"; auto& rm = mOwner->mEngine->getRenderableManager(); auto& tm = mOwner->mEngine->getTransformManager(); diff --git a/libs/iblprefilter/src/IBLPrefilterContext.cpp b/libs/iblprefilter/src/IBLPrefilterContext.cpp index 33705b140df6..8a3c3b046c2c 100644 --- a/libs/iblprefilter/src/IBLPrefilterContext.cpp +++ b/libs/iblprefilter/src/IBLPrefilterContext.cpp @@ -228,16 +228,16 @@ Texture* IBLPrefilterContext::EquirectangularToCubemap::operator()( Renderer* const renderer = mContext.mRenderer; MaterialInstance* const mi = mEquirectMaterial->getDefaultInstance(); - ASSERT_PRECONDITION(equirect != nullptr, "equirect is null!"); + FILAMENT_CHECK_PRECONDITION(equirect != nullptr) << "equirect is null!"; - ASSERT_PRECONDITION(equirect->getTarget() == Texture::Sampler::SAMPLER_2D, - "equirect must be a 2D texture."); + FILAMENT_CHECK_PRECONDITION(equirect->getTarget() == Texture::Sampler::SAMPLER_2D) + << "equirect must be a 2D texture."; UTILS_UNUSED_IN_RELEASE const uint8_t maxLevelCount = std::max(1, std::ilogbf(float(equirect->getWidth())) + 1); - ASSERT_PRECONDITION(equirect->getLevels() == maxLevelCount, - "equirect must have %u mipmap levels allocated.", +maxLevelCount); + FILAMENT_CHECK_PRECONDITION(equirect->getLevels() == maxLevelCount) + << "equirect must have " << +maxLevelCount << " mipmap levels allocated."; if (outCube == nullptr) { outCube = Texture::Builder() @@ -248,8 +248,8 @@ Texture* IBLPrefilterContext::EquirectangularToCubemap::operator()( .build(engine); } - ASSERT_PRECONDITION(outCube->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP, - "outCube must be a Cubemap texture."); + FILAMENT_CHECK_PRECONDITION(outCube->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP) + << "outCube must be a Cubemap texture."; const uint32_t dim = outCube->getWidth(); @@ -376,23 +376,25 @@ filament::Texture* IBLPrefilterContext::IrradianceFilter::operator()( SYSTRACE_CALL(); using namespace backend; - ASSERT_PRECONDITION(environmentCubemap != nullptr, "environmentCubemap is null!"); + FILAMENT_CHECK_PRECONDITION(environmentCubemap != nullptr) << "environmentCubemap is null!"; - ASSERT_PRECONDITION(environmentCubemap->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP, - "environmentCubemap must be a cubemap."); + FILAMENT_CHECK_PRECONDITION( + environmentCubemap->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP) + << "environmentCubemap must be a cubemap."; UTILS_UNUSED_IN_RELEASE const uint8_t maxLevelCount = uint8_t(std::log2(environmentCubemap->getWidth()) + 0.5f) + 1u; - ASSERT_PRECONDITION(environmentCubemap->getLevels() == maxLevelCount, - "environmentCubemap must have %u mipmap levels allocated.", +maxLevelCount); + FILAMENT_CHECK_PRECONDITION(environmentCubemap->getLevels() == maxLevelCount) + << "environmentCubemap must have " << +maxLevelCount << " mipmap levels allocated."; if (outIrradianceTexture == nullptr) { outIrradianceTexture = createIrradianceTexture(); } - ASSERT_PRECONDITION(outIrradianceTexture->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP, - "outReflectionsTexture must be a cubemap."); + FILAMENT_CHECK_PRECONDITION( + outIrradianceTexture->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP) + << "outReflectionsTexture must be a cubemap."; const TextureCubemapFace faces[2][3] = { { TextureCubemapFace::POSITIVE_X, TextureCubemapFace::POSITIVE_Y, TextureCubemapFace::POSITIVE_Z }, @@ -600,27 +602,29 @@ Texture* IBLPrefilterContext::SpecularFilter::operator()( SYSTRACE_CALL(); using namespace backend; - ASSERT_PRECONDITION(environmentCubemap != nullptr, "environmentCubemap is null!"); + FILAMENT_CHECK_PRECONDITION(environmentCubemap != nullptr) << "environmentCubemap is null!"; - ASSERT_PRECONDITION(environmentCubemap->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP, - "environmentCubemap must be a cubemap."); + FILAMENT_CHECK_PRECONDITION( + environmentCubemap->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP) + << "environmentCubemap must be a cubemap."; UTILS_UNUSED_IN_RELEASE const uint8_t maxLevelCount = uint8_t(std::log2(environmentCubemap->getWidth()) + 0.5f) + 1u; - ASSERT_PRECONDITION(environmentCubemap->getLevels() == maxLevelCount, - "environmentCubemap must have %u mipmap levels allocated.", +maxLevelCount); + FILAMENT_CHECK_PRECONDITION(environmentCubemap->getLevels() == maxLevelCount) + << "environmentCubemap must have " << +maxLevelCount << " mipmap levels allocated."; if (outReflectionsTexture == nullptr) { outReflectionsTexture = createReflectionsTexture(); } - ASSERT_PRECONDITION(outReflectionsTexture->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP, - "outReflectionsTexture must be a cubemap."); + FILAMENT_CHECK_PRECONDITION( + outReflectionsTexture->getTarget() == Texture::Sampler::SAMPLER_CUBEMAP) + << "outReflectionsTexture must be a cubemap."; - ASSERT_PRECONDITION(mLevelCount <= outReflectionsTexture->getLevels(), - "outReflectionsTexture has %u levels but %u are requested.", - +outReflectionsTexture->getLevels(), +mLevelCount); + FILAMENT_CHECK_PRECONDITION(mLevelCount <= outReflectionsTexture->getLevels()) + << "outReflectionsTexture has " << +outReflectionsTexture->getLevels() << " levels but " + << +mLevelCount << " are requested."; const TextureCubemapFace faces[2][3] = { { TextureCubemapFace::POSITIVE_X, TextureCubemapFace::POSITIVE_Y, TextureCubemapFace::POSITIVE_Z }, diff --git a/libs/image/src/ImageOps.cpp b/libs/image/src/ImageOps.cpp index fb097d8c84f4..f9338316a22e 100644 --- a/libs/image/src/ImageOps.cpp +++ b/libs/image/src/ImageOps.cpp @@ -34,7 +34,7 @@ LinearImage horizontalStack(std::initializer_list images) { } LinearImage horizontalStack(const LinearImage* first, size_t count) { - ASSERT_PRECONDITION(count > 0, "Must supply one or more images for stacking."); + FILAMENT_CHECK_PRECONDITION(count > 0) << "Must supply one or more images for stacking."; // Compute the final size and allocate memory. uint32_t width = 0; @@ -46,12 +46,12 @@ LinearImage horizontalStack(const LinearImage* first, size_t count) { if (height == 0) { height = img.getHeight(); } else { - ASSERT_PRECONDITION(height == img.getHeight(), "Inconsistent heights."); + FILAMENT_CHECK_PRECONDITION(height == img.getHeight()) << "Inconsistent heights."; } if (nchannels == 0) { nchannels = img.getChannels(); } else { - ASSERT_PRECONDITION(nchannels == img.getChannels(), "Inconsistent channels."); + FILAMENT_CHECK_PRECONDITION(nchannels == img.getChannels()) << "Inconsistent channels."; } } LinearImage result(width, height, nchannels); @@ -79,7 +79,7 @@ LinearImage verticalStack(std::initializer_list images) { // result. This is incredibly lazy, but since we use row-major ordering, copying columns would be // really painful. LinearImage verticalStack(const LinearImage* first, size_t count) { - ASSERT_PRECONDITION(count > 0, "Must supply one or more images for stacking."); + FILAMENT_CHECK_PRECONDITION(count > 0) << "Must supply one or more images for stacking."; std::unique_ptr flipped(new LinearImage[count]); int i = 0; for (size_t c = 0; c < count; ++c) { @@ -133,16 +133,16 @@ LinearImage applyScaleOffset(const LinearImage& image, } LinearImage vectorsToColors(const LinearImage& image) { - ASSERT_PRECONDITION(image.getChannels() == 3 || image.getChannels() == 4, - "Must be a 3 or 4 channel image"); + FILAMENT_CHECK_PRECONDITION(image.getChannels() == 3 || image.getChannels() == 4) + << "Must be a 3 or 4 channel image"; return image.getChannels() == 3 ? applyScaleOffset(image, 0.5f, 0.5f) : applyScaleOffset(image, 0.5f, 0.5f); } LinearImage colorsToVectors(const LinearImage& image) { - ASSERT_PRECONDITION(image.getChannels() == 3 || image.getChannels() == 4, - "Must be a 3 or 4 channel image"); + FILAMENT_CHECK_PRECONDITION(image.getChannels() == 3 || image.getChannels() == 4) + << "Must be a 3 or 4 channel image"; return image.getChannels() == 3 ? applyScaleOffset(image, 2.0f, -1.0f) : applyScaleOffset(image, 2.0f, -1.0f); @@ -151,7 +151,7 @@ LinearImage colorsToVectors(const LinearImage& image) { LinearImage extractChannel(const LinearImage& source, uint32_t channel) { const uint32_t width = source.getWidth(), height = source.getHeight(); const uint32_t nchan = source.getChannels(); - ASSERT_PRECONDITION(channel < nchan, "Channel is out of range."); + FILAMENT_CHECK_PRECONDITION(channel < nchan) << "Channel is out of range."; LinearImage result(width, height, 1); auto src = source.getPixelRef(); auto dst = result.getPixelRef(); @@ -167,14 +167,16 @@ LinearImage combineChannels(std::initializer_list images) { } LinearImage combineChannels(LinearImage const* img, size_t count) { - ASSERT_PRECONDITION(count > 0, "Must supply one or more image planes for combining."); + FILAMENT_CHECK_PRECONDITION(count > 0) << "Must supply one or more image planes for combining."; const uint32_t width = img[0].getWidth(); const uint32_t height = img[0].getHeight(); for (size_t c = 0; c < count; ++c) { const LinearImage& plane = img[c]; - ASSERT_PRECONDITION(plane.getWidth() == width, "Planes must all have same width."); - ASSERT_PRECONDITION(plane.getHeight() == height, "Planes must all have same height."); - ASSERT_PRECONDITION(plane.getChannels() == 1, "Planes must be single channel."); + FILAMENT_CHECK_PRECONDITION(plane.getWidth() == width) + << "Planes must all have same width."; + FILAMENT_CHECK_PRECONDITION(plane.getHeight() == height) + << "Planes must all have same height."; + FILAMENT_CHECK_PRECONDITION(plane.getChannels() == 1) << "Planes must be single channel."; } LinearImage result(width, height, (uint32_t) count); float* dst = result.getPixelRef(); @@ -414,10 +416,12 @@ LinearImage voronoiFromCoordField(const LinearImage& coordField, const LinearIma } void blitImage(LinearImage& target, const LinearImage& source) { - ASSERT_PRECONDITION(source.getWidth() == target.getWidth(), "Images must have same width."); - ASSERT_PRECONDITION(source.getHeight() == target.getHeight(), "Images must have same height."); - ASSERT_PRECONDITION(source.getChannels() == target.getChannels(), - "Images must have same number of channels."); + FILAMENT_CHECK_PRECONDITION(source.getWidth() == target.getWidth()) + << "Images must have same width."; + FILAMENT_CHECK_PRECONDITION(source.getHeight() == target.getHeight()) + << "Images must have same height."; + FILAMENT_CHECK_PRECONDITION(source.getChannels() == target.getChannels()) + << "Images must have same number of channels."; memcpy(target.getPixelRef(), source.getPixelRef(), sizeof(float) * source.getWidth() * source.getHeight() * source.getChannels()); } diff --git a/libs/image/src/ImageSampler.cpp b/libs/image/src/ImageSampler.cpp index 157f15867532..20c9a006d3fb 100644 --- a/libs/image/src/ImageSampler.cpp +++ b/libs/image/src/ImageSampler.cpp @@ -217,8 +217,8 @@ void normalizeImpl(LinearImage& image) { } void normalize(LinearImage& image) { - ASSERT_PRECONDITION(image.getChannels() == 3 || image.getChannels() == 4, - "Must be a 3 or 4 channel image"); + FILAMENT_CHECK_PRECONDITION(image.getChannels() == 3 || image.getChannels() == 4) + << "Must be a 3 or 4 channel image"; if (image.getChannels() == 3) { normalizeImpl< filament::math::float3>(image); } else { @@ -288,11 +288,10 @@ SingleSample::~SingleSample() { LinearImage resampleImage(const LinearImage& source, uint32_t width, uint32_t height, const ImageSampler& sampler) { - ASSERT_PRECONDITION( - sampler.east.mode == Boundary::EXCLUDE && - sampler.north.mode == Boundary::EXCLUDE && - sampler.west.mode == Boundary::EXCLUDE && - sampler.south.mode == Boundary::EXCLUDE, "Not yet implemented."); + FILAMENT_CHECK_PRECONDITION(sampler.east.mode == Boundary::EXCLUDE && + sampler.north.mode == Boundary::EXCLUDE && sampler.west.mode == Boundary::EXCLUDE && + sampler.south.mode == Boundary::EXCLUDE) + << "Not yet implemented."; const auto hfilter = sampler.horizontalFilter; const auto vfilter = sampler.verticalFilter; const float radius = sampler.filterRadiusMultiplier; diff --git a/libs/image/src/Ktx1Bundle.cpp b/libs/image/src/Ktx1Bundle.cpp index ab7f01ca5b5b..f3b9931095a6 100644 --- a/libs/image/src/Ktx1Bundle.cpp +++ b/libs/image/src/Ktx1Bundle.cpp @@ -109,11 +109,12 @@ Ktx1Bundle::Ktx1Bundle(uint32_t numMipLevels, uint32_t arrayLength, bool isCubem Ktx1Bundle::Ktx1Bundle(uint8_t const* bytes, uint32_t nbytes) : mBlobs(new KtxBlobList), mMetadata(new KtxMetadata) { - ASSERT_PRECONDITION(sizeof(SerializationHeader) <= nbytes, "KTX buffer is too small"); + FILAMENT_CHECK_PRECONDITION(sizeof(SerializationHeader) <= nbytes) << "KTX buffer is too small"; // First, "parse" the header by casting it to a struct. SerializationHeader const* header = (SerializationHeader const*) bytes; - ASSERT_PRECONDITION(memcmp(header->magic, MAGIC, 12) == 0, "KTX has unexpected identifier"); + FILAMENT_CHECK_PRECONDITION(memcmp(header->magic, MAGIC, 12) == 0) + << "KTX has unexpected identifier"; mInfo = header->info; // The spec allows 0 or 1 for the number of array layers and mipmap levels, but we replace 0 @@ -263,7 +264,8 @@ uint32_t Ktx1Bundle::getSerializedLength() const { if (blobSize == 0) { blobSize = thisBlobSize; } - ASSERT_PRECONDITION(blobSize == thisBlobSize, "Inconsistent blob sizes within LOD"); + FILAMENT_CHECK_PRECONDITION(blobSize == thisBlobSize) + << "Inconsistent blob sizes within LOD"; total += thisBlobSize; } } diff --git a/libs/image/tests/test_image.cpp b/libs/image/tests/test_image.cpp index a0594a17e71d..ef92bee017e8 100644 --- a/libs/image/tests/test_image.cpp +++ b/libs/image/tests/test_image.cpp @@ -671,8 +671,9 @@ static bool intersect(Ray ray, Sphere sphere, float* t) { static LinearImage diffImages(const LinearImage& a, const LinearImage& b) { const uint32_t width = a.getWidth(), height = a.getHeight(), nchan = a.getChannels(); - ASSERT_PRECONDITION(width == b.getWidth() && height == b.getHeight() && - nchan == b.getChannels(), "Images must have same shape."); + FILAMENT_CHECK_PRECONDITION( + width == b.getWidth() && height == b.getHeight() && nchan == b.getChannels()) + << "Images must have same shape."; LinearImage result(width, height, nchan); float* dst = result.getPixelRef(); float const* srca = a.getPixelRef(); diff --git a/libs/imageio/src/ImageDiffer.cpp b/libs/imageio/src/ImageDiffer.cpp index cef04d626c7c..c0792387bfef 100644 --- a/libs/imageio/src/ImageDiffer.cpp +++ b/libs/imageio/src/ImageDiffer.cpp @@ -51,7 +51,7 @@ void updateOrCompare(LinearImage limgResult, const utils::Path& fnameGolden, // Load the PNG file at the given path. std::ifstream in(fnameGolden, std::ios::binary); - ASSERT_PRECONDITION(in, "Unable to open: %s", fnameGolden.c_str()); + FILAMENT_CHECK_PRECONDITION(in) << "Unable to open: " << fnameGolden.c_str(); LinearImage limgGolden = ImageDecoder::decode(in, fnameGolden); // Convert 4-channel RGBM into proper RGB. @@ -67,7 +67,7 @@ void updateOrCompare(LinearImage limgResult, const utils::Path& fnameGolden, } // Perform a simple comparison of the two images. - ASSERT_PRECONDITION(compare(limgResult, limgGolden, epsilon) == 0, "Image mismatch."); + FILAMENT_CHECK_PRECONDITION(compare(limgResult, limgGolden, epsilon) == 0) << "Image mismatch."; } } diff --git a/libs/utils/include/utils/FixedCapacityVector.h b/libs/utils/include/utils/FixedCapacityVector.h index d734117a358b..1221e7cc326c 100644 --- a/libs/utils/include/utils/FixedCapacityVector.h +++ b/libs/utils/include/utils/FixedCapacityVector.h @@ -328,9 +328,9 @@ class UTILS_PUBLIC FixedCapacityVector { iterator assertCapacityForSize(size_type s) { if constexpr(CapacityCheck || FILAMENT_FORCE_CAPACITY_CHECK) { - ASSERT_PRECONDITION(capacity() >= s, - "capacity exceeded: requested size %lu, available capacity %lu.", - (unsigned long)s, (unsigned long)capacity()); + FILAMENT_CHECK_PRECONDITION(capacity() >= s) + << "capacity exceeded: requested size " << (unsigned long)s + << "u, available capacity " << (unsigned long)capacity() << "u."; } return end(); } diff --git a/libs/utils/include/utils/RangeMap.h b/libs/utils/include/utils/RangeMap.h index 3d69bec8abb2..e7f9581b2417 100644 --- a/libs/utils/include/utils/RangeMap.h +++ b/libs/utils/include/utils/RangeMap.h @@ -119,7 +119,8 @@ class RangeMap { */ const ValueType& get(KeyType key) const { ConstIterator iter = findRange(key); - ASSERT_PRECONDITION(iter != end(), "RangeMap: No element exists at the given key."); + FILAMENT_CHECK_PRECONDITION(iter != end()) + << "RangeMap: No element exists at the given key."; return getValue(iter); } diff --git a/libs/utils/src/JobSystem.cpp b/libs/utils/src/JobSystem.cpp index 3aac3c90f718..de972ccb4602 100644 --- a/libs/utils/src/JobSystem.cpp +++ b/libs/utils/src/JobSystem.cpp @@ -275,14 +275,14 @@ void JobSystem::wait(std::unique_lock& lock, Job* job) noexcept { if (job) { auto runningJobCount = job->runningJobCount.load(); - ASSERT_POSTCONDITION(runningJobCount > 0, - "JobSystem(%p, %u): waiting while job %p has completed and %d jobs are active!", - this, unsigned(id), job, activeJobs); + FILAMENT_CHECK_POSTCONDITION(runningJobCount > 0) + << "JobSystem(" << this << ", " << unsigned(id) << "): waiting while job " + << job << " has completed and " << activeJobs << " jobs are active!"; } - ASSERT_POSTCONDITION(activeJobs <= 0, - "JobSystem(%p, %u): waiting while %d jobs are active!", - this, unsigned(id), activeJobs); + FILAMENT_CHECK_POSTCONDITION(activeJobs <= 0) + << "JobSystem(" << this << ", " << unsigned(id) << "): waiting while " + << activeJobs << " jobs are active!"; } while (true); } @@ -311,7 +311,7 @@ void JobSystem::wake(size_t hint) noexcept { inline JobSystem::ThreadState& JobSystem::getState() noexcept { std::lock_guard const lock(mThreadMapLock); auto iter = mThreadMap.find(std::this_thread::get_id()); - ASSERT_PRECONDITION(iter != mThreadMap.end(), "This thread has not been adopted."); + FILAMENT_CHECK_PRECONDITION(iter != mThreadMap.end()) << "This thread has not been adopted."; return *iter->second; } @@ -445,7 +445,7 @@ void JobSystem::loop(ThreadState* state) noexcept { mThreadMapLock.lock(); bool const inserted = mThreadMap.emplace(std::this_thread::get_id(), state).second; mThreadMapLock.unlock(); - ASSERT_PRECONDITION(inserted, "This thread is already in a loop."); + FILAMENT_CHECK_PRECONDITION(inserted) << "This thread is already in a loop."; // run our main loop... do { @@ -605,9 +605,9 @@ void JobSystem::adopt() { if (state) { // we're already part of a JobSystem, do nothing. - ASSERT_PRECONDITION(this == state->js, - "Called adopt on a thread owned by another JobSystem (%p), this=%p!", - state->js, this); + FILAMENT_CHECK_PRECONDITION(this == state->js) + << "Called adopt on a thread owned by another JobSystem (" << state->js + << "), this=" << this << "!"; return; } @@ -615,8 +615,8 @@ void JobSystem::adopt() { uint16_t const adopted = mAdoptedThreads.fetch_add(1, std::memory_order_relaxed); size_t const index = mThreadCount + adopted; - ASSERT_POSTCONDITION(index < mThreadStates.size(), - "Too many calls to adopt(). No more adoptable threads!"); + FILAMENT_CHECK_POSTCONDITION(index < mThreadStates.size()) + << "Too many calls to adopt(). No more adoptable threads!"; // all threads adopted by the JobSystem need to run at the same priority JobSystem::setThreadPriority(Priority::DISPLAY); @@ -634,8 +634,8 @@ void JobSystem::emancipate() { std::lock_guard const lock(mThreadMapLock); auto iter = mThreadMap.find(tid); ThreadState* const state = iter == mThreadMap.end() ? nullptr : iter->second; - ASSERT_PRECONDITION(state, "this thread is not an adopted thread"); - ASSERT_PRECONDITION(state->js == this, "this thread is not adopted by us"); + FILAMENT_CHECK_PRECONDITION(state) << "this thread is not an adopted thread"; + FILAMENT_CHECK_PRECONDITION(state->js == this) << "this thread is not adopted by us"; mThreadMap.erase(iter); } diff --git a/samples/multiple_windows.cpp b/samples/multiple_windows.cpp index 80adb67a90be..de3710ebe9f6 100644 --- a/samples/multiple_windows.cpp +++ b/samples/multiple_windows.cpp @@ -92,7 +92,7 @@ extern "C" #endif int main(int argc, char *argv[]) { // ---- initialize ---- - ASSERT_POSTCONDITION(SDL_Init(SDL_INIT_EVENTS) == 0, "SDL_Init Failure"); + FILAMENT_CHECK_POSTCONDITION(SDL_Init(SDL_INIT_EVENTS) == 0) << "SDL_Init Failure"; std::vector windows = { Window(), Window() }; uint32_t windowFlags = SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI