diff --git a/filament/backend/include/private/backend/DriverAPI.inc b/filament/backend/include/private/backend/DriverAPI.inc index fed7692e56..6d69f73915 100644 --- a/filament/backend/include/private/backend/DriverAPI.inc +++ b/filament/backend/include/private/backend/DriverAPI.inc @@ -366,6 +366,7 @@ DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage, void*, image) DECL_DRIVER_API_SYNCHRONOUS_N(backend::TimerQueryResult, getTimerQueryValue, backend::TimerQueryHandle, tqh, uint64_t*, elapsedTime) DECL_DRIVER_API_SYNCHRONOUS_N(bool, isWorkaroundNeeded, backend::Workaround, workaround) DECL_DRIVER_API_SYNCHRONOUS_0(backend::FeatureLevel, getFeatureLevel) +DECL_DRIVER_API_SYNCHRONOUS_0(size_t, getUniformBufferOffsetAlignment) /* * Updating driver objects diff --git a/filament/backend/src/metal/MetalBuffer.h b/filament/backend/src/metal/MetalBuffer.h index 464bafd623..c921e4865a 100644 --- a/filament/backend/src/metal/MetalBuffer.h +++ b/filament/backend/src/metal/MetalBuffer.h @@ -19,6 +19,7 @@ #include "MetalContext.h" #include "MetalFlags.h" +#include "MetalUtils.h" #include #include @@ -260,18 +261,8 @@ public: // In practice, MetalRingBuffer is used for argument buffers, which are kept in the constant // address space. Constant buffers have specific alignment requirements when specifying an // offset. -#if defined(FILAMENT_IOS) -#if TARGET_OS_SIMULATOR - // The iOS simulator has differing alignment requirements. - static constexpr auto METAL_CONSTANT_BUFFER_OFFSET_ALIGNMENT = 256; -#else - static constexpr auto METAL_CONSTANT_BUFFER_OFFSET_ALIGNMENT = 4; -#endif // TARGET_OS_SIMULATOR -#else - static constexpr auto METAL_CONSTANT_BUFFER_OFFSET_ALIGNMENT = 32; -#endif static inline auto computeSlotSize(MTLSizeAndAlign layout) { - return align(align(layout.size, layout.align), METAL_CONSTANT_BUFFER_OFFSET_ALIGNMENT); + return align(align(layout.size, layout.align), getUniformBufferOffsetAlignment()); } MetalRingBuffer(id device, MTLResourceOptions options, MTLSizeAndAlign layout, diff --git a/filament/backend/src/metal/MetalDriver.mm b/filament/backend/src/metal/MetalDriver.mm index fab963d7a7..5ce703f840 100644 --- a/filament/backend/src/metal/MetalDriver.mm +++ b/filament/backend/src/metal/MetalDriver.mm @@ -29,6 +29,7 @@ #include "MetalHandles.h" #include "MetalState.h" #include "MetalTimerQuery.h" +#include "MetalUtils.h" #include #include @@ -1252,6 +1253,10 @@ size_t MetalDriver::getMaxArrayTextureLayers() { return 256; } +size_t MetalDriver::getUniformBufferOffsetAlignment() { + return ::filament::backend::getUniformBufferOffsetAlignment(); +} + void MetalDriver::updateIndexBuffer(Handle ibh, BufferDescriptor&& data, uint32_t byteOffset) { FILAMENT_CHECK_PRECONDITION(data.buffer) diff --git a/filament/backend/src/metal/MetalUtils.h b/filament/backend/src/metal/MetalUtils.h index 7802116364..12e8e658c2 100644 --- a/filament/backend/src/metal/MetalUtils.h +++ b/filament/backend/src/metal/MetalUtils.h @@ -50,6 +50,22 @@ id createTextureViewWithLodRange(id texture, NSUInteger */ id createTextureViewWithSingleSlice(id texture, NSUInteger slice); +/** + * Returns the required alignment for uniform buffer offsets. + */ +constexpr size_t getUniformBufferOffsetAlignment() { +#if defined(FILAMENT_IOS) +#if TARGET_OS_SIMULATOR + // The iOS simulator has differing alignment requirements. + return 256; +#else + return 4; +#endif // TARGET_OS_SIMULATOR +#else + return 32; +#endif +} + } // namespace filament::backend #endif //TNT_FILAMENT_DRIVER_METALUTILS_H diff --git a/filament/backend/src/metal/MetalUtils.mm b/filament/backend/src/metal/MetalUtils.mm index 8797ddc89a..e906c0e6c4 100644 --- a/filament/backend/src/metal/MetalUtils.mm +++ b/filament/backend/src/metal/MetalUtils.mm @@ -68,4 +68,5 @@ id createTextureViewWithSingleSlice(id texture, NSUInteg slices:NSMakeRange(slice, 1)]; } + } // namespace filament::backend diff --git a/filament/backend/src/noop/NoopDriver.cpp b/filament/backend/src/noop/NoopDriver.cpp index 23b09ca349..eb5fbc4c95 100644 --- a/filament/backend/src/noop/NoopDriver.cpp +++ b/filament/backend/src/noop/NoopDriver.cpp @@ -274,6 +274,10 @@ size_t NoopDriver::getMaxArrayTextureLayers() { return 256u; } +size_t NoopDriver::getUniformBufferOffsetAlignment() { + return 256u; +} + void NoopDriver::updateIndexBuffer(Handle ibh, BufferDescriptor&& p, uint32_t byteOffset) { scheduleDestroy(std::move(p)); diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index a313240e47..ae6e81711b 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -2666,6 +2666,10 @@ size_t OpenGLDriver::getMaxArrayTextureLayers() { return mContext.gets.max_array_texture_layers; } +size_t OpenGLDriver::getUniformBufferOffsetAlignment() { + return mContext.gets.uniform_buffer_offset_alignment; +} + // ------------------------------------------------------------------------------------------------ // Swap chains // ------------------------------------------------------------------------------------------------ diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index d2bd1de2bc..4798f82196 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -1390,7 +1390,8 @@ uint8_t VulkanDriver::getMaxDrawBuffers() { } size_t VulkanDriver::getMaxUniformBufferSize() { - return mContext.getPhysicalDeviceLimits().maxUniformBufferRange; + return std::max(mContext.getPhysicalDeviceLimits().maxUniformBufferRange, + static_cast(mContext.getPhysicalDeviceLimits().nonCoherentAtomSize)); } size_t VulkanDriver::getMaxTextureSize(SamplerType type) { @@ -1410,6 +1411,10 @@ size_t VulkanDriver::getMaxArrayTextureLayers() { return mContext.getPhysicalDeviceLimits().maxImageArrayLayers; } +size_t VulkanDriver::getUniformBufferOffsetAlignment() { + return mContext.getPhysicalDeviceLimits().minUniformBufferOffsetAlignment; +} + void VulkanDriver::setVertexBufferObject(Handle vbh, uint32_t index, Handle boh) { auto vb = resource_ptr::cast(&mResourceManager, vbh); diff --git a/filament/backend/src/webgpu/WebGPUDriver.cpp b/filament/backend/src/webgpu/WebGPUDriver.cpp index d75c782f8d..796ece2f9f 100644 --- a/filament/backend/src/webgpu/WebGPUDriver.cpp +++ b/filament/backend/src/webgpu/WebGPUDriver.cpp @@ -841,6 +841,10 @@ size_t WebGPUDriver::getMaxArrayTextureLayers() { return mDeviceLimits.maxTextureArrayLayers; } +size_t WebGPUDriver::getUniformBufferOffsetAlignment(){ + return mDeviceLimits.minUniformBufferOffsetAlignment; +} + void WebGPUDriver::updateIndexBuffer(Handle indexBufferHandle, BufferDescriptor&& bufferDescriptor, const uint32_t byteOffset) { // make sure command elements (draws, etc.) prior to the buffer update are processed before the