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(APPKIT_LIBRARY AppKit)
find_library(IOKIT_LIBRARY IOKit) find_library(IOKIT_LIBRARY IOKit)
find_library(OPENGL_LIBRARY OpenGL) 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) find_library(METAL_LIBRARY Metal)
endif() endif()
find_library(QUARTZCORE_LIBRARY QuartzCore) find_library(QUARTZCORE_LIBRARY QuartzCore)

View File

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

View File

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

View File

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

View File

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