diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index c44457f177..8d0f09372e 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -320,4 +320,3 @@ if (ARCHITECTURE_arm64 AND NOT TARGET sse2neon) add_library(sse2neon INTERFACE) target_include_directories(sse2neon INTERFACE sse2neon) endif() - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 20d3112f8a..f0c666fcc7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -184,6 +184,11 @@ else() endif() endif() +if (APPLE) + # TODO: use target_link_libraries + include_directories(${CMAKE_SOURCE_DIR}/externals/metal-cpp) +endif() + add_subdirectory(common) add_subdirectory(core) add_subdirectory(audio_core) diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index e228756613..394b37c8d7 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -374,16 +374,17 @@ if (APPLE) ) list(APPEND sources - renderer_metal/mtl_buffer_cache.mm + renderer_metal/metal_cpp_impl.cpp + renderer_metal/mtl_buffer_cache.cpp renderer_metal/mtl_buffer_cache_base.cpp - renderer_metal/mtl_command_recorder.mm - renderer_metal/mtl_device.mm - renderer_metal/mtl_rasterizer.mm - renderer_metal/mtl_staging_buffer_pool.mm - renderer_metal/mtl_swap_chain.mm - renderer_metal/mtl_texture_cache.mm + renderer_metal/mtl_command_recorder.cpp + renderer_metal/mtl_device.cpp + renderer_metal/mtl_rasterizer.cpp + renderer_metal/mtl_staging_buffer_pool.cpp + renderer_metal/mtl_swap_chain.cpp + renderer_metal/mtl_texture_cache.cpp renderer_metal/mtl_texture_cache_base.cpp - renderer_metal/renderer_metal.mm + renderer_metal/renderer_metal.cpp ) endif() @@ -404,10 +405,6 @@ add_dependencies(video_core host_shaders) target_include_directories(video_core PRIVATE ${HOST_SHADERS_INCLUDE}) target_link_libraries(video_core PRIVATE sirit Vulkan::Headers Vulkan::UtilityHeaders GPUOpen::VulkanMemoryAllocator) -if (APPLE) - target_include_directories(video_core PRIVATE ${CMAKE_SOURCE_DIR}/externals/metal-cpp) -endif() - if (ENABLE_NSIGHT_AFTERMATH) if (NOT DEFINED ENV{NSIGHT_AFTERMATH_SDK}) message(FATAL_ERROR "Environment variable NSIGHT_AFTERMATH_SDK has to be provided") diff --git a/src/video_core/renderer_metal/metal_cpp_impl.cpp b/src/video_core/renderer_metal/metal_cpp_impl.cpp new file mode 100644 index 0000000000..7fa7137b9f --- /dev/null +++ b/src/video_core/renderer_metal/metal_cpp_impl.cpp @@ -0,0 +1,6 @@ +#define NS_PRIVATE_IMPLEMENTATION +#define CA_PRIVATE_IMPLEMENTATION +#define MTL_PRIVATE_IMPLEMENTATION +#include +#include +#include diff --git a/src/video_core/renderer_metal/mtl_buffer_cache.mm b/src/video_core/renderer_metal/mtl_buffer_cache.cpp similarity index 71% rename from src/video_core/renderer_metal/mtl_buffer_cache.mm rename to src/video_core/renderer_metal/mtl_buffer_cache.cpp index 9bd84c6268..4ed4af520d 100644 --- a/src/video_core/renderer_metal/mtl_buffer_cache.mm +++ b/src/video_core/renderer_metal/mtl_buffer_cache.cpp @@ -15,37 +15,36 @@ namespace Metal { namespace { -MTLBuffer_t CreatePrivateBuffer(const Device& device, size_t size) { - return [device.GetDevice() newBufferWithLength:size options:MTLResourceStorageModePrivate]; +MTL::Buffer* CreatePrivateBuffer(const Device& device, size_t size) { + return device.GetDevice()->newBuffer(size, MTL::ResourceStorageModePrivate); } } // Anonymous namespace -BoundBuffer::BoundBuffer(MTLBuffer_t buffer_, size_t offset_, size_t size_) - : buffer{[buffer_ retain]}, offset{offset_}, size{size_} {} +BoundBuffer::BoundBuffer(MTL::Buffer* buffer_, size_t offset_, size_t size_) + : buffer{buffer_->retain()}, offset{offset_}, size{size_} {} BoundBuffer::~BoundBuffer() { if (buffer) { - [buffer release]; + buffer->release(); } } -BufferView::BufferView(MTLBuffer_t buffer_, size_t offset_, size_t size_, +BufferView::BufferView(MTL::Buffer* buffer_, size_t offset_, size_t size_, VideoCore::Surface::PixelFormat format_) - : buffer{[buffer_ retain]}, offset{offset_}, size{size_}, format{format_} {} + : buffer{buffer_->retain()}, offset{offset_}, size{size_}, format{format_} {} BufferView::~BufferView() { - [buffer release]; + buffer->release(); } Buffer::Buffer(BufferCacheRuntime& runtime, VideoCommon::NullBufferParams null_params) - : VideoCommon::BufferBase(null_params), buffer{runtime.CreateNullBuffer()}, - is_null{true}, view(buffer, 0, BufferCacheRuntime::NULL_BUFFER_SIZE) {} + : VideoCommon::BufferBase(null_params), buffer{runtime.CreateNullBuffer()}, is_null{true}, + view(buffer, 0, BufferCacheRuntime::NULL_BUFFER_SIZE) {} Buffer::Buffer(BufferCacheRuntime& runtime, DAddr cpu_addr_, u64 size_bytes_) : VideoCommon::BufferBase(cpu_addr_, size_bytes_), - buffer{CreatePrivateBuffer(runtime.device, size_bytes_)}, - view(buffer, 0, size_bytes_) {} + buffer{CreatePrivateBuffer(runtime.device, size_bytes_)}, view(buffer, 0, size_bytes_) {} BufferView Buffer::View(u32 offset, u32 size, VideoCore::Surface::PixelFormat format) { return BufferView(buffer, offset, size, format); @@ -78,18 +77,18 @@ void BufferCacheRuntime::TickFrame(Common::SlotVector& slot_buffers) noe void BufferCacheRuntime::Finish() {} -void BufferCacheRuntime::CopyBuffer(MTLBuffer_t dst_buffer, MTLBuffer_t src_buffer, +void BufferCacheRuntime::CopyBuffer(MTL::Buffer* dst_buffer, MTL::Buffer* src_buffer, std::span copies, bool barrier, bool can_reorder_upload) { // TODO: copy buffer } -void BufferCacheRuntime::ClearBuffer(MTLBuffer_t dest_buffer, u32 offset, size_t size, u32 value) { +void BufferCacheRuntime::ClearBuffer(MTL::Buffer* dest_buffer, u32 offset, size_t size, u32 value) { // TODO: clear buffer } void BufferCacheRuntime::BindIndexBuffer(PrimitiveTopology topology, IndexFormat index_format, - u32 base_vertex, u32 num_indices, MTLBuffer_t buffer, + u32 base_vertex, u32 num_indices, MTL::Buffer* buffer, u32 offset, [[maybe_unused]] u32 size) { // TODO: convert parameters to Metal enums bound_index_buffer = {BoundBuffer(buffer, offset, size)}; @@ -99,7 +98,7 @@ void BufferCacheRuntime::BindQuadIndexBuffer(PrimitiveTopology topology, u32 fir // TODO: bind quad index buffer } -void BufferCacheRuntime::BindVertexBuffer(u32 index, MTLBuffer_t buffer, u32 offset, u32 size, +void BufferCacheRuntime::BindVertexBuffer(u32 index, MTL::Buffer* buffer, u32 offset, u32 size, u32 stride) { // TODO: use stride bound_vertex_buffers[MAX_METAL_BUFFERS - index - 1] = {BoundBuffer(buffer, offset, size)}; @@ -115,9 +114,8 @@ void BufferCacheRuntime::ReserveNullBuffer() { } } -MTLBuffer_t BufferCacheRuntime::CreateNullBuffer() { - return [device.GetDevice() newBufferWithLength:NULL_BUFFER_SIZE - options:MTLResourceStorageModePrivate]; +MTL::Buffer* BufferCacheRuntime::CreateNullBuffer() { + return CreatePrivateBuffer(device, NULL_BUFFER_SIZE); } -} // namespace Vulkan +} // namespace Metal diff --git a/src/video_core/renderer_metal/mtl_buffer_cache.h b/src/video_core/renderer_metal/mtl_buffer_cache.h index 3dbab2cf45..0fda327b35 100644 --- a/src/video_core/renderer_metal/mtl_buffer_cache.h +++ b/src/video_core/renderer_metal/mtl_buffer_cache.h @@ -19,21 +19,21 @@ class BufferCacheRuntime; struct BoundBuffer { BoundBuffer() = default; - BoundBuffer(MTLBuffer_t buffer_, size_t offset_, size_t size_); + BoundBuffer(MTL::Buffer* buffer_, size_t offset_, size_t size_); ~BoundBuffer(); - MTLBuffer_t buffer = nil; + MTL::Buffer* buffer = nil; size_t offset{}; size_t size{}; }; struct BufferView { - BufferView(MTLBuffer_t buffer_, size_t offset_, size_t size_, + BufferView(MTL::Buffer* buffer_, size_t offset_, size_t size_, VideoCore::Surface::PixelFormat format_ = VideoCore::Surface::PixelFormat::Invalid); ~BufferView(); - MTLBuffer_t buffer = nil; + MTL::Buffer* buffer = nil; size_t offset{}; size_t size{}; VideoCore::Surface::PixelFormat format{}; @@ -50,16 +50,16 @@ public: // TODO: track usage } - [[nodiscard]] MTLBuffer_t Handle() const noexcept { + [[nodiscard]] MTL::Buffer* Handle() const noexcept { return buffer; } - operator MTLBuffer_t() const noexcept { + operator MTL::Buffer*() const noexcept { return buffer; } private: - MTLBuffer_t buffer = nil; + MTL::Buffer* buffer = nil; bool is_null{}; BufferView view; @@ -108,25 +108,25 @@ public: void PreCopyBarrier() {} - void CopyBuffer(MTLBuffer_t src_buffer, MTLBuffer_t dst_buffer, + void CopyBuffer(MTL::Buffer* src_buffer, MTL::Buffer* dst_buffer, std::span copies, bool barrier, bool can_reorder_upload = false); void PostCopyBarrier() {} - void ClearBuffer(MTLBuffer_t dest_buffer, u32 offset, size_t size, u32 value); + void ClearBuffer(MTL::Buffer* dest_buffer, u32 offset, size_t size, u32 value); void BindIndexBuffer(PrimitiveTopology topology, IndexFormat index_format, u32 num_indices, - u32 base_vertex, MTLBuffer_t buffer, u32 offset, u32 size); + u32 base_vertex, MTL::Buffer* buffer, u32 offset, u32 size); void BindQuadIndexBuffer(PrimitiveTopology topology, u32 first, u32 count); - void BindVertexBuffer(u32 index, MTLBuffer_t buffer, u32 offset, u32 size, u32 stride); + void BindVertexBuffer(u32 index, MTL::Buffer* buffer, u32 offset, u32 size, u32 stride); void BindVertexBuffers(VideoCommon::HostBindings& bindings); // TODO: implement - void BindTransformFeedbackBuffer(u32 index, MTLBuffer_t buffer, u32 offset, u32 size) {} + void BindTransformFeedbackBuffer(u32 index, MTL::Buffer* buffer, u32 offset, u32 size) {} // TODO: implement void BindTransformFeedbackBuffers(VideoCommon::HostBindings& bindings) {} @@ -138,11 +138,11 @@ public: return ref.mapped_span; } - void BindUniformBuffer(MTLBuffer_t buffer, u32 offset, u32 size) { + void BindUniformBuffer(MTL::Buffer* buffer, u32 offset, u32 size) { BindBuffer(buffer, offset, size); } - void BindStorageBuffer(MTLBuffer_t buffer, u32 offset, u32 size, + void BindStorageBuffer(MTL::Buffer* buffer, u32 offset, u32 size, [[maybe_unused]] bool is_written) { BindBuffer(buffer, offset, size); } @@ -152,21 +152,21 @@ public: VideoCore::Surface::PixelFormat format) {} private: - void BindBuffer(MTLBuffer_t buffer, u32 offset, u32 size) { + void BindBuffer(MTL::Buffer* buffer, u32 offset, u32 size) { // FIXME: what should be the index? bound_buffers[0] = BoundBuffer(buffer, offset, size); } void ReserveNullBuffer(); - MTLBuffer_t CreateNullBuffer(); + MTL::Buffer* CreateNullBuffer(); const Device& device; CommandRecorder& command_recorder; StagingBufferPool& staging_pool; // Common buffers - MTLBuffer_t null_buffer = nil; - MTLBuffer_t quad_index_buffer = nil; + MTL::Buffer* null_buffer = nil; + MTL::Buffer* quad_index_buffer = nil; // TODO: probably move this into a separate class // Bound state diff --git a/src/video_core/renderer_metal/mtl_command_recorder.mm b/src/video_core/renderer_metal/mtl_command_recorder.cpp similarity index 70% rename from src/video_core/renderer_metal/mtl_command_recorder.mm rename to src/video_core/renderer_metal/mtl_command_recorder.cpp index 65ae62a294..73d8df3a14 100644 --- a/src/video_core/renderer_metal/mtl_command_recorder.mm +++ b/src/video_core/renderer_metal/mtl_command_recorder.cpp @@ -12,10 +12,10 @@ CommandRecorder::CommandRecorder(const Device& device_) : device(device_) {} CommandRecorder::~CommandRecorder() = default; -void CommandRecorder::BeginRenderPass(MTLRenderPassDescriptor* render_pass_descriptor) { +void CommandRecorder::BeginRenderPass(MTL::RenderPassDescriptor* render_pass_descriptor) { RequireCommandBuffer(); EndEncoding(); - encoder = [command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor]; + encoder = command_buffer->renderCommandEncoder(render_pass_descriptor); encoder_type = EncoderType::Render; } @@ -23,7 +23,7 @@ void CommandRecorder::RequireComputeEncoder() { RequireCommandBuffer(); if (!encoder || encoder_type != EncoderType::Compute) { EndEncoding(); - encoder = [command_buffer computeCommandEncoder]; + encoder = command_buffer->computeCommandEncoder(); encoder_type = EncoderType::Compute; } } @@ -32,28 +32,28 @@ void CommandRecorder::RequireBlitEncoder() { RequireCommandBuffer(); if (!encoder || encoder_type != EncoderType::Blit) { EndEncoding(); - encoder = [command_buffer blitCommandEncoder]; + encoder = command_buffer->blitCommandEncoder(); encoder_type = EncoderType::Blit; } } void CommandRecorder::EndEncoding() { if (encoder) { - [encoder endEncoding]; + encoder->endEncoding(); //[encoder release]; encoder = nil; } } -void CommandRecorder::Present(CAMetalDrawable_t drawable) { +void CommandRecorder::Present(CA::MetalDrawable* drawable) { EndEncoding(); - [command_buffer presentDrawable:drawable]; + command_buffer->presentDrawable(drawable); } void CommandRecorder::Submit() { if (command_buffer) { EndEncoding(); - [command_buffer commit]; + command_buffer->commit(); //[command_buffer release]; command_buffer = nil; } @@ -61,7 +61,7 @@ void CommandRecorder::Submit() { void CommandRecorder::RequireCommandBuffer() { if (!command_buffer) { - command_buffer = [device.GetCommandQueue() commandBuffer]; + command_buffer = device.GetCommandQueue()->commandBuffer(); } } diff --git a/src/video_core/renderer_metal/mtl_command_recorder.h b/src/video_core/renderer_metal/mtl_command_recorder.h index db36449480..c0337c776e 100644 --- a/src/video_core/renderer_metal/mtl_command_recorder.h +++ b/src/video_core/renderer_metal/mtl_command_recorder.h @@ -3,8 +3,8 @@ #pragma once -#include "objc_bridge.h" -#include "video_core/renderer_metal/objc_bridge.h" +#include +#include namespace Metal { @@ -17,7 +17,7 @@ public: CommandRecorder(const Device& device_); ~CommandRecorder(); - void BeginRenderPass(MTLRenderPassDescriptor* render_pass_descriptor); + void BeginRenderPass(MTL::RenderPassDescriptor* render_pass_descriptor); void CheckIfRenderPassIsActive() { if (!encoder || encoder_type != EncoderType::Render) { @@ -32,15 +32,15 @@ public: void EndEncoding(); - void Present(CAMetalDrawable_t drawable); + void Present(CA::MetalDrawable* drawable); void Submit(); - MTLCommandBuffer_t GetCommandBuffer() { + MTL::CommandBuffer* GetCommandBuffer() { return command_buffer; } - MTLCommandEncoder_t GetCommandEncoder() { + MTL::CommandEncoder* GetCommandEncoder() { return encoder; } @@ -49,8 +49,8 @@ private: // HACK: Command buffers and encoders currently aren't released every frame due to Xcode // crashing in Debug mode. This leads to memory leaks - MTLCommandBuffer_t command_buffer = nil; - MTLCommandEncoder_t encoder = nil; + MTL::CommandBuffer* command_buffer = nil; + MTL::CommandEncoder* encoder = nil; EncoderType encoder_type; diff --git a/src/video_core/renderer_metal/mtl_device.mm b/src/video_core/renderer_metal/mtl_device.cpp similarity index 75% rename from src/video_core/renderer_metal/mtl_device.mm rename to src/video_core/renderer_metal/mtl_device.cpp index 412d9534bb..3e3cb060f7 100644 --- a/src/video_core/renderer_metal/mtl_device.mm +++ b/src/video_core/renderer_metal/mtl_device.cpp @@ -6,19 +6,19 @@ namespace Metal { Device::Device() { - device = MTLCreateSystemDefaultDevice(); + device = MTL::CreateSystemDefaultDevice(); if (!device) { throw std::runtime_error("Failed to create Metal device"); } - command_queue = [device newCommandQueue]; + command_queue = device->newCommandQueue(); if (!command_queue) { throw std::runtime_error("Failed to create Metal command queue"); } } Device::~Device() { - [command_queue release]; - [device release]; + command_queue->release(); + device->release(); } } // namespace Metal diff --git a/src/video_core/renderer_metal/mtl_device.h b/src/video_core/renderer_metal/mtl_device.h index cc5ea06570..1b3094bcb7 100644 --- a/src/video_core/renderer_metal/mtl_device.h +++ b/src/video_core/renderer_metal/mtl_device.h @@ -3,7 +3,9 @@ #pragma once -#include "video_core/renderer_metal/objc_bridge.h" +#include +#include +#include namespace Metal { @@ -12,17 +14,17 @@ public: explicit Device(); ~Device(); - MTLDevice_t GetDevice() const { + MTL::Device* GetDevice() const { return device; } - MTLCommandQueue_t GetCommandQueue() const { + MTL::CommandQueue* GetCommandQueue() const { return command_queue; } private: - MTLDevice_t device; - MTLCommandQueue_t command_queue; + MTL::Device* device; + MTL::CommandQueue* command_queue; }; } // namespace Metal diff --git a/src/video_core/renderer_metal/mtl_rasterizer.mm b/src/video_core/renderer_metal/mtl_rasterizer.cpp similarity index 100% rename from src/video_core/renderer_metal/mtl_rasterizer.mm rename to src/video_core/renderer_metal/mtl_rasterizer.cpp diff --git a/src/video_core/renderer_metal/mtl_staging_buffer_pool.mm b/src/video_core/renderer_metal/mtl_staging_buffer_pool.cpp similarity index 77% rename from src/video_core/renderer_metal/mtl_staging_buffer_pool.mm rename to src/video_core/renderer_metal/mtl_staging_buffer_pool.cpp index 227355c3fb..97bc9e88fe 100644 --- a/src/video_core/renderer_metal/mtl_staging_buffer_pool.mm +++ b/src/video_core/renderer_metal/mtl_staging_buffer_pool.cpp @@ -18,18 +18,18 @@ namespace Metal { -StagingBufferRef::StagingBufferRef(MTLBuffer_t buffer_, size_t offset_, std::span mapped_span_) - : buffer{[buffer_ retain]}, offset{offset_}, mapped_span{mapped_span_} {} +StagingBufferRef::StagingBufferRef(MTL::Buffer* buffer_, size_t offset_, std::span mapped_span_) + : buffer{buffer_->retain()}, offset{offset_}, mapped_span{mapped_span_} {} StagingBufferRef::~StagingBufferRef() { - [buffer release]; + buffer->release(); } -StagingBuffer::StagingBuffer(MTLBuffer_t buffer_, std::span mapped_span_) - : buffer{[buffer_ retain]}, mapped_span{mapped_span_} {} +StagingBuffer::StagingBuffer(MTL::Buffer* buffer_, std::span mapped_span_) + : buffer{buffer_->retain()}, mapped_span{mapped_span_} {} StagingBuffer::~StagingBuffer() { - [buffer release]; + buffer->release(); } StagingBufferRef StagingBuffer::Ref() const noexcept { @@ -37,13 +37,13 @@ StagingBufferRef StagingBuffer::Ref() const noexcept { } // TODO: use the _MiB suffix -constexpr size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;//128_MiB; +constexpr size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; // 128_MiB; constexpr size_t REGION_SIZE = STREAM_BUFFER_SIZE / StagingBufferPool::NUM_SYNCS; StagingBufferPool::StagingBufferPool(const Device& device_, CommandRecorder& command_recorder_) : device{device_}, command_recorder{command_recorder_} { - stream_buffer = [device.GetDevice() newBufferWithLength:STREAM_BUFFER_SIZE - options:MTLResourceStorageModeShared]; + stream_buffer = + device.GetDevice()->newBuffer(STREAM_BUFFER_SIZE, MTL::ResourceStorageModeShared); } StagingBufferPool::~StagingBufferPool() = default; @@ -57,7 +57,7 @@ StagingBufferRef StagingBufferPool::Request(size_t size, MemoryUsage usage, bool } void StagingBufferPool::FreeDeferred(StagingBufferRef& ref) { - // TODO: implement this + // TODO: implement this } void StagingBufferPool::TickFrame() { @@ -83,10 +83,9 @@ StagingBufferRef StagingBufferPool::GetStagingBuffer(size_t size, MemoryUsage us StagingBufferRef StagingBufferPool::CreateStagingBuffer(size_t size, MemoryUsage usage, bool deferred) { const u32 log2 = Common::Log2Ceil64(size); - MTLBuffer_t buffer = [device.GetDevice() newBufferWithLength:size - options:MTLResourceStorageModeShared]; + MTL::Buffer* buffer = device.GetDevice()->newBuffer(size, MTL::ResourceStorageModeShared); // TODO: check if the mapped span is correct - std::span mapped_span(static_cast([buffer contents]), size); + std::span mapped_span(static_cast(buffer->contents()), size); auto& entry = GetCache(usage)[log2].entries.emplace_back(buffer, mapped_span); return entry.Ref(); diff --git a/src/video_core/renderer_metal/mtl_staging_buffer_pool.h b/src/video_core/renderer_metal/mtl_staging_buffer_pool.h index b3b62d4aea..e065272531 100644 --- a/src/video_core/renderer_metal/mtl_staging_buffer_pool.h +++ b/src/video_core/renderer_metal/mtl_staging_buffer_pool.h @@ -7,10 +7,9 @@ #include #include -#include "common/common_types.h" +#include -#include "objc_bridge.h" -#include "video_core/renderer_metal/objc_bridge.h" +#include "common/common_types.h" namespace Metal { @@ -24,19 +23,19 @@ enum class MemoryUsage { }; struct StagingBufferRef { - StagingBufferRef(MTLBuffer_t buffer_, size_t offset_, std::span mapped_span_); + StagingBufferRef(MTL::Buffer* buffer_, size_t offset_, std::span mapped_span_); ~StagingBufferRef(); - MTLBuffer_t buffer; + MTL::Buffer* buffer; size_t offset; std::span mapped_span; }; struct StagingBuffer { - StagingBuffer(MTLBuffer_t buffer_, std::span mapped_span_); + StagingBuffer(MTL::Buffer* buffer_, std::span mapped_span_); ~StagingBuffer(); - MTLBuffer_t buffer; + MTL::Buffer* buffer; std::span mapped_span; StagingBufferRef Ref() const noexcept; @@ -52,7 +51,7 @@ public: StagingBufferRef Request(size_t size, MemoryUsage usage, bool deferred = false); void FreeDeferred(StagingBufferRef& ref); - [[nodiscard]] MTLBuffer_t GetSTreamBufferHandle() const noexcept { + [[nodiscard]] MTL::Buffer* GetSTreamBufferHandle() const noexcept { return stream_buffer; } @@ -83,7 +82,7 @@ private: const Device& device; CommandRecorder& command_recorder; - MTLBuffer_t stream_buffer{}; + MTL::Buffer* stream_buffer{}; size_t iterator = 0; size_t used_iterator = 0; diff --git a/src/video_core/renderer_metal/mtl_swap_chain.mm b/src/video_core/renderer_metal/mtl_swap_chain.cpp similarity index 70% rename from src/video_core/renderer_metal/mtl_swap_chain.mm rename to src/video_core/renderer_metal/mtl_swap_chain.cpp index 9d3757bc5c..5d69b48cf6 100644 --- a/src/video_core/renderer_metal/mtl_swap_chain.mm +++ b/src/video_core/renderer_metal/mtl_swap_chain.cpp @@ -8,28 +8,28 @@ namespace Metal { SwapChain::SwapChain(const Device& device_, CommandRecorder& command_recorder_, - const CAMetalLayer* layer_) - : device(device_), command_recorder(command_recorder_), layer([layer_ retain]) { + CA::MetalLayer* layer_) + : device(device_), command_recorder(command_recorder_), layer(layer_->retain()) { // Give the layer our device - layer.device = device.GetDevice(); + layer->setDevice(device.GetDevice()); } SwapChain::~SwapChain() { - [layer release]; + layer->release(); } void SwapChain::AcquireNextDrawable() { // Get the next drawable - drawable = [[layer nextDrawable] retain]; + drawable = layer->nextDrawable()->retain(); } void SwapChain::Present() { command_recorder.Present(drawable); - [drawable release]; + drawable->release(); } -MTLTexture_t SwapChain::GetDrawableTexture() { - return drawable.texture; +MTL::Texture* SwapChain::GetDrawableTexture() { + return drawable->texture(); } } // namespace Metal diff --git a/src/video_core/renderer_metal/mtl_swap_chain.h b/src/video_core/renderer_metal/mtl_swap_chain.h index bf188c2b9d..978b6b7554 100644 --- a/src/video_core/renderer_metal/mtl_swap_chain.h +++ b/src/video_core/renderer_metal/mtl_swap_chain.h @@ -3,7 +3,8 @@ #pragma once -#include "video_core/renderer_metal/objc_bridge.h" +#include +#include namespace Metal { @@ -12,8 +13,7 @@ class CommandRecorder; class SwapChain { public: - SwapChain(const Device& device_, CommandRecorder& command_recorder_, - const CAMetalLayer* layer_); + SwapChain(const Device& device_, CommandRecorder& command_recorder_, CA::MetalLayer* layer_); ~SwapChain(); void AcquireNextDrawable(); @@ -21,14 +21,14 @@ public: void Present(); // Can only be called between AcquireNextDrawable and Present - MTLTexture_t GetDrawableTexture(); + MTL::Texture* GetDrawableTexture(); private: const Device& device; CommandRecorder& command_recorder; - const CAMetalLayer* layer; + CA::MetalLayer* layer; - CAMetalDrawable_t drawable = nil; + CA::MetalDrawable* drawable = nil; }; } // namespace Metal diff --git a/src/video_core/renderer_metal/mtl_texture_cache.mm b/src/video_core/renderer_metal/mtl_texture_cache.cpp similarity index 57% rename from src/video_core/renderer_metal/mtl_texture_cache.mm rename to src/video_core/renderer_metal/mtl_texture_cache.cpp index a77e1345d5..78a80b3719 100644 --- a/src/video_core/renderer_metal/mtl_texture_cache.mm +++ b/src/video_core/renderer_metal/mtl_texture_cache.cpp @@ -3,9 +3,9 @@ #include #include -#include #include #include +#include #include "common/bit_cast.h" #include "common/bit_util.h" @@ -37,8 +37,7 @@ using VideoCore::Surface::SurfaceType; TextureCacheRuntime::TextureCacheRuntime(const Device& device_, CommandRecorder& command_recorder_, StagingBufferPool& staging_buffer_pool_) : device{device_}, command_recorder{command_recorder_}, - staging_buffer_pool{staging_buffer_pool_}, - resolution{Settings::values.resolution_info} {} + staging_buffer_pool{staging_buffer_pool_}, resolution{Settings::values.resolution_info} {} void TextureCacheRuntime::TickFrame() {} @@ -54,30 +53,28 @@ void TextureCacheRuntime::FreeDeferredStagingBuffer(StagingBufferRef& ref) { staging_buffer_pool.FreeDeferred(ref); } -Image::Image(TextureCacheRuntime& runtime, const ImageInfo& info, - GPUVAddr gpu_addr_, VAddr cpu_addr_) +Image::Image(TextureCacheRuntime& runtime, const ImageInfo& info, GPUVAddr gpu_addr_, + VAddr cpu_addr_) : VideoCommon::ImageBase(info, gpu_addr_, cpu_addr_) { - MTLTextureDescriptor *texture_descriptor = - [[MTLTextureDescriptor alloc] init]; + MTL::TextureDescriptor* texture_descriptor = MTL::TextureDescriptor::alloc()->init(); // TODO: don't hardcode the format - texture_descriptor.pixelFormat = MTLPixelFormatRGBA8Unorm; - texture_descriptor.width = info.size.width; - texture_descriptor.height = info.size.height; + texture_descriptor->setPixelFormat(MTL::PixelFormatRGBA8Unorm); + texture_descriptor->setWidth(info.size.width); + texture_descriptor->setHeight(info.size.height); - texture = - [runtime.device.GetDevice() newTextureWithDescriptor:texture_descriptor]; + texture = runtime.device.GetDevice()->newTexture(texture_descriptor); } Image::Image(const VideoCommon::NullImageParams& params) : VideoCommon::ImageBase{params} {} Image::~Image() { if (texture) { - [texture release]; + texture->release(); } } // TODO: implement these -void Image::UploadMemory(MTLBuffer_t buffer, size_t offset, +void Image::UploadMemory(MTL::Buffer* buffer, size_t offset, std::span copies) { ; } @@ -87,38 +84,33 @@ void Image::UploadMemory(const StagingBufferRef& map, ; } -void Image::DownloadMemory(MTLBuffer_t buffer, size_t offset, +void Image::DownloadMemory(MTL::Buffer* buffer, size_t offset, std::span copies) { ; } -// TODO: uncomment -/* -void Image::DownloadMemory(std::span buffers, std::span offsets, +void Image::DownloadMemory(std::span buffers, std::span offsets, std::span copies) { ; } -*/ void Image::DownloadMemory(const StagingBufferRef& map, std::span copies) { ; } -ImageView::ImageView(TextureCacheRuntime& runtime, - const VideoCommon::ImageViewInfo& info, ImageId image_id_, - Image& image) +ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, + ImageId image_id_, Image& image) : VideoCommon::ImageViewBase{info, image.info, image_id_, image.gpu_addr} { using Shader::TextureType; - texture = [image.GetHandle() retain]; + texture = image.GetHandle()->retain(); // TODO: create texture view } -ImageView::ImageView(TextureCacheRuntime& runtime, - const VideoCommon::ImageViewInfo& info, ImageId image_id_, - Image& image, const SlotVector& slot_imgs) +ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewInfo& info, + ImageId image_id_, Image& image, const SlotVector& slot_imgs) : ImageView(runtime, info, image_id_, image) { // TODO: save slot images } @@ -134,52 +126,51 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::NullImageV // TODO: implement } -ImageView::~ImageView() { [texture release]; } +ImageView::~ImageView() { + texture->release(); +} -Sampler::Sampler(TextureCacheRuntime& runtime, - const Tegra::Texture::TSCEntry& tsc) { - MTLSamplerDescriptor* sampler_descriptor = - [[MTLSamplerDescriptor alloc] init]; +Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& tsc) { + MTL::SamplerDescriptor* sampler_descriptor = MTL::SamplerDescriptor::alloc()->init(); // TODO: configure the descriptor - sampler_state = [runtime.device.GetDevice() - newSamplerStateWithDescriptor:sampler_descriptor]; + sampler_state = runtime.device.GetDevice()->newSamplerState(sampler_descriptor); } -Framebuffer::Framebuffer(TextureCacheRuntime& runtime, - std::span color_buffers, - ImageView* depth_buffer, - const VideoCommon::RenderTargets& key) { - CreateRenderPassDescriptor(runtime, color_buffers, depth_buffer, - key.is_rescaled, key.size.width, key.size.height); +Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span color_buffers, + ImageView* depth_buffer, const VideoCommon::RenderTargets& key) { + CreateRenderPassDescriptor(runtime, color_buffers, depth_buffer, key.is_rescaled, + key.size.width, key.size.height); } Framebuffer::~Framebuffer() = default; -void Framebuffer::CreateRenderPassDescriptor( - TextureCacheRuntime& runtime, std::span color_buffers, - ImageView* depth_buffer, bool is_rescaled, size_t width, size_t height) { - render_pass = [MTLRenderPassDescriptor renderPassDescriptor]; +void Framebuffer::CreateRenderPassDescriptor(TextureCacheRuntime& runtime, + std::span color_buffers, + ImageView* depth_buffer, bool is_rescaled, + size_t width, size_t height) { + render_pass = MTL::RenderPassDescriptor::alloc()->init(); for (size_t index = 0; index < NUM_RT; ++index) { const ImageView* const color_buffer = color_buffers[index]; if (!color_buffer) { - continue; + continue; } // TODO: don't use index as attachment index - render_pass.colorAttachments[index].clearColor = - MTLClearColorMake(0.5, 1.0, 0.0, 1.0); - render_pass.colorAttachments[index].loadAction = MTLLoadActionClear; - render_pass.colorAttachments[index].storeAction = MTLStoreActionStore; - render_pass.colorAttachments[index].texture = color_buffer->GetHandle(); + auto color_attachment = render_pass->colorAttachments()->object(index); + color_attachment->setClearColor(MTL::ClearColor::Make(0.5, 1.0, 0.0, 1.0)); + color_attachment->setLoadAction(MTL::LoadActionClear); + color_attachment->setStoreAction(MTL::StoreActionStore); + color_attachment->setTexture(color_buffer->GetHandle()); } if (depth_buffer) { - render_pass.depthAttachment.clearDepth = 1.0; - render_pass.depthAttachment.loadAction = MTLLoadActionClear; - render_pass.depthAttachment.storeAction = MTLStoreActionStore; - render_pass.depthAttachment.texture = depth_buffer->GetHandle(); + auto depth_attachment = render_pass->depthAttachment(); + depth_attachment->setClearDepth(1.0); + depth_attachment->setLoadAction(MTL::LoadActionClear); + depth_attachment->setStoreAction(MTL::StoreActionStore); + depth_attachment->setTexture(depth_buffer->GetHandle()); } } -} // namespace Vulkan +} // namespace Metal diff --git a/src/video_core/renderer_metal/mtl_texture_cache.h b/src/video_core/renderer_metal/mtl_texture_cache.h index 0ef60742f4..509c5561fd 100644 --- a/src/video_core/renderer_metal/mtl_texture_cache.h +++ b/src/video_core/renderer_metal/mtl_texture_cache.h @@ -5,12 +5,13 @@ #include +#include + #include "mtl_staging_buffer_pool.h" #include "video_core/texture_cache/texture_cache_base.h" #include "shader_recompiler/shader_info.h" #include "video_core/renderer_metal/mtl_staging_buffer_pool.h" -#include "video_core/renderer_metal/objc_bridge.h" #include "video_core/texture_cache/image_view_base.h" namespace Settings { @@ -127,21 +128,17 @@ public: Image(Image&&) = default; Image& operator=(Image&&) = default; - void UploadMemory(MTLBuffer_t buffer, size_t offset, + void UploadMemory(MTL::Buffer* buffer, size_t offset, std::span copies); void UploadMemory(const StagingBufferRef& map, std::span copies); - void DownloadMemory(MTLBuffer_t buffer, size_t offset, + void DownloadMemory(MTL::Buffer* buffer, size_t offset, std::span copies); - // For some reason, this function cannot be defined in the .mm file since it would report - // undefined symbols - void DownloadMemory(std::span buffers, std::span offsets, - std::span copies) { - // TODO: implement - } + void DownloadMemory(std::span buffers, std::span offsets, + std::span copies); void DownloadMemory(const StagingBufferRef& map, std::span copies); @@ -160,12 +157,12 @@ public: return true; } - MTLTexture_t GetHandle() const noexcept { + MTL::Texture* GetHandle() const noexcept { return texture; } private: - MTLTexture_t texture = nil; + MTL::Texture* texture = nil; bool initialized = false; bool rescaled = false; @@ -188,12 +185,12 @@ public: ImageView(ImageView&&) = default; ImageView& operator=(ImageView&&) = default; - MTLTexture_t GetHandle() const noexcept { + MTL::Texture* GetHandle() const noexcept { return texture; } private: - MTLTexture_t texture; + MTL::Texture* texture; }; class ImageAlloc : public VideoCommon::ImageAllocBase {}; @@ -202,12 +199,12 @@ class Sampler { public: explicit Sampler(TextureCacheRuntime&, const Tegra::Texture::TSCEntry&); - MTLSamplerState_t GetHandle() const noexcept { + MTL::SamplerState* GetHandle() const noexcept { return sampler_state; } private: - MTLSamplerState_t sampler_state; + MTL::SamplerState* sampler_state; }; class Framebuffer { @@ -227,12 +224,12 @@ public: ImageView* depth_buffer, bool is_rescaled, size_t width, size_t height); - MTLRenderPassDescriptor* GetHandle() const noexcept { + MTL::RenderPassDescriptor* GetHandle() const noexcept { return render_pass; } private: - MTLRenderPassDescriptor* render_pass{}; + MTL::RenderPassDescriptor* render_pass{}; }; struct TextureCacheParams { @@ -249,7 +246,7 @@ struct TextureCacheParams { using Sampler = Metal::Sampler; using Framebuffer = Metal::Framebuffer; using AsyncBuffer = Metal::StagingBufferRef; - using BufferType = MTLBuffer_t; + using BufferType = MTL::Buffer*; }; using TextureCache = VideoCommon::TextureCache; diff --git a/src/video_core/renderer_metal/objc_bridge.h b/src/video_core/renderer_metal/objc_bridge.h deleted file mode 100644 index 7ff3b43b7e..0000000000 --- a/src/video_core/renderer_metal/objc_bridge.h +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 suyu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#ifdef __OBJC__ -#import -#import -typedef id MTLDevice_t; -typedef id MTLCommandQueue_t; -typedef id MTLCommandBuffer_t; -typedef id MTLCommandEncoder_t; -typedef id MTLBuffer_t; -typedef id MTLTexture_t; -typedef id MTLSamplerState_t; -typedef id CAMetalDrawable_t; -#else -typedef void* MTLDevice_t; -typedef void* MTLCommandQueue_t; -typedef void* MTLCommandBuffer_t; -typedef void* MTLCommandEncoder_t; -typedef void* MTLBuffer_t; -typedef void* MTLTexture_t; -typedef void* MTLSamplerState_t; -typedef void MTLRenderPassDescriptor; -typedef void CAMetalLayer; -typedef void* CAMetalDrawable_t; -#define nil NULL -#endif diff --git a/src/video_core/renderer_metal/renderer_metal.mm b/src/video_core/renderer_metal/renderer_metal.cpp similarity index 68% rename from src/video_core/renderer_metal/renderer_metal.mm rename to src/video_core/renderer_metal/renderer_metal.cpp index 6c06173f61..e9c6c11155 100644 --- a/src/video_core/renderer_metal/renderer_metal.mm +++ b/src/video_core/renderer_metal/renderer_metal.cpp @@ -4,19 +4,18 @@ #include "core/frontend/emu_window.h" #include "core/frontend/graphics_context.h" #include "video_core/capture.h" -#include "video_core/renderer_metal/renderer_metal.h" #include "video_core/renderer_metal/mtl_device.h" +#include "video_core/renderer_metal/renderer_metal.h" namespace Metal { RendererMetal::RendererMetal(Core::Frontend::EmuWindow& emu_window, Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_, std::unique_ptr context_) - : RendererBase(emu_window, std::move(context_)), device_memory{device_memory_}, - gpu{gpu_}, device{}, - command_recorder(device), + : RendererBase(emu_window, std::move(context_)), device_memory{device_memory_}, gpu{gpu_}, + device{}, command_recorder(device), swap_chain(device, command_recorder, - static_cast(render_window.GetWindowInfo().render_surface)), + static_cast(render_window.GetWindowInfo().render_surface)), rasterizer(gpu_, device_memory, device, command_recorder, swap_chain) {} RendererMetal::~RendererMetal() = default; @@ -30,11 +29,13 @@ void RendererMetal::Composite(std::span framebuf swap_chain.AcquireNextDrawable(); // TODO: copy the framebuffer to the drawable texture instead of this dummy render pass - MTLRenderPassDescriptor* render_pass_descriptor = [MTLRenderPassDescriptor renderPassDescriptor]; - render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0, 0.5, 0.0, 1.0); - render_pass_descriptor.colorAttachments[0].loadAction = MTLLoadActionClear; - render_pass_descriptor.colorAttachments[0].storeAction = MTLStoreActionStore; - render_pass_descriptor.colorAttachments[0].texture = swap_chain.GetDrawableTexture(); + MTL::RenderPassDescriptor* render_pass_descriptor = MTL::RenderPassDescriptor::alloc()->init(); + render_pass_descriptor->colorAttachments()->object(0)->setClearColor( + MTL::ClearColor::Make(1.0, 0.5, 0.0, 1.0)); + render_pass_descriptor->colorAttachments()->object(0)->setLoadAction(MTL::LoadActionClear); + render_pass_descriptor->colorAttachments()->object(0)->setStoreAction(MTL::StoreActionStore); + render_pass_descriptor->colorAttachments()->object(0)->setTexture( + swap_chain.GetDrawableTexture()); command_recorder.BeginRenderPass(render_pass_descriptor); diff --git a/src/video_core/renderer_metal/renderer_metal.h b/src/video_core/renderer_metal/renderer_metal.h index fa3d1ac78f..fd811c66db 100644 --- a/src/video_core/renderer_metal/renderer_metal.h +++ b/src/video_core/renderer_metal/renderer_metal.h @@ -6,7 +6,6 @@ #include #include -#include "objc_bridge.h" #include "video_core/host1x/gpu_device_memory_manager.h" #include "video_core/renderer_base.h" #include "video_core/renderer_metal/mtl_command_recorder.h"