diff --git a/filament/backend/include/backend/DriverEnums.h b/filament/backend/include/backend/DriverEnums.h index cb6df91958..8b5fd245e1 100644 --- a/filament/backend/include/backend/DriverEnums.h +++ b/filament/backend/include/backend/DriverEnums.h @@ -96,7 +96,6 @@ enum class TargetBufferFlags : uint8_t { }; inline TargetBufferFlags getMRTColorFlag(size_t index) noexcept { - assert(index < 4); return TargetBufferFlags(1u << index); } diff --git a/filament/backend/include/backend/Handle.h b/filament/backend/include/backend/Handle.h index 625098a381..ae46710f10 100644 --- a/filament/backend/include/backend/Handle.h +++ b/filament/backend/include/backend/Handle.h @@ -19,8 +19,7 @@ #include #include - -#include +#include namespace filament { namespace backend { @@ -53,7 +52,7 @@ public: constexpr HandleBase() noexcept: object(nullid) {} explicit HandleBase(HandleId id) noexcept : object(id) { - assert(object != nullid); // usually means an uninitialized handle is used + assert_invariant(object != nullid); // usually means an uninitialized handle is used } HandleBase(HandleBase const& rhs) noexcept = default; diff --git a/filament/backend/include/backend/PixelBufferDescriptor.h b/filament/backend/include/backend/PixelBufferDescriptor.h index f77d308d44..327f49a4dc 100644 --- a/filament/backend/include/backend/PixelBufferDescriptor.h +++ b/filament/backend/include/backend/PixelBufferDescriptor.h @@ -23,8 +23,8 @@ #include #include +#include -#include #include #include @@ -117,7 +117,7 @@ public: */ static constexpr size_t computeDataSize(PixelDataFormat format, PixelDataType type, size_t stride, size_t height, size_t alignment) noexcept { - assert(alignment); + assert_invariant(alignment); if (type == PixelDataType::COMPRESSED) { return 0; @@ -166,17 +166,17 @@ public: break; case PixelDataType::UINT_10F_11F_11F_REV: // Special case, format must be RGB and uses 4 bytes - assert(format == PixelDataFormat::RGB); + assert_invariant(format == PixelDataFormat::RGB); bpp = 4; break; case PixelDataType::UINT_2_10_10_10_REV: // Special case, format must be RGBA and uses 4 bytes - assert(format == PixelDataFormat::RGBA); + assert_invariant(format == PixelDataFormat::RGBA); bpp = 4; break; case PixelDataType::USHORT_565: // Special case, format must be RGB and uses 2 bytes - assert(format == PixelDataFormat::RGB); + assert_invariant(format == PixelDataFormat::RGB); bpp = 2; break; } diff --git a/filament/backend/include/private/backend/CommandStream.h b/filament/backend/include/private/backend/CommandStream.h index 93b53be6e1..d76dfb7858 100644 --- a/filament/backend/include/private/backend/CommandStream.h +++ b/filament/backend/include/private/backend/CommandStream.h @@ -179,7 +179,7 @@ struct CommandType { // placement new declared as "throw" to avoid the compiler's null-check inline void* operator new(std::size_t size, void* ptr) { - assert(ptr); + assert_invariant(ptr); return ptr; } }; @@ -300,14 +300,14 @@ private: bool mUsePerformanceCounter = false; inline void* allocateCommand(size_t size) { - assert(mThreadId == std::this_thread::get_id()); + assert_invariant(mThreadId == std::this_thread::get_id()); return mCurrentBuffer->allocate(size); } }; void* CommandStream::allocate(size_t size, size_t alignment) noexcept { // make sure alignment is a power of two - assert(alignment && !(alignment & alignment-1)); + assert_invariant(alignment && !(alignment & alignment-1)); // pad the requested size to accommodate NoopCommand and alignment const size_t s = CustomCommand::align(sizeof(NoopCommand) + size + alignment - 1); @@ -318,7 +318,7 @@ void* CommandStream::allocate(size_t size, size_t alignment) noexcept { // calculate the "user" data pointer void* data = (void *)((uintptr_t(p) + sizeof(NoopCommand) + alignment - 1) & ~(alignment - 1)); - assert(data >= p + sizeof(NoopCommand)); + assert_invariant(data >= p + sizeof(NoopCommand)); return data; } diff --git a/filament/backend/include/private/backend/SamplerGroup.h b/filament/backend/include/private/backend/SamplerGroup.h index 3bae7eefa4..71843961ff 100644 --- a/filament/backend/include/private/backend/SamplerGroup.h +++ b/filament/backend/include/private/backend/SamplerGroup.h @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -101,7 +100,7 @@ private: } explicit static_vector(size_t count) noexcept : mSize(count) { - assert(count < N); + assert_invariant(count < N); std::uninitialized_fill_n(begin(), count, T{}); } @@ -129,12 +128,12 @@ private: } const T& operator[](size_t pos) const noexcept { - assert(pos < mSize); + assert_invariant(pos < mSize); return data()[pos]; } T& operator[](size_t pos) noexcept { - assert(pos < mSize); + assert_invariant(pos < mSize); return data()[pos]; } diff --git a/filament/backend/src/Callable.cpp b/filament/backend/src/Callable.cpp index fa90586b73..040284d299 100644 --- a/filament/backend/src/Callable.cpp +++ b/filament/backend/src/Callable.cpp @@ -17,13 +17,14 @@ #include #include +#include namespace filament { namespace backend { PresentCallable::PresentCallable(PresentFn fn, void* user) noexcept : mPresentFn(fn), mUser(user) { - assert(fn != nullptr); + assert_invariant(fn != nullptr); } void PresentCallable::operator()(bool presentFrame) noexcept { diff --git a/filament/backend/src/CircularBuffer.cpp b/filament/backend/src/CircularBuffer.cpp index 0d298d2c27..820b57d973 100644 --- a/filament/backend/src/CircularBuffer.cpp +++ b/filament/backend/src/CircularBuffer.cpp @@ -29,6 +29,7 @@ #include #include #include +#include using namespace utils; @@ -146,7 +147,7 @@ void CircularBuffer::circularize() noexcept { if (mUsesAshmem > 0) { intptr_t overflow = intptr_t(mHead) - (intptr_t(mData) + ssize_t(mSize)); if (overflow >= 0) { - assert(size_t(overflow) <= mSize); + assert_invariant(size_t(overflow) <= mSize); mHead = (void *) (intptr_t(mData) + overflow); #ifndef NDEBUG memset(mData, 0xA5, size_t(overflow)); diff --git a/filament/backend/src/CommandBufferQueue.cpp b/filament/backend/src/CommandBufferQueue.cpp index 946522af29..b26f9f4354 100644 --- a/filament/backend/src/CommandBufferQueue.cpp +++ b/filament/backend/src/CommandBufferQueue.cpp @@ -16,11 +16,10 @@ #include "private/backend/CommandBufferQueue.h" -#include - #include #include #include +#include #include "private/backend/CommandStream.h" @@ -33,11 +32,11 @@ CommandBufferQueue::CommandBufferQueue(size_t requiredSize, size_t bufferSize) : mRequiredSize((requiredSize + CircularBuffer::BLOCK_MASK) & ~CircularBuffer::BLOCK_MASK), mCircularBuffer(bufferSize), mFreeSpace(mCircularBuffer.size()) { - assert(mCircularBuffer.size() > requiredSize); + assert_invariant(mCircularBuffer.size() > requiredSize); } CommandBufferQueue::~CommandBufferQueue() { - assert(mCommandBuffersToExecute.empty()); + assert_invariant(mCommandBuffersToExecute.empty()); } void CommandBufferQueue::requestExit() { @@ -81,7 +80,7 @@ void CommandBufferQueue::flush() noexcept { mCommandBuffersToExecute.push_back({ tail, head }); // circular buffer is too small, we corrupted the stream - assert(used <= mFreeSpace); + assert_invariant(used <= mFreeSpace); // wait until there is enough space in the buffer mFreeSpace -= used; diff --git a/filament/backend/src/DataReshaper.h b/filament/backend/src/DataReshaper.h index 2217969f46..1e8847442a 100644 --- a/filament/backend/src/DataReshaper.h +++ b/filament/backend/src/DataReshaper.h @@ -21,6 +21,8 @@ #include +#include + namespace filament { namespace backend { @@ -62,7 +64,7 @@ public: const srcComponentType srcMaxValue = getMaxValue(); const size_t width = (srcBytesPerRow / sizeof(srcComponentType)) / srcChannelCount; const size_t minChannelCount = filament::math::min(srcChannelCount, dstChannelCount); - assert(minChannelCount <= 4); + assert_invariant(minChannelCount <= 4); const int inds[4] = {swizzle ? 2 : 0, 1, swizzle ? 0 : 2, 3}; int srcStride; diff --git a/filament/backend/src/DriverBase.h b/filament/backend/src/DriverBase.h index 2fd026f8a8..4e882213f4 100644 --- a/filament/backend/src/DriverBase.h +++ b/filament/backend/src/DriverBase.h @@ -32,7 +32,6 @@ #include #include -#include #include namespace filament { diff --git a/filament/backend/src/Platform.cpp b/filament/backend/src/Platform.cpp index ee193adf56..2460f543a2 100644 --- a/filament/backend/src/Platform.cpp +++ b/filament/backend/src/Platform.cpp @@ -17,6 +17,7 @@ #include #include +#include #if defined(ANDROID) #ifndef FILAMENT_USE_EXTERNAL_GLES3 @@ -78,7 +79,7 @@ Platform::~Platform() noexcept = default; // createDriver(). The passed-in backend hint is replaced with the resolved backend. DefaultPlatform* DefaultPlatform::create(Backend* backend) noexcept { SYSTRACE_CALL(); - assert(backend); + assert_invariant(backend); if (*backend == Backend::DEFAULT) { *backend = Backend::OPENGL; } diff --git a/filament/backend/src/TextureReshaper.cpp b/filament/backend/src/TextureReshaper.cpp index 08212708e8..8b1fbed38e 100644 --- a/filament/backend/src/TextureReshaper.cpp +++ b/filament/backend/src/TextureReshaper.cpp @@ -19,6 +19,7 @@ #include "DataReshaper.h" #include +#include namespace filament { namespace backend { @@ -71,7 +72,7 @@ TextureFormat TextureReshaper::getReshapedFormat() const noexcept { } PixelBufferDescriptor TextureReshaper::reshape(PixelBufferDescriptor& p) const { - assert(mReshapeFunction); + assert_invariant(mReshapeFunction); return mReshapeFunction(p); } diff --git a/filament/backend/src/android/ExternalStreamManagerAndroid.cpp b/filament/backend/src/android/ExternalStreamManagerAndroid.cpp index 9a08f2a694..c333c94771 100644 --- a/filament/backend/src/android/ExternalStreamManagerAndroid.cpp +++ b/filament/backend/src/android/ExternalStreamManagerAndroid.cpp @@ -103,7 +103,7 @@ void ExternalStreamManagerAndroid::release(Stream* handle) noexcept { ASurfaceTexture_release(stream->nSurfaceTexture); } JNIEnv* const env = getEnvironment(); - assert(env); // we should have called attach() by now + assert_invariant(env); // we should have called attach() by now env->DeleteGlobalRef(stream->jSurfaceTexture); delete stream; } @@ -124,7 +124,7 @@ void ExternalStreamManagerAndroid::attach(Stream* handle, intptr_t tname) noexce } } else { JNIEnv* const env = getEnvironment(); - assert(env); // we should have called attach() by now + assert_invariant(env); // we should have called attach() by now // associate our GL texture to the SurfaceTexture jobject jSurfaceTexture = stream->jSurfaceTexture; @@ -152,7 +152,7 @@ void ExternalStreamManagerAndroid::detach(Stream* handle) noexcept { ASurfaceTexture_detachFromGLContext(stream->nSurfaceTexture); } else { JNIEnv* const env = mVm.getEnvironment(); - assert(env); // we should have called attach() by now + assert_invariant(env); // we should have called attach() by now env->CallVoidMethod(stream->jSurfaceTexture, mSurfaceTextureClass_detachFromGLContext); VirtualMachineEnv::handleException(env); } @@ -170,7 +170,7 @@ void ExternalStreamManagerAndroid::updateTexImage(Stream* handle, int64_t* times } } else { JNIEnv* const env = mVm.getEnvironment(); - assert(env); // we should have called attach() by now + assert_invariant(env); // we should have called attach() by now env->CallVoidMethod(stream->jSurfaceTexture, mSurfaceTextureClass_updateTexImage); VirtualMachineEnv::handleException(env); *timestamp = env->CallLongMethod(stream->jSurfaceTexture, mSurfaceTextureClass_getTimestamp); diff --git a/filament/backend/src/android/VirtualMachineEnv.cpp b/filament/backend/src/android/VirtualMachineEnv.cpp index 15c24cba3c..1122e69d61 100644 --- a/filament/backend/src/android/VirtualMachineEnv.cpp +++ b/filament/backend/src/android/VirtualMachineEnv.cpp @@ -16,6 +16,7 @@ #include "VirtualMachineEnv.h" +#include namespace filament { @@ -44,7 +45,7 @@ void VirtualMachineEnv::handleException(JNIEnv* const env) noexcept { UTILS_NOINLINE JNIEnv* VirtualMachineEnv::getEnvironmentSlow() noexcept { mVirtualMachine->AttachCurrentThread(&mJniEnv, nullptr); - assert(mJniEnv); + assert_invariant(mJniEnv); return mJniEnv; } diff --git a/filament/backend/src/android/VirtualMachineEnv.h b/filament/backend/src/android/VirtualMachineEnv.h index 7871813bff..5534129eb9 100644 --- a/filament/backend/src/android/VirtualMachineEnv.h +++ b/filament/backend/src/android/VirtualMachineEnv.h @@ -19,11 +19,10 @@ #include #include +#include #include -#include - namespace filament { class VirtualMachineEnv { @@ -39,7 +38,7 @@ public: static JNIEnv* getThreadEnvironment() noexcept { JNIEnv* env; - assert(sVirtualMachine); + assert_invariant(sVirtualMachine); if (sVirtualMachine->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { return nullptr; // this should not happen } @@ -59,7 +58,7 @@ public: } inline JNIEnv* getEnvironment() noexcept { - assert(mVirtualMachine); + assert_invariant(mVirtualMachine); JNIEnv* env = mJniEnv; if (UTILS_UNLIKELY(!env)) { return getEnvironmentSlow(); diff --git a/filament/backend/src/metal/MetalBufferPool.mm b/filament/backend/src/metal/MetalBufferPool.mm index 8228a30371..c20af00e37 100644 --- a/filament/backend/src/metal/MetalBufferPool.mm +++ b/filament/backend/src/metal/MetalBufferPool.mm @@ -103,7 +103,7 @@ void MetalBufferPool::gc() noexcept { void MetalBufferPool::reset() noexcept { std::lock_guard lock(mMutex); - assert(mUsedStages.empty()); + assert_invariant(mUsedStages.empty()); for (auto pair : mFreeStages) { delete pair.second; } diff --git a/filament/backend/src/metal/MetalContext.mm b/filament/backend/src/metal/MetalContext.mm index 6db5f1e03f..45fd15e690 100644 --- a/filament/backend/src/metal/MetalContext.mm +++ b/filament/backend/src/metal/MetalContext.mm @@ -18,7 +18,7 @@ #include "MetalHandles.h" -#include +#include namespace filament { namespace backend { @@ -42,7 +42,7 @@ void submitPendingCommands(MetalContext* context) { if (!context->pendingCommandBuffer) { return; } - assert(context->pendingCommandBuffer.status != MTLCommandBufferStatusCommitted); + assert_invariant(context->pendingCommandBuffer.status != MTLCommandBufferStatusCommitted); [context->pendingCommandBuffer commit]; context->pendingCommandBuffer = nil; } diff --git a/filament/backend/src/metal/MetalDriver.h b/filament/backend/src/metal/MetalDriver.h index 6c4aa4ae01..8351bf155e 100644 --- a/filament/backend/src/metal/MetalDriver.h +++ b/filament/backend/src/metal/MetalDriver.h @@ -22,6 +22,7 @@ #include #include +#include #include @@ -114,33 +115,33 @@ private: template Dp* handle_cast(HandleMap& handleMap, Handle handle) noexcept { - assert(handle); + assert_invariant(handle); if (!handle) return nullptr; // better to get a NPE than random behavior/corruption std::lock_guard lock(mHandleMapMutex); auto iter = handleMap.find(handle.getId()); - assert(iter != handleMap.end()); + assert_invariant(iter != handleMap.end()); Blob& blob = iter.value(); return reinterpret_cast(blob); } template const Dp* handle_const_cast(HandleMap& handleMap, const Handle& handle) noexcept { - assert(handle); + assert_invariant(handle); if (!handle) return nullptr; // better to get a NPE than random behavior/corruption std::lock_guard lock(mHandleMapMutex); auto iter = handleMap.find(handle.getId()); - assert(iter != handleMap.end()); + assert_invariant(iter != handleMap.end()); Blob& blob = iter.value(); return reinterpret_cast(blob); } template Dp* construct_handle(HandleMap& handleMap, Handle& handle, ARGS&& ... args) noexcept { - assert(handle); + assert_invariant(handle); if (!handle) return nullptr; // better to get a NPE than random behavior/corruption std::lock_guard lock(mHandleMapMutex); auto iter = handleMap.find(handle.getId()); - assert(iter != handleMap.end()); + assert_invariant(iter != handleMap.end()); Blob& blob = iter.value(); Dp* addr = reinterpret_cast(blob); new(addr) Dp(std::forward(args)...); @@ -150,10 +151,10 @@ private: template void destruct_handle(HandleMap& handleMap, Handle& handle) noexcept { std::lock_guard lock(mHandleMapMutex); - assert(handle); + assert_invariant(handle); // Call the destructor, remove the blob, don't bother reclaiming the integer id. auto iter = handleMap.find(handle.getId()); - assert(iter != handleMap.end()); + assert_invariant(iter != handleMap.end()); Blob& blob = iter.value(); reinterpret_cast(blob)->~Dp(); free(blob); diff --git a/filament/backend/src/metal/MetalDriver.mm b/filament/backend/src/metal/MetalDriver.mm index afaf6de653..c67b1a0b69 100644 --- a/filament/backend/src/metal/MetalDriver.mm +++ b/filament/backend/src/metal/MetalDriver.mm @@ -46,7 +46,7 @@ namespace metal { UTILS_NOINLINE Driver* MetalDriver::create(MetalPlatform* const platform) { - assert(platform); + assert_invariant(platform); return new MetalDriver(platform); } @@ -626,7 +626,7 @@ math::float2 MetalDriver::getClipSpaceParams() { void MetalDriver::updateVertexBuffer(Handle vbh, size_t index, BufferDescriptor&& data, uint32_t byteOffset) { - assert(byteOffset == 0); // TODO: handle byteOffset for vertex buffers + assert_invariant(byteOffset == 0); // TODO: handle byteOffset for vertex buffers auto* vb = handle_cast(mHandleMap, vbh); vb->buffers[index]->copyIntoBuffer(data.buffer, data.size); scheduleDestroy(std::move(data)); @@ -634,7 +634,7 @@ void MetalDriver::updateVertexBuffer(Handle vbh, size_t index, void MetalDriver::updateIndexBuffer(Handle ibh, BufferDescriptor&& data, uint32_t byteOffset) { - assert(byteOffset == 0); // TODO: handle byteOffset for index buffers + assert_invariant(byteOffset == 0); // TODO: handle byteOffset for index buffers auto* ib = handle_cast(mHandleMap, ibh); ib->buffer.copyIntoBuffer(data.buffer, data.size); scheduleDestroy(std::move(data)); @@ -1135,7 +1135,7 @@ void MetalDriver::draw(backend::PipelineState ps, Handle rph) if (mContext->pipelineState.stateChanged()) { id pipeline = mContext->pipelineStateCache.getOrCreateState(pipelineState); - assert(pipeline != nil); + assert_invariant(pipeline != nil); [mContext->currentRenderPassEncoder setRenderPipelineState:pipeline]; } @@ -1162,7 +1162,7 @@ void MetalDriver::draw(backend::PipelineState ps, Handle rph) if (mContext->depthStencilState.stateChanged()) { id state = mContext->depthStencilStateCache.getOrCreateState(depthState); - assert(state != nil); + assert_invariant(state != nil); [mContext->currentRenderPassEncoder setDepthStencilState:state]; } @@ -1296,7 +1296,7 @@ void MetalDriver::enumerateSamplerGroups( continue; } SamplerGroup* sb = metalSamplerGroup->sb.get(); - assert(sb->getSize() == samplerGroup.size()); + assert_invariant(sb->getSize() == samplerGroup.size()); size_t samplerIdx = 0; for (const auto& sampler : samplerGroup) { size_t bindingPoint = sampler.binding; diff --git a/filament/backend/src/metal/MetalExternalImage.mm b/filament/backend/src/metal/MetalExternalImage.mm index 17b44acedf..e321852b10 100644 --- a/filament/backend/src/metal/MetalExternalImage.mm +++ b/filament/backend/src/metal/MetalExternalImage.mm @@ -152,7 +152,7 @@ void MetalExternalImage::set(CVPixelBufferRef image, size_t plane) noexcept { }; const MTLPixelFormat format = getPlaneFormat(plane); - assert(format != MTLPixelFormatInvalid); + assert_invariant(format != MTLPixelFormatInvalid); mTexture = createTextureFromImage(image, format, plane); } diff --git a/filament/backend/src/metal/MetalHandles.mm b/filament/backend/src/metal/MetalHandles.mm index 782efe1c29..6aaeabf3a2 100644 --- a/filament/backend/src/metal/MetalHandles.mm +++ b/filament/backend/src/metal/MetalHandles.mm @@ -24,6 +24,7 @@ #include #include +#include #include @@ -78,10 +79,10 @@ MetalSwapChain::MetalSwapChain(MetalContext& context, int32_t width, int32_t hei MetalSwapChain::MetalSwapChain(MetalContext& context, CVPixelBufferRef pixelBuffer, uint64_t flags) : context(context), externalImage(context), type(SwapChainType::CVPIXELBUFFERREF) { - assert(flags & backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER); + assert_invariant(flags & backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER); MetalExternalImage::assertWritableImage(pixelBuffer); externalImage.set(pixelBuffer); - assert(externalImage.isValid()); + assert_invariant(externalImage.isValid()); } MetalSwapChain::~MetalSwapChain() { @@ -138,7 +139,7 @@ id MetalSwapChain::acquireDrawable() { return externalImage.getMetalTextureForDraw(); } - assert(isCaMetalLayer()); + assert_invariant(isCaMetalLayer()); drawable = [layer nextDrawable]; ASSERT_POSTCONDITION(drawable != nil, "Could not obtain drawable."); @@ -220,7 +221,7 @@ void MetalSwapChain::scheduleFrameScheduledCallback() { return; } - assert(drawable); + assert_invariant(drawable); backend::FrameScheduledCallback callback = frameScheduledCallback; // This block strongly captures drawable to keep it alive until the handler executes. // We cannot simply reference this->drawable inside the block because the block would then only @@ -424,7 +425,7 @@ MetalTexture::MetalTexture(MetalContext& context, SamplerType target, uint8_t le metalPixelFormat = decidePixelFormat(context.device, reshapedFormat); bytesPerElement = static_cast(getFormatSize(reshapedFormat)); - assert(bytesPerElement > 0); + assert_invariant(bytesPerElement > 0); blockWidth = static_cast(getBlockWidth(reshapedFormat)); blockHeight = static_cast(getBlockHeight(reshapedFormat)); @@ -561,7 +562,7 @@ void MetalTexture::load3DImage(uint32_t level, uint32_t xoffset, uint32_t yoffse loadSlice(level, xoffset, yoffset, 0, width, height, depth, 0, zoffset, p, blitCommandEncoder, blitCommandBuffer); } else { - assert(target == SamplerType::SAMPLER_3D); + assert_invariant(target == SamplerType::SAMPLER_3D); loadSlice(level, xoffset, yoffset, zoffset, width, height, depth, 0, 0, p, blitCommandEncoder, blitCommandBuffer); } @@ -609,8 +610,8 @@ void MetalTexture::loadSlice(uint32_t level, uint32_t xoffset, uint32_t yoffset, const size_t sourceOffset = (data.left * bytesPerPixel) + (data.top * bytesPerRow) + byteOffset; if (data.type == PixelDataType::COMPRESSED) { - assert(blockWidth > 0); - assert(blockHeight > 0); + assert_invariant(blockWidth > 0); + assert_invariant(blockHeight > 0); // From https://developer.apple.com/documentation/metal/mtltexture/1515464-replaceregion: // For an ordinary or packed pixel format, the stride, in bytes, between rows of source // data. For a compressed pixel format, the stride is the number of bytes from the @@ -757,7 +758,7 @@ void MetalRenderTarget::setUpRenderPassAttachments(MTLRenderPassDescriptor* desc if (multisampledColor[i]) { // We're rendering into our temporary MSAA texture and doing an automatic resolve. // We should not be attempting to load anything into the MSAA texture. - assert(descriptor.colorAttachments[i].loadAction != MTLLoadActionLoad); + assert_invariant(descriptor.colorAttachments[i].loadAction != MTLLoadActionLoad); descriptor.colorAttachments[i].texture = multisampledColor[i]; descriptor.colorAttachments[i].level = 0; @@ -783,7 +784,7 @@ void MetalRenderTarget::setUpRenderPassAttachments(MTLRenderPassDescriptor* desc if (multisampledDepth) { // We're rendering into our temporary MSAA texture and doing an automatic resolve. // We should not be attempting to load anything into the MSAA texture. - assert(descriptor.depthAttachment.loadAction != MTLLoadActionLoad); + assert_invariant(descriptor.depthAttachment.loadAction != MTLLoadActionLoad); descriptor.depthAttachment.texture = multisampledDepth; descriptor.depthAttachment.level = 0; @@ -799,20 +800,20 @@ void MetalRenderTarget::setUpRenderPassAttachments(MTLRenderPassDescriptor* desc } MetalRenderTarget::Attachment MetalRenderTarget::getDrawColorAttachment(size_t index) { - assert(index < MRT::TARGET_COUNT); + assert_invariant(index < MRT::TARGET_COUNT); Attachment result = color[index]; if (index == 0 && defaultRenderTarget) { - assert(context->currentDrawSwapChain); + assert_invariant(context->currentDrawSwapChain); result.texture = context->currentDrawSwapChain->acquireDrawable(); } return result; } MetalRenderTarget::Attachment MetalRenderTarget::getReadColorAttachment(size_t index) { - assert(index < MRT::TARGET_COUNT); + assert_invariant(index < MRT::TARGET_COUNT); Attachment result = color[index]; if (index == 0 && defaultRenderTarget) { - assert(context->currentReadSwapChain); + assert_invariant(context->currentReadSwapChain); result.texture = context->currentReadSwapChain->acquireDrawable(); } return result; diff --git a/filament/backend/src/metal/MetalResourceTracker.cpp b/filament/backend/src/metal/MetalResourceTracker.cpp index 9f2790f565..e17c17222a 100644 --- a/filament/backend/src/metal/MetalResourceTracker.cpp +++ b/filament/backend/src/metal/MetalResourceTracker.cpp @@ -16,6 +16,8 @@ #include "MetalResourceTracker.h" +#include + namespace filament { namespace backend { namespace metal { @@ -31,7 +33,7 @@ bool MetalResourceTracker::trackResource(CommandBuffer buffer, Resource resource return true; } - assert(found != mResources.end()); + assert_invariant(found != mResources.end()); Resources& resources = found.value(); auto inserted = resources.insert({resource, deleter}); return inserted.second; diff --git a/filament/backend/src/opengl/CocoaTouchExternalImage.mm b/filament/backend/src/opengl/CocoaTouchExternalImage.mm index 04b59d1db7..7f79520b1b 100644 --- a/filament/backend/src/opengl/CocoaTouchExternalImage.mm +++ b/filament/backend/src/opengl/CocoaTouchExternalImage.mm @@ -27,6 +27,7 @@ #include #include +#include namespace filament { @@ -74,20 +75,20 @@ CocoaTouchExternalImage::SharedGl::SharedGl() noexcept { glShaderSource(vertexShader, 1, &s_vertexES, nullptr); glCompileShader(vertexShader); glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); + assert_invariant(status == GL_TRUE); fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &s_fragmentES, nullptr); glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); + assert_invariant(status == GL_TRUE); program = glCreateProgram(); glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); glLinkProgram(program); glGetProgramiv(program, GL_LINK_STATUS, &status); - assert(status == GL_TRUE); + assert_invariant(status == GL_TRUE); // Save current program state. GLint currentProgram; @@ -145,7 +146,7 @@ bool CocoaTouchExternalImage::set(CVPixelBufferRef image) noexcept { // The pixel buffer must be locked whenever we do rendering with it. We'll unlock it before // releasing. UTILS_UNUSED_IN_RELEASE CVReturn lockStatus = CVPixelBufferLockBaseAddress(image, 0); - assert(lockStatus == kCVReturnSuccess); + assert_invariant(lockStatus == kCVReturnSuccess); if (planeCount == 0) { mImage = image; @@ -222,7 +223,7 @@ CVOpenGLESTextureRef CocoaTouchExternalImage::createTextureFromImage(CVPixelBuff CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault, mTextureCache, image, nullptr, GL_TEXTURE_2D, glFormat, width, height, glFormat, GL_UNSIGNED_BYTE, plane, &texture); - assert(success == kCVReturnSuccess); + assert_invariant(success == kCVReturnSuccess); return texture; } diff --git a/filament/backend/src/opengl/OpenGLBlitter.cpp b/filament/backend/src/opengl/OpenGLBlitter.cpp index db6ef75104..f1a7f7061b 100644 --- a/filament/backend/src/opengl/OpenGLBlitter.cpp +++ b/filament/backend/src/opengl/OpenGLBlitter.cpp @@ -24,8 +24,6 @@ #include -#include - using namespace filament::math; using namespace utils; @@ -81,20 +79,20 @@ void OpenGLBlitter::init() noexcept { glShaderSource(mVertexShader, 1, vsource + index, nullptr); glCompileShader(mVertexShader); glGetShaderiv(mVertexShader, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); + assert_invariant(status == GL_TRUE); mFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(mFragmentShader, 1, fsource + index, nullptr); glCompileShader(mFragmentShader); glGetShaderiv(mFragmentShader, GL_COMPILE_STATUS, &status); - assert(status == GL_TRUE); + assert_invariant(status == GL_TRUE); mProgram = glCreateProgram(); glAttachShader(mProgram, mVertexShader); glAttachShader(mProgram, mFragmentShader); glLinkProgram(mProgram); glGetProgramiv(mProgram, GL_LINK_STATUS, &status); - assert(status == GL_TRUE); + assert_invariant(status == GL_TRUE); glUseProgram(mProgram); GLint loc = glGetUniformLocation(mProgram, "sampler"); diff --git a/filament/backend/src/opengl/OpenGLContext.cpp b/filament/backend/src/opengl/OpenGLContext.cpp index eaadee33cc..07847098a7 100644 --- a/filament/backend/src/opengl/OpenGLContext.cpp +++ b/filament/backend/src/opengl/OpenGLContext.cpp @@ -113,7 +113,7 @@ OpenGLContext::OpenGLContext() noexcept { initExtensionsGL(major, minor, exts); features.multisample_texture = true; }; - assert(shaderModel != ShaderModel::UNKNOWN); + assert_invariant(shaderModel != ShaderModel::UNKNOWN); mShaderModel = shaderModel; /* @@ -263,7 +263,7 @@ void OpenGLContext::bindBuffer(GLenum target, GLuint buffer) noexcept { if (target == GL_ELEMENT_ARRAY_BUFFER) { // GL_ELEMENT_ARRAY_BUFFER is a special case, where the currently bound VAO remembers // the index buffer, unless there are no VAO bound (see: bindVertexArray) - assert(state.vao.p); + assert_invariant(state.vao.p); if (state.buffers.genericBinding[targetIndex] != buffer || ((state.vao.p != &mDefaultVAO) && (state.vao.p->elementArray != buffer))) { state.buffers.genericBinding[targetIndex] = buffer; diff --git a/filament/backend/src/opengl/OpenGLContext.h b/filament/backend/src/opengl/OpenGLContext.h index 52425fbc01..d72997526d 100644 --- a/filament/backend/src/opengl/OpenGLContext.h +++ b/filament/backend/src/opengl/OpenGLContext.h @@ -20,6 +20,7 @@ #include #include +#include #include "GLUtils.h" @@ -315,7 +316,7 @@ constexpr size_t OpenGLContext::getIndexForCap(GLenum cap) noexcept { //NOLINT #endif default: index = 13; break; // should never happen } - assert(index < 13 && index < state.enables.caps.size()); + assert_invariant(index < 13 && index < state.enables.caps.size()); return index; } @@ -334,21 +335,21 @@ constexpr size_t OpenGLContext::getIndexForBufferTarget(GLenum target) noexcept case GL_PIXEL_UNPACK_BUFFER: index = 7; break; default: index = 8; break; // should never happen } - assert(index < sizeof(state.buffers.genericBinding)/sizeof(state.buffers.genericBinding[0])); // NOLINT(misc-redundant-expression) + assert_invariant(index < sizeof(state.buffers.genericBinding)/sizeof(state.buffers.genericBinding[0])); // NOLINT(misc-redundant-expression) return index; } // ------------------------------------------------------------------------------------------------ void OpenGLContext::activeTexture(GLuint unit) noexcept { - assert(unit < MAX_TEXTURE_UNIT_COUNT); + assert_invariant(unit < MAX_TEXTURE_UNIT_COUNT); update_state(state.textures.active, unit, [&]() { glActiveTexture(GL_TEXTURE0 + unit); }); } void OpenGLContext::bindSampler(GLuint unit, GLuint sampler) noexcept { - assert(unit < MAX_TEXTURE_UNIT_COUNT); + assert_invariant(unit < MAX_TEXTURE_UNIT_COUNT); update_state(state.textures.units[unit].sampler, sampler, [&]() { glBindSampler(unit, sampler); }); @@ -393,7 +394,7 @@ void OpenGLContext::bindVertexArray(RenderPrimitive const* p) noexcept { void OpenGLContext::bindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) noexcept { size_t targetIndex = getIndexForBufferTarget(target); - assert(targetIndex <= 1); // validity check + assert_invariant(targetIndex <= 1); // validity check // this ALSO sets the generic binding if ( state.buffers.targets[targetIndex].buffers[index].name != buffer @@ -433,8 +434,8 @@ void OpenGLContext::bindFramebuffer(GLenum target, GLuint buffer) noexcept { } void OpenGLContext::bindTexture(GLuint unit, GLuint target, GLuint texId, size_t targetIndex) noexcept { - assert(targetIndex == getIndexForTextureTarget(target)); - assert(targetIndex < TEXTURE_TARGET_COUNT); + assert_invariant(targetIndex == getIndexForTextureTarget(target)); + assert_invariant(targetIndex < TEXTURE_TARGET_COUNT); update_state(state.textures.units[unit].targets[targetIndex].texture_id, texId, [&]() { activeTexture(unit); glBindTexture(target, texId); @@ -452,8 +453,8 @@ void OpenGLContext::useProgram(GLuint program) noexcept { } void OpenGLContext::enableVertexAttribArray(GLuint index) noexcept { - assert(state.vao.p); - assert(index < state.vao.p->vertexAttribArray.size()); + assert_invariant(state.vao.p); + assert_invariant(index < state.vao.p->vertexAttribArray.size()); if (UTILS_UNLIKELY(!state.vao.p->vertexAttribArray[index])) { state.vao.p->vertexAttribArray.set(index); glEnableVertexAttribArray(index); @@ -461,8 +462,8 @@ void OpenGLContext::enableVertexAttribArray(GLuint index) noexcept { } void OpenGLContext::disableVertexAttribArray(GLuint index) noexcept { - assert(state.vao.p); - assert(index < state.vao.p->vertexAttribArray.size()); + assert_invariant(state.vao.p); + assert_invariant(index < state.vao.p->vertexAttribArray.size()); if (UTILS_UNLIKELY(state.vao.p->vertexAttribArray[index])) { state.vao.p->vertexAttribArray.unset(index); glDisableVertexAttribArray(index); diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index c86353b5a2..78518ea7db 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -79,7 +79,7 @@ using namespace GLUtils; UTILS_NOINLINE Driver* OpenGLDriver::create( OpenGLPlatform* const platform, void* const sharedGLContext) noexcept { - assert(platform); + assert_invariant(platform); OpenGLPlatform* const ec = platform; { @@ -187,7 +187,7 @@ void OpenGLDriver::terminate() { executeGpuCommandsCompleteOps(); // because we called glFinish(), all callbacks should have been executed - assert(mGpuCommandCompleteOps.empty()); + assert_invariant(mGpuCommandCompleteOps.empty()); for (auto& item : mSamplerMap) { mContext.unbindSampler(item.second); @@ -212,7 +212,7 @@ ShaderModel OpenGLDriver::getShaderModel() const noexcept { // ------------------------------------------------------------------------------------------------ void OpenGLDriver::bindTexture(GLuint unit, GLTexture const* t) noexcept { - assert(t != nullptr); + assert_invariant(t != nullptr); mContext.bindTexture(unit, t->gl.target, t->gl.id, t->gl.targetIndex); } @@ -332,7 +332,7 @@ OpenGLDriver::HandleAllocator::HandleAllocator(const utils::HeapArea& area) } void* OpenGLDriver::HandleAllocator::alloc(size_t size, size_t alignment, size_t extra) noexcept { - assert(size <= mPool2.getSize()); + assert_invariant(size <= mPool2.getSize()); if (size <= mPool0.getSize()) return mPool0.alloc(size, 16, extra); if (size <= mPool1.getSize()) return mPool1.alloc(size, 32, extra); if (size <= mPool2.getSize()) return mPool2.alloc(size, 32, extra); @@ -351,7 +351,7 @@ void OpenGLDriver::HandleAllocator::free(void* p, size_t size) noexcept { UTILS_NOINLINE HandleBase::HandleId OpenGLDriver::allocateHandle(size_t size) noexcept { void* addr = mHandleArena.alloc(size); - assert(addr); + assert_invariant(addr); char* const base = (char *)mHandleArena.getArea().begin(); size_t offset = (char*)addr - base; return HandleBase::HandleId(offset >> HandleAllocator::MIN_ALIGNMENT_SHIFT); @@ -373,7 +373,7 @@ backend::Handle OpenGLDriver::initHandle(ARGS&& ... args) noexcept { template typename std::enable_if::value, D>::type* OpenGLDriver::construct(Handle const& handle, ARGS&& ... args) noexcept { - assert(handle); + assert_invariant(handle); D* addr = handle_cast(const_cast&>(handle)); // currently we implement construct<> with dtor+ctor, we could use operator= also @@ -487,7 +487,7 @@ void OpenGLDriver::createVertexBufferR( GLsizei n = GLsizei(vb->bufferCount); - assert(n <= (GLsizei)vb->gl.buffers.size()); + assert_invariant(n <= (GLsizei)vb->gl.buffers.size()); glGenBuffers(n, vb->gl.buffers.data()); for (GLsizei i = 0; i < n; i++) { @@ -622,7 +622,7 @@ void OpenGLDriver::createTextureR(Handle th, SamplerType target, uint glGenTextures(1, &t->gl.id); t->gl.internalFormat = getInternalFormat(format); - assert(t->gl.internalFormat); + assert_invariant(t->gl.internalFormat); // We DO NOT update targetIndex at function exit to take advantage of the fact that // getIndexForTextureTarget() is constexpr -- so all of this disappears at compile time. @@ -662,12 +662,12 @@ void OpenGLDriver::createTextureR(Handle th, SamplerType target, uint textureStorage(t, w, h, depth); } } else { - assert(any(usage & ( + assert_invariant(any(usage & ( TextureUsage::COLOR_ATTACHMENT | TextureUsage::DEPTH_ATTACHMENT | TextureUsage::STENCIL_ATTACHMENT))); - assert(levels == 1); - assert(target == SamplerType::SAMPLER_2D); + assert_invariant(levels == 1); + assert_invariant(target == SamplerType::SAMPLER_2D); t->gl.internalFormat = getInternalFormat(format); t->gl.target = GL_RENDERBUFFER; glGenRenderbuffers(1, &t->gl.id); @@ -683,7 +683,7 @@ void OpenGLDriver::createTextureSwizzledR(Handle th, TextureSwizzle r, TextureSwizzle g, TextureSwizzle b, TextureSwizzle a) { DEBUG_MARKER() - assert(uint8_t(usage) & uint8_t(TextureUsage::SAMPLEABLE)); + assert_invariant(uint8_t(usage) & uint8_t(TextureUsage::SAMPLEABLE)); createTextureR(th, target, levels, format, samples, w, h, depth, usage); @@ -715,7 +715,7 @@ void OpenGLDriver::importTextureR(Handle th, intptr_t id, t->gl.id = (GLuint)id; t->gl.imported = true; t->gl.internalFormat = getInternalFormat(format); - assert(t->gl.internalFormat); + assert_invariant(t->gl.internalFormat); // We DO NOT update targetIndex at function exit to take advantage of the fact that // getIndexForTextureTarget() is constexpr -- so all of this disappears at compile time. @@ -761,7 +761,7 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, GLRenderTarget const* rt, GLenum attachment) noexcept { #if !defined(NDEBUG) - // Only used by assert() checks below + // Only used by assert_invariant() checks below UTILS_UNUSED_IN_RELEASE auto valueForLevel = [](size_t level, size_t value) { return std::max(size_t(1), value >> level); }; @@ -769,8 +769,8 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, GLTexture* t = handle_cast(binfo.handle); - assert(t->target != SamplerType::SAMPLER_EXTERNAL); - assert(rt->width <= valueForLevel(binfo.level, t->width) && + assert_invariant(t->target != SamplerType::SAMPLER_EXTERNAL); + assert_invariant(rt->width <= valueForLevel(binfo.level, t->width) && rt->height <= valueForLevel(binfo.level, t->height)); // Declare a small mask of bits that will later be OR'd into the texture's resolve mask. @@ -811,7 +811,7 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, break; } - assert(pRenderBuffer); + assert_invariant(pRenderBuffer); // depth/stencil attachment must match the rendertarget sample count // this is because EXT_multisampled_render_to_texture doesn't guarantee depth/stencil @@ -866,7 +866,7 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, target, t->gl.id, binfo.level); } else { - assert(target == GL_TEXTURE_2D); + assert_invariant(target == GL_TEXTURE_2D); glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, t->gl.id); } @@ -887,7 +887,7 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, if (!attachmentTypeNotSupportedByMSRTT && (t->depth <= 1) && ((gl.ext.EXT_multisampled_render_to_texture && attachment == GL_COLOR_ATTACHMENT0) || gl.ext.EXT_multisampled_render_to_texture2)) { - assert(rt->gl.samples > 1); + assert_invariant(rt->gl.samples > 1); // We have a multi-sample rendertarget and we have EXT_multisampled_render_to_texture, // so, we can directly use a 1-sample texture as attachment, multi-sample resolve, // will happen automagically and efficiently in the driver. @@ -903,8 +903,8 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, } else #endif if (!any(t->usage & TextureUsage::SAMPLEABLE) && t->samples > 1) { - assert(rt->gl.samples > 1); - assert(glIsRenderbuffer(t->gl.id)); + assert_invariant(rt->gl.samples > 1); + assert_invariant(glIsRenderbuffer(t->gl.id)); // Since this attachment is not sampleable, there is no need for a sidecar or explicit // resolve. We can simply render directly into the renderbuffer that was allocated in @@ -917,8 +917,8 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, resolveFlags = TargetBufferFlags::NONE; } else { - assert(rt->gl.samples > 1); - assert(pRenderBuffer->rb == 0); + assert_invariant(rt->gl.samples > 1); + assert_invariant(pRenderBuffer->rb == 0); // Here we emulate EXT_multisampled_render_to_texture. // @@ -953,7 +953,7 @@ void OpenGLDriver::framebufferTexture(backend::TargetBufferInfo const& binfo, glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, target, t->gl.id, binfo.level); } else { - assert(target == GL_TEXTURE_2D); + assert_invariant(target == GL_TEXTURE_2D); glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, t->gl.id); } @@ -1087,7 +1087,7 @@ void OpenGLDriver::createRenderTargetR(Handle rth, // handle special cases first (where depth/stencil are packed) bool specialCased = false; if ((targets & TargetBufferFlags::DEPTH_AND_STENCIL) == TargetBufferFlags::DEPTH_AND_STENCIL) { - assert(!stencil.handle || stencil.handle == depth.handle); + assert_invariant(!stencil.handle || stencil.handle == depth.handle); rt->gl.depth.texture = handle_cast(depth.handle); rt->gl.depth.level = depth.level; if (any(rt->gl.depth.texture->usage & TextureUsage::SAMPLEABLE) || @@ -1266,7 +1266,7 @@ void OpenGLDriver::destroyTexture(Handle th) { glDeleteTextures(1, &t->gl.id); } } else { - assert(t->gl.target == GL_RENDERBUFFER); + assert_invariant(t->gl.target == GL_RENDERBUFFER); glDeleteRenderbuffers(1, &t->gl.id); } if (t->gl.fence) { @@ -1403,7 +1403,7 @@ void OpenGLDriver::updateStreams(DriverApi* driver) { if (UTILS_UNLIKELY(!mExternalStreams.empty())) { OpenGLBlitter::State state; for (GLTexture* t : mExternalStreams) { - assert(t); + assert_invariant(t); GLStream* s = static_cast(t->hwStream); if (UTILS_UNLIKELY(s == nullptr)) { @@ -1632,7 +1632,7 @@ void OpenGLDriver::updateIndexBuffer( auto& gl = mContext; GLIndexBuffer* ib = handle_cast(ibh); - assert(ib->elementSize == 2 || ib->elementSize == 4); + assert_invariant(ib->elementSize == 2 || ib->elementSize == 4); gl.bindVertexArray(nullptr); gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, ib->gl.buffer); @@ -1658,8 +1658,8 @@ void OpenGLDriver::loadUniformBuffer(Handle ubh, BufferDescript void OpenGLDriver::updateBuffer(GLenum target, GLBuffer* buffer, BufferDescriptor const& p, uint32_t alignment) noexcept { - assert(buffer->capacity >= p.size); - assert(buffer->id); + assert_invariant(buffer->capacity >= p.size); + assert_invariant(buffer->id); auto& gl = mContext; gl.bindBuffer(target, buffer->id); @@ -1752,7 +1752,7 @@ void OpenGLDriver::setMinMaxLevels(Handle th, uint32_t minLevel, uint gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1); // Must fit within int8_t. - assert(minLevel <= 0x7f && maxLevel <= 0x7f); + assert_invariant(minLevel <= 0x7f && maxLevel <= 0x7f); t->gl.baseLevel = minLevel; glTexParameteri(t->gl.target, GL_TEXTURE_BASE_LEVEL, t->gl.baseLevel); @@ -1794,7 +1794,7 @@ void OpenGLDriver::generateMipmaps(Handle th) { auto& gl = mContext; GLTexture* t = handle_cast(th); - assert(t->gl.target != GL_TEXTURE_2D_MULTISAMPLE); + assert_invariant(t->gl.target != GL_TEXTURE_2D_MULTISAMPLE); // Note: glGenerateMimap can also fail if the internal format is not both // color-renderable and filterable (i.e.: doesn't work for depth) bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t); @@ -1823,9 +1823,9 @@ void OpenGLDriver::setTextureData(GLTexture* t, DEBUG_MARKER() auto& gl = mContext; - assert(xoffset + width <= std::max(1u, t->width >> level)); - assert(yoffset + height <= std::max(1u, t->height >> level)); - assert(t->samples <= 1); + assert_invariant(xoffset + width <= std::max(1u, t->width >> level)); + assert_invariant(yoffset + height <= std::max(1u, t->height >> level)); + assert_invariant(t->samples <= 1); if (UTILS_UNLIKELY(t->gl.target == GL_TEXTURE_EXTERNAL_OES)) { // this is in fact an external texture, this becomes a no-op. @@ -1849,32 +1849,32 @@ void OpenGLDriver::setTextureData(GLTexture* t, // NOTE: GL_TEXTURE_2D_MULTISAMPLE is not allowed bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t); gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1); - assert(t->gl.target == GL_TEXTURE_2D); + assert_invariant(t->gl.target == GL_TEXTURE_2D); glTexSubImage2D(t->gl.target, GLint(level), GLint(xoffset), GLint(yoffset), width, height, glFormat, glType, p.buffer); break; case SamplerType::SAMPLER_3D: - assert(zoffset + depth <= std::max(1u, t->depth >> level)); + assert_invariant(zoffset + depth <= std::max(1u, t->depth >> level)); bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t); gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1); - assert(t->gl.target == GL_TEXTURE_3D); + assert_invariant(t->gl.target == GL_TEXTURE_3D); glTexSubImage3D(t->gl.target, GLint(level), GLint(xoffset), GLint(yoffset), GLint(zoffset), width, height, depth, glFormat, glType, p.buffer); break; case SamplerType::SAMPLER_2D_ARRAY: - assert(zoffset + depth <= t->depth); + assert_invariant(zoffset + depth <= t->depth); // NOTE: GL_TEXTURE_2D_MULTISAMPLE is not allowed bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t); gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1); - assert(t->gl.target == GL_TEXTURE_2D_ARRAY); + assert_invariant(t->gl.target == GL_TEXTURE_2D_ARRAY); glTexSubImage3D(t->gl.target, GLint(level), GLint(xoffset), GLint(yoffset), GLint(zoffset), width, height, depth, glFormat, glType, p.buffer); break; case SamplerType::SAMPLER_CUBEMAP: { - assert(t->gl.target == GL_TEXTURE_CUBE_MAP); + assert_invariant(t->gl.target == GL_TEXTURE_CUBE_MAP); bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t); gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1); FaceOffsets const& offsets = *faceOffsets; @@ -1913,10 +1913,10 @@ void OpenGLDriver::setCompressedTextureData(GLTexture* t, uint32_t level, DEBUG_MARKER() auto& gl = mContext; - assert(xoffset + width <= t->width >> level); - assert(yoffset + height <= t->height >> level); - assert(zoffset + depth <= t->depth); - assert(t->samples <= 1); + assert_invariant(xoffset + width <= t->width >> level); + assert_invariant(yoffset + height <= t->height >> level); + assert_invariant(zoffset + depth <= t->depth); + assert_invariant(t->samples <= 1); if (UTILS_UNLIKELY(t->gl.target == GL_TEXTURE_EXTERNAL_OES)) { // this is in fact an external texture, this becomes a no-op. @@ -1938,7 +1938,7 @@ void OpenGLDriver::setCompressedTextureData(GLTexture* t, uint32_t level, // NOTE: GL_TEXTURE_2D_MULTISAMPLE is not allowed bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t); gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1); - assert(t->gl.target == GL_TEXTURE_2D); + assert_invariant(t->gl.target == GL_TEXTURE_2D); glCompressedTexSubImage2D(t->gl.target, GLint(level), GLint(xoffset), GLint(yoffset), width, height, t->gl.internalFormat, imageSize, p.buffer); @@ -1946,20 +1946,20 @@ void OpenGLDriver::setCompressedTextureData(GLTexture* t, uint32_t level, case SamplerType::SAMPLER_3D: bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t); gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1); - assert(t->gl.target == GL_TEXTURE_3D); + assert_invariant(t->gl.target == GL_TEXTURE_3D); glCompressedTexSubImage3D(t->gl.target, GLint(level), GLint(xoffset), GLint(yoffset), GLint(zoffset), width, height, depth, t->gl.internalFormat, imageSize, p.buffer); break; case SamplerType::SAMPLER_2D_ARRAY: - assert(t->gl.target == GL_TEXTURE_2D_ARRAY); + assert_invariant(t->gl.target == GL_TEXTURE_2D_ARRAY); glCompressedTexSubImage3D(t->gl.target, GLint(level), GLint(xoffset), GLint(yoffset), GLint(zoffset), width, height, depth, t->gl.internalFormat, imageSize, p.buffer); break; case SamplerType::SAMPLER_CUBEMAP: { - assert(faceOffsets); - assert(t->gl.target == GL_TEXTURE_CUBE_MAP); + assert_invariant(faceOffsets); + assert_invariant(t->gl.target == GL_TEXTURE_CUBE_MAP); bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t); gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1); FaceOffsets const& offsets = *faceOffsets; @@ -2015,8 +2015,8 @@ void OpenGLDriver::setExternalTexture(GLTexture* t, void* image) { if (gl.ext.OES_EGL_image_external_essl3) { DEBUG_MARKER() - assert(t->target == SamplerType::SAMPLER_EXTERNAL); - assert(t->gl.target == GL_TEXTURE_EXTERNAL_OES); + assert_invariant(t->target == SamplerType::SAMPLER_EXTERNAL); + assert_invariant(t->gl.target == GL_TEXTURE_EXTERNAL_OES); bindTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1, t); gl.activeTexture(OpenGLContext::MAX_TEXTURE_UNIT_COUNT - 1); @@ -2061,7 +2061,7 @@ void OpenGLDriver::attachStream(GLTexture* t, GLStream* hwStream) noexcept { mPlatform.attach(hwStream->stream, t->gl.id); break; case StreamType::TEXTURE_ID: - assert(t->target == SamplerType::SAMPLER_EXTERNAL); + assert_invariant(t->target == SamplerType::SAMPLER_EXTERNAL); // The texture doesn't need a texture name anymore, get rid of it gl.unbindTexture(t->gl.target, t->gl.id); glDeleteTextures(1, &t->gl.id); @@ -2103,7 +2103,7 @@ void OpenGLDriver::detachStream(GLTexture* t) noexcept { UTILS_NOINLINE void OpenGLDriver::replaceStream(GLTexture* texture, GLStream* newStream) noexcept { - assert(newStream && "Do not use replaceStream to detach a stream."); + assert_invariant(newStream && "Do not use replaceStream to detach a stream."); // This could be implemented via detachStream + attachStream but inlining allows // a few small optimizations, like not touching the mExternalStreams list. @@ -2125,7 +2125,7 @@ void OpenGLDriver::replaceStream(GLTexture* texture, GLStream* newStream) noexce mPlatform.attach(newStream->stream, texture->gl.id); break; case StreamType::TEXTURE_ID: - assert(texture->target == SamplerType::SAMPLER_EXTERNAL); + assert_invariant(texture->target == SamplerType::SAMPLER_EXTERNAL); texture->gl.id = newStream->user_thread.read[newStream->user_thread.cur]; break; case StreamType::ACQUIRED: @@ -2255,7 +2255,7 @@ void OpenGLDriver::endRenderPass(int) { DEBUG_MARKER() auto& gl = mContext; - assert(mRenderPassTarget); // endRenderPass() called without beginRenderPass()? + assert_invariant(mRenderPassTarget); // endRenderPass() called without beginRenderPass()? GLRenderTarget const* const rt = handle_cast(mRenderPassTarget); @@ -2303,7 +2303,7 @@ void OpenGLDriver::nextSubpass(int) {} void OpenGLDriver::resolvePass(ResolveAction action, GLRenderTarget const* rt, backend::TargetBufferFlags discardFlags) noexcept { - assert(rt->gl.fbo_read); + assert_invariant(rt->gl.fbo_read); auto& gl = mContext; const TargetBufferFlags resolve = rt->gl.resolve & ~discardFlags; GLbitfield mask = getAttachmentBitfield(resolve); @@ -2328,7 +2328,7 @@ void OpenGLDriver::resolvePass(ResolveAction action, GLRenderTarget const* rt, GLsizei OpenGLDriver::getAttachments(std::array& attachments, GLRenderTarget const* rt, TargetBufferFlags buffers) noexcept { - assert(buffers <= rt->targets); + assert_invariant(buffers <= rt->targets); GLsizei attachmentCount = 0; // the default framebuffer uses different constants!!! @@ -2337,15 +2337,15 @@ GLsizei OpenGLDriver::getAttachments(std::array& attachments, attachments[attachmentCount++] = defaultFramebuffer ? GL_COLOR : GL_COLOR_ATTACHMENT0; } if (any(buffers & TargetBufferFlags::COLOR1)) { - assert(!defaultFramebuffer); + assert_invariant(!defaultFramebuffer); attachments[attachmentCount++] = GL_COLOR_ATTACHMENT1; } if (any(buffers & TargetBufferFlags::COLOR2)) { - assert(!defaultFramebuffer); + assert_invariant(!defaultFramebuffer); attachments[attachmentCount++] = GL_COLOR_ATTACHMENT2; } if (any(buffers & TargetBufferFlags::COLOR3)) { - assert(!defaultFramebuffer); + assert_invariant(!defaultFramebuffer); attachments[attachmentCount++] = GL_COLOR_ATTACHMENT3; } if (any(buffers & TargetBufferFlags::DEPTH)) { @@ -2368,7 +2368,7 @@ void OpenGLDriver::setRenderPrimitiveBuffer(Handle rph, GLVertexBuffer const* const eb = handle_cast(vbh); GLIndexBuffer const* const ib = handle_cast(ibh); - assert(ib->elementSize == 2 || ib->elementSize == 4); + assert_invariant(ib->elementSize == 2 || ib->elementSize == 4); gl.bindVertexArray(&rp->gl); CHECK_GL_ERROR(utils::slog.e) @@ -2378,7 +2378,7 @@ void OpenGLDriver::setRenderPrimitiveBuffer(Handle rph, for (size_t i = 0, n = eb->attributes.size(); i < n; i++) { if (enabledAttributes & (1U << i)) { uint8_t bi = eb->attributes[i].buffer; - assert(bi != 0xFF); + assert_invariant(bi != 0xFF); gl.bindBuffer(GL_ARRAY_BUFFER, eb->gl.buffers[bi]); if (UTILS_UNLIKELY(eb->attributes[i].flags & Attribute::FLAG_INTEGER_TARGET)) { @@ -2473,8 +2473,8 @@ void OpenGLDriver::updateStreamAcquired(GLTexture* gltexture, DriverApi* driver) SYSTRACE_CALL(); GLStream* glstream = static_cast(gltexture->hwStream); - assert(glstream); - assert(glstream->streamType == StreamType::ACQUIRED); + assert_invariant(glstream); + assert_invariant(glstream->streamType == StreamType::ACQUIRED); // If there's no pending image, do nothing. Note that GL_OES_EGL_image does not let you pass // NULL to glEGLImageTargetTexture2DOES, and there is no concept of "detaching" an EGLimage from @@ -2505,8 +2505,8 @@ void OpenGLDriver::updateStreamTexId(GLTexture* t, DriverApi* driver) noexcept { auto& gl = mContext; GLStream* s = static_cast(t->hwStream); - assert(s); - assert(s->streamType == StreamType::TEXTURE_ID); + assert_invariant(s); + assert_invariant(s->streamType == StreamType::TEXTURE_ID); // round-robin to the next texture name if (UTILS_UNLIKELY(DEBUG_NO_EXTERNAL_STREAM_COPY || @@ -2679,7 +2679,7 @@ void OpenGLDriver::bindUniformBuffer(size_t index, Handle ubh) DEBUG_MARKER() auto& gl = mContext; GLUniformBuffer* ub = handle_cast(ubh); - assert(ub->gl.ubo.base == 0); + assert_invariant(ub->gl.ubo.base == 0); gl.bindBufferRange(GL_UNIFORM_BUFFER, GLuint(index), ub->gl.ubo.id, 0, ub->gl.ubo.capacity); CHECK_GL_ERROR(utils::slog.e) } @@ -2691,8 +2691,8 @@ void OpenGLDriver::bindUniformBufferRange(size_t index, Handle GLUniformBuffer* ub = handle_cast(ubh); // TODO: Is this assert really needed? Note that size is only populated for STREAM buffers. - assert(size <= ub->gl.ubo.size); - assert(ub->gl.ubo.base + offset + size <= ub->gl.ubo.capacity); + assert_invariant(size <= ub->gl.ubo.size); + assert_invariant(ub->gl.ubo.base + offset + size <= ub->gl.ubo.capacity); gl.bindBufferRange(GL_UNIFORM_BUFFER, GLuint(index), ub->gl.ubo.id, ub->gl.ubo.base + offset, size); CHECK_GL_ERROR(utils::slog.e) } @@ -2701,14 +2701,14 @@ void OpenGLDriver::bindSamplers(size_t index, Handle sbh) { DEBUG_MARKER() GLSamplerGroup* sb = handle_cast(sbh); - assert(index < Program::SAMPLER_BINDING_COUNT); + assert_invariant(index < Program::SAMPLER_BINDING_COUNT); mSamplerBindings[index] = sb; CHECK_GL_ERROR(utils::slog.e) } GLuint OpenGLDriver::getSamplerSlow(SamplerParams params) const noexcept { - assert(mSamplerMap.find(params.u) == mSamplerMap.end()); + assert_invariant(mSamplerMap.find(params.u) == mSamplerMap.end()); GLuint s; glGenSamplers(1, &s); @@ -2918,9 +2918,9 @@ void OpenGLDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) { if (UTILS_UNLIKELY(!mExternalStreams.empty())) { OpenGLPlatform& platform = mPlatform; for (GLTexture const* t : mExternalStreams) { - assert(t && t->hwStream); + assert_invariant(t && t->hwStream); if (t->hwStream->streamType == StreamType::NATIVE) { - assert(t->hwStream->stream); + assert_invariant(t->hwStream->stream); platform.updateTexImage(t->hwStream->stream, &static_cast(t->hwStream)->user_thread.timestamp); // NOTE: We assume that updateTexImage() binds the texture on our behalf @@ -2966,7 +2966,7 @@ void OpenGLDriver::finish(int) { executeGpuCommandsCompleteOps(); executeEveryNowAndThenOps(); // Note: since we executed a glFinish(), all pending tasks should be done - assert(mGpuCommandCompleteOps.empty()); + assert_invariant(mGpuCommandCompleteOps.empty()); // however, some tasks rely on a separated thread to publish their result (e.g. // endTimerQuery), so the result could very well not be ready, and the task will @@ -3045,7 +3045,7 @@ void OpenGLDriver::blit(TargetBufferFlags buffers, // With GLES 3.x, GL_INVALID_OPERATION is generated if the value of GL_SAMPLE_BUFFERS // for the draw buffer is greater than zero. This works with OpenGL, so we want to // make sure to catch this scenario. - assert(d->gl.samples <= 1); + assert_invariant(d->gl.samples <= 1); // GL_INVALID_OPERATION is generated if GL_SAMPLE_BUFFERS for the read buffer is greater // than zero and the formats of draw and read buffers are not identical. @@ -3060,7 +3060,7 @@ void OpenGLDriver::blit(TargetBufferFlags buffers, // happens when blitting from an "implicit" resolve render target (does it work?), so // to ere on the safe side, we don't allow it. if (s->gl.samples > 1) { - assert(!memcmp(&dstRect, &srcRect, sizeof(srcRect))); + assert_invariant(!memcmp(&dstRect, &srcRect, sizeof(srcRect))); } gl.bindFramebuffer(GL_READ_FRAMEBUFFER, s->gl.fbo); diff --git a/filament/backend/src/opengl/OpenGLDriver.h b/filament/backend/src/opengl/OpenGLDriver.h index 8d9b51f3ab..1b306184f7 100644 --- a/filament/backend/src/opengl/OpenGLDriver.h +++ b/filament/backend/src/opengl/OpenGLDriver.h @@ -30,8 +30,6 @@ #include -#include - #ifndef FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB # define FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB 2 #endif @@ -289,12 +287,12 @@ private: std::is_pointer::value && std::is_base_of::type>::value, Dp>::type handle_cast(backend::Handle& handle) noexcept { - assert(handle); + assert_invariant(handle); if (!handle) return nullptr; // better to get a NPE than random behavior/corruption char* const base = (char *)mHandleArena.getArea().begin(); size_t offset = handle.getId() << HandleAllocator::MIN_ALIGNMENT_SHIFT; // assert that this handle is even a valid one - assert(base + offset + sizeof(typename std::remove_pointer::type) <= (char *)mHandleArena.getArea().end()); + assert_invariant(base + offset + sizeof(typename std::remove_pointer::type) <= (char *)mHandleArena.getArea().end()); return static_cast(static_cast(base + offset)); } @@ -359,9 +357,9 @@ private: GLuint getSamplerSlow(backend::SamplerParams sp) const noexcept; inline GLuint getSampler(backend::SamplerParams sp) const noexcept { - assert(!sp.padding0); - assert(!sp.padding1); - assert(!sp.padding2); + assert_invariant(!sp.padding0); + assert_invariant(!sp.padding1); + assert_invariant(!sp.padding2); auto& samplerMap = mSamplerMap; auto pos = samplerMap.find(sp.u); if (UTILS_UNLIKELY(pos == samplerMap.end())) { diff --git a/filament/backend/src/opengl/OpenGLProgram.cpp b/filament/backend/src/opengl/OpenGLProgram.cpp index 56215a6b4d..cebae2156f 100644 --- a/filament/backend/src/opengl/OpenGLProgram.cpp +++ b/filament/backend/src/opengl/OpenGLProgram.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -210,7 +211,7 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* gl) noexcept { SamplerGroup::Sampler const* const UTILS_RESTRICT samplers = sb.getSamplers(); for (uint8_t j = 0, m = blockInfo.count ; j <= m; ++j, ++tmu) { // "<=" on purpose here const uint8_t index = indicesRun[tmu]; - assert(index < sb.getSize()); + assert_invariant(index < sb.getSize()); Handle th = samplers[index].t; if (UTILS_UNLIKELY(!th)) { diff --git a/filament/backend/src/opengl/PlatformCocoaTouchGL.mm b/filament/backend/src/opengl/PlatformCocoaTouchGL.mm index 70f627e50b..2389446f9e 100644 --- a/filament/backend/src/opengl/PlatformCocoaTouchGL.mm +++ b/filament/backend/src/opengl/PlatformCocoaTouchGL.mm @@ -87,7 +87,7 @@ Driver* PlatformCocoaTouchGL::createDriver(void* const sharedGLContext) noexcept CVReturn success = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, nullptr, pImpl->mGLContext, nullptr, &pImpl->mTextureCache); - assert(success == kCVReturnSuccess); + assert_invariant(success == kCVReturnSuccess); pImpl->mExternalImageSharedGl = new CocoaTouchExternalImage::SharedGl(); diff --git a/filament/backend/src/opengl/PlatformEGL.cpp b/filament/backend/src/opengl/PlatformEGL.cpp index ba8c8d6d5f..cf925b7790 100644 --- a/filament/backend/src/opengl/PlatformEGL.cpp +++ b/filament/backend/src/opengl/PlatformEGL.cpp @@ -26,9 +26,6 @@ #include #include -#include - - using namespace utils; namespace filament { @@ -85,7 +82,7 @@ PlatformEGL::PlatformEGL() noexcept = default; Driver* PlatformEGL::createDriver(void* sharedContext) noexcept { mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - assert(mEGLDisplay != EGL_NO_DISPLAY); + assert_invariant(mEGLDisplay != EGL_NO_DISPLAY); EGLint major, minor; EGLBoolean initialized = eglInitialize(mEGLDisplay, &major, &minor); diff --git a/filament/backend/src/opengl/PlatformEGLAndroid.cpp b/filament/backend/src/opengl/PlatformEGLAndroid.cpp index 91cca947bd..c954e63913 100644 --- a/filament/backend/src/opengl/PlatformEGLAndroid.cpp +++ b/filament/backend/src/opengl/PlatformEGLAndroid.cpp @@ -33,8 +33,6 @@ #include -#include - #include diff --git a/filament/backend/src/opengl/TimerQuery.cpp b/filament/backend/src/opengl/TimerQuery.cpp index 0572ec4194..94be225fe2 100644 --- a/filament/backend/src/opengl/TimerQuery.cpp +++ b/filament/backend/src/opengl/TimerQuery.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace filament { @@ -125,7 +126,7 @@ void TimerQueryFence::flush() { } void TimerQueryFence::beginTimeElapsedQuery(GLTimerQuery* query) { - assert(!mActiveQuery); + assert_invariant(!mActiveQuery); // We can't use a fence to figure out when a GPU operation starts (only when it finishes) // so instead, we use when glFlush() was issued as a proxy. if (UTILS_UNLIKELY(!query->gl.emulation)) { @@ -137,7 +138,7 @@ void TimerQueryFence::beginTimeElapsedQuery(GLTimerQuery* query) { } void TimerQueryFence::endTimeElapsedQuery(GLTimerQuery* query) { - assert(mActiveQuery); + assert_invariant(mActiveQuery); Platform::Fence* fence = mPlatform.createFence(); std::weak_ptr weak = query->gl.emulation; mActiveQuery = nullptr; diff --git a/filament/backend/src/vulkan/VulkanBinder.cpp b/filament/backend/src/vulkan/VulkanBinder.cpp index 98432fa532..3393a03bb0 100644 --- a/filament/backend/src/vulkan/VulkanBinder.cpp +++ b/filament/backend/src/vulkan/VulkanBinder.cpp @@ -77,7 +77,7 @@ bool VulkanBinder::getOrCreateDescriptors(VkDescriptorSet descriptorSets[3], // If no bindings have been dirtied, update the timestamp (most recent access) and return false // to indicate there's no need to re-bind. if (!mDirtyDescriptor) { - assert(mCurrentDescriptorBundle && mCurrentDescriptorBundle->bound); + assert_invariant(mCurrentDescriptorBundle && mCurrentDescriptorBundle->bound); descriptorSets[0] = mCurrentDescriptorBundle->handles[0]; descriptorSets[1] = mCurrentDescriptorBundle->handles[1]; descriptorSets[2] = mCurrentDescriptorBundle->handles[2]; @@ -196,12 +196,12 @@ bool VulkanBinder::getOrCreatePipeline(VkPipeline* pipeline) noexcept { // If no bindings have been dirtied, update the timestamp (most recent access) and return false // to indicate there's no need to re-bind. if (!mDirtyPipeline) { - assert(mCurrentPipeline && mCurrentPipeline->bound); + assert_invariant(mCurrentPipeline && mCurrentPipeline->bound); *pipeline = mCurrentPipeline->handle; mCurrentPipeline->timestamp = mCurrentTime; return false; } - assert(mPipelineKey.shaders[0] && "Vertex shader is not bound."); + assert_invariant(mPipelineKey.shaders[0] && "Vertex shader is not bound."); // Release the previously bound pipeline and update its time stamp. if (mCurrentPipeline) { diff --git a/filament/backend/src/vulkan/VulkanBlitter.cpp b/filament/backend/src/vulkan/VulkanBlitter.cpp index 2fa77a60c7..ff86b86779 100644 --- a/filament/backend/src/vulkan/VulkanBlitter.cpp +++ b/filament/backend/src/vulkan/VulkanBlitter.cpp @@ -106,7 +106,7 @@ void VulkanBlitter::blitFast(VkImageAspectFlags aspect, VkFilter filter, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst.level, 1, 1, aspect); if (src.texture && src.texture->samples > 1 && dst.texture && dst.texture->samples == 1) { - assert(aspect != VK_IMAGE_ASPECT_DEPTH_BIT && "Resolve with depth is not yet supported."); + assert_invariant(aspect != VK_IMAGE_ASPECT_DEPTH_BIT && "Resolve with depth is not yet supported."); vkCmdResolveImage(cmdbuffer, src.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, resolveRegions); } else { @@ -144,7 +144,7 @@ void VulkanBlitter::lazyInit() noexcept { if (mVertex) { return; } - assert(mContext.device); + assert_invariant(mContext.device); VkShaderModuleCreateInfo moduleInfo = {}; moduleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; diff --git a/filament/backend/src/vulkan/VulkanBuffer.cpp b/filament/backend/src/vulkan/VulkanBuffer.cpp index 3213246886..a738a12b46 100644 --- a/filament/backend/src/vulkan/VulkanBuffer.cpp +++ b/filament/backend/src/vulkan/VulkanBuffer.cpp @@ -44,7 +44,7 @@ VulkanBuffer::~VulkanBuffer() { } void VulkanBuffer::loadFromCpu(const void* cpuData, uint32_t byteOffset, uint32_t numBytes) { - assert(byteOffset == 0); + assert_invariant(byteOffset == 0); VulkanStage const* stage = mStagePool.acquireStage(numBytes); void* mapped; vmaMapMemory(mContext.allocator, stage->memory, &mapped); diff --git a/filament/backend/src/vulkan/VulkanContext.cpp b/filament/backend/src/vulkan/VulkanContext.cpp index 4178376978..d2e5b751d1 100644 --- a/filament/backend/src/vulkan/VulkanContext.cpp +++ b/filament/backend/src/vulkan/VulkanContext.cpp @@ -596,7 +596,7 @@ void waitForIdle(VulkanContext& context) { uint32_t nfences = 0; auto& surfaceContext = *context.currentSurface; for (auto& swapContext : surfaceContext.swapContexts) { - assert(nfences < 4); + assert_invariant(nfences < 4); if (swapContext.commands.fence && swapContext.commands.fence->submitted) { fences[nfences++] = swapContext.commands.fence->fence; swapContext.commands.fence->submitted = false; @@ -638,7 +638,7 @@ bool acquireSwapCommandBuffer(VulkanContext& context) { return false; } - assert(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR); + assert_invariant(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR); } SwapContext& swap = getSwapContext(context); @@ -767,7 +767,7 @@ void createFinalDepthBuffer(VulkanContext& context, VulkanSurfaceContext& surfac .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, }; VkResult error = vkCreateImage(context.device, &imageInfo, VKALLOC, &depthImage); - assert(!error && "Unable to create depth image."); + assert_invariant(!error && "Unable to create depth image."); // Allocate memory for the VkImage and bind it. VkMemoryRequirements memReqs; @@ -780,9 +780,9 @@ void createFinalDepthBuffer(VulkanContext& context, VulkanSurfaceContext& surfac }; error = vkAllocateMemory(context.device, &allocInfo, nullptr, &surfaceContext.depth.memory); - assert(!error && "Unable to allocate depth memory."); + assert_invariant(!error && "Unable to allocate depth memory."); error = vkBindImageMemory(context.device, depthImage, surfaceContext.depth.memory, 0); - assert(!error && "Unable to bind depth memory."); + assert_invariant(!error && "Unable to bind depth memory."); // Create a VkImageView so that we can attach depth to the framebuffer. VkImageView depthView; @@ -798,7 +798,7 @@ void createFinalDepthBuffer(VulkanContext& context, VulkanSurfaceContext& surfac }, }; error = vkCreateImageView(context.device, &viewInfo, VKALLOC, &depthView); - assert(!error && "Unable to create depth view."); + assert_invariant(!error && "Unable to create depth view."); // Unlike the color attachments (which are double-buffered or triple-buffered), we only need one // depth attachment in the entire chain. diff --git a/filament/backend/src/vulkan/VulkanDisposer.cpp b/filament/backend/src/vulkan/VulkanDisposer.cpp index 7ea60d24f1..d312db02f6 100644 --- a/filament/backend/src/vulkan/VulkanDisposer.cpp +++ b/filament/backend/src/vulkan/VulkanDisposer.cpp @@ -16,6 +16,8 @@ #include "vulkan/VulkanDisposer.h" +#include + namespace filament { namespace backend { @@ -24,12 +26,12 @@ void VulkanDisposer::createDisposable(Key resource, std::function destru } void VulkanDisposer::addReference(Key resource) noexcept { - assert(mDisposables[resource].refcount > 0); + assert_invariant(mDisposables[resource].refcount > 0); ++mDisposables[resource].refcount; } void VulkanDisposer::removeReference(Key resource) noexcept { - assert(mDisposables[resource].refcount > 0); + assert_invariant(mDisposables[resource].refcount > 0); if (--mDisposables[resource].refcount == 0) { mGraveyard.emplace_back(std::move(mDisposables[resource])); mDisposables.erase(resource); @@ -62,7 +64,7 @@ void VulkanDisposer::gc() noexcept { void VulkanDisposer::reset() noexcept { gc(); - assert(mDisposables.empty()); + assert_invariant(mDisposables.empty()); } } // namespace filament diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 7afe88ca0f..cef43fe4b4 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -239,7 +239,7 @@ VulkanDriver::~VulkanDriver() noexcept = default; UTILS_NOINLINE Driver* VulkanDriver::create(VulkanPlatform* const platform, const char* const* ppEnabledExtensions, uint32_t enabledExtensionCount) noexcept { - assert(platform); + assert_invariant(platform); return new VulkanDriver(platform, ppEnabledExtensions, enabledExtensionCount); } @@ -568,7 +568,7 @@ void VulkanDriver::destroyRenderTarget(Handle rth) { void VulkanDriver::createFenceR(Handle fh, int) { // We prefer the fence to be created inside a frame, otherwise there's no command buffer. - assert(mContext.currentCommands != nullptr && "Fences should be created within a frame."); + assert_invariant(mContext.currentCommands != nullptr && "Fences should be created within a frame."); // As a fallback in release builds, trigger the fence based on the work command buffer. if (mContext.currentCommands == nullptr) { @@ -596,7 +596,7 @@ void VulkanDriver::createSwapChainR(Handle sch, void* nativeWindow, void VulkanDriver::createSwapChainHeadlessR(Handle sch, uint32_t width, uint32_t height, uint64_t flags) { - assert(width > 0 && height > 0 && "Vulkan requires non-zero swap chain dimensions."); + assert_invariant(width > 0 && height > 0 && "Vulkan requires non-zero swap chain dimensions."); auto* swapChain = construct_handle(mHandleMap, sch, mContext, width, height); mContext.currentSurface = &swapChain->surfaceContext; } @@ -762,7 +762,7 @@ FenceStatus VulkanDriver::wait(Handle fh, uint64_t timeout) { std::unique_lock lock(cmdfence->mutex); if (!cmdfence->submitted) { cmdfence->condition.wait(lock); - assert(cmdfence->submitted); + assert_invariant(cmdfence->submitted); } else { lock.unlock(); } @@ -776,7 +776,7 @@ FenceStatus VulkanDriver::wait(Handle fh, uint64_t timeout) { // We create all textures using VK_IMAGE_TILING_OPTIMAL, so our definition of "supported" is that // the GPU supports the given texture format with non-zero optimal tiling features. bool VulkanDriver::isTextureFormatSupported(TextureFormat format) { - assert(mContext.physicalDevice); + assert_invariant(mContext.physicalDevice); VkFormat vkformat = getVkFormat(format); // We automatically use an alternative format when the client requests DEPTH24. if (format == TextureFormat::DEPTH24) { @@ -804,7 +804,7 @@ bool VulkanDriver::isTextureFormatMipmappable(backend::TextureFormat format) { } bool VulkanDriver::isRenderTargetFormatSupported(TextureFormat format) { - assert(mContext.physicalDevice); + assert_invariant(mContext.physicalDevice); VkFormat vkformat = getVkFormat(format); // We automatically use an alternative format when the client requests DEPTH24. if (format == TextureFormat::DEPTH24) { @@ -852,7 +852,7 @@ void VulkanDriver::updateIndexBuffer(Handle ibh, BufferDescriptor void VulkanDriver::update2DImage(Handle th, uint32_t level, uint32_t xoffset, uint32_t yoffset, uint32_t width, uint32_t height, PixelBufferDescriptor&& data) { - assert(xoffset == 0 && yoffset == 0 && "Offsets not yet supported."); + assert_invariant(xoffset == 0 && yoffset == 0 && "Offsets not yet supported."); handle_cast(mHandleMap, th)->update2DImage(data, width, height, level); scheduleDestroy(std::move(data)); } @@ -866,7 +866,7 @@ void VulkanDriver::update3DImage( uint32_t level, uint32_t xoffset, uint32_t yoffset, uint32_t zoffset, uint32_t width, uint32_t height, uint32_t depth, PixelBufferDescriptor&& data) { - assert(xoffset == 0 && yoffset == 0 && zoffset == 0 && "Offsets not yet supported."); + assert_invariant(xoffset == 0 && yoffset == 0 && zoffset == 0 && "Offsets not yet supported."); handle_cast(mHandleMap, th)->update3DImage(data, width, height, depth, level); scheduleDestroy(std::move(data)); } @@ -974,14 +974,14 @@ void VulkanDriver::updateSamplerGroup(Handle sbh, } void VulkanDriver::beginRenderPass(Handle rth, const RenderPassParams& params) { - assert(mContext.currentCommands); - assert(mContext.currentSurface); + assert_invariant(mContext.currentCommands); + assert_invariant(mContext.currentSurface); VulkanSurfaceContext& surface = *mContext.currentSurface; mCurrentRenderTarget = handle_cast(mHandleMap, rth); VulkanRenderTarget* rt = mCurrentRenderTarget; const VkExtent2D extent = rt->getExtent(); - assert(extent.width > 0 && extent.height > 0); + assert_invariant(extent.width > 0 && extent.height > 0); const VulkanAttachment depth = rt->getDepth(); @@ -1030,20 +1030,20 @@ void VulkanDriver::beginRenderPass(Handle rth, const RenderPassP } else if (fbkey.samples == 1) { fbkey.color[i] = rt->getColor(i).view; fbkey.resolve[i] = VK_NULL_HANDLE; - assert(fbkey.color[i]); + assert_invariant(fbkey.color[i]); } else { fbkey.color[i] = rt->getMsaaColor(i).view; VulkanTexture* texture = rt->getColor(i).texture; if (texture && texture->samples == 1) { fbkey.resolve[i] = rt->getColor(i).view; - assert(fbkey.resolve[i]); + assert_invariant(fbkey.resolve[i]); } - assert(fbkey.color[i]); + assert_invariant(fbkey.color[i]); } } if (depth.format != VK_FORMAT_UNDEFINED) { fbkey.depth = rpkey.samples == 1 ? depth.view : rt->getMsaaDepth().view; - assert(fbkey.depth); + assert_invariant(fbkey.depth); } VkFramebuffer vkfb = mFramebufferCache.getFramebuffer(fbkey); @@ -1118,9 +1118,9 @@ void VulkanDriver::beginRenderPass(Handle rth, const RenderPassP } void VulkanDriver::endRenderPass(int) { - assert(mContext.currentCommands); - assert(mContext.currentSurface); - assert(mCurrentRenderTarget); + assert_invariant(mContext.currentCommands); + assert_invariant(mContext.currentSurface); + assert_invariant(mCurrentRenderTarget); vkCmdEndRenderPass(mContext.currentCommands->cmdbuffer); mCurrentRenderTarget = VK_NULL_HANDLE; if (mContext.currentRenderPass.currentSubpass > 0) { @@ -1136,10 +1136,10 @@ void VulkanDriver::nextSubpass(int) { ASSERT_PRECONDITION(mContext.currentRenderPass.currentSubpass == 0, "Only two subpasses are currently supported."); - assert(mContext.currentCommands); - assert(mContext.currentSurface); - assert(mCurrentRenderTarget); - assert(mContext.currentRenderPass.subpassMask); + assert_invariant(mContext.currentCommands); + assert_invariant(mContext.currentSurface); + assert_invariant(mCurrentRenderTarget); + assert_invariant(mContext.currentRenderPass.subpassMask); vkCmdNextSubpass(mContext.currentCommands->cmdbuffer, VK_SUBPASS_CONTENTS_INLINE); @@ -1252,7 +1252,7 @@ void VulkanDriver::commit(Handle sch) { } // The surface can be "out of date" when it has been resized, which is not an error. - assert(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR || + assert_invariant(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR || result == VK_ERROR_OUT_OF_DATE_KHR); } @@ -1631,7 +1631,7 @@ void VulkanDriver::draw(PipelineState pipelineState, Handle r continue; } SamplerGroup* sb = vksb->sb.get(); - assert(sb->getSize() == samplerGroup.size()); + assert_invariant(sb->getSize() == samplerGroup.size()); size_t samplerIdx = 0; for (const auto& sampler : samplerGroup) { size_t bindingPoint = sampler.binding; @@ -1744,7 +1744,7 @@ void VulkanDriver::endTimerQuery(Handle tqh) { void VulkanDriver::refreshSwapChain() { VulkanSurfaceContext& surface = *mContext.currentSurface; - assert(!surface.headlessQueue && "Resizing headless swap chains is not supported."); + assert_invariant(!surface.headlessQueue && "Resizing headless swap chains is not supported."); backend::destroySwapChain(mContext, surface, mDisposer); createSwapChain(mContext, surface); @@ -1765,10 +1765,10 @@ void VulkanDriver::debugCommand(const char* methodName) { static bool inRenderPass = false; // for debug only const utils::StaticString command = utils::StaticString::make(methodName, strlen(methodName)); if (command == BEGIN_COMMAND) { - assert(!inRenderPass); + assert_invariant(!inRenderPass); inRenderPass = true; } else if (command == END_COMMAND) { - assert(inRenderPass); + assert_invariant(inRenderPass); inRenderPass = false; } else if (inRenderPass && OUTSIDE_COMMANDS.find(command) != OUTSIDE_COMMANDS.end()) { utils::slog.e << command.c_str() << " issued inside a render pass." << utils::io::endl; diff --git a/filament/backend/src/vulkan/VulkanDriver.h b/filament/backend/src/vulkan/VulkanDriver.h index 65a517fac5..ba765fa647 100644 --- a/filament/backend/src/vulkan/VulkanDriver.h +++ b/filament/backend/src/vulkan/VulkanDriver.h @@ -98,37 +98,37 @@ private: template Dp* handle_cast(HandleMap& handleMap, Handle handle) noexcept { - assert(handle); + assert_invariant(handle); if (!handle) return nullptr; // better to get a NPE than random behavior/corruption std::lock_guard lock(mHandleMapMutex); auto iter = handleMap.find(handle.getId()); - assert(iter != handleMap.end()); + assert_invariant(iter != handleMap.end()); Blob& blob = iter->second; - assert(blob.size() == sizeof(Dp)); + assert_invariant(blob.size() == sizeof(Dp)); return reinterpret_cast(blob.data()); } template const Dp* handle_const_cast(HandleMap& handleMap, const Handle& handle) noexcept { - assert(handle); + assert_invariant(handle); if (!handle) return nullptr; // better to get a NPE than random behavior/corruption std::lock_guard lock(mHandleMapMutex); auto iter = handleMap.find(handle.getId()); - assert(iter != handleMap.end()); + assert_invariant(iter != handleMap.end()); Blob& blob = iter->second; - assert(blob.size() == sizeof(Dp)); + assert_invariant(blob.size() == sizeof(Dp)); return reinterpret_cast(blob.data()); } template Dp* construct_handle(HandleMap& handleMap, Handle& handle, ARGS&& ... args) noexcept { - assert(handle); + assert_invariant(handle); if (!handle) return nullptr; // better to get a NPE than random behavior/corruption std::lock_guard lock(mHandleMapMutex); auto iter = handleMap.find(handle.getId()); - assert(iter != handleMap.end()); + assert_invariant(iter != handleMap.end()); Blob& blob = iter->second; - assert(blob.size() == sizeof(Dp)); + assert_invariant(blob.size() == sizeof(Dp)); Dp* addr = reinterpret_cast(blob.data()); new(addr) Dp(std::forward(args)...); return addr; @@ -139,9 +139,9 @@ private: std::lock_guard lock(mHandleMapMutex); // Call the destructor, remove the blob, don't bother reclaiming the integer id. auto iter = handleMap.find(handle.getId()); - assert(iter != handleMap.end()); + assert_invariant(iter != handleMap.end()); Blob& blob = iter->second; - assert(blob.size() == sizeof(Dp)); + assert_invariant(blob.size() == sizeof(Dp)); reinterpret_cast(blob.data())->~Dp(); handleMap.erase(handle.getId()); } diff --git a/filament/backend/src/vulkan/VulkanFboCache.cpp b/filament/backend/src/vulkan/VulkanFboCache.cpp index de599883eb..07afa3fe2c 100644 --- a/filament/backend/src/vulkan/VulkanFboCache.cpp +++ b/filament/backend/src/vulkan/VulkanFboCache.cpp @@ -228,7 +228,7 @@ VkRenderPass VulkanFboCache::getRenderPass(RenderPassKey config) noexcept { // If there are subpasses, we require the input attachment to be the first attachment. // Breaking this assumption would likely require enhancements to the Driver API in order // to supply Vulkan with all the information needed. - assert(config.subpassMask == 1); + assert_invariant(config.subpassMask == 1); if (config.subpassMask & (1 << i)) { index = subpasses[0].colorAttachmentCount++; diff --git a/filament/backend/src/vulkan/VulkanHandles.cpp b/filament/backend/src/vulkan/VulkanHandles.cpp index 6435ddc34e..d8407f8144 100644 --- a/filament/backend/src/vulkan/VulkanHandles.cpp +++ b/filament/backend/src/vulkan/VulkanHandles.cpp @@ -245,8 +245,8 @@ VulkanSwapChain::VulkanSwapChain(VulkanContext& context, uint32_t width, uint32_ .tiling = VK_IMAGE_TILING_OPTIMAL, .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, }; - assert(iCreateInfo.extent.width > 0); - assert(iCreateInfo.extent.height > 0); + assert_invariant(iCreateInfo.extent.width > 0); + assert_invariant(iCreateInfo.extent.height > 0); vkCreateImage(context.device, &iCreateInfo, VKALLOC, &image); VkMemoryRequirements memReqs = {}; @@ -638,7 +638,7 @@ void VulkanTexture::update2DImage(const PixelBufferDescriptor& data, uint32_t wi void VulkanTexture::update3DImage(const PixelBufferDescriptor& data, uint32_t width, uint32_t height, uint32_t depth, int miplevel) { - assert(width <= this->width && height <= this->height && depth <= this->depth); + assert_invariant(width <= this->width && height <= this->height && depth <= this->depth); const uint32_t srcBytesPerTexel = getBytesPerPixel(format); const bool reshape = srcBytesPerTexel == 3 || srcBytesPerTexel == 6; const void* cpuData = data.buffer; @@ -690,7 +690,7 @@ void VulkanTexture::update3DImage(const PixelBufferDescriptor& data, uint32_t wi void VulkanTexture::updateCubeImage(const PixelBufferDescriptor& data, const FaceOffsets& faceOffsets, int miplevel) { - assert(this->target == SamplerType::SAMPLER_CUBEMAP); + assert_invariant(this->target == SamplerType::SAMPLER_CUBEMAP); const bool reshape = getBytesPerPixel(format) == 3; const void* cpuData = data.buffer; const uint32_t numSrcBytes = data.size; @@ -824,7 +824,7 @@ void VulkanTexture::copyBufferToImage(VkCommandBuffer cmd, VkBuffer buffer, VkIm uint32_t width, uint32_t height, uint32_t depth, FaceOffsets const* faceOffsets, uint32_t miplevel) { VkExtent3D extent { width, height, depth }; if (target == SamplerType::SAMPLER_CUBEMAP) { - assert(faceOffsets); + assert_invariant(faceOffsets); VkBufferImageCopy regions[6] = {{}}; for (size_t face = 0; face < 6; face++) { auto& region = regions[face]; @@ -882,7 +882,7 @@ void VulkanRenderPrimitive::setBuffers(VulkanVertexBuffer* vertexBuffer, memset(varray.buffers, 0, sizeof(varray.buffers)); // Position should always be present. - assert(enabledAttributes & 1); + assert_invariant(enabledAttributes & 1); // For each enabled attribute, append to each of the above lists. Note that a single VkBuffer // handle might be appended more than once, which is perfectly fine. @@ -930,7 +930,7 @@ VulkanTimerQuery::VulkanTimerQuery(VulkanContext& context) : mContext(context) { std::unique_lock lock(context.timestamps.mutex); utils::bitset32& bitset = context.timestamps.used; const size_t maxTimers = bitset.size(); - assert(bitset.count() < maxTimers); + assert_invariant(bitset.count() < maxTimers); for (size_t timerIndex = 0; timerIndex < maxTimers; ++timerIndex) { if (!bitset.test(timerIndex)) { bitset.set(timerIndex); diff --git a/filament/backend/src/vulkan/VulkanStagePool.cpp b/filament/backend/src/vulkan/VulkanStagePool.cpp index aae79b4df8..ded0aa7e16 100644 --- a/filament/backend/src/vulkan/VulkanStagePool.cpp +++ b/filament/backend/src/vulkan/VulkanStagePool.cpp @@ -93,7 +93,7 @@ void VulkanStagePool::gc() noexcept { } void VulkanStagePool::reset() noexcept { - assert(mUsedStages.empty()); + assert_invariant(mUsedStages.empty()); for (auto pair : mFreeStages) { vmaDestroyBuffer(mContext.allocator, pair.second->buffer, pair.second->memory); delete pair.second; diff --git a/filament/backend/src/vulkan/VulkanUtility.cpp b/filament/backend/src/vulkan/VulkanUtility.cpp index 93c5788ef2..6981875292 100644 --- a/filament/backend/src/vulkan/VulkanUtility.cpp +++ b/filament/backend/src/vulkan/VulkanUtility.cpp @@ -17,6 +17,7 @@ #include "VulkanUtility.h" #include +#include #include "private/backend/BackendUtils.h" @@ -374,7 +375,7 @@ PixelDataType getComponentType(VkFormat format) { case VK_FORMAT_R32G32B32A32_UINT: return PixelDataType::UINT; case VK_FORMAT_R32G32B32A32_SINT: return PixelDataType::INT; case VK_FORMAT_R32G32B32A32_SFLOAT: return PixelDataType::FLOAT; - default: assert(false && "Unknown data type, conversion is not supported."); + default: assert_invariant(false && "Unknown data type, conversion is not supported."); } return {}; } diff --git a/filament/backend/test/BackendTest.cpp b/filament/backend/test/BackendTest.cpp index b7c96b10b9..67fafe5a0a 100644 --- a/filament/backend/test/BackendTest.cpp +++ b/filament/backend/test/BackendTest.cpp @@ -53,7 +53,7 @@ BackendTest::~BackendTest() { void BackendTest::initializeDriver() { auto backend = static_cast(sBackend); DefaultPlatform* platform = DefaultPlatform::create(&backend); - assert(static_cast(backend) == static_cast(sBackend)); + assert_invariant(static_cast(backend) == static_cast(sBackend)); driver = platform->createDriver(nullptr); commandStream = CommandStream(*driver, commandBufferQueue.getCircularBuffer()); } diff --git a/filament/backend/test/ShaderGenerator.cpp b/filament/backend/test/ShaderGenerator.cpp index 96e8228daa..2d97cf42bc 100644 --- a/filament/backend/test/ShaderGenerator.cpp +++ b/filament/backend/test/ShaderGenerator.cpp @@ -128,14 +128,14 @@ ShaderGenerator::Blob ShaderGenerator::transpileShader(Backend backend, bool isM std::cerr << "ERROR: Unable to parse " << (stage == ShaderStage::VERTEX ? "vertex" : "fragment") << " shader:" << std::endl; std::cerr << tShader.getInfoLog() << std::endl; - assert(false); + assert_invariant(false); } program.addShader(&tShader); bool linkOk = program.link(msg); if (!linkOk) { std::cerr << tShader.getInfoLog() << std::endl; - assert(false); + assert_invariant(false); } SpirvBlob spirv; @@ -144,7 +144,7 @@ ShaderGenerator::Blob ShaderGenerator::transpileShader(Backend backend, bool isM std::string result; - assert(backend == Backend::OPENGL || + assert_invariant(backend == Backend::OPENGL || backend == Backend::METAL || backend == Backend::VULKAN); diff --git a/filament/backend/test/test_ReadPixels.cpp b/filament/backend/test/test_ReadPixels.cpp index dafcd8c4e3..b3b0d70703 100644 --- a/filament/backend/test/test_ReadPixels.cpp +++ b/filament/backend/test/test_ReadPixels.cpp @@ -278,7 +278,7 @@ TEST_F(BackendTest, ReadPixels) { t.alignment, t.left, t.top, t.getPixelBufferStride(), [](void* buffer, size_t size, void* user) { const TestCase* test = (const TestCase*) user; - assert(test); + assert_invariant(test); test->exportScreenshot(buffer); diff --git a/filament/src/ColorGrading.cpp b/filament/src/ColorGrading.cpp index ecabd3d646..95337a79a7 100644 --- a/filament/src/ColorGrading.cpp +++ b/filament/src/ColorGrading.cpp @@ -470,7 +470,7 @@ FColorGrading::FColorGrading(FEngine& engine, const Builder& builder) { PixelDataFormat format; PixelDataType type; selectLutTextureParams(builder->quality, textureFormat, format, type); - assert(FTexture::validatePixelFormatAndType(textureFormat, format, type)); + assert_invariant(FTexture::validatePixelFormatAndType(textureFormat, format, type)); void* converted = nullptr; if (type == PixelDataType::UINT_2_10_10_10_REV) { diff --git a/filament/src/Engine.cpp b/filament/src/Engine.cpp index ce9c41c9fb..1069154212 100644 --- a/filament/src/Engine.cpp +++ b/filament/src/Engine.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include @@ -796,7 +797,7 @@ bool FEngine::destroy(const FMaterial* ptr) { bool FEngine::destroy(const FMaterialInstance* ptr) { if (ptr == nullptr) return true; auto pos = mMaterialInstances.find(ptr->getMaterial()); - assert(pos != mMaterialInstances.cend()); + assert_invariant(pos != mMaterialInstances.cend()); if (pos != mMaterialInstances.cend()) { return terminateAndDestroy(ptr, pos->second); } diff --git a/filament/src/Fence.cpp b/filament/src/Fence.cpp index 87098f44d1..b4497d2365 100644 --- a/filament/src/Fence.cpp +++ b/filament/src/Fence.cpp @@ -21,6 +21,7 @@ #include #include +#include namespace filament { @@ -62,7 +63,7 @@ void FFence::terminate(FEngine& engine) noexcept { UTILS_NOINLINE FenceStatus FFence::waitAndDestroy(FFence* fence, Mode mode) noexcept { - assert(fence); + assert_invariant(fence); FenceStatus status = fence->wait(mode, FENCE_WAIT_FOR_EVER); fence->mEngine.destroy(fence); return status; diff --git a/filament/src/FrameInfo.h b/filament/src/FrameInfo.h index 37a0bb75de..97d871f66f 100644 --- a/filament/src/FrameInfo.h +++ b/filament/src/FrameInfo.h @@ -24,7 +24,6 @@ #include #include -#include #include namespace filament { diff --git a/filament/src/FrameSkipper.cpp b/filament/src/FrameSkipper.cpp index 1be125454a..67468726ef 100644 --- a/filament/src/FrameSkipper.cpp +++ b/filament/src/FrameSkipper.cpp @@ -15,6 +15,8 @@ */ #include +#include + #include "details/FrameSkipper.h" #include "details/Engine.h" @@ -25,7 +27,7 @@ using namespace backend; FrameSkipper::FrameSkipper(FEngine& engine, size_t latency) noexcept : mEngine(engine), mLast(latency) { - assert(latency <= MAX_FRAME_LATENCY); + assert_invariant(latency <= MAX_FRAME_LATENCY); } FrameSkipper::~FrameSkipper() noexcept { diff --git a/filament/src/Froxelizer.cpp b/filament/src/Froxelizer.cpp index a54c660e6f..a5055e34dd 100644 --- a/filament/src/Froxelizer.cpp +++ b/filament/src/Froxelizer.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -179,10 +180,10 @@ bool Froxelizer::prepare( uint32_t(GROUP_COUNT) }; - assert(mFroxelBufferUser.begin()); - assert(mRecordBufferUser.begin()); - assert(mLightRecords.begin()); - assert(mFroxelShardedData.begin()); + assert_invariant(mFroxelBufferUser.begin()); + assert_invariant(mRecordBufferUser.begin()); + assert_invariant(mLightRecords.begin()); + assert_invariant(mFroxelShardedData.begin()); // initialize buffers that need to be memset(mLightRecords.data(), 0, mLightRecords.sizeInBytes()); @@ -218,9 +219,9 @@ void Froxelizer::computeFroxelLayout( froxelCountX = (width + froxelDimension - 1) / froxelDimension; froxelCountY = (height + froxelDimension - 1) / froxelDimension; - assert(froxelCountX); - assert(froxelCountY); - assert(froxelCountX * froxelCountY <= froxelPlaneCount); + assert_invariant(froxelCountX); + assert_invariant(froxelCountY); + assert_invariant(froxelCountX * froxelCountY <= froxelPlaneCount); *dim = froxelDimension; *countX = uint16_t(froxelCountX); @@ -287,10 +288,10 @@ bool Froxelizer::update() noexcept { mPlanesY = mArena.alloc(froxelCountY + 1); mBoundingSpheres = mArena.alloc(froxelCount); - assert(mDistancesZ); - assert(mPlanesX); - assert(mPlanesY); - assert(mBoundingSpheres); + assert_invariant(mDistancesZ); + assert_invariant(mPlanesX); + assert_invariant(mPlanesY); + assert_invariant(mBoundingSpheres); mDistancesZ[0] = 0.0f; const float zLightNear = mZLightNear; @@ -318,10 +319,10 @@ bool Froxelizer::update() noexcept { } if (UTILS_UNLIKELY(mDirtyFlags & (PROJECTION_CHANGED | VIEWPORT_CHANGED))) { - assert(mDistancesZ); - assert(mPlanesX); - assert(mPlanesY); - assert(mBoundingSpheres); + assert_invariant(mDistancesZ); + assert_invariant(mPlanesX); + assert_invariant(mPlanesY); + assert_invariant(mBoundingSpheres); // clip-space dimensions const float froxelWidthInClipSpace = (2.0f * mFroxelDimension.x) / mViewport.width; @@ -361,7 +362,7 @@ bool Froxelizer::update() noexcept { // n0.(n1 x n2) // use stack memory here, it's only 16 KiB max - assert(mFroxelCountX <= 2048); + assert_invariant(mFroxelCountX <= 2048); typename std::aligned_storage::type stack[2048]; float2* const UTILS_RESTRICT minMaxX = reinterpret_cast(stack); @@ -385,7 +386,7 @@ bool Froxelizer::update() noexcept { // the camera. minp.z = -planesZ[iz+1]; maxp.z = -planesZ[iz]; - assert(minp.z < maxp.z); + assert_invariant(minp.z < maxp.z); for (size_t ix = 0, nx = froxelCountX; ix < nx; ++ix) { // left, right planes for all froxels at ix @@ -401,7 +402,7 @@ bool Froxelizer::update() noexcept { minp.x = std::min(minp.x, px); maxp.x = std::max(maxp.x, px); } - assert(minp.x < maxp.x); + assert_invariant(minp.x < maxp.x); minMaxX[ix] = float2{ minp.x, maxp.x }; } @@ -419,11 +420,11 @@ bool Froxelizer::update() noexcept { minp.y = std::min(minp.y, py); maxp.y = std::max(maxp.y, py); } - assert(minp.y < maxp.y); + assert_invariant(minp.y < maxp.y); for (size_t ix = 0, nx = froxelCountX; ix < nx; ++ix) { // note: clang vectorizes this loop! - assert(getFroxelIndex(ix, iy, iz) == fi); + assert_invariant(getFroxelIndex(ix, iy, iz) == fi); minp.x = minMaxX[ix][0]; maxp.x = minMaxX[ix][1]; boundingSpheres[fi++] = { (maxp + minp) * 0.5f, length((maxp - minp) * 0.5f) }; @@ -461,15 +462,15 @@ bool Froxelizer::update() noexcept { } uniformsNeedUpdating = true; } - assert(mZLightNear >= mNear); + assert_invariant(mZLightNear >= mNear); mDirtyFlags = 0; return uniformsNeedUpdating; } Froxel Froxelizer::getFroxelAt(size_t x, size_t y, size_t z) const noexcept { - assert(x < mFroxelCountX); - assert(y < mFroxelCountY); - assert(z < mFroxelCountZ); + assert_invariant(x < mFroxelCountX); + assert_invariant(y < mFroxelCountY); + assert_invariant(z < mFroxelCountZ); Froxel froxel; froxel.planes[Froxel::LEFT] = mPlanesX[x]; froxel.planes[Froxel::BOTTOM] = mPlanesY[y]; @@ -539,13 +540,13 @@ void Froxelizer::froxelizeLights(FEngine& engine, // go through every lights for that froxel for (size_t i = 0; i < entry.count; i++) { // get the light index - assert(entry.offset + i < RECORD_BUFFER_ENTRY_COUNT); + assert_invariant(entry.offset + i < RECORD_BUFFER_ENTRY_COUNT); size_t lightIndex = recordBufferUser[entry.offset + i]; - assert(lightIndex <= CONFIG_MAX_LIGHT_INDEX); + assert_invariant(lightIndex <= CONFIG_MAX_LIGHT_INDEX); // make sure it corresponds to an existing light - assert(lightIndex < lightData.size() - FScene::DIRECTIONAL_LIGHTS_COUNT); + assert_invariant(lightIndex < lightData.size() - FScene::DIRECTIONAL_LIGHTS_COUNT); } } } @@ -585,7 +586,7 @@ void Froxelizer::froxelizeLoop(FEngine& engine, const size_t group = i % GROUP_COUNT; const size_t bit = i / GROUP_COUNT; - assert(bit < LIGHT_PER_GROUP); + assert_invariant(bit < LIGHT_PER_GROUP); FroxelThreadData& threadData = froxelThreadData[group]; froxelizePointAndSpotLight(threadData, bit, projection, light); @@ -780,9 +781,9 @@ void Froxelizer::froxelizePointAndSpotLight( const size_t y1 = imax.second; // y1 points to the last value const size_t z1 = findSliceZ(zfar); // z1 points to the last value - assert(x0 < x1); - assert(y0 <= y1); - assert(z0 <= z1); + assert_invariant(x0 < x1); + assert_invariant(y0 <= y1); + assert_invariant(z0 <= z1); #endif const size_t zcenter = findSliceZ(s.z); @@ -848,7 +849,7 @@ void Froxelizer::froxelizePointAndSpotLight( // the loops below assume 1-past the end for the right side of the range ex++; - assert(bx <= mFroxelCountX && ex <= mFroxelCountX); + assert_invariant(bx <= mFroxelCountX && ex <= mFroxelCountX); size_t fi = getFroxelIndex(bx, iy, iz); if (light.invSin != std::numeric_limits::infinity()) { diff --git a/filament/src/GPUBuffer.cpp b/filament/src/GPUBuffer.cpp index ce0eb2c215..36466531a5 100644 --- a/filament/src/GPUBuffer.cpp +++ b/filament/src/GPUBuffer.cpp @@ -17,6 +17,8 @@ #include "GPUBuffer.h" #include "private/backend/DriverApi.h" +#include + #include namespace filament { @@ -51,7 +53,7 @@ static backend::TextureFormat dataTypeToTextureFormat(GPUBuffer::Element element }; size_t index = size_t(element.type); - assert(index < 8 && element.size > 0 && element.size <= 4); + assert_invariant(index < 8 && element.size > 0 && element.size <= 4); return formats[index][element.size - 1]; } @@ -119,7 +121,7 @@ void GPUBuffer::terminate(backend::DriverApi& driverApi) noexcept { void GPUBuffer::commitSlow(backend::DriverApi& driverApi, void const* begin, void const* end) noexcept { const uintptr_t sizeInBytes = uintptr_t(end) - uintptr_t(begin); - assert(sizeInBytes <= mRowSizeInBytes * mHeight); + assert_invariant(sizeInBytes <= mRowSizeInBytes * mHeight); driverApi.update2DImage(mTexture, 0, 0, 0, mWidth, mHeight, { begin, sizeInBytes, mFormat, mType }); } diff --git a/filament/src/Material.cpp b/filament/src/Material.cpp index 991a296158..fdb61e9b60 100644 --- a/filament/src/Material.cpp +++ b/filament/src/Material.cpp @@ -68,7 +68,7 @@ static MaterialParser* createParser(Backend backend, const void* data, size_t si ASSERT_PRECONDITION(version == MATERIAL_VERSION, "Material version mismatch. Expected %d but " "received %d.", MATERIAL_VERSION, version); - assert(backend != Backend::DEFAULT && "Default backend has not been resolved."); + assert_invariant(backend != Backend::DEFAULT && "Default backend has not been resolved."); return materialParser; } @@ -150,7 +150,7 @@ static void addSamplerGroup(Program& pb, uint8_t bindingPoint, SamplerInterfaceB list[i].name.c_str())); uint8_t binding = 0; UTILS_UNUSED bool ok = map.getSamplerBinding(bindingPoint, (uint8_t)i, &binding); - assert(ok); + assert_invariant(ok); const bool strict = (bindingPoint == filament::BindingPoints::PER_MATERIAL_INSTANCE); samplers[i] = { std::move(uniformName), binding, strict }; } @@ -166,13 +166,13 @@ FMaterial::FMaterial(FEngine& engine, const Material::Builder& builder) mMaterialParser = parser; UTILS_UNUSED_IN_RELEASE bool nameOk = parser->getName(&mName); - assert(nameOk); + assert_invariant(nameOk); UTILS_UNUSED_IN_RELEASE bool sibOK = parser->getSIB(&mSamplerInterfaceBlock); - assert(sibOK); + assert_invariant(sibOK); UTILS_UNUSED_IN_RELEASE bool uibOK = parser->getUIB(&mUniformInterfaceBlock); - assert(uibOK); + assert_invariant(uibOK); // Older materials will not have a subpass chunk; this should not be an error. if (!parser->getSubpasses(&mSubpassInfo)) { @@ -358,9 +358,9 @@ Handle FMaterial::getSurfaceProgramSlow(uint8_t variantKey) const noexcept { // filterVariant() has already been applied in generateCommands(), shouldn't be needed here // if we're unlit, we don't have any bits that correspond to lit materials - assert( variantKey == Variant::filterVariant(variantKey, isVariantLit()) ); + assert_invariant( variantKey == Variant::filterVariant(variantKey, isVariantLit()) ); - assert(!Variant::isReserved(variantKey)); + assert_invariant(!Variant::isReserved(variantKey)); uint8_t vertexVariantKey = Variant::filterVariantVertex(variantKey); uint8_t fragmentVariantKey = Variant::filterVariantFragment(variantKey); @@ -442,7 +442,7 @@ Program FMaterial::getProgramBuilderWithVariants( Handle FMaterial::createAndCacheProgram(Program&& p, uint8_t variantKey) const noexcept { auto program = mEngine.getDriverApi().createProgram(std::move(p)); - assert(program); + assert_invariant(program); mCachedPrograms[variantKey] = program; return program; diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index 6fc13c513b..1c9c5e52b4 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -99,7 +99,7 @@ PostProcessManager::PostProcessMaterial& PostProcessManager::PostProcessMaterial } PostProcessManager::PostProcessMaterial::~PostProcessMaterial() { - assert(!mHasMaterial || mMaterial == nullptr); + assert_invariant(!mHasMaterial || mMaterial == nullptr); } void PostProcessManager::PostProcessMaterial::terminate(FEngine& engine) noexcept { @@ -181,7 +181,7 @@ void PostProcessManager::registerPostProcessMaterial(utils::StaticString name, u } PostProcessManager::PostProcessMaterial& PostProcessManager::getPostProcessMaterial(utils::StaticString name) noexcept { - assert(mMaterialRegistry.find(name) != mMaterialRegistry.end()); + assert_invariant(mMaterialRegistry.find(name) != mMaterialRegistry.end()); return mMaterialRegistry[name]; } @@ -294,7 +294,7 @@ FrameGraphId PostProcessManager::structure(FrameGraph& fg, // We limit the lowest lod size to 32 pixels (which is where the -5 comes from) const size_t levelCount = FTexture::maxLevelCount(width, height) - 5; - assert(levelCount >= 1); + assert_invariant(levelCount >= 1); // generate depth pass at the requested resolution auto& structurePass = fg.addPass("Structure Pass", @@ -380,7 +380,7 @@ FrameGraphId PostProcessManager::screenSpaceAmbientOcclusion( Handle fullScreenRenderPrimitive = engine.getFullScreenRenderPrimitive(); FrameGraphId depth = fg.getBlackboard().get("structure"); - assert(depth.isValid()); + assert_invariant(depth.isValid()); const size_t levelCount = fg.getDescriptor(depth).levels; @@ -603,7 +603,7 @@ FrameGraphId PostProcessManager::bilateralBlurPass( .width = desc.width, .height = desc.height, .format = format }); auto depth = fg.getBlackboard().get("structure"); - assert(depth.isValid()); + assert_invariant(depth.isValid()); builder.read(depth); // Here we use the depth test to skip pixels at infinity (i.e. the skybox) @@ -792,8 +792,8 @@ FrameGraphId PostProcessManager::gaussianBlurPass(FrameGraph& // vertical pass auto width = FTexture::valueForLevel(dstLevel, outDesc.width); auto height = FTexture::valueForLevel(dstLevel, outDesc.height); - assert(width == hwOutRT.params.viewport.width); - assert(height == hwOutRT.params.viewport.height); + assert_invariant(width == hwOutRT.params.viewport.width); + assert_invariant(height == hwOutRT.params.viewport.height); mi->setParameter("source", hwTemp, { .filterMag = SamplerMagFilter::LINEAR, @@ -850,7 +850,7 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, Blackboard& blackboard = fg.getBlackboard(); auto depth = blackboard.get("depth"); - assert(depth.isValid()); + assert_invariant(depth.isValid()); // the downsampled target is multiple of 8, so we can have 4 clean mipmap levels constexpr const uint32_t maxMipLevels = 4u; @@ -935,7 +935,7 @@ FrameGraphId PostProcessManager::dof(FrameGraph& fg, FrameGraphRenderTargetHandle rt[3]; }; - assert(mipmapCount - 1 + assert_invariant(mipmapCount - 1 <= sizeof(PostProcessDofMipmap::rt) / sizeof(FrameGraphRenderTargetHandle)); auto& ppDoFMipmap = fg.addPass("DoF Mipmap", @@ -1880,7 +1880,7 @@ FrameGraphId PostProcessManager::taa(FrameGraph& fg, Blackboard& blackboard = fg.getBlackboard(); auto depth = blackboard.get("depth"); - assert(depth.isValid()); + assert_invariant(depth.isValid()); struct TAAData { FrameGraphId color; @@ -2005,7 +2005,7 @@ FrameGraphId PostProcessManager::opaqueBlit(FrameGraph& fg, // we currently have no use for this case, so we just assert. This is better for now to trap // cases that we might not intend. - assert(inputDesc.samples <= 1); + assert_invariant(inputDesc.samples <= 1); // FIXME: here we use sample() instead of read() because this forces the // backend to use a texture (instead of a renderbuffer). We need this because @@ -2174,7 +2174,7 @@ FrameGraphId PostProcessManager::vsmMipmapPass(FrameGraph& fg auto width = resources.getDescriptor(data.in).width; UTILS_UNUSED_IN_RELEASE auto height = resources.getDescriptor(data.in).height; - assert(width == height); + assert_invariant(width == height); int dim = width >> (level + 1); driver.setMinMaxLevels(in, level, level); diff --git a/filament/src/RenderPass.cpp b/filament/src/RenderPass.cpp index 27c9aa607b..057920a229 100644 --- a/filament/src/RenderPass.cpp +++ b/filament/src/RenderPass.cpp @@ -90,7 +90,7 @@ RenderPass::Command* RenderPass::appendCommands(CommandTypeFlags const commandTy if (UTILS_UNLIKELY(vr.empty())) { return commands.end(); } - assert(mRenderableSoa); + assert_invariant(mRenderableSoa); // trace the number of visible renderables SYSTRACE_VALUE32("visibleRenderables", vr.size()); diff --git a/filament/src/RenderPass.h b/filament/src/RenderPass.h index fb86577557..39f788805d 100644 --- a/filament/src/RenderPass.h +++ b/filament/src/RenderPass.h @@ -29,6 +29,7 @@ #include #include +#include #include @@ -194,7 +195,7 @@ public: template static CommandKey makeField(T value, uint64_t mask, unsigned shift) noexcept { - assert(!((uint64_t(value) << shift) & ~mask)); + assert_invariant(!((uint64_t(value) << shift) & ~mask)); return uint64_t(value) << shift; } @@ -225,7 +226,7 @@ public: bool operator < (Command const& rhs) const noexcept { return key < rhs.key; } // placement new declared as "throw" to avoid the compiler's null-check inline void* operator new (std::size_t size, void* ptr) { - assert(ptr); + assert_invariant(ptr); return ptr; } }; diff --git a/filament/src/RenderPrimitive.cpp b/filament/src/RenderPrimitive.cpp index 7b4930b711..d628829505 100644 --- a/filament/src/RenderPrimitive.cpp +++ b/filament/src/RenderPrimitive.cpp @@ -21,12 +21,14 @@ #include "details/IndexBuffer.h" #include "details/Material.h" +#include + namespace filament { void FRenderPrimitive::init(backend::DriverApi& driver, const RenderableManager::Builder::Entry& entry) noexcept { - assert(entry.materialInstance); + assert_invariant(entry.materialInstance); mHandle = driver.createRenderPrimitive(); mMaterialInstance = upcast(entry.materialInstance); diff --git a/filament/src/Renderer.cpp b/filament/src/Renderer.cpp index 67fdc561b3..4e007cf318 100644 --- a/filament/src/Renderer.cpp +++ b/filament/src/Renderer.cpp @@ -39,8 +39,7 @@ #include #include #include - -#include +#include // this helps visualize what dynamic-scaling is doing #define DEBUG_DYNAMIC_SCALING false @@ -159,7 +158,7 @@ TextureFormat FRenderer::getLdrFormat(bool translucent) const noexcept { void FRenderer::render(FView const* view) { SYSTRACE_CALL(); - assert(mSwapChain); + assert_invariant(mSwapChain); if (mBeginFrameInternal) { mBeginFrameInternal(); @@ -696,7 +695,7 @@ FrameGraphId FRenderer::colorPass(FrameGraph& fg, const char* data.structure = blackboard.get("structure"); if (config.hasContactShadows) { - assert(data.structure.isValid()); + assert_invariant(data.structure.isValid()); data.structure = builder.sample(data.structure); } @@ -780,7 +779,7 @@ FrameGraphId FRenderer::colorPass(FrameGraph& fg, const char* view.prepareShadow(data.shadows.isValid() ? resources.getTexture(data.shadows) : ppm.getOneTextureArray()); - assert(data.structure.isValid()); + assert_invariant(data.structure.isValid()); if (data.structure.isValid()) { const auto& structure = resources.getTexture(data.structure); view.prepareStructure(structure ? structure : ppm.getOneTexture()); @@ -827,8 +826,8 @@ void FRenderer::copyFrame(FSwapChain* dstSwapChain, filament::Viewport const& ds filament::Viewport const& srcViewport, CopyFrameFlag flags) { SYSTRACE_CALL(); - assert(mSwapChain); - assert(dstSwapChain); + assert_invariant(mSwapChain); + assert_invariant(dstSwapChain); FEngine& engine = getEngine(); FEngine::DriverApi& driver = engine.getDriverApi(); @@ -853,7 +852,7 @@ void FRenderer::copyFrame(FSwapChain* dstSwapChain, filament::Viewport const& ds driver.beginRenderPass(mRenderTarget, params); // Verify that the source swap chain is readable. - assert(mSwapChain->isReadable()); + assert_invariant(mSwapChain->isReadable()); driver.blit(TargetBufferFlags::COLOR, mRenderTarget, dstViewport, mRenderTarget, srcViewport, SamplerMagFilter::LINEAR); if (flags & SET_PRESENTATION_TIME) { @@ -873,7 +872,7 @@ void FRenderer::copyFrame(FSwapChain* dstSwapChain, filament::Viewport const& ds bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeNano, backend::FrameScheduledCallback callback, void* user) { - assert(swapChain); + assert_invariant(swapChain); SYSTRACE_CALL(); diff --git a/filament/src/ResourceAllocator.cpp b/filament/src/ResourceAllocator.cpp index 36cbc12343..af743b58da 100644 --- a/filament/src/ResourceAllocator.cpp +++ b/filament/src/ResourceAllocator.cpp @@ -21,6 +21,7 @@ #include "details/Texture.h" #include +#include using namespace utils; @@ -82,12 +83,12 @@ ResourceAllocator::ResourceAllocator(DriverApi& driverApi) noexcept } ResourceAllocator::~ResourceAllocator() noexcept { - assert(!mTextureCache.size()); - assert(!mInUseTextures.size()); + assert_invariant(!mTextureCache.size()); + assert_invariant(!mInUseTextures.size()); } void ResourceAllocator::terminate() noexcept { - assert(!mInUseTextures.size()); + assert_invariant(!mInUseTextures.size()); auto& textureCache = mTextureCache; for (auto it = textureCache.begin(); it != textureCache.end();) { mBackend.destroyTexture(it->second.handle); @@ -156,7 +157,7 @@ void ResourceAllocator::destroyTexture(TextureHandle h) noexcept { if (mEnabled) { // find the texture in the in-use list (it must be there!) auto it = mInUseTextures.find(h); - assert(it != mInUseTextures.end()); + assert_invariant(it != mInUseTextures.end()); // move it to the cache const TextureKey key = it->second; diff --git a/filament/src/ShadowMap.cpp b/filament/src/ShadowMap.cpp index 43db58d960..36e1f9f666 100644 --- a/filament/src/ShadowMap.cpp +++ b/filament/src/ShadowMap.cpp @@ -26,6 +26,8 @@ #include +#include + #include using namespace filament::math; @@ -385,8 +387,8 @@ void ShadowMap::computeShadowCameraDirectional( return; } - assert(lsLightFrustumBounds.min.x < lsLightFrustumBounds.max.x); - assert(lsLightFrustumBounds.min.y < lsLightFrustumBounds.max.y); + assert_invariant(lsLightFrustumBounds.min.x < lsLightFrustumBounds.max.x); + assert_invariant(lsLightFrustumBounds.min.y < lsLightFrustumBounds.max.y); // compute focus scale and offset float2 s = 2.0f / float2(lsLightFrustumBounds.max.xy - lsLightFrustumBounds.min.xy); @@ -899,7 +901,7 @@ size_t ShadowMap::intersectFrustumWithBox( } } - assert(vertexCount <= outVertices.size()); + assert_invariant(vertexCount <= outVertices.size()); return vertexCount; } diff --git a/filament/src/ShadowMapManager.cpp b/filament/src/ShadowMapManager.cpp index 919139861e..c55dae6efa 100644 --- a/filament/src/ShadowMapManager.cpp +++ b/filament/src/ShadowMapManager.cpp @@ -23,6 +23,8 @@ #include +#include + namespace filament { using namespace backend; @@ -61,7 +63,7 @@ void ShadowMapManager::reset() noexcept { } void ShadowMapManager::setShadowCascades(size_t lightIndex, size_t cascades) noexcept { - assert(cascades <= CONFIG_MAX_SHADOW_CASCADES); + assert_invariant(cascades <= CONFIG_MAX_SHADOW_CASCADES); for (size_t c = 0; c < cascades; c++) { mCascadeShadowMaps.emplace_back(mCascadeShadowMapCache[c].get(), lightIndex); } @@ -69,7 +71,7 @@ void ShadowMapManager::setShadowCascades(size_t lightIndex, size_t cascades) noe void ShadowMapManager::addSpotShadowMap(size_t lightIndex) noexcept { const size_t maps = mSpotShadowMaps.size(); - assert(maps < CONFIG_MAX_SHADOW_CASTING_SPOTS); + assert_invariant(maps < CONFIG_MAX_SHADOW_CASTING_SPOTS); mSpotShadowMaps.emplace_back(mSpotShadowMapCache[maps].get(), lightIndex); } @@ -88,7 +90,7 @@ void ShadowMapManager::render(FrameGraph& fg, FEngine& engine, FView& view, passes.reserve(MAX_SHADOW_LAYERS); uint8_t layerSampleCount[MAX_SHADOW_LAYERS] = {}; - assert(mTextureRequirements.layers <= MAX_SHADOW_LAYERS); + assert_invariant(mTextureRequirements.layers <= MAX_SHADOW_LAYERS); // These loops fill render passes with appropriate rendering commands for each shadow map. // The actual render pass execution is deferred to the frame graph. @@ -99,11 +101,11 @@ void ShadowMapManager::render(FrameGraph& fg, FEngine& engine, FView& view, map.getShadowMap()->render(driver, view.getVisibleDirectionalShadowCasters(), pass, view); - assert(map.getLayout().layer < mTextureRequirements.layers); + assert_invariant(map.getLayout().layer < mTextureRequirements.layers); passes.emplace_back(&map, pass); const uint8_t layer = map.getLayout().layer; - assert(layer < MAX_SHADOW_LAYERS); + assert_invariant(layer < MAX_SHADOW_LAYERS); layerSampleCount[layer] = map.getLayout().vsmSamples; } for (size_t i = 0; i < mSpotShadowMaps.size(); i++) { @@ -116,14 +118,14 @@ void ShadowMapManager::render(FrameGraph& fg, FEngine& engine, FView& view, map.getShadowMap()->render(driver, view.getVisibleSpotShadowCasters(), pass, view); pass.clearVisibilityMask(); - assert(map.getLayout().layer < mTextureRequirements.layers); + assert_invariant(map.getLayout().layer < mTextureRequirements.layers); passes.emplace_back(&map, pass); const uint8_t layer = map.getLayout().layer; - assert(layer < MAX_SHADOW_LAYERS); + assert_invariant(layer < MAX_SHADOW_LAYERS); layerSampleCount[layer] = map.getLayout().vsmSamples; } - assert(passes.size() <= mTextureRequirements.layers); + assert_invariant(passes.size() <= mTextureRequirements.layers); const bool fillWithCheckerboard = engine.debug.shadowmap.checkerboard && !view.hasVsm(); @@ -229,7 +231,7 @@ void ShadowMapManager::render(FrameGraph& fg, FEngine& engine, FView& view, auto& debugPatternPass = fg.addPass("Shadow Debug Pattern Pass", [&](FrameGraph::Builder& builder, DebugPatternData& data) { - assert(shadows.isValid()); + assert_invariant(shadows.isValid()); data.shadows = builder.write(shadows); }, [=](FrameGraphPassResources const& resources, DebugPatternData const& data, @@ -380,7 +382,7 @@ ShadowMapManager::ShadowTechnique ShadowMapManager::updateCascadeShadowMaps( // Compute the frustum for the directional light. ShadowMap& shadowMap = *entry.getShadowMap(); UTILS_UNUSED_IN_RELEASE size_t l = entry.getLightIndex(); - assert(l == 0); + assert_invariant(l == 0); const size_t textureDimension = entry.getLayout().size; const ShadowMap::ShadowMapLayout layout{ diff --git a/filament/src/Texture.cpp b/filament/src/Texture.cpp index f535db4fef..f269e0ded5 100644 --- a/filament/src/Texture.cpp +++ b/filament/src/Texture.cpp @@ -97,7 +97,7 @@ Texture::Builder& Texture::Builder::usage(Texture::Usage usage) noexcept { } Texture::Builder& Texture::Builder::import(intptr_t id) noexcept { - assert(id); // imported id can't be zero + assert_invariant(id); // imported id can't be zero mImpl->mImportedId = id; return *this; } @@ -555,7 +555,7 @@ void FTexture::generatePrefilterMipmap(FEngine& engine, // this cannot happen due to the checks above break; } - assert(bytesPerPixel); + assert_invariant(bytesPerPixel); Image temp; Cubemap cml = CubemapUtils::create(temp, size); diff --git a/filament/src/UniformBuffer.h b/filament/src/UniformBuffer.h index aac566cdd3..3e057cd0ad 100644 --- a/filament/src/UniformBuffer.h +++ b/filament/src/UniformBuffer.h @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -31,8 +32,6 @@ #include #include -#include - namespace filament { @@ -68,7 +67,7 @@ public: // invalidate a range of uniforms and return a pointer to it. offset and size given in bytes void* invalidateUniforms(size_t offset, size_t size) { - assert(offset + size <= mSize); + assert_invariant(offset + size <= mSize); mSomethingDirty = true; return static_cast(mBuffer) + offset; } diff --git a/filament/src/View.cpp b/filament/src/View.cpp index 88332faa43..82d48fe736 100644 --- a/filament/src/View.cpp +++ b/filament/src/View.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -37,12 +38,12 @@ #include #include #include +#include #include #include #include -#include using namespace filament::math; using namespace utils; @@ -227,7 +228,7 @@ void FView::prepareShadowing(FEngine& engine, backend::DriverApi& driver, const bool hasDirectionalShadows = directionalLight && lcm.isShadowCaster(directionalLight); if (UTILS_UNLIKELY(hasDirectionalShadows)) { const auto& shadowOptions = lcm.getShadowOptions(directionalLight); - assert(shadowOptions.shadowCascades >= 1 && + assert_invariant(shadowOptions.shadowCascades >= 1 && shadowOptions.shadowCascades <= CONFIG_MAX_SHADOW_CASCADES); mShadowMapManager.setShadowCascades(0, shadowOptions.shadowCascades); } @@ -500,7 +501,7 @@ void FView::prepare(FEngine& engine, backend::DriverApi& driver, ArenaScope& are } else { // TODO: should we shrink the underlying UBO at some point? } - assert(mRenderableUbh); + assert_invariant(mRenderableUbh); scene->updateUBOs(merged, mRenderableUbh); } } @@ -806,7 +807,7 @@ void FView::prepareVisibleLights(FLightManager const& lcm, utils::JobSystem&, [](auto const& it) { return it.template get() != 0; }); - assert(visibleLightCount == size_t(last - lightData.begin())); + assert_invariant(visibleLightCount == size_t(last - lightData.begin())); lightData.resize(visibleLightCount); } diff --git a/filament/src/components/CameraManager.cpp b/filament/src/components/CameraManager.cpp index e809884c38..33bdc1bae8 100644 --- a/filament/src/components/CameraManager.cpp +++ b/filament/src/components/CameraManager.cpp @@ -21,6 +21,7 @@ #include #include +#include #include @@ -82,7 +83,7 @@ void FCameraManager::destroy(Entity e) noexcept { Instance i = manager.getInstance(e); if (i) { FCamera* camera = manager.elementAt(i); - assert(camera); + assert_invariant(camera); camera->terminate(mEngine); mEngine.getHeapAllocator().destroy(camera); manager.removeComponent(e); diff --git a/filament/src/components/LightManager.cpp b/filament/src/components/LightManager.cpp index 770f465664..7a8dc666e6 100644 --- a/filament/src/components/LightManager.cpp +++ b/filament/src/components/LightManager.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include using namespace filament::math; using namespace utils; @@ -148,7 +148,7 @@ FLightManager::FLightManager(FEngine& engine) noexcept : mEngine(engine) { FLightManager::~FLightManager() { // all components should have been destroyed when we get here // (terminate should have been called from Engine's shutdown()) - assert(mManager.getComponentCount() == 0); + assert_invariant(mManager.getComponentCount() == 0); } void FLightManager::init(FEngine& engine) noexcept { @@ -161,7 +161,7 @@ void FLightManager::create(const FLightManager::Builder& builder, utils::Entity destroy(entity); } Instance i = manager.addComponent(entity); - assert(i); + assert_invariant(i); if (i) { // This needs to happen before we call the set() methods below @@ -228,13 +228,13 @@ void FLightManager::terminate() noexcept { } void FLightManager::setLocalPosition(Instance i, const float3& position) noexcept { - assert(i); + assert_invariant(i); auto& manager = mManager; manager[i].position = position; } void FLightManager::setLocalDirection(Instance i, float3 direction) noexcept { - assert(i); + assert_invariant(i); auto& manager = mManager; manager[i].direction = direction; } @@ -264,7 +264,7 @@ void FLightManager::setIntensity(Instance i, float intensity, IntensityUnit unit // li = lp / (4 * pi) luminousIntensity = luminousPower * f::ONE_OVER_PI * 0.25f; } else { - assert(unit == IntensityUnit::CANDELA); + assert_invariant(unit == IntensityUnit::CANDELA); // intensity specified directly in candela, no conversion needed luminousIntensity = luminousPower; } @@ -277,7 +277,7 @@ void FLightManager::setIntensity(Instance i, float intensity, IntensityUnit unit // li = lp / (2 * pi * (1 - cos(cone_outer / 2))) luminousIntensity = luminousPower / (f::TAU * (1.0f - cosOuter)); } else { - assert(unit == IntensityUnit::CANDELA); + assert_invariant(unit == IntensityUnit::CANDELA); // intensity specified directly in candela, no conversion needed luminousIntensity = luminousPower; // lp = li * (2 * pi * (1 - cos(cone_outer / 2))) @@ -291,7 +291,7 @@ void FLightManager::setIntensity(Instance i, float intensity, IntensityUnit unit // li = lp / pi luminousIntensity = luminousPower * f::ONE_OVER_PI; } else { - assert(unit == IntensityUnit::CANDELA); + assert_invariant(unit == IntensityUnit::CANDELA); // intensity specified directly in candela, no conversion needed luminousIntensity = luminousPower; } diff --git a/filament/src/components/RenderableManager.cpp b/filament/src/components/RenderableManager.cpp index 36ee769d88..f971caf121 100644 --- a/filament/src/components/RenderableManager.cpp +++ b/filament/src/components/RenderableManager.cpp @@ -28,6 +28,7 @@ #include #include +#include using namespace filament::math; using namespace utils; @@ -60,7 +61,7 @@ struct RenderableManager::BuilderDetails { using BuilderType = RenderableManager; BuilderType::Builder::Builder(size_t count) noexcept : BuilderBase(count) { - assert(mImpl->mEntries.size() == count); + assert_invariant(mImpl->mEntries.size() == count); } BuilderType::Builder::~Builder() noexcept = default; BuilderType::Builder::Builder(BuilderType::Builder&& rhs) noexcept = default; @@ -250,7 +251,7 @@ FRenderableManager::FRenderableManager(FEngine& engine) noexcept : mEngine(engin FRenderableManager::~FRenderableManager() { // all components should have been destroyed when we get here // (terminate should have been called from Engine's shutdown()) - assert(mManager.getComponentCount() == 0); + assert_invariant(mManager.getComponentCount() == 0); } void FRenderableManager::create( @@ -263,7 +264,7 @@ void FRenderableManager::create( destroy(entity); } Instance ci = manager.addComponent(entity); - assert(ci); + assert_invariant(ci); if (ci) { // create and initialize all needed RenderPrimitives @@ -307,7 +308,7 @@ void FRenderableManager::create( UniformBuffer{ count * sizeof(PerRenderableUibBone) }, count }); - assert(bones); + assert_invariant(bones); if (bones) { setSkinning(ci, count > 0); if (builder->mUserBones) { @@ -384,7 +385,7 @@ void FRenderableManager::prepare( std::unique_ptr const * const UTILS_RESTRICT bones = manager.raw_array(); for (uint32_t index : list) { size_t i = instances[index].asValue(); - assert(i); // we should never get the null instance here + assert_invariant(i); // we should never get the null instance here if (UTILS_UNLIKELY(bones[i])) { if (bones[i]->bones.isDirty()) { driver.loadUniformBuffer(bones[i]->handle, bones[i]->bones.toBufferDescriptor(driver)); @@ -470,7 +471,7 @@ void FRenderableManager::setBones(Instance ci, Bone const* UTILS_RESTRICT transforms, size_t boneCount, size_t offset) noexcept { if (ci) { std::unique_ptr const& bones = mManager[ci].bones; - assert(bones && offset + boneCount <= bones->count); + assert_invariant(bones && offset + boneCount <= bones->count); if (bones) { boneCount = std::min(boneCount, bones->count - offset); PerRenderableUibBone* UTILS_RESTRICT out = (PerRenderableUibBone*)bones->bones.invalidateUniforms( @@ -489,7 +490,7 @@ void FRenderableManager::setBones(Instance ci, mat4f const* UTILS_RESTRICT transforms, size_t boneCount, size_t offset) noexcept { if (ci) { std::unique_ptr const& bones = mManager[ci].bones; - assert(bones && offset + boneCount <= bones->count); + assert_invariant(bones && offset + boneCount <= bones->count); if (bones) { boneCount = std::min(boneCount, bones->count - offset); PerRenderableUibBone* UTILS_RESTRICT out = (PerRenderableUibBone*)bones->bones.invalidateUniforms( diff --git a/filament/src/components/TransformManager.cpp b/filament/src/components/TransformManager.cpp index d6d2d83bb5..79277f329c 100644 --- a/filament/src/components/TransformManager.cpp +++ b/filament/src/components/TransformManager.cpp @@ -18,6 +18,8 @@ #include +#include + using namespace utils; using namespace filament::math; @@ -43,8 +45,8 @@ void FTransformManager::create(Entity entity, Instance parent, const mat4f& loca destroy(entity); } Instance i = manager.addComponent(entity); - assert(i); - assert(i != parent); + assert_invariant(i); + assert_invariant(i != parent); if (i && i != parent) { manager[i].parent = 0; @@ -148,7 +150,7 @@ void FTransformManager::updateNodeTransform(Instance i) noexcept { validateNode(i); auto& manager = mManager; - assert(i); + assert_invariant(i); // find our parent's world transform, if any // note: by using the raw_array() we don't need to check that parent is valid. @@ -185,7 +187,7 @@ void FTransformManager::commitLocalTransformTransaction() noexcept { swapNode(i, manager[i].parent); } Instance parent = manager[i].parent; - assert(parent < i); + assert_invariant(parent < i); manager[i].world = world[parent] * static_cast(manager[i].local); } } @@ -195,7 +197,7 @@ void FTransformManager::commitLocalTransformTransaction() noexcept { void FTransformManager::insertNode(Instance i, Instance parent) noexcept { auto& manager = mManager; - assert(manager[i].parent == Instance{}); + assert_invariant(manager[i].parent == Instance{}); manager[i].parent = parent; manager[i].prev = 0; @@ -231,7 +233,7 @@ void FTransformManager::swapNode(Instance i, Instance j) noexcept { // node to fix-up the linked-list pointers // Here we are guaranteed to have enough capacity for our temporary storage, so we // can safely use the item just past the end of the array. - assert(manager.getSoA().capacity() >= manager.getSoA().size() + 1); + assert_invariant(manager.getSoA().capacity() >= manager.getSoA().size() + 1); const Instance t = manager.end(); @@ -301,7 +303,7 @@ void FTransformManager::updateNode(Instance i) noexcept { // re-parent our children to us Instance child = manager[i].firstChild; while (child) { - assert(child != i); + assert_invariant(child != i); manager[child].parent = i; child = manager[child].next; } @@ -338,35 +340,35 @@ void FTransformManager::validateNode(Instance i) noexcept { Instance firstChild = manager[i].firstChild; Instance prev = manager[i].prev; Instance next = manager[i].next; - assert(parent != i); - assert(prev != i); - assert(next != i); - assert(firstChild != i); + assert_invariant(parent != i); + assert_invariant(prev != i); + assert_invariant(next != i); + assert_invariant(firstChild != i); if (prev) { if (parent) { - assert(manager[parent].firstChild != i); + assert_invariant(manager[parent].firstChild != i); } - assert(manager[prev].next == i); + assert_invariant(manager[prev].next == i); } else { if (parent) { - assert(manager[parent].firstChild == i); + assert_invariant(manager[parent].firstChild == i); } } if (next) { - assert(manager[next].prev == i); + assert_invariant(manager[next].prev == i); } if (parent) { // make sure we are in the child list of our parent Instance child = manager[parent].firstChild; - assert(child); + assert_invariant(child); while (child && child != i) { child = manager[child].next; } - assert(child); + assert_invariant(child); } if (firstChild) { - assert(manager[firstChild].parent == i); - assert(manager[firstChild].prev == 0); + assert_invariant(manager[firstChild].parent == i); + assert_invariant(manager[firstChild].prev == 0); } } #endif diff --git a/filament/src/details/Engine.h b/filament/src/details/Engine.h index f86117f67a..568099e290 100644 --- a/filament/src/details/Engine.h +++ b/filament/src/details/Engine.h @@ -209,7 +209,7 @@ public: } ResourceAllocator& getResourceAllocator() noexcept { - assert(mResourceAllocator); + assert_invariant(mResourceAllocator); return *mResourceAllocator; } diff --git a/filament/src/details/Scene.h b/filament/src/details/Scene.h index 6c05041983..26dcd13610 100644 --- a/filament/src/details/Scene.h +++ b/filament/src/details/Scene.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -166,8 +167,8 @@ public: // layer : 4 // -- MSB ------------- uint32_t pack() const { - assert(index < 16); - assert(layer < 16); + assert_invariant(index < 16); + assert_invariant(layer < 16); return uint8_t(castsShadows) << 0u | uint8_t(contactShadows) << 1u | index << 2u | diff --git a/filament/src/fg/FrameGraph.cpp b/filament/src/fg/FrameGraph.cpp index 71feb96ad4..6d10101ff3 100644 --- a/filament/src/fg/FrameGraph.cpp +++ b/filament/src/fg/FrameGraph.cpp @@ -57,7 +57,7 @@ const char* FrameGraph::Builder::getPassName() const noexcept { const char* FrameGraph::Builder::getName(FrameGraphHandle const& r) const noexcept { ResourceNode& resourceNode = mFrameGraph.getResourceNodeUnchecked(r); fg::ResourceEntryBase* pResource = resourceNode.resource; - assert(pResource); + assert_invariant(pResource); return pResource ? pResource->name : "(invalid)"; } @@ -108,7 +108,7 @@ FrameGraph::~FrameGraph() = default; bool FrameGraph::isValid(FrameGraphHandle handle) const noexcept { if (!handle.isValid()) return false; auto const& registry = mResourceNodes; - assert(handle.index < registry.size()); + assert_invariant(handle.index < registry.size()); ResourceNode const& node = *registry[handle.index]; return node.version == node.resource->version; } @@ -121,10 +121,10 @@ bool FrameGraph::equal(FrameGraphHandle lhs, FrameGraphHandle rhs) const noexcep return false; } auto const& registry = mResourceNodes; - assert(lhs.index < registry.size()); - assert(rhs.index < registry.size()); - assert(registry[lhs.index]->resource); - assert(registry[rhs.index]->resource); + assert_invariant(lhs.index < registry.size()); + assert_invariant(rhs.index < registry.size()); + assert_invariant(registry[lhs.index]->resource); + assert_invariant(registry[rhs.index]->resource); return registry[lhs.index]->resource == registry[rhs.index]->resource; } @@ -148,10 +148,10 @@ void FrameGraph::moveResourceBase(FrameGraphHandle fromHandle, FrameGraphHandle // (note: there can only be a single pass that can be a writer) if (from.writerIndex.isValid()) { PassNode* const pass = &mPassNodes[from.writerIndex.index]; - assert(pass); + assert_invariant(pass); auto pos = std::find_if(pass->writes.begin(), pass->writes.end(), [fromHandle](auto handle) { return handle == fromHandle; }); - assert(pos != pass->writes.end()); + assert_invariant(pos != pass->writes.end()); pass->writes.erase(pos); from.writerIndex = to.writerIndex; } @@ -235,9 +235,9 @@ FrameGraphHandle FrameGraph::create(fg::ResourceEntryBase* pResourceEntry) noexc ResourceNode& FrameGraph::getResourceNodeUnchecked(FrameGraphHandle r) { auto& resourceNodes = mResourceNodes; - assert(r.index < resourceNodes.size()); + assert_invariant(r.index < resourceNodes.size()); ResourceNode& node = *resourceNodes[r.index]; - assert(node.resource); + assert_invariant(node.resource); return node; } @@ -253,13 +253,13 @@ ResourceNode& FrameGraph::getResourceNode(FrameGraphHandle r) { fg::ResourceEntryBase& FrameGraph::getResourceEntryBase(FrameGraphHandle r) noexcept { ResourceNode& node = getResourceNode(r); - assert(node.resource); + assert_invariant(node.resource); return *node.resource; } fg::ResourceEntryBase& FrameGraph::getResourceEntryBaseUnchecked(FrameGraphHandle r) noexcept { ResourceNode& node = getResourceNodeUnchecked(r); - assert(node.resource); + assert_invariant(node.resource); return *node.resource; } @@ -278,14 +278,14 @@ FrameGraph& FrameGraph::compile() noexcept { // compute resources reference counts (i.e. resources we're reading from) for (FrameGraphHandle resource : pass.reads) { - assert(resource.isValid()); + assert_invariant(resource.isValid()); // add a reference for each pass that reads from this resource resourceNodes[resource.index]->readerCount++; } // set the writers for (FrameGraphHandle resource : pass.writes) { - assert(resource.isValid()); + assert_invariant(resource.isValid()); resourceNodes[resource.index]->writer = &pass; } } @@ -306,10 +306,10 @@ FrameGraph& FrameGraph::compile() noexcept { stack.pop_back(); PassNode* const writer = pNode->writer; if (writer) { - assert(writer->refCount >= 1); + assert_invariant(writer->refCount >= 1); if (--writer->refCount == 0) { // this pass is culled - assert(!writer->hasSideEffect); + assert_invariant(!writer->hasSideEffect); auto const& reads = writer->reads; for (FrameGraphHandle resource : reads) { ResourceNode& r = *resourceNodes[resource.index]; @@ -372,7 +372,7 @@ FrameGraph& FrameGraph::compile() noexcept { if (resource->priority == priority && resource->refs) { auto *pFirst = resource->first; auto *pLast = resource->last; - assert(!pFirst == !pLast); + assert_invariant(!pFirst == !pLast); if (pFirst && pLast) { pFirst->devirtualize.push_back(resource.get()); pLast->destroy.push_back(resource.get()); @@ -385,7 +385,7 @@ FrameGraph& FrameGraph::compile() noexcept { } void FrameGraph::executeInternal(PassNode const& node, DriverApi& driver) noexcept { - assert(node.base); + assert_invariant(node.base); // create concrete resources and rendertargets for (VirtualResource* resource : node.devirtualize) { resource->preExecuteDevirtualize(*this); diff --git a/filament/src/fg/FrameGraphHandle.cpp b/filament/src/fg/FrameGraphHandle.cpp index e4ef8f8635..d227121f36 100644 --- a/filament/src/fg/FrameGraphHandle.cpp +++ b/filament/src/fg/FrameGraphHandle.cpp @@ -22,11 +22,9 @@ #ifndef NDEBUG -#include "details/Texture.h" // only needed for assert() +#include "details/Texture.h" // only needed for assert_invariant() #endif -#include - namespace filament { using namespace backend; @@ -43,7 +41,7 @@ void FrameGraphTexture::create(ResourceAllocatorInterface& allocator, const char return; } - assert(any(desc.usage)); + assert_invariant(any(desc.usage)); // texture that can't be sampled can't have LOD -- they obviously can't be accessed // note: this could happen if a texture was created with LODs, but a later pass didn't @@ -52,10 +50,10 @@ void FrameGraphTexture::create(ResourceAllocatorInterface& allocator, const char if (!(desc.usage & TextureUsage::SAMPLEABLE)) { levels = 1; } - assert(levels <= FTexture::maxLevelCount(desc.width, desc.height)); + assert_invariant(levels <= FTexture::maxLevelCount(desc.width, desc.height)); uint8_t samples = desc.samples; - assert(samples <= 1 || none(desc.usage & TextureUsage::SAMPLEABLE)); + assert_invariant(samples <= 1 || none(desc.usage & TextureUsage::SAMPLEABLE)); if (samples > 1 && any(desc.usage & TextureUsage::SAMPLEABLE)) { // Sampleable textures can't be multi-sampled // This should never happen (and will be caught by the assert above), but just to be safe, @@ -66,7 +64,7 @@ void FrameGraphTexture::create(ResourceAllocatorInterface& allocator, const char texture = allocator.createTexture(name, desc.type, levels, desc.format, samples, desc.width, desc.height, desc.depth, desc.usage); - assert(texture); + assert_invariant(texture); } void FrameGraphTexture::destroy(ResourceAllocatorInterface& allocator) noexcept { diff --git a/filament/src/fg/FrameGraphPassResources.cpp b/filament/src/fg/FrameGraphPassResources.cpp index 9d4e6e6fe2..23189fbe94 100644 --- a/filament/src/fg/FrameGraphPassResources.cpp +++ b/filament/src/fg/FrameGraphPassResources.cpp @@ -44,7 +44,7 @@ fg::ResourceEntryBase const& FrameGraphPassResources::getResourceEntryBase(Frame ResourceNode& node = mFrameGraph.getResourceNodeUnchecked(r); fg::ResourceEntryBase const* const pResource = node.resource; - assert(pResource); + assert_invariant(pResource); // TODO: we should check for write to // // check that this FrameGraphHandle is indeed used by this pass diff --git a/filament/src/fg/fg/PassNode.cpp b/filament/src/fg/fg/PassNode.cpp index 7f1696c0a4..7d072c4dd1 100644 --- a/filament/src/fg/fg/PassNode.cpp +++ b/filament/src/fg/fg/PassNode.cpp @@ -113,7 +113,7 @@ FrameGraphHandle PassNode::write(FrameGraph& fg, const FrameGraphHandle& handle) // record the write auto& newNode = fg.getResourceNodeUnchecked(r); - assert(!newNode.writerIndex.isValid()); + assert_invariant(!newNode.writerIndex.isValid()); newNode.writerIndex = FrameGraphHandle(this->id); // needed by move resources writes.push_back(r); diff --git a/filament/src/fg/fg/RenderTargetResourceEntry.cpp b/filament/src/fg/fg/RenderTargetResourceEntry.cpp index 36ac910e10..d65b1d49a3 100644 --- a/filament/src/fg/fg/RenderTargetResourceEntry.cpp +++ b/filament/src/fg/fg/RenderTargetResourceEntry.cpp @@ -166,7 +166,7 @@ void RenderTargetResourceEntry::update(FrameGraph& fg, PassNode const& pass) noe void RenderTargetResourceEntry::preExecuteDevirtualize(FrameGraph& fg) noexcept { if (!imported) { - assert(any(attachments)); + assert_invariant(any(attachments)); // TODO: we could cache the result of this loop backend::TargetBufferInfo info[FrameGraphRenderTarget::Attachments::COUNT]; @@ -182,7 +182,7 @@ void RenderTargetResourceEntry::preExecuteDevirtualize(FrameGraph& fg) noexcept TargetBufferFlags::STENCIL }; static_assert(sizeof(flags)/sizeof(*flags) == FrameGraphRenderTarget::Attachments::COUNT, "array sizes don't match"); - assert(bool(attachments & flags[i]) == attachmentInfo.isValid()); + assert_invariant(bool(attachments & flags[i]) == attachmentInfo.isValid()); #endif if (attachmentInfo.isValid()) { fg::ResourceEntry const& entry = @@ -191,11 +191,11 @@ void RenderTargetResourceEntry::preExecuteDevirtualize(FrameGraph& fg) noexcept info[i].level = attachmentInfo.getLevel(); info[i].layer = attachmentInfo.getLayer(); // the attachment buffer (texture or renderbuffer) must be valid - assert(info[i].handle); + assert_invariant(info[i].handle); // the attachment level must be within range - assert(info[i].level < entry.descriptor.levels); + assert_invariant(info[i].level < entry.descriptor.levels); // if the attachment is multisampled, then the rendertarget must be too - assert(entry.descriptor.samples <= 1 || entry.descriptor.samples == descriptor.samples); + assert_invariant(entry.descriptor.samples <= 1 || entry.descriptor.samples == descriptor.samples); } } diff --git a/libs/utils/CMakeLists.txt b/libs/utils/CMakeLists.txt index e6dd4e7d47..1650b33c00 100644 --- a/libs/utils/CMakeLists.txt +++ b/libs/utils/CMakeLists.txt @@ -14,6 +14,7 @@ file(GLOB_RECURSE PUBLIC_HDRS ${PUBLIC_HDR_DIR}/${TARGET}/*.h) set(DIST_HDRS ${PUBLIC_HDR_DIR}/${TARGET}/algorithm.h ${PUBLIC_HDR_DIR}/${TARGET}/bitset.h + ${PUBLIC_HDR_DIR}/${TARGET}/debug.h ${PUBLIC_HDR_DIR}/${TARGET}/Allocator.h ${PUBLIC_HDR_DIR}/${TARGET}/BitmaskEnum.h ${PUBLIC_HDR_DIR}/${TARGET}/compiler.h @@ -46,6 +47,7 @@ set(DIST_GENERIC_HDRS set(SRCS src/api_level.cpp src/ashmem.cpp + src/debug.cpp src/Allocator.cpp src/CallStack.cpp src/CString.cpp diff --git a/libs/utils/include/utils/debug.h b/libs/utils/include/utils/debug.h new file mode 100644 index 0000000000..1d4cf9f661 --- /dev/null +++ b/libs/utils/include/utils/debug.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TNT_UTILS_DEBUG_H +#define TNT_UTILS_DEBUG_H + +#include + +namespace utils { +void panic(const char *func, const char * file, int line, const char *assertion) noexcept; +} // namespace filament + +#ifdef NDEBUG +# define assert_invariant(e) ((void)0) +#else +# define assert_invariant(e) \ + (UTILS_LIKELY(e) ? ((void)0) : utils::panic(__func__, __FILE__, __LINE__, #e)) +#endif // NDEBUG + +#endif //TNT_UTILS_DEBUG_H diff --git a/libs/utils/src/debug.cpp b/libs/utils/src/debug.cpp new file mode 100644 index 0000000000..d03d7cf938 --- /dev/null +++ b/libs/utils/src/debug.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "utils/debug.h" + +#include + +namespace utils { + +void panic(const char *func, const char * file, int line, const char *assertion) noexcept { + PANIC_LOG("%s:%d: failed assertion `%s'\n", file, line, assertion); +} + +} // namespace filament