PR Introduces GPU_storagebuf_sync_to_host as an explicit routine to flush GPU-resident storage buffer memory back to the host within the GPU command stream. The previous implmentation relied on implicit synchronization of resources using OpenGL barriers which does not match the paradigm of explicit APIs, where indiviaul resources may need to be tracked. This patch ensures GPU_storagebuf_read can be called without stalling the GPU pipeline while work finishes executing. There are two possible use cases: 1) If GPU_storagebuf_read is called AFTER an explicit call to GPU_storagebuf_sync_to_host, the read will be synchronized. If the dependent work is still executing on the GPU, the host will stall until GPU work has completed and results are available. 2) If GPU_storagebuf_read is called WITHOUT an explicit call to GPU_storagebuf_sync_to_host, the read will be asynchronous and whatever memory is visible to the host at that time will be used. (This is the same as assuming a sync event has already been signalled.) This patch also addresses a gap in the Metal implementation where there was missing read support for GPU-only storage buffers. This routine now uses a staging buffer to copy results if no host-visible buffer was available. Reading from a GPU-only storage buffer will always stall the host, as it is not possible to pre-flush results, as no host-resident buffer is available. Authored by Apple: Michael Parkin-White Pull Request: https://projects.blender.org/blender/blender/pulls/113456
53 lines
1.2 KiB
C++
53 lines
1.2 KiB
C++
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "gpu_storage_buffer_private.hh"
|
|
|
|
namespace blender {
|
|
namespace gpu {
|
|
|
|
/**
|
|
* Implementation of Storage Buffers using OpenGL.
|
|
*/
|
|
class GLStorageBuf : public StorageBuf {
|
|
private:
|
|
/** Slot to which this UBO is currently bound. -1 if not bound. */
|
|
int slot_ = -1;
|
|
/** OpenGL Object handle. */
|
|
GLuint ssbo_id_ = 0;
|
|
/** Usage type. */
|
|
GPUUsageType usage_;
|
|
|
|
public:
|
|
GLStorageBuf(size_t size, GPUUsageType usage, const char *name);
|
|
~GLStorageBuf();
|
|
|
|
void update(const void *data) override;
|
|
void bind(int slot) override;
|
|
void unbind() override;
|
|
void clear(uint32_t clear_value) override;
|
|
void copy_sub(VertBuf *src, uint dst_offset, uint src_offset, uint copy_size) override;
|
|
void read(void *data) override;
|
|
void async_flush_to_host() override;
|
|
|
|
/* Special internal function to bind SSBOs to indirect argument targets. */
|
|
void bind_as(GLenum target);
|
|
|
|
private:
|
|
void init();
|
|
|
|
MEM_CXX_CLASS_ALLOC_FUNCS("GLStorageBuf");
|
|
};
|
|
|
|
} // namespace gpu
|
|
} // namespace blender
|