HECL metal shader support

This commit is contained in:
Jack Andersen 2015-11-18 13:55:25 -10:00
parent b97ad76c45
commit 62fae60042
6 changed files with 64 additions and 36 deletions

View File

@ -53,7 +53,7 @@ elseif(APPLE)
find_library(APPKIT_LIBRARY AppKit)
find_library(IOKIT_LIBRARY IOKit)
find_library(OPENGL_LIBRARY OpenGL)
if (CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER 10.10)
if (NOT CMAKE_OSX_DEPLOYMENT_TARGET OR CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER 10.10)
find_library(METAL_LIBRARY Metal)
endif()
find_library(QUARTZCORE_LIBRARY QuartzCore)

View File

@ -36,6 +36,7 @@ public:
ITextureD* newDynamicTexture(size_t width, size_t height, TextureFormat fmt);
ITextureR* newRenderTexture(size_t width, size_t height, size_t samples);
bool bindingNeedsVertexFormat() const {return false;}
IVertexFormat* newVertexFormat(size_t elementCount, const VertexElementDescriptor* elements);
IShaderPipeline* newShaderPipeline(const char* vertSource, const char* fragSource,

View File

@ -76,10 +76,13 @@ class MetalTextureS : public ITextureS
MetalTextureS(MetalContext* ctx, size_t width, size_t height, size_t mips,
TextureFormat fmt, const void* data, size_t sz)
{
NSPtr<MTLTextureDescriptor*> desc =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
NSPtr<MTLTextureDescriptor*> desc;
@autoreleasepool
{
desc = [[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
width:width height:height
mipmapped:(mips>1)?YES:NO];
mipmapped:(mips>1)?YES:NO] retain];
}
desc.get().usage = MTLTextureUsageShaderRead;
desc.get().mipmapLevelCount = mips;
m_tex = [ctx->m_dev.get() newTextureWithDescriptor:desc.get()];
@ -111,10 +114,13 @@ class MetalTextureD : public ITextureD
MetalTextureD(MetalCommandQueue* q, MetalContext* ctx, size_t width, size_t height, TextureFormat fmt)
: m_q(q), m_width(width), m_height(height)
{
NSPtr<MTLTextureDescriptor*> desc =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
NSPtr<MTLTextureDescriptor*> desc;
@autoreleasepool
{
desc = [[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
width:width height:height
mipmapped:NO];
mipmapped:NO] retain];
}
desc.get().usage = MTLTextureUsageShaderRead;
m_texs[0] = [ctx->m_dev.get() newTextureWithDescriptor:desc.get()];
m_texs[1] = [ctx->m_dev.get() newTextureWithDescriptor:desc.get()];
@ -138,12 +144,12 @@ class MetalTextureR : public ITextureR
void Setup(MetalContext* ctx, size_t width, size_t height, size_t samples)
{
NSPtr<MTLTextureDescriptor*> desc =
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
width:width height:height
mipmapped:NO];
NSPtr<MTLTextureDescriptor*> desc;
@autoreleasepool
{
desc = [[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
width:width height:height
mipmapped:NO] retain];
m_passDesc = [[MTLRenderPassDescriptor renderPassDescriptor] retain];
}
desc.get().usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
@ -436,7 +442,10 @@ struct MetalCommandQueue : IGraphicsCommandQueue
{
MetalTextureR* ctarget = static_cast<MetalTextureR*>(target);
[m_enc.get() endEncoding];
m_enc = [m_cmdBuf.get() renderCommandEncoderWithDescriptor:ctarget->m_passDesc.get()];
@autoreleasepool
{
m_enc = [[m_cmdBuf.get() renderCommandEncoderWithDescriptor:ctarget->m_passDesc.get()] retain];
}
m_boundTarget = ctarget;
}
@ -454,6 +463,8 @@ struct MetalCommandQueue : IGraphicsCommandQueue
m_texResizes[ctex] = std::make_pair(width, height);
}
void flushBufferUpdates() {}
float m_clearColor[4] = {0.0,0.0,0.0,1.0};
void setClearColor(const float rgba[4])
{
@ -515,20 +526,26 @@ struct MetalCommandQueue : IGraphicsCommandQueue
MetalTextureR* csource = static_cast<MetalTextureR*>(source);
[m_enc.get() endEncoding];
m_enc.reset();
NSPtr<id<CAMetalDrawable>> drawable = [w.m_metalLayer nextDrawable];
NSPtr<id<MTLTexture>> dest = drawable.get().texture;
NSPtr<id<MTLBlitCommandEncoder>> blitEnc = [m_cmdBuf.get() blitCommandEncoder];
[blitEnc.get() copyFromTexture:csource->m_tex.get()
@autoreleasepool
{
id<CAMetalDrawable> drawable = [w.m_metalLayer nextDrawable];
if (drawable)
{
id<MTLTexture> dest = drawable.texture;
id<MTLBlitCommandEncoder> blitEnc = [m_cmdBuf.get() blitCommandEncoder];
[blitEnc copyFromTexture:csource->m_tex.get()
sourceSlice:0
sourceLevel:0
sourceOrigin:MTLOriginMake(0, 0, 0)
sourceSize:MTLSizeMake(dest.get().width, dest.get().height, 1)
toTexture:dest.get()
sourceSize:MTLSizeMake(dest.width, dest.height, 1)
toTexture:dest
destinationSlice:0
destinationLevel:0
destinationOrigin:MTLOriginMake(0, 0, 0)];
[blitEnc.get() endEncoding];
[m_cmdBuf.get() presentDrawable:drawable.get()];
[blitEnc endEncoding];
[m_cmdBuf.get() presentDrawable:drawable];
}
}
}
bool m_inProgress = false;
@ -570,7 +587,6 @@ void MetalGraphicsBufferD::load(const void* data, size_t sz)
{
id<MTLBuffer> res = m_bufs[m_q->m_fillBuf].get();
memcpy(res.contents, data, sz);
[res didModifyRange:NSMakeRange(0, sz)];
}
void* MetalGraphicsBufferD::map(size_t sz)
{
@ -578,11 +594,7 @@ void* MetalGraphicsBufferD::map(size_t sz)
id<MTLBuffer> res = m_bufs[m_q->m_fillBuf].get();
return res.contents;
}
void MetalGraphicsBufferD::unmap()
{
id<MTLBuffer> res = m_bufs[m_q->m_fillBuf].get();
[res didModifyRange:NSMakeRange(0, m_mappedSz)];
}
void MetalGraphicsBufferD::unmap() {}
void MetalTextureD::load(const void* data, size_t sz)
{

View File

@ -5,6 +5,8 @@
#include "boo/graphicsdev/Metal.hpp"
#include "CocoaCommon.hpp"
#include <LogVisor/LogVisor.hpp>
namespace boo {class ApplicationCocoa;}
@interface AppDelegate : NSObject <NSApplicationDelegate>
{
@ -17,6 +19,7 @@ namespace boo {class ApplicationCocoa;}
namespace boo
{
static LogVisor::LogModule Log("boo::ApplicationCocoa");
IWindow* _WindowCocoaNew(const SystemString& title, NSOpenGLContext* lastGLCtx, MetalContext* metalCtx);
@ -101,8 +104,13 @@ public:
{
m_metalCtx.m_dev = MTLCreateSystemDefaultDevice();
m_metalCtx.m_q = [m_metalCtx.m_dev.get() newCommandQueue];
Log.report(LogVisor::Info, "using Metal renderer");
break;
}
if (!m_metalCtx.m_dev)
Log.report(LogVisor::Info, "using OpenGL renderer");
#else
Log.report(LogVisor::Info, "using OpenGL renderer");
#endif
}

View File

@ -27,9 +27,11 @@ public:
#include <Metal/Metal.h>
#include <QuartzCore/CAMetalLayer.h>
#include <unordered_map>
namespace boo
{
class IWindow;
struct MetalContext
{
NSPtr<id<MTLDevice>> m_dev;

View File

@ -245,8 +245,8 @@ public:
[nspf release];
if (!m_mainCtx)
Log.report(LogVisor::FatalError, "unable to make main NSOpenGLContext");
[m_mainCtx makeCurrentContext];
}
[m_mainCtx makeCurrentContext];
return m_dataFactory;
}
@ -259,8 +259,8 @@ public:
[nspf release];
if (!m_loadCtx)
Log.report(LogVisor::FatalError, "unable to make load NSOpenGLContext");
[m_loadCtx makeCurrentContext];
}
[m_loadCtx makeCurrentContext];
return m_dataFactory;
}
@ -389,6 +389,11 @@ public:
return m_dataFactory;
}
IGraphicsDataFactory* getMainContextDataFactory()
{
return m_dataFactory;
}
IGraphicsDataFactory* getLoadContextDataFactory()
{
return m_dataFactory;