mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-02 13:02:44 +01:00
metal: create swap chain to manage metal layer
This commit is contained in:
parent
380af618d3
commit
79ff60356d
8 changed files with 115 additions and 29 deletions
|
@ -376,6 +376,7 @@ if (APPLE)
|
||||||
list(APPEND sources
|
list(APPEND sources
|
||||||
renderer_metal/mtl_device.mm
|
renderer_metal/mtl_device.mm
|
||||||
renderer_metal/mtl_rasterizer.mm
|
renderer_metal/mtl_rasterizer.mm
|
||||||
|
renderer_metal/mtl_swap_chain.mm
|
||||||
renderer_metal/renderer_metal.mm
|
renderer_metal/renderer_metal.mm
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "objc_bridge.h"
|
||||||
#include "video_core/control/channel_state_cache.h"
|
#include "video_core/control/channel_state_cache.h"
|
||||||
#include "video_core/engines/maxwell_dma.h"
|
#include "video_core/engines/maxwell_dma.h"
|
||||||
#include "video_core/rasterizer_interface.h"
|
#include "video_core/rasterizer_interface.h"
|
||||||
|
@ -15,6 +16,7 @@ class System;
|
||||||
namespace Metal {
|
namespace Metal {
|
||||||
|
|
||||||
class Device;
|
class Device;
|
||||||
|
class SwapChain;
|
||||||
|
|
||||||
class RasterizerMetal;
|
class RasterizerMetal;
|
||||||
|
|
||||||
|
@ -36,7 +38,7 @@ public:
|
||||||
class RasterizerMetal final : public VideoCore::RasterizerInterface,
|
class RasterizerMetal final : public VideoCore::RasterizerInterface,
|
||||||
protected VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> {
|
protected VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> {
|
||||||
public:
|
public:
|
||||||
explicit RasterizerMetal(Tegra::GPU& gpu_, const Device& device_, const CAMetalLayer* layer_);
|
explicit RasterizerMetal(Tegra::GPU& gpu_, const Device& device_, const SwapChain& swap_chain_);
|
||||||
~RasterizerMetal() override;
|
~RasterizerMetal() override;
|
||||||
|
|
||||||
void Draw(bool is_indexed, u32 instance_count) override;
|
void Draw(bool is_indexed, u32 instance_count) override;
|
||||||
|
@ -90,7 +92,9 @@ private:
|
||||||
AccelerateDMA accelerate_dma;
|
AccelerateDMA accelerate_dma;
|
||||||
|
|
||||||
const Device& device;
|
const Device& device;
|
||||||
const CAMetalLayer* layer;
|
const SwapChain& swap_chain;
|
||||||
|
|
||||||
|
MTLCommandBuffer_t command_buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Metal
|
} // namespace Metal
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
#include "video_core/control/channel_state.h"
|
#include "video_core/control/channel_state.h"
|
||||||
#include "video_core/host1x/host1x.h"
|
#include "video_core/host1x/host1x.h"
|
||||||
#include "video_core/memory_manager.h"
|
#include "video_core/memory_manager.h"
|
||||||
|
#include "video_core/buffer_cache/buffer_cache.h"
|
||||||
|
#include "video_core/engines/draw_manager.h"
|
||||||
|
#include "video_core/engines/kepler_compute.h"
|
||||||
|
#include "video_core/engines/maxwell_3d.h"
|
||||||
#include "video_core/renderer_metal/mtl_rasterizer.h"
|
#include "video_core/renderer_metal/mtl_rasterizer.h"
|
||||||
#include "video_core/renderer_metal/mtl_device.h"
|
#include "video_core/renderer_metal/mtl_device.h"
|
||||||
|
|
||||||
|
@ -20,11 +24,31 @@ bool AccelerateDMA::BufferClear(GPUVAddr src_address, u64 amount, u32 value) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RasterizerMetal::RasterizerMetal(Tegra::GPU& gpu_, const Device& device_, const CAMetalLayer* layer_)
|
RasterizerMetal::RasterizerMetal(Tegra::GPU& gpu_, const Device& device_, const SwapChain& swap_chain_)
|
||||||
: gpu{gpu_}, device{device_}, layer{layer_} {}
|
: gpu{gpu_}, device{device_}, swap_chain{swap_chain_} {}
|
||||||
RasterizerMetal::~RasterizerMetal() = default;
|
RasterizerMetal::~RasterizerMetal() = default;
|
||||||
|
|
||||||
void RasterizerMetal::Draw(bool is_indexed, u32 instance_count) {}
|
void RasterizerMetal::Draw(bool is_indexed, u32 instance_count) {
|
||||||
|
//const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
|
||||||
|
if (is_indexed) {
|
||||||
|
std::cout << "DrawIndexed" << std::endl;
|
||||||
|
/*[command_buffer drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||||
|
indexCount:draw_params.num_indices
|
||||||
|
indexType:MTLIndexTypeUInt32
|
||||||
|
indexBuffer:draw_state.index_buffer
|
||||||
|
indexBufferOffset:draw_params.first_index * sizeof(u32)
|
||||||
|
instanceCount:draw_params.num_instances
|
||||||
|
baseVertex:draw_params.base_vertex
|
||||||
|
baseInstance:draw_params.base_instance];*/
|
||||||
|
//cmdbuf.DrawIndexed(draw_params.num_vertices, draw_params.num_instances,
|
||||||
|
// draw_params.first_index, draw_params.base_vertex,
|
||||||
|
// draw_params.base_instance);
|
||||||
|
} else {
|
||||||
|
std::cout << "Draw" << std::endl;
|
||||||
|
//cmdbuf.Draw(draw_params.num_vertices, draw_params.num_instances,
|
||||||
|
// draw_params.base_vertex, draw_params.base_instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
void RasterizerMetal::DrawTexture() {}
|
void RasterizerMetal::DrawTexture() {}
|
||||||
void RasterizerMetal::Clear(u32 layer_count) {}
|
void RasterizerMetal::Clear(u32 layer_count) {}
|
||||||
void RasterizerMetal::DispatchCompute() {}
|
void RasterizerMetal::DispatchCompute() {}
|
||||||
|
|
29
src/video_core/renderer_metal/mtl_swap_chain.h
Normal file
29
src/video_core/renderer_metal/mtl_swap_chain.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "video_core/renderer_metal/objc_bridge.h"
|
||||||
|
|
||||||
|
namespace Metal {
|
||||||
|
|
||||||
|
class Device;
|
||||||
|
|
||||||
|
class SwapChain {
|
||||||
|
public:
|
||||||
|
SwapChain(const Device& device_, const CAMetalLayer* layer_);
|
||||||
|
~SwapChain();
|
||||||
|
|
||||||
|
void AcquireNextDrawable();
|
||||||
|
|
||||||
|
void Present(MTLCommandBuffer_t command_buffer);
|
||||||
|
|
||||||
|
MTLTexture_t GetDrawableTexture();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Device& device;
|
||||||
|
const CAMetalLayer* layer;
|
||||||
|
|
||||||
|
CAMetalDrawable_t drawable;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Metal
|
30
src/video_core/renderer_metal/mtl_swap_chain.mm
Normal file
30
src/video_core/renderer_metal/mtl_swap_chain.mm
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "video_core/renderer_metal/mtl_device.h"
|
||||||
|
#include "video_core/renderer_metal/mtl_swap_chain.h"
|
||||||
|
|
||||||
|
namespace Metal {
|
||||||
|
|
||||||
|
SwapChain::SwapChain(const Device& device_, const CAMetalLayer* layer_) : device(device_), layer([layer_ retain]) {
|
||||||
|
// Give the layer our device
|
||||||
|
layer.device = device.GetDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapChain::~SwapChain() {
|
||||||
|
[layer release];
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapChain::AcquireNextDrawable() {
|
||||||
|
// Get the next drawable
|
||||||
|
drawable = [layer nextDrawable];
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapChain::Present(MTLCommandBuffer_t command_buffer) {
|
||||||
|
[command_buffer presentDrawable:drawable];
|
||||||
|
}
|
||||||
|
|
||||||
|
MTLTexture_t SwapChain::GetDrawableTexture() {
|
||||||
|
return drawable.texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Metal
|
|
@ -7,10 +7,14 @@
|
||||||
#import <QuartzCore/QuartzCore.h>
|
#import <QuartzCore/QuartzCore.h>
|
||||||
typedef id<MTLDevice> MTLDevice_t;
|
typedef id<MTLDevice> MTLDevice_t;
|
||||||
typedef id<MTLCommandQueue> MTLCommandQueue_t;
|
typedef id<MTLCommandQueue> MTLCommandQueue_t;
|
||||||
|
typedef id<MTLCommandBuffer> MTLCommandBuffer_t;
|
||||||
typedef id<MTLTexture> MTLTexture_t;
|
typedef id<MTLTexture> MTLTexture_t;
|
||||||
|
typedef id<CAMetalDrawable> CAMetalDrawable_t;
|
||||||
#else
|
#else
|
||||||
typedef void* MTLDevice_t;
|
typedef void* MTLDevice_t;
|
||||||
typedef void* MTLCommandQueue_t;
|
typedef void* MTLCommandQueue_t;
|
||||||
|
typedef void* MTLCommandBuffer_t;
|
||||||
typedef void* MTLTexture_t;
|
typedef void* MTLTexture_t;
|
||||||
typedef void CAMetalLayer;
|
typedef void CAMetalLayer;
|
||||||
|
typedef void* CAMetalDrawable_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/renderer_metal/mtl_device.h"
|
#include "video_core/renderer_metal/mtl_device.h"
|
||||||
#include "video_core/renderer_metal/mtl_rasterizer.h"
|
#include "video_core/renderer_metal/mtl_rasterizer.h"
|
||||||
|
#include "video_core/renderer_metal/mtl_swap_chain.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class TelemetrySession;
|
class TelemetrySession;
|
||||||
|
@ -49,8 +50,7 @@ private:
|
||||||
Tegra::GPU& gpu;
|
Tegra::GPU& gpu;
|
||||||
|
|
||||||
Device device;
|
Device device;
|
||||||
// TODO: use the layer to get the drawable when drawing directly to the screen
|
SwapChain swap_chain;
|
||||||
const CAMetalLayer* layer;
|
|
||||||
|
|
||||||
RasterizerMetal rasterizer;
|
RasterizerMetal rasterizer;
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,17 +12,11 @@ RendererMetal::RendererMetal(Core::Frontend::EmuWindow& emu_window,
|
||||||
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_,
|
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_,
|
||||||
std::unique_ptr<Core::Frontend::GraphicsContext> context_)
|
std::unique_ptr<Core::Frontend::GraphicsContext> context_)
|
||||||
: RendererBase(emu_window, std::move(context_)), device_memory{device_memory_},
|
: RendererBase(emu_window, std::move(context_)), device_memory{device_memory_},
|
||||||
gpu{gpu_}, device{},
|
gpu{gpu_}, device{},
|
||||||
layer([static_cast<const CAMetalLayer*>(render_window.GetWindowInfo().render_surface)
|
swap_chain(device, static_cast<const CAMetalLayer*>(render_window.GetWindowInfo().render_surface)),
|
||||||
retain]),
|
rasterizer(gpu_, device, swap_chain) {}
|
||||||
rasterizer(gpu_, device, layer) {
|
|
||||||
// Give the layer our device
|
|
||||||
layer.device = device.GetDevice();
|
|
||||||
}
|
|
||||||
|
|
||||||
RendererMetal::~RendererMetal() {
|
RendererMetal::~RendererMetal() = default;
|
||||||
[layer release];
|
|
||||||
}
|
|
||||||
|
|
||||||
void RendererMetal::Composite(std::span<const Tegra::FramebufferConfig> framebuffers) {
|
void RendererMetal::Composite(std::span<const Tegra::FramebufferConfig> framebuffers) {
|
||||||
if (framebuffers.empty()) {
|
if (framebuffers.empty()) {
|
||||||
|
@ -31,20 +25,20 @@ void RendererMetal::Composite(std::span<const Tegra::FramebufferConfig> framebuf
|
||||||
|
|
||||||
// HACK
|
// HACK
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
id<CAMetalDrawable> drawable = [layer nextDrawable];
|
swap_chain.AcquireNextDrawable();
|
||||||
|
|
||||||
MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
|
MTLRenderPassDescriptor* render_pass_descriptor = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||||
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0, 0.5, 0.0, 1.0);
|
render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0, 0.5, 0.0, 1.0);
|
||||||
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
|
render_pass_descriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||||
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
|
render_pass_descriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||||
renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
|
render_pass_descriptor.colorAttachments[0].texture = swap_chain.GetDrawableTexture();
|
||||||
|
|
||||||
id<MTLCommandBuffer> commandBuffer = [device.GetCommandQueue() commandBuffer];
|
id<MTLCommandBuffer> command_buffer = [device.GetCommandQueue() commandBuffer];
|
||||||
id<MTLRenderCommandEncoder> renderEncoder = [commandBuffer
|
id<MTLRenderCommandEncoder> render_encoder = [command_buffer
|
||||||
renderCommandEncoderWithDescriptor:renderPassDescriptor];
|
renderCommandEncoderWithDescriptor:render_pass_descriptor];
|
||||||
[renderEncoder endEncoding];
|
[render_encoder endEncoding];
|
||||||
[commandBuffer presentDrawable:drawable];
|
swap_chain.Present(command_buffer);
|
||||||
[commandBuffer commit];
|
[command_buffer commit];
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu.RendererFrameEndNotify();
|
gpu.RendererFrameEndNotify();
|
||||||
|
|
Loading…
Reference in a new issue