20# pragma clang diagnostic ignored "-Wdeprecated-declarations"
36#include <Cocoa/Cocoa.h>
37#include <Metal/Metal.h>
38#include <QuartzCore/QuartzCore.h>
42@class MTLCommandQueue;
43@class MTLRenderPipelineState;
49class MTLCommandBufferManager;
65 return (used == other.used &&
state == other.
state);
110 :
ctx(context),
cmd(command_buffer_manager){};
139 bool use_argument_buffer_for_samplers,
142 bool use_argument_buffer_for_samplers,
158 :
ctx(context),
cmd(command_buffer_manager){};
174 void bind_pso(id<MTLComputePipelineState> pso);
180 bool use_argument_buffer_for_samplers,
232 bool stencil_state_equality =
true;
234 stencil_state_equality =
247 return depth_state_equality && stencil_state_equality;
260 std::size_t boolean_bitmask = (this->depth_write_enable ? 1 : 0) |
261 ((this->depth_test_enabled ? 1 : 0) << 1) |
262 ((this->depth_bias_enabled_for_points ? 1 : 0) << 2) |
263 ((this->depth_bias_enabled_for_lines ? 1 : 0) << 3) |
264 ((this->depth_bias_enabled_for_tris ? 1 : 0) << 4) |
265 ((this->stencil_test_enabled ? 1 : 0) << 5) |
266 ((this->has_depth_target ? 1 : 0) << 6) |
267 ((this->has_stencil_target ? 1 : 0) << 7);
269 std::size_t stencilop_bitmask = ((std::size_t)this->stencil_op_front_stencil_fail) |
270 ((std::size_t)this->stencil_op_front_depth_fail << 3) |
271 ((std::size_t)this->stencil_op_front_depthstencil_pass << 6) |
272 ((std::size_t)this->stencil_op_back_stencil_fail << 9) |
273 ((std::size_t)this->stencil_op_back_depth_fail << 12) |
274 ((std::size_t)this->stencil_op_back_depthstencil_pass << 15);
276 std::size_t main_hash = (std::size_t)this->depth_function;
277 if (this->has_stencil_target) {
278 main_hash += (std::size_t)(this->stencil_read_mask & 0xFF) << 8;
279 main_hash += (std::size_t)(this->stencil_write_mask & 0xFF) << 16;
281 main_hash ^= (std::size_t)this->stencil_func << 16;
282 main_hash ^= stencilop_bitmask;
284 std::size_t final_hash = (main_hash << 8) | boolean_bitmask;
337 [item.value release];
382 id<MTLComputePipelineState> buffer_clear_pso_ = nil;
388 if (buffer_clear_pso_) {
389 [buffer_clear_pso_ release];
390 buffer_clear_pso_ = nil;
404 if (this->num_samplers != other.num_samplers) {
407 return (memcmp(this->mtl_sampler_flags,
408 other.mtl_sampler_flags,
416 hash ^=
uint32_t(this->mtl_sampler_flags[i]) << (i % 3);
557 bool supports_render_ =
false;
560 id<MTLCommandBuffer> active_command_buffer_ = nil;
561 id<MTLCommandBuffer> last_submitted_command_buffer_ = nil;
565 MTL_NO_COMMAND_ENCODER = 0,
566 MTL_RENDER_COMMAND_ENCODER = 1,
567 MTL_BLIT_COMMAND_ENCODER = 2,
568 MTL_COMPUTE_COMMAND_ENCODER = 3
569 } active_command_encoder_type_ = MTL_NO_COMMAND_ENCODER;
571 id<MTLRenderCommandEncoder> active_render_command_encoder_ = nil;
572 id<MTLBlitCommandEncoder> active_blit_command_encoder_ = nil;
573 id<MTLComputeCommandEncoder> active_compute_command_encoder_ = nil;
578 MTLRenderPassDescriptor *active_pass_descriptor_ =
nullptr;
585 int current_draw_call_count_ = 0;
586 int encoder_count_ = 0;
587 int vertex_submitted_count_ = 0;
592 std::vector<std::string> debug_group_stack;
595 std::vector<std::string> debug_group_pushed_stack;
599 : context_(context), render_pass_state_(context, *this), compute_state_(context, *this){};
600 void prepare(
bool supports_render =
true);
619 return render_pass_state_;
627 return compute_state_;
658 id<MTLCommandBuffer> ensure_begin();
660 void register_encoder_counters();
663 void unfold_pending_debug_groups();
688 id<MTLCommandQueue> queue = nil;
710 id<MTLTexture> default_fbo_mtltexture_ = nil;
727 id<MTLSamplerState> default_sampler_state_ = nil;
738 bool is_inside_frame_ =
false;
739 uint current_frame_index_;
743 bool visibility_is_dirty_ =
false;
747 id<MTLBuffer> null_buffer_;
748 id<MTLBuffer> null_attribute_buffer_;
758 MTLContext(
void *ghost_window,
void *ghost_context);
768 void flush()
override;
859 void compute_dispatch(
int groups_x_len,
int groups_y_len,
int groups_z_len);
863 void set_viewport(
int origin_x,
int origin_y,
int width,
int height);
865 void set_scissor(
int scissor_x,
int scissor_y,
int scissor_width,
int scissor_height);
883 return texture_utils_;
889 return compute_utils_;
899 return is_inside_frame_;
904 return current_frame_index_;
965 void set_ghost_context(GHOST_ContextHandle ghostCtxHandle);
966 void set_ghost_window(GHOST_WindowHandle ghostWinHandle);
970void present(MTLRenderPassDescriptor *blit_descriptor,
971 id<MTLRenderPipelineState> blit_pso,
972 id<MTLTexture> swapchain_texture,
973 id<CAMetalDrawable> drawable);
#define ENUM_OPERATORS(_type, _max)
#define GPU_MAX_VIEWPORTS
void GPU_shader_free(GPUShader *shader)
static const int GPU_SAMPLER_FILTERING_TYPES_COUNT
#define GPU_SAMPLER_CUSTOM_TYPES_COUNT
#define GPU_SAMPLER_EXTEND_MODES_COUNT
Read Guarded memory(de)allocation.
struct GPUShader GPUShader
ItemIterator items() const
MTLFrameBuffer * get_active_framebuffer()
void encode_signal_event(id< MTLEvent > event, uint64_t value)
id< MTLComputeCommandEncoder > get_active_compute_command_encoder()
MTLCommandBufferManager(MTLContext &context)
bool end_active_command_encoder()
bool do_break_submission()
void register_draw_counters(int vertex_submission)
void prepare(bool supports_render=true)
MTLRenderPassState & get_render_pass_state()
id< MTLRenderCommandEncoder > ensure_begin_render_command_encoder(MTLFrameBuffer *ctx_framebuffer, bool force_begin, bool *r_new_pass)
bool is_inside_render_pass()
id< MTLComputeCommandEncoder > ensure_begin_compute_encoder()
bool insert_memory_barrier(eGPUBarrier barrier_bits, eGPUStageBarrierBits before_stages, eGPUStageBarrierBits after_stages)
static int num_active_cmd_bufs
MTLComputeState & get_compute_state()
id< MTLBlitCommandEncoder > ensure_begin_blit_encoder()
void push_debug_group(const char *name, int index)
id< MTLRenderCommandEncoder > get_active_render_command_encoder()
void encode_wait_for_event(id< MTLEvent > event, uint64_t value)
id< MTLBlitCommandEncoder > get_active_blit_command_encoder()
MTLComputeState(MTLContext &context, MTLCommandBufferManager &command_buffer_manager)
void bind_compute_bytes(const void *bytes, uint64_t length, uint index)
id< MTLComputePipelineState > bound_pso
void bind_compute_sampler(MTLSamplerBinding &sampler_binding, bool use_argument_buffer_for_samplers, uint slot)
MTLCommandBufferManager & cmd
BufferBindingCached cached_compute_buffer_bindings[MTL_MAX_BUFFER_BINDINGS]
void bind_compute_texture(id< MTLTexture > tex, uint slot)
TextureBindingCached cached_compute_texture_bindings[MTL_MAX_TEXTURE_SLOTS]
void bind_compute_buffer(id< MTLBuffer > buffer, uint64_t buffer_offset, uint index)
void bind_pso(id< MTLComputePipelineState > pso)
SamplerStateBindingCached cached_compute_sampler_state_bindings[MTL_MAX_TEXTURE_SLOTS]
id< MTLComputePipelineState > get_buffer_clear_pso()
bool ensure_render_pipeline_state(MTLPrimitiveType prim_type)
MTLFrameBuffer * get_current_framebuffer()
MTLFrameBuffer * get_default_framebuffer()
static std::atomic< int64_t > avg_drawable_latency_us
MTLContextComputeUtils & get_compute_utils()
const MTLComputePipelineStateInstance * ensure_compute_pipeline_state()
void clear_visibility_dirty()
id< MTLSamplerState > get_sampler_from_state(MTLSamplerState state)
MTLContext(void *ghost_window, void *ghost_context)
void deactivate() override
static void latency_resolve_average(int64_t frame_latency_us)
gpu::MTLBuffer * get_visibility_buffer() const
void debug_unbind_all_ubo() override
void set_visibility_buffer(gpu::MTLBuffer *buffer)
void set_scissor_enabled(bool scissor_enabled)
void framebuffer_bind(MTLFrameBuffer *framebuffer)
id< MTLRenderCommandEncoder > ensure_begin_render_pass()
static MTLContext * get()
id< MTLBuffer > get_null_buffer()
id< MTLBuffer > get_null_attribute_buffer()
static void global_memory_manager_release_ref()
MTLScratchBufferManager memory_manager
void pipeline_state_init()
MTLContextGlobalShaderPipelineState pipeline_state
void ensure_depth_stencil_state(MTLPrimitiveType prim_type)
bool debug_capture_begin(const char *title) override
void * debug_capture_scope_create(const char *name) override
void debug_capture_scope_end(void *scope) override
static MTLBufferPool * global_memory_manager
void end_frame() override
static int global_memory_manager_refcount
uint get_current_frame_index()
MTLShader * get_active_shader()
void set_viewport(int origin_x, int origin_y, int width, int height)
static int64_t frame_latency[MTL_FRAME_AVERAGE_COUNT]
static std::mutex global_memory_manager_reflock
void sampler_bind(MTLSamplerState, uint sampler_unit)
void texture_bind(gpu::MTLTexture *mtl_texture, uint texture_unit, bool is_image)
gpu::MTLTexture * get_dummy_texture(eGPUTextureType type, eGPUSamplerFormat sampler_format)
void begin_frame() override
void framebuffer_restore()
void set_viewports(int count, const int(&viewports)[GPU_MAX_VIEWPORTS][4])
void ensure_texture_bindings(id< MTLRenderCommandEncoder > rec, MTLShaderInterface *shader_interface, const MTLRenderPipelineStateInstance *pipeline_state_instance)
void compute_dispatch_indirect(StorageBuf *indirect_buf)
void debug_group_begin(const char *name, int index) override
void sampler_state_cache_init()
static void check_error(const char *info)
void texture_unbind(gpu::MTLTexture *mtl_texture, bool is_image)
void set_scissor(int scissor_x, int scissor_y, int scissor_width, int scissor_height)
bool debug_capture_scope_begin(void *scope) override
MTLCommandBufferManager main_command_buffer
void debug_group_end() override
id< MTLSamplerState > get_default_sampler_state()
bool is_visibility_dirty() const
void texture_unbind_all(bool is_image)
static void global_memory_manager_acquire_ref()
void memory_statistics_get(int *r_total_mem, int *r_free_mem) override
void free_dummy_resources()
bool ensure_buffer_bindings(id< MTLRenderCommandEncoder > rec, const MTLShaderInterface *shader_interface, const MTLRenderPipelineStateInstance *pipeline_state_instance)
MTLScratchBufferManager & get_scratchbuffer_manager()
void debug_unbind_all_ssbo() override
void compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len)
MTLContextTextureUtils & get_texture_utils()
static MTLBufferPool * get_global_memory_manager()
void debug_capture_end() override
static std::atomic< int > max_drawables_in_flight
MTLRenderPassState(MTLContext &context, MTLCommandBufferManager &command_buffer_manager)
void bind_fragment_sampler(MTLSamplerBinding &sampler_binding, bool use_argument_buffer_for_samplers, uint slot)
void bind_fragment_bytes(const void *bytes, uint64_t length, uint index)
SamplerStateBindingCached cached_fragment_sampler_state_bindings[MTL_MAX_TEXTURE_SLOTS]
void bind_vertex_sampler(MTLSamplerBinding &sampler_binding, bool use_argument_buffer_for_samplers, uint slot)
void bind_vertex_buffer(id< MTLBuffer > buffer, uint64_t buffer_offset, uint index)
void bind_vertex_texture(id< MTLTexture > tex, uint slot)
void bind_vertex_bytes(const void *bytes, uint64_t length, uint index)
id< MTLDepthStencilState > bound_ds_state
TextureBindingCached cached_vertex_texture_bindings[MTL_MAX_TEXTURE_SLOTS]
SamplerStateBindingCached cached_vertex_sampler_state_bindings[MTL_MAX_TEXTURE_SLOTS]
MTLScissorRect last_scissor_rect
uint last_used_stencil_ref_value
MTLCommandBufferManager & cmd
BufferBindingCached cached_fragment_buffer_bindings[MTL_MAX_BUFFER_BINDINGS]
id< MTLRenderPipelineState > bound_pso
BufferBindingCached cached_vertex_buffer_bindings[MTL_MAX_BUFFER_BINDINGS]
TextureBindingCached cached_fragment_texture_bindings[MTL_MAX_TEXTURE_SLOTS]
MTLBoundShaderState last_bound_shader_state
void bind_fragment_texture(id< MTLTexture > tex, uint slot)
void bind_fragment_buffer(id< MTLBuffer > buffer, uint64_t buffer_offset, uint index)
#define MTL_MAX_SAMPLER_SLOTS
#define MTL_MAX_BUFFER_BINDINGS
#define MTL_MAX_TEXTURE_SLOTS
#define MTL_FRAME_AVERAGE_COUNT
void present(MTLRenderPassDescriptor *blit_descriptor, id< MTLRenderPipelineState > blit_pso, id< MTLTexture > swapchain_texture, id< CAMetalDrawable > drawable)
static int sampler_binding(int32_t program, uint32_t uniform_index, int32_t uniform_location, int *sampler_len)
MTLPipelineStateDirtyFlag
@ MTL_PIPELINE_STATE_CULLMODE_FLAG
@ MTL_PIPELINE_STATE_PSO_FLAG
@ MTL_PIPELINE_STATE_SCISSOR_FLAG
@ MTL_PIPELINE_STATE_FRONT_FACING_FLAG
@ MTL_PIPELINE_STATE_DEPTHSTENCIL_FLAG
@ MTL_PIPELINE_STATE_NULL_FLAG
@ MTL_PIPELINE_STATE_VIEWPORT_FLAG
@ MTL_PIPELINE_STATE_ALL_FLAG
unsigned __int64 uint64_t
id< MTLBuffer > metal_buffer
void set(MTLShader *shader, uint pso_index)
bool depth_bias_enabled_for_lines
MTLCompareFunction depth_function
bool operator==(const MTLContextDepthStencilState &other) const
MTLStencilOperation stencil_op_back_depthstencil_pass
MTLCompareFunction stencil_func
MTLStencilOperation stencil_op_back_stencil_fail
MTLStencilOperation stencil_op_front_stencil_fail
bool depth_bias_enabled_for_tris
MTLStencilOperation stencil_op_front_depthstencil_pass
MTLStencilOperation stencil_op_front_depth_fail
MTLStencilOperation stencil_op_back_depth_fail
bool depth_bias_enabled_for_points
bool stencil_test_enabled
MTLColorWriteMask color_write_mask
MTLBlendFactor src_rgb_blend_factor
MTLStorageBufferBinding ssbo_bindings[MTL_MAX_BUFFER_BINDINGS]
MTLBlendOperation alpha_blend_op
MTLBlendFactor src_alpha_blend_factor
MTLTextureBinding texture_bindings[MTL_MAX_TEXTURE_SLOTS]
MTLShader * active_shader
MTLPipelineStateDirtyFlag dirty_flags
MTLUniformBufferBinding ubo_bindings[MTL_MAX_BUFFER_BINDINGS]
MTLBlendFactor dest_alpha_blend_factor
int viewport_width[GPU_MAX_VIEWPORTS]
MTLContextDepthStencilState depth_stencil_state
int viewport_height[GPU_MAX_VIEWPORTS]
MTLTextureBinding image_bindings[MTL_MAX_TEXTURE_SLOTS]
MTLSamplerBinding sampler_bindings[MTL_MAX_SAMPLER_SLOTS]
int viewport_offset_x[GPU_MAX_VIEWPORTS]
MTLBlendOperation rgb_blend_op
int viewport_offset_y[GPU_MAX_VIEWPORTS]
MTLBlendFactor dest_rgb_blend_factor
eGPUFaceCullTest cull_mode
bool clip_distance_enabled[6]
blender::Map< TextureReadRoutineSpecialisation, id< MTLComputePipelineState > > texture_1d_array_read_compute_psos
void free_cached_pso_map(blender::Map< T, id< MTLComputePipelineState > > &map)
blender::Map< TextureUpdateRoutineSpecialisation, id< MTLComputePipelineState > > texture_cube_update_compute_psos
blender::Map< TextureUpdateRoutineSpecialisation, id< MTLComputePipelineState > > texture_3d_update_compute_psos
blender::Map< TextureUpdateRoutineSpecialisation, id< MTLComputePipelineState > > texture_1d_update_compute_psos
blender::Map< TextureReadRoutineSpecialisation, id< MTLComputePipelineState > > texture_3d_read_compute_psos
GPUShader * fullscreen_blit_shader
blender::Map< TextureReadRoutineSpecialisation, id< MTLComputePipelineState > > texture_cube_read_compute_psos
blender::Map< TextureUpdateRoutineSpecialisation, id< MTLComputePipelineState > > texture_1d_array_update_compute_psos
blender::Map< TextureReadRoutineSpecialisation, id< MTLComputePipelineState > > texture_1d_read_compute_psos
blender::Map< TextureReadRoutineSpecialisation, id< MTLComputePipelineState > > texture_buffer_read_compute_psos
blender::Map< TextureUpdateRoutineSpecialisation, id< MTLComputePipelineState > > texture_2d_array_update_compute_psos
blender::Map< TextureUpdateRoutineSpecialisation, id< MTLComputePipelineState > > texture_buffer_update_compute_psos
blender::Map< TextureReadRoutineSpecialisation, id< MTLComputePipelineState > > texture_2d_array_read_compute_psos
blender::Map< TextureReadRoutineSpecialisation, id< MTLComputePipelineState > > texture_2d_read_compute_psos
blender::Map< DepthTextureUpdateRoutineSpecialisation, GPUShader * > depth_2d_update_shaders
blender::Map< TextureUpdateRoutineSpecialisation, id< MTLComputePipelineState > > texture_cube_array_update_compute_psos
blender::Map< TextureReadRoutineSpecialisation, id< MTLComputePipelineState > > texture_cube_array_read_compute_psos
blender::Map< TextureUpdateRoutineSpecialisation, id< MTLComputePipelineState > > texture_2d_update_compute_psos
MTLSamplerState mtl_sampler_flags[MTL_MAX_TEXTURE_SLOTS]
bool operator==(const MTLSamplerArray &other) const
id< MTLSamplerState > mtl_sampler[MTL_MAX_TEXTURE_SLOTS]
bool operator==(MTLSamplerBinding const &other) const
gpu::MTLTexture * texture_resource
bool is_arg_buffer_binding
MTLSamplerState binding_state
id< MTLSamplerState > sampler_state
id< MTLTexture > metal_texture