Fix Metal backend (finally)
This commit is contained in:
parent
0283cebcb8
commit
8237eeb05b
12 changed files with 150 additions and 88 deletions
|
@ -38,6 +38,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "iOS")
|
|||
set(ENABLE_VULKAN TRUE)
|
||||
set(ENABLE_DARWIN TRUE)
|
||||
set(ENABLE_IOS TRUE)
|
||||
set(ENABLE_METAL TRUE)
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "tvOS")
|
||||
|
@ -46,6 +47,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "tvOS")
|
|||
set(ENABLE_VULKAN TRUE)
|
||||
set(ENABLE_DARWIN TRUE)
|
||||
set(ENABLE_TVOS TRUE)
|
||||
set(ENABLE_METAL TRUE)
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||
|
|
|
@ -44,6 +44,8 @@ public:
|
|||
GFXPipeline* create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) override;
|
||||
GFXPipeline* create_compute_pipeline(const GFXComputePipelineCreateInfo& info) override;
|
||||
|
||||
GFXSize get_alignment(GFXSize size) override;
|
||||
|
||||
GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use = false) override;
|
||||
|
||||
void submit(GFXCommandBuffer* command_buffer, platform::window_ptr window = nullptr) override;
|
||||
|
@ -51,7 +53,7 @@ public:
|
|||
private:
|
||||
struct NativeMTLView {
|
||||
platform::window_ptr identifier = nullptr;
|
||||
CA::MetalDrawable* layer = nullptr;
|
||||
MTL::PixelFormat format;
|
||||
};
|
||||
|
||||
std::vector<NativeMTLView*> nativeViews;
|
||||
|
|
|
@ -172,10 +172,7 @@ void GFXMetal::initialize_view(void* native_handle, const platform::window_ptr i
|
|||
NativeMTLView* native = new NativeMTLView();
|
||||
native->identifier = identifier;
|
||||
|
||||
//native->layer = (CAMetalLayer*)native_handle;
|
||||
//native->layer.device = device;
|
||||
|
||||
//native->layer.allowsNextDrawableTimeout = true;
|
||||
native->format = (MTL::PixelFormat)platform::initialize_metal_layer(identifier, device);
|
||||
|
||||
nativeViews.push_back(native);
|
||||
}
|
||||
|
@ -426,8 +423,9 @@ MTL::FunctionConstantValues* get_constant_values(GFXShaderConstants constants) {
|
|||
|
||||
GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) {
|
||||
GFXMetalPipeline* pipeline = new GFXMetalPipeline();
|
||||
pipeline->label = info.label;
|
||||
|
||||
NS::Error* error = nil;
|
||||
NS::Error* error = nullptr;
|
||||
|
||||
MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
||||
|
||||
|
@ -552,7 +550,7 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
|||
unsigned int i = 0;
|
||||
for(const auto& attachment : metalRenderPass->attachments) {
|
||||
if(attachment != MTL::PixelFormatDepth32Float) {
|
||||
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = MTL::RenderPipelineColorAttachmentDescriptor::alloc()->init();
|
||||
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = pipelineDescriptor->colorAttachments()->object(i++);
|
||||
|
||||
colorAttachmentDescriptor->setPixelFormat(attachment);
|
||||
colorAttachmentDescriptor->setBlendingEnabled(info.blending.enable_blending);
|
||||
|
@ -562,16 +560,14 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
|||
|
||||
colorAttachmentDescriptor->setSourceAlphaBlendFactor(toBlendFactor(info.blending.src_alpha));
|
||||
colorAttachmentDescriptor->setDestinationAlphaBlendFactor(toBlendFactor(info.blending.dst_alpha));
|
||||
|
||||
pipelineDescriptor->colorAttachments()->setObject(colorAttachmentDescriptor, i++);
|
||||
} else {
|
||||
pipelineDescriptor->setDepthAttachmentPixelFormat(MTL::PixelFormatDepth32Float);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = MTL::RenderPipelineColorAttachmentDescriptor::alloc()->init();
|
||||
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = pipelineDescriptor->colorAttachments()->object(0);
|
||||
|
||||
//colorAttachmentDescriptor->setPixelFormat(attachment); [nativeViews[0]->layer pixelFormat];
|
||||
colorAttachmentDescriptor->setPixelFormat(nativeViews[0]->format);
|
||||
colorAttachmentDescriptor->setBlendingEnabled(info.blending.enable_blending);
|
||||
|
||||
colorAttachmentDescriptor->setSourceRGBBlendFactor(toBlendFactor(info.blending.src_rgb));
|
||||
|
@ -579,8 +575,6 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
|||
|
||||
colorAttachmentDescriptor->setSourceAlphaBlendFactor(toBlendFactor(info.blending.src_alpha));
|
||||
colorAttachmentDescriptor->setDestinationAlphaBlendFactor(toBlendFactor(info.blending.dst_alpha));
|
||||
|
||||
pipelineDescriptor->colorAttachments()->setObject(colorAttachmentDescriptor, 0);
|
||||
}
|
||||
|
||||
if(debug_enabled) {
|
||||
|
@ -601,11 +595,6 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
|||
break;
|
||||
}
|
||||
|
||||
for(auto& binding : info.shader_input.bindings) {
|
||||
if(binding.type == GFXBindingType::PushConstant)
|
||||
pipeline->pushConstantIndex = binding.binding;
|
||||
}
|
||||
|
||||
pipeline->winding_mode = info.rasterization.winding_mode;
|
||||
|
||||
MTL::DepthStencilDescriptor* depthStencil = MTL::DepthStencilDescriptor::alloc()->init();
|
||||
|
@ -651,7 +640,6 @@ GFXPipeline* GFXMetal::create_compute_pipeline(const GFXComputePipelineCreateInf
|
|||
|
||||
NS::Error* error = nullptr;
|
||||
|
||||
// vertex
|
||||
MTL::Library* computeLibrary;
|
||||
{
|
||||
std::string compute_src;
|
||||
|
@ -688,17 +676,20 @@ GFXPipeline* GFXMetal::create_compute_pipeline(const GFXComputePipelineCreateInf
|
|||
pipeline->compute_handle = device->newComputePipelineState(pipelineDescriptor, MTL::PipelineOptionNone, nullptr, &error);
|
||||
if(!pipeline->compute_handle)
|
||||
prism::log("Compute pipeline error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding));
|
||||
|
||||
for(auto& binding : info.shader_input.bindings) {
|
||||
if(binding.type == GFXBindingType::PushConstant)
|
||||
pipeline->pushConstantIndex = binding.binding;
|
||||
}
|
||||
|
||||
computeLibrary->release();
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
GFXSize GFXMetal::get_alignment(GFXSize size) {
|
||||
#ifdef PLATFORM_MACOS
|
||||
return (size + 32 / 2) & ~int(32 - 1);
|
||||
#else
|
||||
return size;
|
||||
#endif
|
||||
}
|
||||
|
||||
GFXCommandBuffer* GFXMetal::acquire_command_buffer(bool for_presentation_use) {
|
||||
GFXCommandBuffer* cmdbuf = nullptr;
|
||||
while(cmdbuf == nullptr) {
|
||||
|
@ -719,10 +710,13 @@ GFXCommandBuffer* GFXMetal::acquire_command_buffer(bool for_presentation_use) {
|
|||
}
|
||||
|
||||
void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_ptr window) {
|
||||
NS::AutoreleasePool* pPool = NS::AutoreleasePool::alloc()->init();
|
||||
|
||||
NativeMTLView* native = getNativeView(window);
|
||||
//id<CAMetalDrawable> drawable = nil;
|
||||
//if(native != nullptr)
|
||||
// drawable = [native->layer nextDrawable];
|
||||
|
||||
CA::MetalDrawable* drawable = nullptr;
|
||||
if(native != nullptr)
|
||||
drawable = ((CA::MetalDrawable*)platform::get_next_drawable(window));
|
||||
|
||||
MTL::CommandBuffer* commandBuffer = command_queue->commandBuffer();
|
||||
|
||||
|
@ -747,18 +741,18 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
|
||||
const auto needEncoder = [&](CurrentEncoder encoder, bool needs_reset = false) {
|
||||
if(encoder != current_encoder || needs_reset) {
|
||||
if(renderEncoder != nil)
|
||||
if(renderEncoder != nullptr)
|
||||
renderEncoder->endEncoding();
|
||||
|
||||
if(computeEncoder != nil)
|
||||
if(computeEncoder != nullptr)
|
||||
computeEncoder->endEncoding();
|
||||
|
||||
if(blitEncoder != nil)
|
||||
if(blitEncoder != nullptr)
|
||||
blitEncoder->endEncoding();
|
||||
|
||||
renderEncoder = nil;
|
||||
computeEncoder = nil;
|
||||
blitEncoder = nil;
|
||||
renderEncoder = nullptr;
|
||||
computeEncoder = nullptr;
|
||||
blitEncoder = nullptr;
|
||||
}
|
||||
|
||||
if(current_encoder == encoder && !needs_reset)
|
||||
|
@ -775,35 +769,29 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
unsigned int i = 0;
|
||||
for(const auto& attachment : currentFramebuffer->attachments) {
|
||||
if(attachment->format == MTL::PixelFormatDepth32Float) {
|
||||
MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = MTL::RenderPassDepthAttachmentDescriptor::alloc()->init();
|
||||
MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = descriptor->depthAttachment();
|
||||
depthAttachment->setTexture(attachment->handle);
|
||||
depthAttachment->setLoadAction(MTL::LoadActionClear);
|
||||
depthAttachment->setStoreAction(MTL::StoreActionStore);
|
||||
|
||||
descriptor->setDepthAttachment(depthAttachment);
|
||||
} else {
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = MTL::RenderPassColorAttachmentDescriptor::alloc()->init();
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = descriptor->colorAttachments()->object(i);
|
||||
|
||||
colorAttachment->setTexture(attachment->handle);
|
||||
colorAttachment->setLoadAction(MTL::LoadActionClear);
|
||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||
colorAttachment->setClearColor(currentClearColor);
|
||||
|
||||
descriptor->colorAttachments()->setObject(colorAttachment, i++);
|
||||
}
|
||||
}
|
||||
|
||||
renderEncoder = commandBuffer->renderCommandEncoder(descriptor);
|
||||
} else {
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = MTL::RenderPassColorAttachmentDescriptor::alloc()->init();
|
||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = descriptor->colorAttachments()->object(0);
|
||||
|
||||
//colorAttachment->setTexture(attachment->handle); drawable.texture
|
||||
colorAttachment->setTexture(drawable->texture());
|
||||
colorAttachment->setLoadAction(MTL::LoadActionClear);
|
||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||
colorAttachment->setClearColor(currentClearColor);
|
||||
|
||||
descriptor->colorAttachments()->setObject(colorAttachment, 0);
|
||||
}
|
||||
|
||||
renderEncoder = commandBuffer->renderCommandEncoder(descriptor);
|
||||
|
||||
if(currentViewport.width != 0.0f && currentViewport.height != 0.0f)
|
||||
renderEncoder->setViewport(currentViewport);
|
||||
|
@ -833,13 +821,12 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
case GFXCommandType::SetRenderPass:
|
||||
{
|
||||
currentClearColor = MTL::ClearColor(command.data.set_render_pass.clear_color.r,
|
||||
command.data.set_render_pass.clear_color.g,
|
||||
command.data.set_render_pass.clear_color.b,
|
||||
command.data.set_render_pass.clear_color.a );
|
||||
command.data.set_render_pass.clear_color.g,
|
||||
command.data.set_render_pass.clear_color.b,
|
||||
command.data.set_render_pass.clear_color.a );
|
||||
|
||||
currentFramebuffer = (GFXMetalFramebuffer*)command.data.set_render_pass.framebuffer;
|
||||
currentRenderPass = (GFXMetalRenderPass*)command.data.set_render_pass.render_pass;
|
||||
|
||||
currentViewport = MTL::Viewport();
|
||||
|
||||
needEncoder(CurrentEncoder::Render, true);
|
||||
|
@ -849,12 +836,10 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
{
|
||||
needEncoder(CurrentEncoder::Render);
|
||||
|
||||
renderEncoder->setRenderPipelineState(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->handle);
|
||||
|
||||
currentPipeline = (GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline;
|
||||
|
||||
|
||||
renderEncoder->setRenderPipelineState(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->handle);
|
||||
renderEncoder->setDepthStencilState(currentPipeline->depthStencil);
|
||||
|
||||
renderEncoder->setCullMode(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->cullMode);
|
||||
renderEncoder->setFrontFacingWinding(toWinding(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->winding_mode));
|
||||
|
||||
|
@ -1032,7 +1017,7 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
viewport.znear = command.data.set_viewport.viewport.min_depth;
|
||||
viewport.zfar = command.data.set_viewport.viewport.max_depth;
|
||||
|
||||
if(renderEncoder != nil)
|
||||
if(renderEncoder != nullptr)
|
||||
renderEncoder->setViewport(viewport);
|
||||
|
||||
currentViewport = viewport;
|
||||
|
@ -1081,6 +1066,9 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
case CurrentEncoder::Blit:
|
||||
blitEncoder->insertDebugSignpost(NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding));
|
||||
break;
|
||||
case CurrentEncoder::Compute:
|
||||
computeEncoder->insertDebugSignpost(NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1095,31 +1083,30 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
|||
}
|
||||
}
|
||||
|
||||
if(renderEncoder != nil)
|
||||
if(renderEncoder != nullptr)
|
||||
renderEncoder->endEncoding();
|
||||
|
||||
if(blitEncoder != nil)
|
||||
if(blitEncoder != nullptr)
|
||||
blitEncoder->endEncoding();
|
||||
|
||||
if(computeEncoder != nullptr)
|
||||
computeEncoder->endEncoding();
|
||||
|
||||
/*[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> _Nonnull) {
|
||||
commandBuffer->addCompletedHandler([command_buffer](MTL::CommandBuffer* _) {
|
||||
for(auto [i, buffer] : utility::enumerate(command_buffers)) {
|
||||
if(buffer == command_buffer)
|
||||
free_command_buffers[i] = true;
|
||||
}
|
||||
}];
|
||||
});
|
||||
|
||||
if(window != nullptr) {
|
||||
[commandBuffer presentDrawable:drawable];
|
||||
[commandBuffer commit];
|
||||
commandBuffer->presentDrawable(drawable);
|
||||
commandBuffer->commit();
|
||||
|
||||
currentFrameIndex = (currentFrameIndex + 1) % 3;
|
||||
} else {
|
||||
[commandBuffer commit];
|
||||
}*/
|
||||
|
||||
if(window != nullptr) {
|
||||
|
||||
} else {
|
||||
commandBuffer->commit();
|
||||
}
|
||||
|
||||
pPool->release();
|
||||
}
|
||||
|
|
|
@ -177,4 +177,10 @@ namespace platform {
|
|||
void begin_text_input();
|
||||
|
||||
void end_text_input();
|
||||
|
||||
// metal specific stuff
|
||||
#ifdef ENABLE_METAL
|
||||
unsigned int initialize_metal_layer(window_ptr window, void* device);
|
||||
void* get_next_drawable(window_ptr window);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -91,12 +91,8 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ
|
|||
|
||||
command_buffer->set_graphics_pipeline(pipeline);
|
||||
|
||||
if(draw_data->TotalVtxCount > 0) {
|
||||
if(draw_data->TotalVtxCount > 0)
|
||||
update_buffers(target, *draw_data);
|
||||
|
||||
command_buffer->set_vertex_buffer(target.vertex_buffer[target.current_frame], 0, 0);
|
||||
command_buffer->set_index_buffer(target.index_buffer[target.current_frame], IndexType::UINT16);
|
||||
}
|
||||
|
||||
const Matrix4x4 projection = prism::orthographic(draw_data->DisplayPos.x,
|
||||
draw_data->DisplayPos.x + draw_data->DisplaySize.x,
|
||||
|
@ -142,8 +138,11 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ
|
|||
scissor.extent.height = (uint32_t)(clip_max.y - clip_min.y);
|
||||
|
||||
command_buffer->set_scissor(scissor);
|
||||
|
||||
command_buffer->set_vertex_buffer(target.vertex_buffer[target.current_frame], 0, 0);
|
||||
command_buffer->set_index_buffer(target.index_buffer[target.current_frame], sizeof(ImDrawIdx) == 2 ? IndexType::UINT16 : IndexType::UINT32);
|
||||
|
||||
command_buffer->draw_indexed(pcmd->ElemCount,
|
||||
command_buffer->draw_indexed(pcmd->ElemCount,
|
||||
(index_offset + pcmd->IdxOffset),
|
||||
(vertex_offset + pcmd->VtxOffset), 0);
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ void SMAAPass::create_render_target_resources(RenderTarget& target) {
|
|||
|
||||
void SMAAPass::render(GFXCommandBuffer* command_buffer, RenderTarget& target) {
|
||||
GFXRenderPassBeginInfo beginInfo = {};
|
||||
beginInfo.clear_color.a = 0.0f;
|
||||
beginInfo.render_area.extent = target.extent;
|
||||
beginInfo.render_pass = render_pass;
|
||||
|
||||
|
|
3
extern/metal-cpp/src/metal.cpp
vendored
3
extern/metal-cpp/src/metal.cpp
vendored
|
@ -1,4 +1,5 @@
|
|||
#define NS_PRIVATE_IMPLEMENTATION
|
||||
#define CA_PRIVATE_IMPLEMENTATION
|
||||
#define MTL_PRIVATE_IMPLEMENTATION
|
||||
#include <Metal/Metal.hpp>
|
||||
#include <Metal/Metal.hpp>
|
||||
#include <QuartzCore/QuartzCore.hpp>
|
|
@ -52,7 +52,7 @@ add_platform(
|
|||
${QUARTZ}
|
||||
${METAL}
|
||||
${CORE_GRAPHICS}
|
||||
GFXVulkan
|
||||
GFXMetal
|
||||
COMPILE_OPTIONS
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <MetalKit/MetalKit.h>
|
||||
#define VK_USE_PLATFORM_METAL_EXT
|
||||
#include <gfx_vulkan.hpp>
|
||||
#include <gfx_metal.hpp>
|
||||
#include <GameController/GameController.h>
|
||||
#import "QuartzCore/QuartzCore.hpp"
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
@ -30,7 +30,8 @@ float leftX = 0.0f, leftY = 0.0f;
|
|||
- (void)draw {
|
||||
engine->update(1.0f / (float)maxFPS);
|
||||
engine->begin_frame(1.0f / (float)maxFPS);
|
||||
engine->render(0);
|
||||
engine->render((void*)1);
|
||||
engine->end_frame();
|
||||
}
|
||||
|
||||
- (void) controllerConnected {
|
||||
|
@ -113,13 +114,17 @@ bool mouse_down = false;
|
|||
|
||||
int width, height;
|
||||
int drawable_width, drawable_height;
|
||||
CAMetalLayer* layer;
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
view = (GameView*)self.view;
|
||||
view.userInteractionEnabled = true;
|
||||
|
||||
layer = (CAMetalLayer*)view.layer;
|
||||
|
||||
CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:view selector:@selector(draw)];
|
||||
displayLink.preferredFramesPerSecond = [UIScreen mainScreen].maximumFramesPerSecond;
|
||||
maxFPS = [UIScreen mainScreen].maximumFramesPerSecond;
|
||||
[displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSDefaultRunLoopMode];
|
||||
|
||||
width = [view frame].size.width;
|
||||
|
@ -136,13 +141,13 @@ int drawable_width, drawable_height;
|
|||
GFXCreateInfo createInfo = {};
|
||||
createInfo.api_validation_enabled = true;
|
||||
|
||||
GFXVulkan* gfx = new GFXVulkan();
|
||||
GFXMetal* gfx = new GFXMetal();
|
||||
gfx->initialize(createInfo);
|
||||
engine->set_gfx(gfx);
|
||||
|
||||
app_main(engine);
|
||||
|
||||
engine->add_window((void*)CFBridgingRetain([view layer]), 0, {static_cast<uint32_t>(width), static_cast<uint32_t>(height)});
|
||||
engine->add_window((void*)CFBridgingRetain([view layer]), (void*)1, {static_cast<uint32_t>(width), static_cast<uint32_t>(height)});
|
||||
|
||||
app->initialize_render();
|
||||
|
||||
|
@ -182,16 +187,27 @@ void platform::end_text_input() {
|
|||
}
|
||||
|
||||
void* platform::create_native_surface(platform::window_ptr index, void* instance) {
|
||||
VkMetalSurfaceCreateInfoEXT surfaceInfo = {};
|
||||
/*VkMetalSurfaceCreateInfoEXT surfaceInfo = {};
|
||||
surfaceInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
||||
surfaceInfo.pNext = 0;
|
||||
surfaceInfo.flags = 0;
|
||||
surfaceInfo.pLayer = (CAMetalLayer*)layer;
|
||||
surfaceInfo.pLayer = layer;
|
||||
|
||||
VkSurfaceKHR surface;
|
||||
vkCreateMetalSurfaceEXT((VkInstance)instance, &surfaceInfo, nullptr, &surface);
|
||||
|
||||
return surface;
|
||||
return surface;*/
|
||||
return nullptr;
|
||||
}
|
||||
unsigned int platform::initialize_metal_layer(platform::window_ptr index, void* device) {
|
||||
layer.device = (__bridge id<MTLDevice>)device;
|
||||
layer.allowsNextDrawableTimeout = true;
|
||||
|
||||
return (unsigned int)layer.pixelFormat;
|
||||
}
|
||||
|
||||
void* platform::get_next_drawable(window_ptr window) {
|
||||
return (__bridge CA::MetalDrawable*)[layer nextDrawable];
|
||||
}
|
||||
|
||||
bool platform::is_main_window(platform::window_ptr index) {
|
||||
|
@ -199,7 +215,8 @@ bool platform::is_main_window(platform::window_ptr index) {
|
|||
}
|
||||
|
||||
std::vector<const char*> platform::get_native_surface_extension() {
|
||||
return {VK_EXT_METAL_SURFACE_EXTENSION_NAME};
|
||||
//return {VK_EXT_METAL_SURFACE_EXTENSION_NAME};
|
||||
return {};
|
||||
}
|
||||
|
||||
void platform::show_window(const platform::window_ptr index) {
|
||||
|
@ -251,7 +268,7 @@ bool platform::get_key_down(InputButton key) {
|
|||
}
|
||||
|
||||
platform::window_ptr platform::open_window(const std::string_view title, const prism::Rectangle rect, const WindowFlags flags) {
|
||||
return 0;
|
||||
return (void*)1;
|
||||
}
|
||||
|
||||
void platform::set_window_title(const platform::window_ptr index, const std::string_view title) {
|
||||
|
|
|
@ -4,10 +4,13 @@ if(ENABLE_MACOS)
|
|||
find_library(METAL Metal)
|
||||
|
||||
set(EXTRA_LIBRARIES GFXMetal ${METAL})
|
||||
set(EXTRA_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sdl_metal.mm)
|
||||
endif()
|
||||
|
||||
add_platform(
|
||||
SRC ${CMAKE_CURRENT_SOURCE_DIR}/file.cpp
|
||||
SRC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/file.cpp
|
||||
${EXTRA_SRC}
|
||||
MAIN_FILE
|
||||
main.cpp.in
|
||||
EXECUTABLE_PROPERTIES
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
GFX* gfx_interface = nullptr;
|
||||
|
||||
std::vector<SDL_Window*> windows;
|
||||
std::map<SDL_Window*, SDL_Renderer*> renderers;
|
||||
SDL_Window* main_window = nullptr;
|
||||
|
||||
SDL_Window* get_window(const platform::window_ptr index) {
|
||||
|
@ -126,6 +127,11 @@ platform::window_ptr platform::open_window(const std::string_view title, const p
|
|||
if(windows.size() == 1)
|
||||
main_window = win;
|
||||
|
||||
#ifdef ENABLE_METAL
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||
renderers[win] = renderer;
|
||||
#endif
|
||||
|
||||
engine->add_window((void*)win, win, {static_cast<uint32_t>(real_width), static_cast<uint32_t>(real_height)});
|
||||
app->initialize_render();
|
||||
|
||||
|
@ -304,7 +310,7 @@ int main(int argc, char* argv[]) {
|
|||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
|
||||
|
||||
#ifdef ENABLE_METAL
|
||||
SDL_setenv("METAL_DEVICE_WRAPPER_TYPE", "1", 0);
|
||||
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal");
|
||||
#endif
|
||||
|
||||
engine = new prism::engine(argc, argv);
|
||||
|
|
40
platforms/sdl/sdl_metal.mm
Normal file
40
platforms/sdl/sdl_metal.mm
Normal file
|
@ -0,0 +1,40 @@
|
|||
#include "platform.hpp"
|
||||
#import "QuartzCore/QuartzCore.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <SDL.h>
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
extern std::vector<SDL_Window*> windows;
|
||||
extern std::map<SDL_Window*, SDL_Renderer*> renderers;
|
||||
|
||||
SDL_Window* get_window(platform::window_ptr index);
|
||||
CAMetalLayer* get_layer(platform::window_ptr index) {
|
||||
return (__bridge CAMetalLayer*)SDL_RenderGetMetalLayer(renderers[get_window(index)]);
|
||||
}
|
||||
|
||||
// instance == MTL::Device
|
||||
unsigned int platform::initialize_metal_layer(platform::window_ptr index, void* device) {
|
||||
auto layer = get_layer(index);
|
||||
|
||||
layer.device = (__bridge id<MTLDevice>)device;
|
||||
layer.allowsNextDrawableTimeout = true;
|
||||
|
||||
return (unsigned int)layer.pixelFormat;
|
||||
}
|
||||
|
||||
void* platform::get_next_drawable(window_ptr window) {
|
||||
auto renderer = renderers[get_window(window)];
|
||||
auto layer = get_layer(window);
|
||||
|
||||
int width, height;
|
||||
SDL_GetRendererOutputSize(renderer, &width, &height);
|
||||
layer.drawableSize = CGSizeMake(width, height);
|
||||
|
||||
auto drawable = (__bridge CA::MetalDrawable*)[layer nextDrawable];
|
||||
drawable->retain();
|
||||
|
||||
return drawable;
|
||||
}
|
Reference in a new issue