buffer update opt: Add new API for getting uniform buffer offset alignment (#9347)

This commit is contained in:
Doris Wu
2025-10-29 11:29:31 +08:00
committed by GitHub
parent bfd23fcb4f
commit 379b63d11b
9 changed files with 43 additions and 12 deletions
@@ -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
+2 -11
View File
@@ -19,6 +19,7 @@
#include "MetalContext.h"
#include "MetalFlags.h"
#include "MetalUtils.h"
#include <backend/DriverEnums.h>
#include <backend/platforms/PlatformMetal.h>
@@ -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<MTLDevice> device, MTLResourceOptions options, MTLSizeAndAlign layout,
@@ -29,6 +29,7 @@
#include "MetalHandles.h"
#include "MetalState.h"
#include "MetalTimerQuery.h"
#include "MetalUtils.h"
#include <backend/platforms/PlatformMetal.h>
#include <backend/platforms/PlatformMetal-ObjC.h>
@@ -1252,6 +1253,10 @@ size_t MetalDriver::getMaxArrayTextureLayers() {
return 256;
}
size_t MetalDriver::getUniformBufferOffsetAlignment() {
return ::filament::backend::getUniformBufferOffsetAlignment();
}
void MetalDriver::updateIndexBuffer(Handle<HwIndexBuffer> ibh, BufferDescriptor&& data,
uint32_t byteOffset) {
FILAMENT_CHECK_PRECONDITION(data.buffer)
+16
View File
@@ -50,6 +50,22 @@ id<MTLTexture> createTextureViewWithLodRange(id<MTLTexture> texture, NSUInteger
*/
id<MTLTexture> createTextureViewWithSingleSlice(id<MTLTexture> 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
+1
View File
@@ -68,4 +68,5 @@ id<MTLTexture> createTextureViewWithSingleSlice(id<MTLTexture> texture, NSUInteg
slices:NSMakeRange(slice, 1)];
}
} // namespace filament::backend
+4
View File
@@ -274,6 +274,10 @@ size_t NoopDriver::getMaxArrayTextureLayers() {
return 256u;
}
size_t NoopDriver::getUniformBufferOffsetAlignment() {
return 256u;
}
void NoopDriver::updateIndexBuffer(Handle<HwIndexBuffer> ibh, BufferDescriptor&& p,
uint32_t byteOffset) {
scheduleDestroy(std::move(p));
@@ -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
// ------------------------------------------------------------------------------------------------
+6 -1
View File
@@ -1390,7 +1390,8 @@ uint8_t VulkanDriver::getMaxDrawBuffers() {
}
size_t VulkanDriver::getMaxUniformBufferSize() {
return mContext.getPhysicalDeviceLimits().maxUniformBufferRange;
return std::max(mContext.getPhysicalDeviceLimits().maxUniformBufferRange,
static_cast<uint32_t>(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<HwVertexBuffer> vbh, uint32_t index,
Handle<HwBufferObject> boh) {
auto vb = resource_ptr<VulkanVertexBuffer>::cast(&mResourceManager, vbh);
@@ -841,6 +841,10 @@ size_t WebGPUDriver::getMaxArrayTextureLayers() {
return mDeviceLimits.maxTextureArrayLayers;
}
size_t WebGPUDriver::getUniformBufferOffsetAlignment(){
return mDeviceLimits.minUniformBufferOffsetAlignment;
}
void WebGPUDriver::updateIndexBuffer(Handle<HwIndexBuffer> indexBufferHandle,
BufferDescriptor&& bufferDescriptor, const uint32_t byteOffset) {
// make sure command elements (draws, etc.) prior to the buffer update are processed before the