diff options
Diffstat (limited to 'source/blender/gpu/metal/mtl_context.hh')
-rw-r--r-- | source/blender/gpu/metal/mtl_context.hh | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/source/blender/gpu/metal/mtl_context.hh b/source/blender/gpu/metal/mtl_context.hh new file mode 100644 index 00000000000..e855f9cb91a --- /dev/null +++ b/source/blender/gpu/metal/mtl_context.hh @@ -0,0 +1,185 @@ +/** \file + * \ingroup gpu + */ +#include "MEM_guardedalloc.h" + +#include "gpu_context_private.hh" + +#include "GPU_context.h" + +#include "mtl_texture.hh" + +#include <Cocoa/Cocoa.h> +#include <Metal/Metal.h> +#include <QuartzCore/QuartzCore.h> + +@class CAMetalLayer; +@class MTLCommandQueue; +@class MTLRenderPipelineState; + +namespace blender::gpu { + +typedef struct MTLContextTextureUtils { + + /* Depth Update Utilities */ + /* Depth texture updates are not directly supported with Blit operations, similarly, we cannot + * use a compute shader to write to depth, so we must instead render to a depth target. + * These processes use vertex/fragment shaders to render texture data from an intermediate + * source, in order to prime the depth buffer*/ + blender::Map<DepthTextureUpdateRoutineSpecialisation, GPUShader *> depth_2d_update_shaders; + GPUShader *fullscreen_blit_shader = nullptr; + + /* Texture Read/Update routines */ + blender::Map<TextureReadRoutineSpecialisation, id<MTLComputePipelineState>> + texture_1d_read_compute_psos; + blender::Map<TextureReadRoutineSpecialisation, id<MTLComputePipelineState>> + texture_1d_array_read_compute_psos; + blender::Map<TextureReadRoutineSpecialisation, id<MTLComputePipelineState>> + texture_2d_read_compute_psos; + blender::Map<TextureReadRoutineSpecialisation, id<MTLComputePipelineState>> + texture_2d_array_read_compute_psos; + blender::Map<TextureReadRoutineSpecialisation, id<MTLComputePipelineState>> + texture_3d_read_compute_psos; + blender::Map<TextureReadRoutineSpecialisation, id<MTLComputePipelineState>> + texture_cube_read_compute_psos; + blender::Map<TextureReadRoutineSpecialisation, id<MTLComputePipelineState>> + texture_cube_array_read_compute_psos; + blender::Map<TextureReadRoutineSpecialisation, id<MTLComputePipelineState>> + texture_buffer_read_compute_psos; + + blender::Map<TextureUpdateRoutineSpecialisation, id<MTLComputePipelineState>> + texture_1d_update_compute_psos; + blender::Map<TextureUpdateRoutineSpecialisation, id<MTLComputePipelineState>> + texture_1d_array_update_compute_psos; + blender::Map<TextureUpdateRoutineSpecialisation, id<MTLComputePipelineState>> + texture_2d_update_compute_psos; + blender::Map<TextureUpdateRoutineSpecialisation, id<MTLComputePipelineState>> + texture_2d_array_update_compute_psos; + blender::Map<TextureUpdateRoutineSpecialisation, id<MTLComputePipelineState>> + texture_3d_update_compute_psos; + blender::Map<TextureUpdateRoutineSpecialisation, id<MTLComputePipelineState>> + texture_cube_update_compute_psos; + blender::Map<TextureUpdateRoutineSpecialisation, id<MTLComputePipelineState>> + texture_cube_array_update_compute_psos; + blender::Map<TextureUpdateRoutineSpecialisation, id<MTLComputePipelineState>> + texture_buffer_update_compute_psos; + + template<typename T> + inline void free_cached_pso_map(blender::Map<T, id<MTLComputePipelineState>> &map) + { + for (typename blender::Map<T, id<MTLComputePipelineState>>::MutableItem item : map.items()) { + [item.value release]; + } + map.clear(); + } + + inline void init() + { + fullscreen_blit_shader = nullptr; + } + + inline void cleanup() + { + if (fullscreen_blit_shader) { + GPU_shader_free(fullscreen_blit_shader); + } + + /* Free Read shader maps */ + free_cached_pso_map(texture_1d_read_compute_psos); + free_cached_pso_map(texture_1d_read_compute_psos); + free_cached_pso_map(texture_1d_array_read_compute_psos); + free_cached_pso_map(texture_2d_read_compute_psos); + free_cached_pso_map(texture_2d_array_read_compute_psos); + free_cached_pso_map(texture_3d_read_compute_psos); + free_cached_pso_map(texture_cube_read_compute_psos); + free_cached_pso_map(texture_cube_array_read_compute_psos); + free_cached_pso_map(texture_buffer_read_compute_psos); + free_cached_pso_map(texture_1d_update_compute_psos); + free_cached_pso_map(texture_1d_array_update_compute_psos); + free_cached_pso_map(texture_2d_update_compute_psos); + free_cached_pso_map(texture_2d_array_update_compute_psos); + free_cached_pso_map(texture_3d_update_compute_psos); + free_cached_pso_map(texture_cube_update_compute_psos); + free_cached_pso_map(texture_cube_array_update_compute_psos); + free_cached_pso_map(texture_buffer_update_compute_psos); + } + +} MTLContextTextureUtils; + +typedef struct MTLContextGlobalShaderPipelineState { + /* ..TODO(Metal): More elements to be added as backend fleshed out.. */ + + /*** DATA and IMAGE access state ***/ + uint unpack_row_length; +} MTLContextGlobalShaderPipelineState; + +/* Metal Buffer */ +typedef struct MTLTemporaryBufferRange { + id<MTLBuffer> metal_buffer; + void *host_ptr; + unsigned long long buffer_offset; + unsigned long long size; + MTLResourceOptions options; + + void flush(); + bool requires_flush(); +} MTLTemporaryBufferRange; + +/** MTLContext -- Core render loop and state management **/ +/* Note(Metal): Partial MTLContext stub to provide wrapper functionality + * for work-in-progress MTL* classes. */ + +class MTLContext : public Context { + friend class MTLBackend; + + private: + /* Compute and specialisation caches */ + MTLContextTextureUtils texture_utils_; + + public: + /* METAL API Resource Handles. */ + id<MTLCommandQueue> queue = nil; + id<MTLDevice> device = nil; + + /* GPUContext interface. */ + MTLContext(void *ghost_window); + ~MTLContext(); + + static void check_error(const char *info); + + void activate(void) override; + void deactivate(void) override; + + void flush(void) override; + void finish(void) override; + + void memory_statistics_get(int *total_mem, int *free_mem) override; + + void debug_group_begin(const char *name, int index) override; + void debug_group_end(void) override; + + /*** Context Utility functions */ + /* + * All below functions modify the global state for the context, controlling the flow of + * rendering, binding resources, setting global state, resource management etc; + */ + + /* Metal Context Core functions */ + /* Command Buffer Management */ + id<MTLCommandBuffer> get_active_command_buffer(); + + /* Render Pass State and Management */ + void begin_render_pass(); + void end_render_pass(); + + /* Shaders and Pipeline state */ + MTLContextGlobalShaderPipelineState pipeline_state; + + /* Texture utilities */ + MTLContextTextureUtils &get_texture_utils() + { + return this->texture_utils_; + } +}; + +} // namespace blender::gpu |