This commit is contained in:
Branimir Karadžić 2015-10-06 18:17:46 -07:00
parent 1bca8a29ac
commit 780fbb83fa
2 changed files with 283 additions and 73 deletions

View file

@ -23,7 +23,7 @@ namespace bgfx { namespace mtl
// objects with creation functions starting with 'new' has a refcount 1 after creation, object must be destroyed with release.
// commandBuffer, commandEncoders are autoreleased objects. Needs AutoreleasePool!
#define MTL_CLASS(name) \
#define MTL_CLASS(name) \
class name \
{ \
public: \
@ -37,8 +37,15 @@ namespace bgfx { namespace mtl
//TODO: ??MTLBlitCommandEncoder??
MTL_CLASS(Buffer)
void* contents() { return m_obj.contents; }
uint32_t length() { return (uint32_t)m_obj.length; }
void* contents()
{
return m_obj.contents;
}
uint32_t length()
{
return (uint32_t)m_obj.length;
}
MTL_CLASS_END
MTL_CLASS(CommandBuffer)
@ -80,52 +87,104 @@ namespace bgfx { namespace mtl
MTL_CLASS_END
MTL_CLASS(CommandQueue)
id<MTLCommandBuffer> commandBuffer() { return [m_obj commandBuffer]; }
id<MTLCommandBuffer> commandBufferWithUnretainedReferences() { return [m_obj commandBufferWithUnretainedReferences]; }
id<MTLCommandBuffer> commandBuffer()
{
return [m_obj commandBuffer];
}
id<MTLCommandBuffer> commandBufferWithUnretainedReferences()
{
return [m_obj commandBufferWithUnretainedReferences];
}
MTL_CLASS_END
MTL_CLASS(ComputeCommandEncoder)
void setComputePipelineState(id<MTLComputePipelineState> _state) { [m_obj setComputePipelineState:_state]; }
void setComputePipelineState(id<MTLComputePipelineState> _state)
{
[m_obj setComputePipelineState:_state];
}
void setBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index) { [m_obj setBuffer:_buffer offset:_offset atIndex:_index]; }
void setBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index)
{
[m_obj setBuffer:_buffer offset:_offset atIndex:_index];
}
void setTexture(id<MTLTexture> _texture, NSUInteger _index) { [m_obj setTexture:_texture atIndex:_index]; }
void setTexture(id<MTLTexture> _texture, NSUInteger _index)
{
[m_obj setTexture:_texture atIndex:_index];
}
void setSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index) { [m_obj setSamplerState:_sampler atIndex:_index]; }
void setSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index)
{
[m_obj setSamplerState:_sampler atIndex:_index];
}
void endEncoding() {[m_obj endEncoding] ;}
void endEncoding()
{
[m_obj endEncoding];
}
MTL_CLASS_END
MTL_CLASS(Device)
bool supportsFeatureSet(MTLFeatureSet _featureSet) { return [m_obj supportsFeatureSet:_featureSet]; }
bool supportsFeatureSet(MTLFeatureSet _featureSet)
{
return [m_obj supportsFeatureSet:_featureSet];
}
id<MTLLibrary> newLibraryWithData(const void* _data) {
id<MTLLibrary> newLibraryWithData(const void* _data)
{
NSError* error;
id<MTLLibrary> lib = [m_obj newLibraryWithData:(dispatch_data_t)_data error:&error];
BX_WARN(error==NULL,"newLibraryWithData failed:%s", [error.localizedDescription UTF8String] );
return lib;
}
id<MTLLibrary> newLibraryWithSource(const char* _source) {
id<MTLLibrary> newLibraryWithSource(const char* _source)
{
NSError* error;
id<MTLLibrary> lib = [m_obj newLibraryWithSource:@(_source) options:nil error:&error];
if (error!=nil) NSLog(@"Shader compilation failed:%@", error.localizedDescription);
//TODO: sometimes prints null as paremeter. string is too large
BX_WARN(error==NULL,"Shader compilation failed:%s", [error.localizedDescription UTF8String]);
BX_WARN(error==NULL,"Shader compilation failed:%s", [error.localizedDescription UTF8String]);
return lib;
}
id<MTLCommandQueue> newCommandQueue() { return [m_obj newCommandQueue]; }
id<MTLCommandQueue> newCommandQueueWithMaxCommandBufferCount(NSUInteger _maxCommandBufferCount) { return [m_obj newCommandQueueWithMaxCommandBufferCount:_maxCommandBufferCount]; }
id<MTLCommandQueue> newCommandQueue()
{
return [m_obj newCommandQueue];
}
id<MTLCommandQueue> newCommandQueueWithMaxCommandBufferCount(NSUInteger _maxCommandBufferCount)
{
return [m_obj newCommandQueueWithMaxCommandBufferCount:_maxCommandBufferCount];
}
// Creating Resources
id<MTLBuffer> newBufferWithLength(unsigned int _length, MTLResourceOptions _options) { return [m_obj newBufferWithLength:_length options:_options ]; }
id<MTLBuffer> newBufferWithBytes(const void *_pointer, NSUInteger _length, MTLResourceOptions _options) { return [m_obj newBufferWithBytes:_pointer length:_length options:_options]; }
id<MTLBuffer> newBufferWithLength(unsigned int _length, MTLResourceOptions _options)
{
return [m_obj newBufferWithLength:_length options:_options ];
}
id<MTLTexture> newTextureWithDescriptor(MTLTextureDescriptor * _descriptor) { return [m_obj newTextureWithDescriptor:_descriptor]; }
id<MTLSamplerState> newSamplerStateWithDescriptor(MTLSamplerDescriptor * _descriptor) { return [m_obj newSamplerStateWithDescriptor:_descriptor]; }
id<MTLBuffer> newBufferWithBytes(const void *_pointer, NSUInteger _length, MTLResourceOptions _options)
{
return [m_obj newBufferWithBytes:_pointer length:_length options:_options];
}
id<MTLTexture> newTextureWithDescriptor(MTLTextureDescriptor * _descriptor)
{
return [m_obj newTextureWithDescriptor:_descriptor];
}
id<MTLSamplerState> newSamplerStateWithDescriptor(MTLSamplerDescriptor * _descriptor)
{
return [m_obj newSamplerStateWithDescriptor:_descriptor];
}
// Creating Command Objects Needed to Render Graphics
id<MTLDepthStencilState> newDepthStencilStateWithDescriptor(MTLDepthStencilDescriptor * _descriptor) { return [m_obj newDepthStencilStateWithDescriptor:_descriptor]; }
id<MTLDepthStencilState> newDepthStencilStateWithDescriptor(MTLDepthStencilDescriptor * _descriptor)
{
return [m_obj newDepthStencilStateWithDescriptor:_descriptor];
}
id <MTLRenderPipelineState> newRenderPipelineStateWithDescriptor(MTLRenderPipelineDescriptor *_descriptor)
{
@ -164,27 +223,92 @@ namespace bgfx { namespace mtl
MTL_CLASS(RenderCommandEncoder)
// Setting Graphics Rendering State
void setBlendColor(float _red, float _green, float _blue, float _alpha) { [m_obj setBlendColorRed:_red green:_green blue:_blue alpha:_alpha]; }
void setCullMode(MTLCullMode _cullMode) { [m_obj setCullMode:_cullMode]; }
void setDepthBias(float _depthBias, float _slopeScale, float _clamp) { [m_obj setDepthBias:_depthBias slopeScale:_slopeScale clamp:_clamp]; }
void setDepthStencilState(id<MTLDepthStencilState> _depthStencilState) { [m_obj setDepthStencilState:_depthStencilState];}
void setFrontFacingWinding(MTLWinding _frontFacingWinding) { [m_obj setFrontFacingWinding:_frontFacingWinding]; }
void setRenderPipelineState(id<MTLRenderPipelineState> _pipelineState) { [m_obj setRenderPipelineState:_pipelineState]; }
void setScissorRect(MTLScissorRect _rect) { [m_obj setScissorRect:_rect]; }
void setStencilReferenceValue(uint32_t _ref) { [m_obj setStencilReferenceValue:_ref]; }
void setTriangleFillMode(MTLTriangleFillMode _fillMode) { [m_obj setTriangleFillMode:_fillMode]; }
void setViewport(MTLViewport _viewport) { [m_obj setViewport:_viewport]; }
void setVisibilityResultMode(MTLVisibilityResultMode _mode, NSUInteger _offset) { [m_obj setVisibilityResultMode:_mode offset:_offset]; }
void setBlendColor(float _red, float _green, float _blue, float _alpha)
{
[m_obj setBlendColorRed:_red green:_green blue:_blue alpha:_alpha];
}
void setCullMode(MTLCullMode _cullMode)
{
[m_obj setCullMode:_cullMode];
}
void setDepthBias(float _depthBias, float _slopeScale, float _clamp)
{
[m_obj setDepthBias:_depthBias slopeScale:_slopeScale clamp:_clamp];
}
void setDepthStencilState(id<MTLDepthStencilState> _depthStencilState)
{
[m_obj setDepthStencilState:_depthStencilState];
}
void setFrontFacingWinding(MTLWinding _frontFacingWinding)
{
[m_obj setFrontFacingWinding:_frontFacingWinding];
}
void setRenderPipelineState(id<MTLRenderPipelineState> _pipelineState)
{
[m_obj setRenderPipelineState:_pipelineState];
}
void setScissorRect(MTLScissorRect _rect)
{
[m_obj setScissorRect:_rect];
}
void setStencilReferenceValue(uint32_t _ref)
{
[m_obj setStencilReferenceValue:_ref];
}
void setTriangleFillMode(MTLTriangleFillMode _fillMode)
{
[m_obj setTriangleFillMode:_fillMode];
}
void setViewport(MTLViewport _viewport)
{
[m_obj setViewport:_viewport];
}
void setVisibilityResultMode(MTLVisibilityResultMode _mode, NSUInteger _offset)
{
[m_obj setVisibilityResultMode:_mode offset:_offset];
}
// Specifying Resources for a Vertex Function
void setVertexBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index) { [m_obj setVertexBuffer:_buffer offset:_offset atIndex:_index]; }
void setVertexSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index) { [m_obj setVertexSamplerState:_sampler atIndex:_index]; }
void setVertexTexture(id<MTLTexture> _texture, NSUInteger _index) { [m_obj setVertexTexture:_texture atIndex:_index]; }
void setVertexBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index)
{
[m_obj setVertexBuffer:_buffer offset:_offset atIndex:_index];
}
void setVertexSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index)
{
[m_obj setVertexSamplerState:_sampler atIndex:_index];
}
void setVertexTexture(id<MTLTexture> _texture, NSUInteger _index)
{
[m_obj setVertexTexture:_texture atIndex:_index];
}
// Specifying Resources for a Fragment Function
void setFragmentBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index) { [m_obj setFragmentBuffer:_buffer offset:_offset atIndex:_index]; }
void setFragmentSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index) { [m_obj setFragmentSamplerState:_sampler atIndex:_index]; }
void setFragmentTexture(id<MTLTexture> _texture, NSUInteger _index) { [m_obj setFragmentTexture:_texture atIndex:_index]; }
void setFragmentBuffer(id<MTLBuffer> _buffer, NSUInteger _offset, NSUInteger _index)
{
[m_obj setFragmentBuffer:_buffer offset:_offset atIndex:_index];
}
void setFragmentSamplerState(id<MTLSamplerState> _sampler, NSUInteger _index)
{
[m_obj setFragmentSamplerState:_sampler atIndex:_index];
}
void setFragmentTexture(id<MTLTexture> _texture, NSUInteger _index)
{
[m_obj setFragmentTexture:_texture atIndex:_index];
}
//Drawing Geometric Primitives
//NOTE: not exposing functions without instanceCount, it seems they are just wrappers
@ -193,29 +317,66 @@ namespace bgfx { namespace mtl
[m_obj drawIndexedPrimitives:_primitiveType indexCount:_indexCount indexType:_indexType indexBuffer:_indexBuffer indexBufferOffset:_indexBufferOffset instanceCount:_instanceCount];
}
void drawPrimitives(MTLPrimitiveType _primitiveType, NSUInteger _vertexStart, NSUInteger _vertexCount, NSUInteger _instanceCount) {
[m_obj drawPrimitives:_primitiveType vertexStart:_vertexStart vertexCount:_vertexCount instanceCount:_instanceCount];}
void drawPrimitives(MTLPrimitiveType _primitiveType, NSUInteger _vertexStart, NSUInteger _vertexCount, NSUInteger _instanceCount)
{
[m_obj drawPrimitives:_primitiveType vertexStart:_vertexStart vertexCount:_vertexCount instanceCount:_instanceCount];
}
void insertDebugSignpost(const char* _string) { [m_obj insertDebugSignpost:@(_string)]; }
void pushDebugGroup(const char* _string) { [m_obj pushDebugGroup:@(_string)]; }
void popDebugGroup() { [m_obj popDebugGroup]; }
void insertDebugSignpost(const char* _string)
{
[m_obj insertDebugSignpost:@(_string)];
}
void endEncoding() { [m_obj endEncoding]; }
void pushDebugGroup(const char* _string)
{
[m_obj pushDebugGroup:@(_string)];
}
void popDebugGroup()
{
[m_obj popDebugGroup];
}
void endEncoding()
{
[m_obj endEncoding];
}
MTL_CLASS_END
MTL_CLASS(Texture)
// Copying Data into a Texture Image
void replaceRegion(MTLRegion _region, NSUInteger _level, NSUInteger _slice, const void *_pixelBytes, NSUInteger _bytesPerRow, NSUInteger _bytesPerImage) { [m_obj replaceRegion:_region mipmapLevel:_level slice:_slice withBytes:_pixelBytes bytesPerRow:_bytesPerRow bytesPerImage:_bytesPerImage]; }
void replaceRegion(MTLRegion _region, NSUInteger _level, NSUInteger _slice, const void *_pixelBytes, NSUInteger _bytesPerRow, NSUInteger _bytesPerImage)
{
[m_obj replaceRegion:_region mipmapLevel:_level slice:_slice withBytes:_pixelBytes bytesPerRow:_bytesPerRow bytesPerImage:_bytesPerImage];
}
// Copying Data from a Texture Image
void getBytes(void *_pixelBytes, NSUInteger _bytesPerRow, NSUInteger _bytesPerImage, MTLRegion _region, NSUInteger _mipmapLevel, NSUInteger _slice) { [m_obj getBytes:_pixelBytes bytesPerRow:_bytesPerRow bytesPerImage:_bytesPerImage fromRegion:_region mipmapLevel:_mipmapLevel slice:_slice]; }
void getBytes(void *_pixelBytes, NSUInteger _bytesPerRow, NSUInteger _bytesPerImage, MTLRegion _region, NSUInteger _mipmapLevel, NSUInteger _slice)
{
[m_obj getBytes:_pixelBytes bytesPerRow:_bytesPerRow bytesPerImage:_bytesPerImage fromRegion:_region mipmapLevel:_mipmapLevel slice:_slice];
}
// Creating Textures by Reusing Image Data
id<MTLTexture> newTextureViewWithPixelFormat(MTLPixelFormat _pixelFormat) { return [m_obj newTextureViewWithPixelFormat:_pixelFormat]; }
id<MTLTexture> newTextureViewWithPixelFormat(MTLPixelFormat _pixelFormat)
{
return [m_obj newTextureViewWithPixelFormat:_pixelFormat];
}
//properties
uint32_t width() { return (uint32_t)m_obj.width; }
uint32_t height() { return (uint32_t)m_obj.height; }
MTLPixelFormat pixelFormat() const { return m_obj.pixelFormat; }
uint32_t width()
{
return (uint32_t)m_obj.width;
}
uint32_t height()
{
return (uint32_t)m_obj.height;
}
MTLPixelFormat pixelFormat() const
{
return m_obj.pixelFormat;
}
MTL_CLASS_END
typedef id<MTLComputePipelineState> ComputePipelineState;
@ -226,47 +387,90 @@ namespace bgfx { namespace mtl
//descriptors
//NOTE: [class new] is same as [[class alloc] init]
typedef MTLRenderPipelineDescriptor* RenderPipelineDescriptor;
RenderPipelineDescriptor newRenderPipelineDescriptor() { return [MTLRenderPipelineDescriptor new]; }
void reset(RenderPipelineDescriptor _desc) { [_desc reset]; };
RenderPipelineDescriptor newRenderPipelineDescriptor()
{
return [MTLRenderPipelineDescriptor new];
}
void reset(RenderPipelineDescriptor _desc)
{
[_desc reset];
}
typedef MTLRenderPipelineColorAttachmentDescriptor* RenderPipelineColorAttachmentDescriptor;
typedef MTLDepthStencilDescriptor* DepthStencilDescriptor;
MTLDepthStencilDescriptor* newDepthStencilDescriptor() { return [MTLDepthStencilDescriptor new]; }
MTLDepthStencilDescriptor* newDepthStencilDescriptor()
{
return [MTLDepthStencilDescriptor new];
}
typedef MTLStencilDescriptor* StencilDescriptor;
MTLStencilDescriptor* newStencilDescriptor() { return [MTLStencilDescriptor new]; }
MTLStencilDescriptor* newStencilDescriptor()
{
return [MTLStencilDescriptor new];
}
typedef MTLRenderPassColorAttachmentDescriptor* RenderPassColorAttachmentDescriptor;
typedef MTLRenderPassDepthAttachmentDescriptor* RenderPassDepthAttachmentDescriptor;
typedef MTLRenderPassStencilAttachmentDescriptor* RenderPassStencilAttachmentDescriptor;
typedef MTLRenderPassDescriptor* RenderPassDescriptor;
MTLRenderPassDescriptor* newRenderPassDescriptor() { return [MTLRenderPassDescriptor new]; }
MTLRenderPassDescriptor* newRenderPassDescriptor()
{
return [MTLRenderPassDescriptor new];
}
typedef MTLVertexDescriptor* VertexDescriptor;
MTLVertexDescriptor* newVertexDescriptor() { return [MTLVertexDescriptor new]; }
void reset(VertexDescriptor _desc) { [_desc reset]; };
MTLVertexDescriptor* newVertexDescriptor()
{
return [MTLVertexDescriptor new];
}
void reset(VertexDescriptor _desc)
{
[_desc reset];
}
typedef MTLSamplerDescriptor* SamplerDescriptor;
MTLSamplerDescriptor* newSamplerDescriptor() { return [MTLSamplerDescriptor new]; }
MTLSamplerDescriptor* newSamplerDescriptor()
{
return [MTLSamplerDescriptor new];
}
typedef MTLTextureDescriptor* TextureDescriptor;
MTLTextureDescriptor* newTextureDescriptor() { return [MTLTextureDescriptor new]; }
MTLTextureDescriptor* newTextureDescriptor()
{
return [MTLTextureDescriptor new];
}
typedef MTLRenderPipelineReflection* RenderPipelineReflection;
//helper functions
void release(NSObject* _obj) { [_obj release]; }
void retain(NSObject* _obj) { [_obj retain]; }
const char* utf8String(NSString* _str) { return [_str UTF8String]; }
//helper functions
void release(NSObject* _obj)
{
[_obj release];
}
void retain(NSObject* _obj)
{
[_obj retain];
}
const char* utf8String(NSString* _str)
{
return [_str UTF8String];
}
#define MTL_RELEASE(_obj) \
[_obj release]; \
_obj = nil;
#if BX_PLATFORM_IOS
bool OsVersionEqualOrGreater(const char* _version) { return ([[[UIDevice currentDevice] systemVersion] compare:@(_version) options:NSNumericSearch] != NSOrderedAscending); }
bool OsVersionEqualOrGreater(const char* _version)
{
return ([[[UIDevice currentDevice] systemVersion] compare:@(_version) options:NSNumericSearch] != NSOrderedAscending);
}
//TODO: this could be in bx ?
#endif //
@ -481,9 +685,8 @@ namespace bgfx { namespace mtl
uint8_t m_num; // number of color handles
};
#endif
} /* namespace metal */ } // namespace bgfx
#endif // BGFX_CONFIG_RENDERER_METAL
#endif // BGFX_RENDERER_METAL_H_HEADER_GUARD

