Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/metal/mtl_context.hh
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| /** \file | /** \file | ||||
| * \ingroup gpu | * \ingroup gpu | ||||
| */ | */ | ||||
| #pragma once | #pragma once | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "gpu_context_private.hh" | #include "gpu_context_private.hh" | ||||
| #include "GPU_common_types.h" | #include "GPU_common_types.h" | ||||
| #include "GPU_context.h" | #include "GPU_context.h" | ||||
| #include "intern/GHOST_Context.h" | |||||
| #include "intern/GHOST_ContextCGL.h" | |||||
| #include "intern/GHOST_Window.h" | |||||
| #include "mtl_backend.hh" | #include "mtl_backend.hh" | ||||
| #include "mtl_capabilities.hh" | #include "mtl_capabilities.hh" | ||||
| #include "mtl_common.hh" | #include "mtl_common.hh" | ||||
| #include "mtl_framebuffer.hh" | #include "mtl_framebuffer.hh" | ||||
| #include "mtl_memory.hh" | #include "mtl_memory.hh" | ||||
| #include "mtl_shader.hh" | #include "mtl_shader.hh" | ||||
| #include "mtl_shader_interface.hh" | #include "mtl_shader_interface.hh" | ||||
| #include "mtl_texture.hh" | #include "mtl_texture.hh" | ||||
| ▲ Show 20 Lines • Show All 542 Lines • ▼ Show 20 Lines | |||||
| }; | }; | ||||
| /** MTLContext -- Core render loop and state management. **/ | /** MTLContext -- Core render loop and state management. **/ | ||||
| /* NOTE(Metal): Partial #MTLContext stub to provide wrapper functionality | /* NOTE(Metal): Partial #MTLContext stub to provide wrapper functionality | ||||
| * for work-in-progress `MTL*` classes. */ | * for work-in-progress `MTL*` classes. */ | ||||
| class MTLContext : public Context { | class MTLContext : public Context { | ||||
| friend class MTLBackend; | friend class MTLBackend; | ||||
| friend class MTLRenderPassState; | |||||
| public: | |||||
| /* Swapchain and latency management. */ | |||||
| static std::atomic<int> max_drawables_in_flight; | |||||
| static std::atomic<int64_t> avg_drawable_latency_us; | |||||
fclem: Use `int64_t` instead. Applies to all the PR. | |||||
| static int64_t frame_latency[MTL_FRAME_AVERAGE_COUNT]; | |||||
| public: | |||||
| /* Shaders and Pipeline state. */ | |||||
| MTLContextGlobalShaderPipelineState pipeline_state; | |||||
| /* Metal API Resource Handles. */ | |||||
| id<MTLCommandQueue> queue = nil; | |||||
| id<MTLDevice> device = nil; | |||||
| #ifndef NDEBUG | |||||
| /* Label for Context debug name assignemnt. */ | |||||
| NSString *label = nil; | |||||
| #endif | |||||
| /* Memory Management. */ | |||||
| MTLScratchBufferManager memory_manager; | |||||
| static MTLBufferPool global_memory_manager; | |||||
| /* CommandBuffer managers. */ | |||||
| MTLCommandBufferManager main_command_buffer; | |||||
| private: | private: | ||||
| /* Null buffers for empty/uninitialized bindings. | /* Parent Context. */ | ||||
| * Null attribute buffer follows default attribute format of OpenGL Back-end. */ | GHOST_ContextCGL *ghost_context_; | ||||
| id<MTLBuffer> null_buffer_; /* All zero's. */ | |||||
| id<MTLBuffer> null_attribute_buffer_; /* Value float4(0.0,0.0,0.0,1.0). */ | /* Render Passes and Framebuffers. */ | ||||
| id<MTLTexture> default_fbo_mtltexture_ = nil; | |||||
| gpu::MTLTexture *default_fbo_gputexture_ = nullptr; | |||||
| /* Depth-stencil state cache. */ | |||||
| blender::Map<MTLContextDepthStencilState, id<MTLDepthStencilState>> depth_stencil_state_cache; | |||||
| /* Compute and specialization caches. */ | /* Compute and specialization caches. */ | ||||
| MTLContextTextureUtils texture_utils_; | MTLContextTextureUtils texture_utils_; | ||||
| /* Texture Samplers. */ | /* Texture Samplers. */ | ||||
| /* Cache of generated #MTLSamplerState objects based on permutations of `eGPUSamplerState`. */ | /* Cache of generated #MTLSamplerState objects based on permutations of `eGPUSamplerState`. */ | ||||
| id<MTLSamplerState> sampler_state_cache_[GPU_SAMPLER_MAX]; | id<MTLSamplerState> sampler_state_cache_[GPU_SAMPLER_MAX]; | ||||
| id<MTLSamplerState> default_sampler_state_ = nil; | id<MTLSamplerState> default_sampler_state_ = nil; | ||||
| Show All 9 Lines | private: | ||||
| /* Frame. */ | /* Frame. */ | ||||
| bool is_inside_frame_ = false; | bool is_inside_frame_ = false; | ||||
| uint current_frame_index_; | uint current_frame_index_; | ||||
| /* Visibility buffer for MTLQuery results. */ | /* Visibility buffer for MTLQuery results. */ | ||||
| gpu::MTLBuffer *visibility_buffer_ = nullptr; | gpu::MTLBuffer *visibility_buffer_ = nullptr; | ||||
| bool visibility_is_dirty_ = false; | bool visibility_is_dirty_ = false; | ||||
| public: | /* Null buffers for empty/unintialized bindings. | ||||
| /* Shaders and Pipeline state. */ | * Null attribute buffer follows default attribute format of OpenGL Backend. */ | ||||
| MTLContextGlobalShaderPipelineState pipeline_state; | id<MTLBuffer> null_buffer_; /* All zero's. */ | ||||
| id<MTLBuffer> null_attribute_buffer_; /* Value float4(0.0,0.0,0.0,1.0). */ | |||||
| /* Metal API Resource Handles. */ | |||||
| id<MTLCommandQueue> queue = nil; | |||||
| id<MTLDevice> device = nil; | |||||
| /* Memory Management */ | /** Dummy Resources */ | ||||
| MTLScratchBufferManager memory_manager; | /* Maximum of 32 texture types. Though most combinations invalid. */ | ||||
| static MTLBufferPool global_memory_manager; | gpu::MTLTexture *dummy_textures_[GPU_TEXTURE_BUFFER] = {nullptr}; | ||||
| GPUVertFormat dummy_vertformat_; | |||||
| /* CommandBuffer managers. */ | GPUVertBuf *dummy_verts_ = nullptr; | ||||
| MTLCommandBufferManager main_command_buffer; | |||||
| public: | |||||
| /* GPUContext interface. */ | /* GPUContext interface. */ | ||||
| MTLContext(void *ghost_window); | MTLContext(void *ghost_window, void *ghost_context); | ||||
| ~MTLContext(); | ~MTLContext(); | ||||
| static void check_error(const char *info); | static void check_error(const char *info); | ||||
| void activate() override; | void activate() override; | ||||
| void deactivate() override; | void deactivate() override; | ||||
| void begin_frame() override; | void begin_frame() override; | ||||
| void end_frame() override; | void end_frame() override; | ||||
| Show All 39 Lines | public: | ||||
| id<MTLSamplerState> get_sampler_from_state(MTLSamplerState state); | id<MTLSamplerState> get_sampler_from_state(MTLSamplerState state); | ||||
| id<MTLSamplerState> generate_sampler_from_state(MTLSamplerState state); | id<MTLSamplerState> generate_sampler_from_state(MTLSamplerState state); | ||||
| id<MTLSamplerState> get_default_sampler_state(); | id<MTLSamplerState> get_default_sampler_state(); | ||||
| /* Metal Context pipeline state. */ | /* Metal Context pipeline state. */ | ||||
| void pipeline_state_init(); | void pipeline_state_init(); | ||||
| MTLShader *get_active_shader(); | MTLShader *get_active_shader(); | ||||
| /* These functions ensure that the current RenderCommandEncoder has | |||||
| * the correct global state assigned. This should be called prior | |||||
| * to every draw call, to ensure that all state is applied and up | |||||
| * to date. We handle: | |||||
| * | |||||
| * - Buffer bindings (Vertex buffers, Uniforms, UBOs, transform feedback) | |||||
| * - Texture bindings | |||||
| * - Sampler bindings (+ argument buffer bindings) | |||||
| * - Dynamic Render pipeline state (on encoder) | |||||
| * - Baking Pipeline State Objects (PSOs) for current shader, based | |||||
| * on final pipeline state. | |||||
| * | |||||
| * `ensure_render_pipeline_state` will return false if the state is | |||||
| * invalid and cannot be applied. This should cancel a draw call. */ | |||||
| bool ensure_render_pipeline_state(MTLPrimitiveType prim_type); | |||||
| bool ensure_uniform_buffer_bindings( | |||||
| id<MTLRenderCommandEncoder> rec, | |||||
| const MTLShaderInterface *shader_interface, | |||||
| const MTLRenderPipelineStateInstance *pipeline_state_instance); | |||||
| void ensure_texture_bindings(id<MTLRenderCommandEncoder> rec, | |||||
| MTLShaderInterface *shader_interface, | |||||
| const MTLRenderPipelineStateInstance *pipeline_state_instance); | |||||
| void ensure_depth_stencil_state(MTLPrimitiveType prim_type); | |||||
| id<MTLBuffer> get_null_buffer(); | |||||
| id<MTLBuffer> get_null_attribute_buffer(); | |||||
| gpu::MTLTexture *get_dummy_texture(eGPUTextureType type); | |||||
| void free_dummy_resources(); | |||||
| /* State assignment. */ | /* State assignment. */ | ||||
| void set_viewport(int origin_x, int origin_y, int width, int height); | void set_viewport(int origin_x, int origin_y, int width, int height); | ||||
| void set_scissor(int scissor_x, int scissor_y, int scissor_width, int scissor_height); | void set_scissor(int scissor_x, int scissor_y, int scissor_width, int scissor_height); | ||||
| void set_scissor_enabled(bool scissor_enabled); | void set_scissor_enabled(bool scissor_enabled); | ||||
| /* Visibility buffer control. */ | /* Visibility buffer control. */ | ||||
| void set_visibility_buffer(gpu::MTLBuffer *buffer); | void set_visibility_buffer(gpu::MTLBuffer *buffer); | ||||
| gpu::MTLBuffer *get_visibility_buffer() const; | gpu::MTLBuffer *get_visibility_buffer() const; | ||||
| Show All 31 Lines | public: | ||||
| { | { | ||||
| return this->memory_manager; | return this->memory_manager; | ||||
| } | } | ||||
| static MTLBufferPool &get_global_memory_manager() | static MTLBufferPool &get_global_memory_manager() | ||||
| { | { | ||||
| return MTLContext::global_memory_manager; | return MTLContext::global_memory_manager; | ||||
| } | } | ||||
| /* Uniform Buffer Bindings to command encoders. */ | |||||
| id<MTLBuffer> get_null_buffer(); | /* Swapchain and latency management. */ | ||||
| id<MTLBuffer> get_null_attribute_buffer(); | static void latency_resolve_average(int64_t frame_latency_us) | ||||
| { | |||||
| int64_t avg = 0; | |||||
| int64_t frame_c = 0; | |||||
| for (int i = MTL_FRAME_AVERAGE_COUNT - 1; i > 0; i--) { | |||||
| MTLContext::frame_latency[i] = MTLContext::frame_latency[i - 1]; | |||||
| avg += MTLContext::frame_latency[i]; | |||||
| frame_c += (MTLContext::frame_latency[i] > 0) ? 1 : 0; | |||||
| } | |||||
| MTLContext::frame_latency[0] = frame_latency_us; | |||||
| avg += MTLContext::frame_latency[0]; | |||||
| if (frame_c > 0) { | |||||
| avg /= frame_c; | |||||
| } | |||||
| else { | |||||
| avg = 0; | |||||
| } | |||||
| MTLContext::avg_drawable_latency_us = avg; | |||||
| } | |||||
| private: | |||||
| void set_ghost_context(GHOST_ContextHandle ghostCtxHandle); | |||||
| void set_ghost_window(GHOST_WindowHandle ghostWinHandle); | |||||
| }; | }; | ||||
| /* GHOST Context callback and present. */ | |||||
| void present(MTLRenderPassDescriptor *blit_descriptor, | |||||
| id<MTLRenderPipelineState> blit_pso, | |||||
| id<MTLTexture> swapchain_texture, | |||||
| id<CAMetalDrawable> drawable); | |||||
| } // namespace blender::gpu | } // namespace blender::gpu | ||||
Use int64_t instead. Applies to all the PR.