diff options
Diffstat (limited to 'source/blender/gpu/metal/mtl_context.mm')
-rw-r--r-- | source/blender/gpu/metal/mtl_context.mm | 92 |
1 files changed, 59 insertions, 33 deletions
diff --git a/source/blender/gpu/metal/mtl_context.mm b/source/blender/gpu/metal/mtl_context.mm index 6ecdb3f48b3..26cfe6632ef 100644 --- a/source/blender/gpu/metal/mtl_context.mm +++ b/source/blender/gpu/metal/mtl_context.mm @@ -16,44 +16,25 @@ using namespace blender::gpu; namespace blender::gpu { -/* -------------------------------------------------------------------- */ -/** \name Memory Management - * \{ */ - -bool MTLTemporaryBufferRange::requires_flush() -{ - /* We do not need to flush shared memory. */ - return this->options & MTLResourceStorageModeManaged; -} - -void MTLTemporaryBufferRange::flush() -{ - if (this->requires_flush()) { - BLI_assert(this->metal_buffer); - BLI_assert((this->buffer_offset + this->size) <= [this->metal_buffer length]); - BLI_assert(this->buffer_offset >= 0); - [this->metal_buffer - didModifyRange:NSMakeRange(this->buffer_offset, this->size - this->buffer_offset)]; - } -} - -/** \} */ +/* Global memory manager. */ +MTLBufferPool MTLContext::global_memory_manager; /* -------------------------------------------------------------------- */ /** \name MTLContext * \{ */ /* Placeholder functions */ -MTLContext::MTLContext(void *ghost_window) +MTLContext::MTLContext(void *ghost_window) : memory_manager(*this), main_command_buffer(*this) { /* Init debug. */ debug::mtl_debug_init(); /* Initialize command buffer state. */ - this->main_command_buffer.prepare(this); + this->main_command_buffer.prepare(); /* Frame management. */ is_inside_frame_ = false; + current_frame_index_ = 0; /* Create FrameBuffer handles. */ MTLFrameBuffer *mtl_front_left = new MTLFrameBuffer(this, "front_left"); @@ -65,9 +46,14 @@ MTLContext::MTLContext(void *ghost_window) * initialization). */ MTLBackend::platform_init(this); MTLBackend::capabilities_init(this); + /* Initialize Metal modules. */ + this->memory_manager.init(); this->state_manager = new MTLStateManager(this); + /* Ensure global memory manager is initialized. */ + MTLContext::global_memory_manager.init(this->device); + /* Initialize texture read/update structures. */ this->get_texture_utils().init(); @@ -93,7 +79,7 @@ MTLContext::~MTLContext() this->finish(); /* End frame. */ - if (is_inside_frame_) { + if (this->get_inside_frame()) { this->end_frame(); } } @@ -112,7 +98,7 @@ MTLContext::~MTLContext() void MTLContext::begin_frame() { BLI_assert(MTLBackend::get()->is_inside_render_boundary()); - if (is_inside_frame_) { + if (this->get_inside_frame()) { return; } @@ -122,7 +108,7 @@ void MTLContext::begin_frame() void MTLContext::end_frame() { - BLI_assert(is_inside_frame_); + BLI_assert(this->get_inside_frame()); /* Ensure pre-present work is committed. */ this->flush(); @@ -136,20 +122,20 @@ void MTLContext::check_error(const char *info) /* TODO(Metal): Implement. */ } -void MTLContext::activate(void) +void MTLContext::activate() { /* TODO(Metal): Implement. */ } -void MTLContext::deactivate(void) +void MTLContext::deactivate() { /* TODO(Metal): Implement. */ } -void MTLContext::flush(void) +void MTLContext::flush() { /* TODO(Metal): Implement. */ } -void MTLContext::finish(void) +void MTLContext::finish() { /* TODO(Metal): Implement. */ } @@ -180,7 +166,7 @@ id<MTLRenderCommandEncoder> MTLContext::ensure_begin_render_pass() BLI_assert(this); /* Ensure the rendering frame has started. */ - if (!is_inside_frame_) { + if (!this->get_inside_frame()) { this->begin_frame(); } @@ -202,7 +188,8 @@ id<MTLRenderCommandEncoder> MTLContext::ensure_begin_render_pass() * framebuffer state has been modified (is_dirty). */ if (!this->main_command_buffer.is_inside_render_pass() || this->active_fb != this->main_command_buffer.get_active_framebuffer() || - this->main_command_buffer.get_active_framebuffer()->get_dirty()) { + this->main_command_buffer.get_active_framebuffer()->get_dirty() || + this->is_visibility_dirty()) { /* Validate bound framebuffer before beginning render pass. */ if (!static_cast<MTLFrameBuffer *>(this->active_fb)->validate_render_pass()) { @@ -386,6 +373,45 @@ void MTLContext::set_scissor_enabled(bool scissor_enabled) /** \} */ /* -------------------------------------------------------------------- */ +/** \name Visibility buffer control for MTLQueryPool. + * \{ */ + +void MTLContext::set_visibility_buffer(gpu::MTLBuffer *buffer) +{ + /* Flag visibility buffer as dirty if the buffer being used for visibility has changed -- + * This is required by the render pass, and we will break the pass if the results destination + * buffer is modified. */ + if (buffer) { + visibility_is_dirty_ = (buffer != visibility_buffer_) || visibility_is_dirty_; + visibility_buffer_ = buffer; + visibility_buffer_->debug_ensure_used(); + } + else { + /* If buffer is null, reset visibility state, mark dirty to break render pass if results are no + * longer needed. */ + visibility_is_dirty_ = (visibility_buffer_ != nullptr) || visibility_is_dirty_; + visibility_buffer_ = nullptr; + } +} + +gpu::MTLBuffer *MTLContext::get_visibility_buffer() const +{ + return visibility_buffer_; +} + +void MTLContext::clear_visibility_dirty() +{ + visibility_is_dirty_ = false; +} + +bool MTLContext::is_visibility_dirty() const +{ + return visibility_is_dirty_; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Texture State Management * \{ */ |