View file

@ -348,7 +348,8 @@ namespace bgfx { namespace mtl
//on iOS we need the layer as CAmetalLayer
#if BX_PLATFORM_IOS
CAMetalLayer* metalLayer = (CAMetalLayer*)g_platformData.nwh;
if (metalLayer == nil || ![metalLayer isKindOfClass:NSClassFromString(@"CAMetalLayer")])
if (NULL == metalLayer
|| ![metalLayer isKindOfClass:NSClassFromString(@"CAMetalLayer")])
{
BX_WARN(NULL != m_device, "Unable to create Metal device. Please set platform data window to a CAMetalLayer");
return false;
@ -378,7 +379,8 @@ namespace bgfx { namespace mtl
return false;
}
m_metalLayer.device = m_device;
m_metalLayer.device = m_device;
m_metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
m_commandQueue = m_device.newCommandQueue();
BGFX_FATAL(NULL != m_commandQueue, Fatal::UnableToInitialize, "Unable to create Metal device.");
@ -410,7 +412,7 @@ namespace bgfx { namespace mtl
);
g_caps.maxTextureSize = 2048; //ASK: real caps width/height: 4096, but max depth(3D) size is only: 2048
//TODO: OSX
//TODO: OSX
#if BX_PLATFORM_IOS
g_caps.maxFBAttachments = uint8_t(bx::uint32_min(m_device.supportsFeatureSet(MTLFeatureSet_iOS_GPUFamily2_v1) ? 8 :4, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS));
#endif // BX_PLATFORM_*
@ -448,7 +450,6 @@ namespace bgfx { namespace mtl
bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1, "%3d ", ii);
}
BX_TRACE("x");
return true;
}
@ -675,8 +676,11 @@ namespace bgfx { namespace mtl
void saveScreenShot(const char* _filePath) BX_OVERRIDE
{
if ( NULL == m_drawable || NULL == m_drawable.texture)
if (NULL == m_drawable
|| NULL == m_drawable.texture)
{
return;
}
//TODO: we should wait for completion of pending commandBuffers
//TODO: implement this with saveScreenshotBegin/End
@ -804,8 +808,11 @@ namespace bgfx { namespace mtl
void flip(HMD& /*_hmd*/) BX_OVERRIDE
{
if ( m_drawable == nil || m_commandBuffer == nil) //there was no draw call, cannot flip
if (NULL == m_drawable
|| NULL == m_commandBuffer)
{
return;
}
// Present and commit the command buffer
m_commandBuffer.presentDrawable(m_drawable);