diff --git a/src/renderer_mtl.h b/src/renderer_mtl.h index aaeb0d8c..e25f4b96 100644 --- a/src/renderer_mtl.h +++ b/src/renderer_mtl.h @@ -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 commandBuffer() { return [m_obj commandBuffer]; } - id commandBufferWithUnretainedReferences() { return [m_obj commandBufferWithUnretainedReferences]; } + id commandBuffer() + { + return [m_obj commandBuffer]; + } + + id commandBufferWithUnretainedReferences() + { + return [m_obj commandBufferWithUnretainedReferences]; + } MTL_CLASS_END MTL_CLASS(ComputeCommandEncoder) - void setComputePipelineState(id _state) { [m_obj setComputePipelineState:_state]; } + void setComputePipelineState(id _state) + { + [m_obj setComputePipelineState:_state]; + } - void setBuffer(id _buffer, NSUInteger _offset, NSUInteger _index) { [m_obj setBuffer:_buffer offset:_offset atIndex:_index]; } + void setBuffer(id _buffer, NSUInteger _offset, NSUInteger _index) + { + [m_obj setBuffer:_buffer offset:_offset atIndex:_index]; + } - void setTexture(id _texture, NSUInteger _index) { [m_obj setTexture:_texture atIndex:_index]; } + void setTexture(id _texture, NSUInteger _index) + { + [m_obj setTexture:_texture atIndex:_index]; + } - void setSamplerState(id _sampler, NSUInteger _index) { [m_obj setSamplerState:_sampler atIndex:_index]; } + void setSamplerState(id _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 newLibraryWithData(const void* _data) { + id newLibraryWithData(const void* _data) + { NSError* error; id lib = [m_obj newLibraryWithData:(dispatch_data_t)_data error:&error]; BX_WARN(error==NULL,"newLibraryWithData failed:%s", [error.localizedDescription UTF8String] ); return lib; } - id newLibraryWithSource(const char* _source) { + + id newLibraryWithSource(const char* _source) + { NSError* error; id 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 newCommandQueue() { return [m_obj newCommandQueue]; } - id newCommandQueueWithMaxCommandBufferCount(NSUInteger _maxCommandBufferCount) { return [m_obj newCommandQueueWithMaxCommandBufferCount:_maxCommandBufferCount]; } + id newCommandQueue() + { + return [m_obj newCommandQueue]; + } + + id newCommandQueueWithMaxCommandBufferCount(NSUInteger _maxCommandBufferCount) + { + return [m_obj newCommandQueueWithMaxCommandBufferCount:_maxCommandBufferCount]; + } // Creating Resources - id newBufferWithLength(unsigned int _length, MTLResourceOptions _options) { return [m_obj newBufferWithLength:_length options:_options ]; } - id newBufferWithBytes(const void *_pointer, NSUInteger _length, MTLResourceOptions _options) { return [m_obj newBufferWithBytes:_pointer length:_length options:_options]; } + id newBufferWithLength(unsigned int _length, MTLResourceOptions _options) + { + return [m_obj newBufferWithLength:_length options:_options ]; + } - id newTextureWithDescriptor(MTLTextureDescriptor * _descriptor) { return [m_obj newTextureWithDescriptor:_descriptor]; } - id newSamplerStateWithDescriptor(MTLSamplerDescriptor * _descriptor) { return [m_obj newSamplerStateWithDescriptor:_descriptor]; } + id newBufferWithBytes(const void *_pointer, NSUInteger _length, MTLResourceOptions _options) + { + return [m_obj newBufferWithBytes:_pointer length:_length options:_options]; + } + + id newTextureWithDescriptor(MTLTextureDescriptor * _descriptor) + { + return [m_obj newTextureWithDescriptor:_descriptor]; + } + + id newSamplerStateWithDescriptor(MTLSamplerDescriptor * _descriptor) + { + return [m_obj newSamplerStateWithDescriptor:_descriptor]; + } // Creating Command Objects Needed to Render Graphics - id newDepthStencilStateWithDescriptor(MTLDepthStencilDescriptor * _descriptor) { return [m_obj newDepthStencilStateWithDescriptor:_descriptor]; } + id newDepthStencilStateWithDescriptor(MTLDepthStencilDescriptor * _descriptor) + { + return [m_obj newDepthStencilStateWithDescriptor:_descriptor]; + } id 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 _depthStencilState) { [m_obj setDepthStencilState:_depthStencilState];} - void setFrontFacingWinding(MTLWinding _frontFacingWinding) { [m_obj setFrontFacingWinding:_frontFacingWinding]; } - void setRenderPipelineState(id _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 _depthStencilState) + { + [m_obj setDepthStencilState:_depthStencilState]; + } + + void setFrontFacingWinding(MTLWinding _frontFacingWinding) + { + [m_obj setFrontFacingWinding:_frontFacingWinding]; + } + + void setRenderPipelineState(id _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 _buffer, NSUInteger _offset, NSUInteger _index) { [m_obj setVertexBuffer:_buffer offset:_offset atIndex:_index]; } - void setVertexSamplerState(id _sampler, NSUInteger _index) { [m_obj setVertexSamplerState:_sampler atIndex:_index]; } - void setVertexTexture(id _texture, NSUInteger _index) { [m_obj setVertexTexture:_texture atIndex:_index]; } + void setVertexBuffer(id _buffer, NSUInteger _offset, NSUInteger _index) + { + [m_obj setVertexBuffer:_buffer offset:_offset atIndex:_index]; + } + + void setVertexSamplerState(id _sampler, NSUInteger _index) + { + [m_obj setVertexSamplerState:_sampler atIndex:_index]; + } + + void setVertexTexture(id _texture, NSUInteger _index) + { + [m_obj setVertexTexture:_texture atIndex:_index]; + } // Specifying Resources for a Fragment Function - void setFragmentBuffer(id _buffer, NSUInteger _offset, NSUInteger _index) { [m_obj setFragmentBuffer:_buffer offset:_offset atIndex:_index]; } - void setFragmentSamplerState(id _sampler, NSUInteger _index) { [m_obj setFragmentSamplerState:_sampler atIndex:_index]; } - void setFragmentTexture(id _texture, NSUInteger _index) { [m_obj setFragmentTexture:_texture atIndex:_index]; } + void setFragmentBuffer(id _buffer, NSUInteger _offset, NSUInteger _index) + { + [m_obj setFragmentBuffer:_buffer offset:_offset atIndex:_index]; + } + + void setFragmentSamplerState(id _sampler, NSUInteger _index) + { + [m_obj setFragmentSamplerState:_sampler atIndex:_index]; + } + + void setFragmentTexture(id _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 newTextureViewWithPixelFormat(MTLPixelFormat _pixelFormat) { return [m_obj newTextureViewWithPixelFormat:_pixelFormat]; } + id 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 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 diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index 183f2ef4..983c7d63 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -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);