Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Fielder <jason_apple>2022-06-27 12:41:04 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-06-27 12:45:49 +0300
commit9130a60d3d833718c932d3f971b746ba253734bc (patch)
treedaa060bb87ee0bf52c96699aea103ea78e29caa7 /source/blender/gpu/intern
parent7b6b740ace1e56a8217fb44ed9fd3cf0c0a324f4 (diff)
MTLCommandBufferState for coordinating GPU workload submission and render pass coordination.
MTLFrameBuffer has been implemented to support creation of RenderCommandEncoders, along with supporting functionality in the Metal Context. Optimisation stubs for GPU_framebuffer_bind_ext has been added, which enables specific assignment of attachment load-store ops at the bind level, rather than on a framebuffer object as a whole. Begin and end frame markers are used to encapsulate frame boundaries for explicit workload submission. This is required for explicit APIs where implicit flushing of work does not occur. Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D15027
Diffstat (limited to 'source/blender/gpu/intern')
-rw-r--r--source/blender/gpu/intern/gpu_context.cc16
-rw-r--r--source/blender/gpu/intern/gpu_context_private.hh2
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.cc60
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer_private.hh7
4 files changed, 85 insertions, 0 deletions
diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc
index 9fb5826506a..4a0a9ecc7f6 100644
--- a/source/blender/gpu/intern/gpu_context.cc
+++ b/source/blender/gpu/intern/gpu_context.cc
@@ -123,6 +123,22 @@ GPUContext *GPU_context_active_get()
return wrap(Context::get());
}
+void GPU_context_begin_frame(GPUContext *ctx)
+{
+ blender::gpu::Context *_ctx = unwrap(ctx);
+ if (_ctx) {
+ _ctx->begin_frame();
+ }
+}
+
+void GPU_context_end_frame(GPUContext *ctx)
+{
+ blender::gpu::Context *_ctx = unwrap(ctx);
+ if (_ctx) {
+ _ctx->end_frame();
+ }
+}
+
/* -------------------------------------------------------------------- */
/** \name Main context global mutex
*
diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh
index af9791fde88..9cdf0075632 100644
--- a/source/blender/gpu/intern/gpu_context_private.hh
+++ b/source/blender/gpu/intern/gpu_context_private.hh
@@ -63,6 +63,8 @@ class Context {
virtual void activate() = 0;
virtual void deactivate() = 0;
+ virtual void begin_frame() = 0;
+ virtual void end_frame() = 0;
/* Will push all pending commands to the GPU. */
virtual void flush() = 0;
diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc
index 08d761106e5..f12d8fd7e55 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.cc
+++ b/source/blender/gpu/intern/gpu_framebuffer.cc
@@ -124,6 +124,43 @@ void FrameBuffer::attachment_remove(GPUAttachmentType type)
dirty_attachments_ = true;
}
+void FrameBuffer::load_store_config_array(const GPULoadStore *load_store_actions, uint actions_len)
+{
+ /* Follows attachment structure of GPU_framebuffer_config_array/GPU_framebuffer_ensure_config */
+ const GPULoadStore &depth_action = load_store_actions[0];
+ Span<GPULoadStore> color_attachments(load_store_actions + 1, actions_len - 1);
+
+ if (this->attachments_[GPU_FB_DEPTH_STENCIL_ATTACHMENT].tex) {
+ this->attachment_set_loadstore_op(
+ GPU_FB_DEPTH_STENCIL_ATTACHMENT, depth_action.load_action, depth_action.store_action);
+ }
+ if (this->attachments_[GPU_FB_DEPTH_ATTACHMENT].tex) {
+ this->attachment_set_loadstore_op(
+ GPU_FB_DEPTH_ATTACHMENT, depth_action.load_action, depth_action.store_action);
+ }
+
+ GPUAttachmentType type = GPU_FB_COLOR_ATTACHMENT0;
+ for (const GPULoadStore &actions : color_attachments) {
+ if (this->attachments_[type].tex) {
+ this->attachment_set_loadstore_op(type, actions.load_action, actions.store_action);
+ }
+ ++type;
+ }
+}
+
+unsigned int FrameBuffer::get_bits_per_pixel(void)
+{
+ unsigned int total_bits = 0;
+ for (GPUAttachment &attachment : attachments_) {
+ Texture *tex = reinterpret_cast<Texture *>(attachment.tex);
+ if (tex != nullptr) {
+ int bits = to_bytesize(tex->format_get()) * to_component_len(tex->format_get());
+ total_bits += bits;
+ }
+ }
+ return total_bits;
+}
+
void FrameBuffer::recursive_downsample(int max_lvl,
void (*callback)(void *userData, int level),
void *userData)
@@ -149,10 +186,21 @@ void FrameBuffer::recursive_downsample(int max_lvl,
attachment.mip = mip_lvl;
}
}
+
/* Update the internal attachments and viewport size. */
dirty_attachments_ = true;
this->bind(true);
+ /* Optimise load-store state. */
+ GPUAttachmentType type = GPU_FB_DEPTH_ATTACHMENT;
+ for (GPUAttachment &attachment : attachments_) {
+ Texture *tex = reinterpret_cast<Texture *>(attachment.tex);
+ if (tex != nullptr) {
+ this->attachment_set_loadstore_op(type, GPU_LOADACTION_DONT_CARE, GPU_STOREACTION_STORE);
+ }
+ ++type;
+ }
+
callback(userData, mip_lvl);
}
@@ -198,6 +246,18 @@ void GPU_framebuffer_bind(GPUFrameBuffer *gpu_fb)
unwrap(gpu_fb)->bind(enable_srgb);
}
+void GPU_framebuffer_bind_loadstore(GPUFrameBuffer *gpu_fb,
+ const GPULoadStore *load_store_actions,
+ uint actions_len)
+{
+ /* Bind */
+ GPU_framebuffer_bind(gpu_fb);
+
+ /* Update load store */
+ FrameBuffer *fb = unwrap(gpu_fb);
+ fb->load_store_config_array(load_store_actions, actions_len);
+}
+
void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *gpu_fb)
{
const bool enable_srgb = false;
diff --git a/source/blender/gpu/intern/gpu_framebuffer_private.hh b/source/blender/gpu/intern/gpu_framebuffer_private.hh
index d218662d17f..8cecc6b8b15 100644
--- a/source/blender/gpu/intern/gpu_framebuffer_private.hh
+++ b/source/blender/gpu/intern/gpu_framebuffer_private.hh
@@ -114,6 +114,10 @@ class FrameBuffer {
eGPUDataFormat data_format,
const void *clear_value) = 0;
+ virtual void attachment_set_loadstore_op(GPUAttachmentType type,
+ eGPULoadOp load_action,
+ eGPUStoreOp store_action) = 0;
+
virtual void read(eGPUFrameBufferBits planes,
eGPUDataFormat format,
const int area[4],
@@ -128,12 +132,15 @@ class FrameBuffer {
int dst_offset_x,
int dst_offset_y) = 0;
+ void load_store_config_array(const GPULoadStore *load_store_actions, uint actions_len);
+
void attachment_set(GPUAttachmentType type, const GPUAttachment &new_attachment);
void attachment_remove(GPUAttachmentType type);
void recursive_downsample(int max_lvl,
void (*callback)(void *userData, int level),
void *userData);
+ uint get_bits_per_pixel();
inline void size_set(int width, int height)
{