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_VULKAN TRUE)
|
||||||
set(ENABLE_DARWIN TRUE)
|
set(ENABLE_DARWIN TRUE)
|
||||||
set(ENABLE_IOS TRUE)
|
set(ENABLE_IOS TRUE)
|
||||||
|
set(ENABLE_METAL TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "tvOS")
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "tvOS")
|
||||||
|
@ -46,6 +47,7 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "tvOS")
|
||||||
set(ENABLE_VULKAN TRUE)
|
set(ENABLE_VULKAN TRUE)
|
||||||
set(ENABLE_DARWIN TRUE)
|
set(ENABLE_DARWIN TRUE)
|
||||||
set(ENABLE_TVOS TRUE)
|
set(ENABLE_TVOS TRUE)
|
||||||
|
set(ENABLE_METAL TRUE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||||
|
|
|
@ -44,6 +44,8 @@ public:
|
||||||
GFXPipeline* create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) override;
|
GFXPipeline* create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) override;
|
||||||
GFXPipeline* create_compute_pipeline(const GFXComputePipelineCreateInfo& 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;
|
GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use = false) override;
|
||||||
|
|
||||||
void submit(GFXCommandBuffer* command_buffer, platform::window_ptr window = nullptr) override;
|
void submit(GFXCommandBuffer* command_buffer, platform::window_ptr window = nullptr) override;
|
||||||
|
@ -51,7 +53,7 @@ public:
|
||||||
private:
|
private:
|
||||||
struct NativeMTLView {
|
struct NativeMTLView {
|
||||||
platform::window_ptr identifier = nullptr;
|
platform::window_ptr identifier = nullptr;
|
||||||
CA::MetalDrawable* layer = nullptr;
|
MTL::PixelFormat format;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<NativeMTLView*> nativeViews;
|
std::vector<NativeMTLView*> nativeViews;
|
||||||
|
|
|
@ -172,10 +172,7 @@ void GFXMetal::initialize_view(void* native_handle, const platform::window_ptr i
|
||||||
NativeMTLView* native = new NativeMTLView();
|
NativeMTLView* native = new NativeMTLView();
|
||||||
native->identifier = identifier;
|
native->identifier = identifier;
|
||||||
|
|
||||||
//native->layer = (CAMetalLayer*)native_handle;
|
native->format = (MTL::PixelFormat)platform::initialize_metal_layer(identifier, device);
|
||||||
//native->layer.device = device;
|
|
||||||
|
|
||||||
//native->layer.allowsNextDrawableTimeout = true;
|
|
||||||
|
|
||||||
nativeViews.push_back(native);
|
nativeViews.push_back(native);
|
||||||
}
|
}
|
||||||
|
@ -426,8 +423,9 @@ MTL::FunctionConstantValues* get_constant_values(GFXShaderConstants constants) {
|
||||||
|
|
||||||
GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) {
|
GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) {
|
||||||
GFXMetalPipeline* pipeline = new GFXMetalPipeline();
|
GFXMetalPipeline* pipeline = new GFXMetalPipeline();
|
||||||
|
pipeline->label = info.label;
|
||||||
|
|
||||||
NS::Error* error = nil;
|
NS::Error* error = nullptr;
|
||||||
|
|
||||||
MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
||||||
|
|
||||||
|
@ -552,7 +550,7 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for(const auto& attachment : metalRenderPass->attachments) {
|
for(const auto& attachment : metalRenderPass->attachments) {
|
||||||
if(attachment != MTL::PixelFormatDepth32Float) {
|
if(attachment != MTL::PixelFormatDepth32Float) {
|
||||||
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = MTL::RenderPipelineColorAttachmentDescriptor::alloc()->init();
|
MTL::RenderPipelineColorAttachmentDescriptor* colorAttachmentDescriptor = pipelineDescriptor->colorAttachments()->object(i++);
|
||||||
|
|
||||||
colorAttachmentDescriptor->setPixelFormat(attachment);
|
colorAttachmentDescriptor->setPixelFormat(attachment);
|
||||||
colorAttachmentDescriptor->setBlendingEnabled(info.blending.enable_blending);
|
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->setSourceAlphaBlendFactor(toBlendFactor(info.blending.src_alpha));
|
||||||
colorAttachmentDescriptor->setDestinationAlphaBlendFactor(toBlendFactor(info.blending.dst_alpha));
|
colorAttachmentDescriptor->setDestinationAlphaBlendFactor(toBlendFactor(info.blending.dst_alpha));
|
||||||
|
|
||||||
pipelineDescriptor->colorAttachments()->setObject(colorAttachmentDescriptor, i++);
|
|
||||||
} else {
|
} else {
|
||||||
pipelineDescriptor->setDepthAttachmentPixelFormat(MTL::PixelFormatDepth32Float);
|
pipelineDescriptor->setDepthAttachmentPixelFormat(MTL::PixelFormatDepth32Float);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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->setBlendingEnabled(info.blending.enable_blending);
|
||||||
|
|
||||||
colorAttachmentDescriptor->setSourceRGBBlendFactor(toBlendFactor(info.blending.src_rgb));
|
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->setSourceAlphaBlendFactor(toBlendFactor(info.blending.src_alpha));
|
||||||
colorAttachmentDescriptor->setDestinationAlphaBlendFactor(toBlendFactor(info.blending.dst_alpha));
|
colorAttachmentDescriptor->setDestinationAlphaBlendFactor(toBlendFactor(info.blending.dst_alpha));
|
||||||
|
|
||||||
pipelineDescriptor->colorAttachments()->setObject(colorAttachmentDescriptor, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(debug_enabled) {
|
if(debug_enabled) {
|
||||||
|
@ -601,11 +595,6 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto& binding : info.shader_input.bindings) {
|
|
||||||
if(binding.type == GFXBindingType::PushConstant)
|
|
||||||
pipeline->pushConstantIndex = binding.binding;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipeline->winding_mode = info.rasterization.winding_mode;
|
pipeline->winding_mode = info.rasterization.winding_mode;
|
||||||
|
|
||||||
MTL::DepthStencilDescriptor* depthStencil = MTL::DepthStencilDescriptor::alloc()->init();
|
MTL::DepthStencilDescriptor* depthStencil = MTL::DepthStencilDescriptor::alloc()->init();
|
||||||
|
@ -651,7 +640,6 @@ GFXPipeline* GFXMetal::create_compute_pipeline(const GFXComputePipelineCreateInf
|
||||||
|
|
||||||
NS::Error* error = nullptr;
|
NS::Error* error = nullptr;
|
||||||
|
|
||||||
// vertex
|
|
||||||
MTL::Library* computeLibrary;
|
MTL::Library* computeLibrary;
|
||||||
{
|
{
|
||||||
std::string compute_src;
|
std::string compute_src;
|
||||||
|
@ -689,16 +677,19 @@ GFXPipeline* GFXMetal::create_compute_pipeline(const GFXComputePipelineCreateInf
|
||||||
if(!pipeline->compute_handle)
|
if(!pipeline->compute_handle)
|
||||||
prism::log("Compute pipeline error: {}", error->debugDescription()->cString(NS::ASCIIStringEncoding));
|
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();
|
computeLibrary->release();
|
||||||
|
|
||||||
return pipeline;
|
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* GFXMetal::acquire_command_buffer(bool for_presentation_use) {
|
||||||
GFXCommandBuffer* cmdbuf = nullptr;
|
GFXCommandBuffer* cmdbuf = nullptr;
|
||||||
while(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) {
|
void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_ptr window) {
|
||||||
|
NS::AutoreleasePool* pPool = NS::AutoreleasePool::alloc()->init();
|
||||||
|
|
||||||
NativeMTLView* native = getNativeView(window);
|
NativeMTLView* native = getNativeView(window);
|
||||||
//id<CAMetalDrawable> drawable = nil;
|
|
||||||
//if(native != nullptr)
|
CA::MetalDrawable* drawable = nullptr;
|
||||||
// drawable = [native->layer nextDrawable];
|
if(native != nullptr)
|
||||||
|
drawable = ((CA::MetalDrawable*)platform::get_next_drawable(window));
|
||||||
|
|
||||||
MTL::CommandBuffer* commandBuffer = command_queue->commandBuffer();
|
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) {
|
const auto needEncoder = [&](CurrentEncoder encoder, bool needs_reset = false) {
|
||||||
if(encoder != current_encoder || needs_reset) {
|
if(encoder != current_encoder || needs_reset) {
|
||||||
if(renderEncoder != nil)
|
if(renderEncoder != nullptr)
|
||||||
renderEncoder->endEncoding();
|
renderEncoder->endEncoding();
|
||||||
|
|
||||||
if(computeEncoder != nil)
|
if(computeEncoder != nullptr)
|
||||||
computeEncoder->endEncoding();
|
computeEncoder->endEncoding();
|
||||||
|
|
||||||
if(blitEncoder != nil)
|
if(blitEncoder != nullptr)
|
||||||
blitEncoder->endEncoding();
|
blitEncoder->endEncoding();
|
||||||
|
|
||||||
renderEncoder = nil;
|
renderEncoder = nullptr;
|
||||||
computeEncoder = nil;
|
computeEncoder = nullptr;
|
||||||
blitEncoder = nil;
|
blitEncoder = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(current_encoder == encoder && !needs_reset)
|
if(current_encoder == encoder && !needs_reset)
|
||||||
|
@ -775,36 +769,30 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
for(const auto& attachment : currentFramebuffer->attachments) {
|
for(const auto& attachment : currentFramebuffer->attachments) {
|
||||||
if(attachment->format == MTL::PixelFormatDepth32Float) {
|
if(attachment->format == MTL::PixelFormatDepth32Float) {
|
||||||
MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = MTL::RenderPassDepthAttachmentDescriptor::alloc()->init();
|
MTL::RenderPassDepthAttachmentDescriptor* depthAttachment = descriptor->depthAttachment();
|
||||||
depthAttachment->setTexture(attachment->handle);
|
depthAttachment->setTexture(attachment->handle);
|
||||||
depthAttachment->setLoadAction(MTL::LoadActionClear);
|
depthAttachment->setLoadAction(MTL::LoadActionClear);
|
||||||
depthAttachment->setStoreAction(MTL::StoreActionStore);
|
depthAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
|
|
||||||
descriptor->setDepthAttachment(depthAttachment);
|
|
||||||
} else {
|
} else {
|
||||||
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = MTL::RenderPassColorAttachmentDescriptor::alloc()->init();
|
MTL::RenderPassColorAttachmentDescriptor* colorAttachment = descriptor->colorAttachments()->object(i);
|
||||||
|
|
||||||
colorAttachment->setTexture(attachment->handle);
|
colorAttachment->setTexture(attachment->handle);
|
||||||
colorAttachment->setLoadAction(MTL::LoadActionClear);
|
colorAttachment->setLoadAction(MTL::LoadActionClear);
|
||||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
colorAttachment->setClearColor(currentClearColor);
|
colorAttachment->setClearColor(currentClearColor);
|
||||||
|
|
||||||
descriptor->colorAttachments()->setObject(colorAttachment, i++);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderEncoder = commandBuffer->renderCommandEncoder(descriptor);
|
|
||||||
} else {
|
} 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->setLoadAction(MTL::LoadActionClear);
|
||||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
colorAttachment->setClearColor(currentClearColor);
|
colorAttachment->setClearColor(currentClearColor);
|
||||||
|
|
||||||
descriptor->colorAttachments()->setObject(colorAttachment, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderEncoder = commandBuffer->renderCommandEncoder(descriptor);
|
||||||
|
|
||||||
if(currentViewport.width != 0.0f && currentViewport.height != 0.0f)
|
if(currentViewport.width != 0.0f && currentViewport.height != 0.0f)
|
||||||
renderEncoder->setViewport(currentViewport);
|
renderEncoder->setViewport(currentViewport);
|
||||||
|
|
||||||
|
@ -833,13 +821,12 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
||||||
case GFXCommandType::SetRenderPass:
|
case GFXCommandType::SetRenderPass:
|
||||||
{
|
{
|
||||||
currentClearColor = MTL::ClearColor(command.data.set_render_pass.clear_color.r,
|
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.g,
|
||||||
command.data.set_render_pass.clear_color.b,
|
command.data.set_render_pass.clear_color.b,
|
||||||
command.data.set_render_pass.clear_color.a );
|
command.data.set_render_pass.clear_color.a );
|
||||||
|
|
||||||
currentFramebuffer = (GFXMetalFramebuffer*)command.data.set_render_pass.framebuffer;
|
currentFramebuffer = (GFXMetalFramebuffer*)command.data.set_render_pass.framebuffer;
|
||||||
currentRenderPass = (GFXMetalRenderPass*)command.data.set_render_pass.render_pass;
|
currentRenderPass = (GFXMetalRenderPass*)command.data.set_render_pass.render_pass;
|
||||||
|
|
||||||
currentViewport = MTL::Viewport();
|
currentViewport = MTL::Viewport();
|
||||||
|
|
||||||
needEncoder(CurrentEncoder::Render, true);
|
needEncoder(CurrentEncoder::Render, true);
|
||||||
|
@ -849,12 +836,10 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
||||||
{
|
{
|
||||||
needEncoder(CurrentEncoder::Render);
|
needEncoder(CurrentEncoder::Render);
|
||||||
|
|
||||||
renderEncoder->setRenderPipelineState(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->handle);
|
|
||||||
|
|
||||||
currentPipeline = (GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline;
|
currentPipeline = (GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline;
|
||||||
|
|
||||||
|
renderEncoder->setRenderPipelineState(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->handle);
|
||||||
renderEncoder->setDepthStencilState(currentPipeline->depthStencil);
|
renderEncoder->setDepthStencilState(currentPipeline->depthStencil);
|
||||||
|
|
||||||
renderEncoder->setCullMode(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->cullMode);
|
renderEncoder->setCullMode(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->cullMode);
|
||||||
renderEncoder->setFrontFacingWinding(toWinding(((GFXMetalPipeline*)command.data.set_graphics_pipeline.pipeline)->winding_mode));
|
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.znear = command.data.set_viewport.viewport.min_depth;
|
||||||
viewport.zfar = command.data.set_viewport.viewport.max_depth;
|
viewport.zfar = command.data.set_viewport.viewport.max_depth;
|
||||||
|
|
||||||
if(renderEncoder != nil)
|
if(renderEncoder != nullptr)
|
||||||
renderEncoder->setViewport(viewport);
|
renderEncoder->setViewport(viewport);
|
||||||
|
|
||||||
currentViewport = viewport;
|
currentViewport = viewport;
|
||||||
|
@ -1081,6 +1066,9 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
||||||
case CurrentEncoder::Blit:
|
case CurrentEncoder::Blit:
|
||||||
blitEncoder->insertDebugSignpost(NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding));
|
blitEncoder->insertDebugSignpost(NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding));
|
||||||
break;
|
break;
|
||||||
|
case CurrentEncoder::Compute:
|
||||||
|
computeEncoder->insertDebugSignpost(NS::String::string(command.data.insert_label.name.data(), NS::ASCIIStringEncoding));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1095,31 +1083,30 @@ void GFXMetal::submit(GFXCommandBuffer* command_buffer, const platform::window_p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(renderEncoder != nil)
|
if(renderEncoder != nullptr)
|
||||||
renderEncoder->endEncoding();
|
renderEncoder->endEncoding();
|
||||||
|
|
||||||
if(blitEncoder != nil)
|
if(blitEncoder != nullptr)
|
||||||
blitEncoder->endEncoding();
|
blitEncoder->endEncoding();
|
||||||
|
|
||||||
/*[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> _Nonnull) {
|
if(computeEncoder != nullptr)
|
||||||
|
computeEncoder->endEncoding();
|
||||||
|
|
||||||
|
commandBuffer->addCompletedHandler([command_buffer](MTL::CommandBuffer* _) {
|
||||||
for(auto [i, buffer] : utility::enumerate(command_buffers)) {
|
for(auto [i, buffer] : utility::enumerate(command_buffers)) {
|
||||||
if(buffer == command_buffer)
|
if(buffer == command_buffer)
|
||||||
free_command_buffers[i] = true;
|
free_command_buffers[i] = true;
|
||||||
}
|
}
|
||||||
}];
|
});
|
||||||
|
|
||||||
if(window != nullptr) {
|
if(window != nullptr) {
|
||||||
[commandBuffer presentDrawable:drawable];
|
commandBuffer->presentDrawable(drawable);
|
||||||
[commandBuffer commit];
|
commandBuffer->commit();
|
||||||
|
|
||||||
currentFrameIndex = (currentFrameIndex + 1) % 3;
|
currentFrameIndex = (currentFrameIndex + 1) % 3;
|
||||||
} else {
|
|
||||||
[commandBuffer commit];
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if(window != nullptr) {
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
commandBuffer->commit();
|
commandBuffer->commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pPool->release();
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,4 +177,10 @@ namespace platform {
|
||||||
void begin_text_input();
|
void begin_text_input();
|
||||||
|
|
||||||
void end_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,13 +91,9 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ
|
||||||
|
|
||||||
command_buffer->set_graphics_pipeline(pipeline);
|
command_buffer->set_graphics_pipeline(pipeline);
|
||||||
|
|
||||||
if(draw_data->TotalVtxCount > 0) {
|
if(draw_data->TotalVtxCount > 0)
|
||||||
update_buffers(target, *draw_data);
|
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,
|
const Matrix4x4 projection = prism::orthographic(draw_data->DisplayPos.x,
|
||||||
draw_data->DisplayPos.x + draw_data->DisplaySize.x,
|
draw_data->DisplayPos.x + draw_data->DisplaySize.x,
|
||||||
draw_data->DisplayPos.y + draw_data->DisplaySize.y,
|
draw_data->DisplayPos.y + draw_data->DisplaySize.y,
|
||||||
|
@ -143,7 +139,10 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& targ
|
||||||
|
|
||||||
command_buffer->set_scissor(scissor);
|
command_buffer->set_scissor(scissor);
|
||||||
|
|
||||||
command_buffer->draw_indexed(pcmd->ElemCount,
|
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,
|
||||||
(index_offset + pcmd->IdxOffset),
|
(index_offset + pcmd->IdxOffset),
|
||||||
(vertex_offset + pcmd->VtxOffset), 0);
|
(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) {
|
void SMAAPass::render(GFXCommandBuffer* command_buffer, RenderTarget& target) {
|
||||||
GFXRenderPassBeginInfo beginInfo = {};
|
GFXRenderPassBeginInfo beginInfo = {};
|
||||||
beginInfo.clear_color.a = 0.0f;
|
|
||||||
beginInfo.render_area.extent = target.extent;
|
beginInfo.render_area.extent = target.extent;
|
||||||
beginInfo.render_pass = render_pass;
|
beginInfo.render_pass = render_pass;
|
||||||
|
|
||||||
|
|
1
extern/metal-cpp/src/metal.cpp
vendored
1
extern/metal-cpp/src/metal.cpp
vendored
|
@ -2,3 +2,4 @@
|
||||||
#define CA_PRIVATE_IMPLEMENTATION
|
#define CA_PRIVATE_IMPLEMENTATION
|
||||||
#define MTL_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}
|
${QUARTZ}
|
||||||
${METAL}
|
${METAL}
|
||||||
${CORE_GRAPHICS}
|
${CORE_GRAPHICS}
|
||||||
GFXVulkan
|
GFXMetal
|
||||||
COMPILE_OPTIONS
|
COMPILE_OPTIONS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <MetalKit/MetalKit.h>
|
#include <MetalKit/MetalKit.h>
|
||||||
#define VK_USE_PLATFORM_METAL_EXT
|
#include <gfx_metal.hpp>
|
||||||
#include <gfx_vulkan.hpp>
|
|
||||||
#include <GameController/GameController.h>
|
#include <GameController/GameController.h>
|
||||||
|
#import "QuartzCore/QuartzCore.hpp"
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@ -30,7 +30,8 @@ float leftX = 0.0f, leftY = 0.0f;
|
||||||
- (void)draw {
|
- (void)draw {
|
||||||
engine->update(1.0f / (float)maxFPS);
|
engine->update(1.0f / (float)maxFPS);
|
||||||
engine->begin_frame(1.0f / (float)maxFPS);
|
engine->begin_frame(1.0f / (float)maxFPS);
|
||||||
engine->render(0);
|
engine->render((void*)1);
|
||||||
|
engine->end_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) controllerConnected {
|
- (void) controllerConnected {
|
||||||
|
@ -113,13 +114,17 @@ bool mouse_down = false;
|
||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
int drawable_width, drawable_height;
|
int drawable_width, drawable_height;
|
||||||
|
CAMetalLayer* layer;
|
||||||
|
|
||||||
- (void)viewDidLoad {
|
- (void)viewDidLoad {
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
view = (GameView*)self.view;
|
view = (GameView*)self.view;
|
||||||
view.userInteractionEnabled = true;
|
view.userInteractionEnabled = true;
|
||||||
|
layer = (CAMetalLayer*)view.layer;
|
||||||
|
|
||||||
CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:view selector:@selector(draw)];
|
CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:view selector:@selector(draw)];
|
||||||
|
displayLink.preferredFramesPerSecond = [UIScreen mainScreen].maximumFramesPerSecond;
|
||||||
|
maxFPS = [UIScreen mainScreen].maximumFramesPerSecond;
|
||||||
[displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSDefaultRunLoopMode];
|
[displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSDefaultRunLoopMode];
|
||||||
|
|
||||||
width = [view frame].size.width;
|
width = [view frame].size.width;
|
||||||
|
@ -136,13 +141,13 @@ int drawable_width, drawable_height;
|
||||||
GFXCreateInfo createInfo = {};
|
GFXCreateInfo createInfo = {};
|
||||||
createInfo.api_validation_enabled = true;
|
createInfo.api_validation_enabled = true;
|
||||||
|
|
||||||
GFXVulkan* gfx = new GFXVulkan();
|
GFXMetal* gfx = new GFXMetal();
|
||||||
gfx->initialize(createInfo);
|
gfx->initialize(createInfo);
|
||||||
engine->set_gfx(gfx);
|
engine->set_gfx(gfx);
|
||||||
|
|
||||||
app_main(engine);
|
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();
|
app->initialize_render();
|
||||||
|
|
||||||
|
@ -182,16 +187,27 @@ void platform::end_text_input() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void* platform::create_native_surface(platform::window_ptr index, void* instance) {
|
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.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
|
||||||
surfaceInfo.pNext = 0;
|
surfaceInfo.pNext = 0;
|
||||||
surfaceInfo.flags = 0;
|
surfaceInfo.flags = 0;
|
||||||
surfaceInfo.pLayer = (CAMetalLayer*)layer;
|
surfaceInfo.pLayer = layer;
|
||||||
|
|
||||||
VkSurfaceKHR surface;
|
VkSurfaceKHR surface;
|
||||||
vkCreateMetalSurfaceEXT((VkInstance)instance, &surfaceInfo, nullptr, &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) {
|
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() {
|
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) {
|
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) {
|
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) {
|
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)
|
find_library(METAL Metal)
|
||||||
|
|
||||||
set(EXTRA_LIBRARIES GFXMetal ${METAL})
|
set(EXTRA_LIBRARIES GFXMetal ${METAL})
|
||||||
|
set(EXTRA_SRC ${CMAKE_CURRENT_SOURCE_DIR}/sdl_metal.mm)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_platform(
|
add_platform(
|
||||||
SRC ${CMAKE_CURRENT_SOURCE_DIR}/file.cpp
|
SRC
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/file.cpp
|
||||||
|
${EXTRA_SRC}
|
||||||
MAIN_FILE
|
MAIN_FILE
|
||||||
main.cpp.in
|
main.cpp.in
|
||||||
EXECUTABLE_PROPERTIES
|
EXECUTABLE_PROPERTIES
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
GFX* gfx_interface = nullptr;
|
GFX* gfx_interface = nullptr;
|
||||||
|
|
||||||
std::vector<SDL_Window*> windows;
|
std::vector<SDL_Window*> windows;
|
||||||
|
std::map<SDL_Window*, SDL_Renderer*> renderers;
|
||||||
SDL_Window* main_window = nullptr;
|
SDL_Window* main_window = nullptr;
|
||||||
|
|
||||||
SDL_Window* get_window(const platform::window_ptr index) {
|
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)
|
if(windows.size() == 1)
|
||||||
main_window = win;
|
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)});
|
engine->add_window((void*)win, win, {static_cast<uint32_t>(real_width), static_cast<uint32_t>(real_height)});
|
||||||
app->initialize_render();
|
app->initialize_render();
|
||||||
|
|
||||||
|
@ -304,7 +310,7 @@ int main(int argc, char* argv[]) {
|
||||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
|
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
|
||||||
|
|
||||||
#ifdef ENABLE_METAL
|
#ifdef ENABLE_METAL
|
||||||
SDL_setenv("METAL_DEVICE_WRAPPER_TYPE", "1", 0);
|
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
engine = new prism::engine(argc, argv);
|
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