buffer update opt: Add new API for getting uniform buffer offset alignment (#9347)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -68,4 +68,5 @@ id<MTLTexture> createTextureViewWithSingleSlice(id<MTLTexture> texture, NSUInteg
|
||||
slices:NSMakeRange(slice, 1)];
|
||||
}
|
||||
|
||||
|
||||
} // namespace filament::backend
|
||||
|
||||
@@ -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
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user