diff options
Diffstat (limited to '3rdparty/bgfx/src/renderer_mtl.h')
-rw-r--r-- | 3rdparty/bgfx/src/renderer_mtl.h | 262 |
1 files changed, 213 insertions, 49 deletions
diff --git a/3rdparty/bgfx/src/renderer_mtl.h b/3rdparty/bgfx/src/renderer_mtl.h index 95e038405dc..1ceba862ca3 100644 --- a/3rdparty/bgfx/src/renderer_mtl.h +++ b/3rdparty/bgfx/src/renderer_mtl.h @@ -1,6 +1,6 @@ /* * Copyright 2011-2015 Attila Kocsis, Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE */ #ifndef BGFX_RENDERER_METAL_H_HEADER_GUARD @@ -18,6 +18,21 @@ # import <UIKit/UIKit.h> #endif // BX_PLATFORM_* +#define BGFX_MTL_PROFILER_BEGIN(_view, _abgr) \ + BX_MACRO_BLOCK_BEGIN \ + BGFX_PROFILER_BEGIN(s_viewName[view], _abgr); \ + BX_MACRO_BLOCK_END + +#define BGFX_MTL_PROFILER_BEGIN_LITERAL(_name, _abgr) \ + BX_MACRO_BLOCK_BEGIN \ + BGFX_PROFILER_BEGIN_LITERAL("" _name, _abgr); \ + BX_MACRO_BLOCK_END + +#define BGFX_MTL_PROFILER_END() \ + BX_MACRO_BLOCK_BEGIN \ + BGFX_PROFILER_END(); \ + BX_MACRO_BLOCK_END + namespace bgfx { namespace mtl { //runtime os check @@ -52,8 +67,6 @@ 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_MAX_FRAMES_IN_FLIGHT (3) - #define MTL_CLASS(name) \ class name \ { \ @@ -64,7 +77,7 @@ namespace bgfx { namespace mtl #define MTL_CLASS_END }; - typedef void (*mtlCallback)(void* userData); + typedef void (*mtlCallback)(void* userData); MTL_CLASS(BlitCommandEncoder) void copyFromTexture( @@ -112,6 +125,11 @@ namespace bgfx { namespace mtl destinationSlice:_destinationSlice destinationLevel:_destinationLevel destinationOrigin:_destinationOrigin]; } + void generateMipmapsForTexture(id<MTLTexture> _texture) + { + [m_obj generateMipmapsForTexture:_texture]; + } + #if BX_PLATFORM_OSX void synchronizeTexture(id<MTLTexture> _texture, NSUInteger _slice, NSUInteger _level) { @@ -140,6 +158,11 @@ namespace bgfx { namespace mtl { return (uint32_t)m_obj.length; } + + void setLabel(const char* _label) + { + [m_obj setLabel:@(_label)]; + } MTL_CLASS_END MTL_CLASS(CommandBuffer) @@ -223,10 +246,31 @@ namespace bgfx { namespace mtl [m_obj setSamplerState:_sampler atIndex:_index]; } + void dispatchThreadgroups(MTLSize _threadgroupsPerGrid, MTLSize _threadsPerThreadgroup) + { + [m_obj dispatchThreadgroups:_threadgroupsPerGrid threadsPerThreadgroup:_threadsPerThreadgroup]; + } + + void dispatchThreadgroupsWithIndirectBuffer(id <MTLBuffer> _indirectBuffer, + NSUInteger _indirectBufferOffset, MTLSize _threadsPerThreadgroup) + { + [m_obj dispatchThreadgroupsWithIndirectBuffer:_indirectBuffer indirectBufferOffset:_indirectBufferOffset threadsPerThreadgroup:_threadsPerThreadgroup]; + } + void endEncoding() { [m_obj endEncoding]; } + + void pushDebugGroup(const char* _string) + { + [m_obj pushDebugGroup:@(_string)]; + } + + void popDebugGroup() + { + [m_obj popDebugGroup]; + } MTL_CLASS_END MTL_CLASS(Device) @@ -322,10 +366,14 @@ namespace bgfx { namespace mtl } // Creating Command Objects Needed to Perform Computational Tasks - id <MTLComputePipelineState> newComputePipelineStateWithFunction(id <MTLFunction> _computeFunction) + id <MTLComputePipelineState> newComputePipelineStateWithFunction( + id <MTLFunction> _computeFunction + , MTLPipelineOption _options + , MTLComputePipelineReflection** _reflection + ) { NSError* error; - id <MTLComputePipelineState> state = [m_obj newComputePipelineStateWithFunction:_computeFunction error:&error]; + id <MTLComputePipelineState> state = [m_obj newComputePipelineStateWithFunction:_computeFunction options:_options reflection:_reflection error:&error]; BX_WARN(NULL == error , "newComputePipelineStateWithFunction failed: %s" @@ -487,6 +535,25 @@ namespace bgfx { namespace mtl [m_obj drawPrimitives:_primitiveType vertexStart:_vertexStart vertexCount:_vertexCount instanceCount:_instanceCount]; } + void drawPrimitives( + MTLPrimitiveType _primitiveType + , id <MTLBuffer> _indirectBuffer + , NSUInteger _indirectBufferOffset) + { + [m_obj drawPrimitives:_primitiveType indirectBuffer:_indirectBuffer indirectBufferOffset:_indirectBufferOffset]; + } + + void drawIndexedPrimitives( + MTLPrimitiveType _primitiveType + , MTLIndexType _indexType + , id <MTLBuffer> _indexBuffer + , NSUInteger _indexBufferOffset + , id <MTLBuffer> _indirectBuffer + , NSUInteger _indirectBufferOffset) + { + [m_obj drawIndexedPrimitives:_primitiveType indexType:_indexType indexBuffer:_indexBuffer indexBufferOffset:_indexBufferOffset indirectBuffer:_indirectBuffer indirectBufferOffset:_indirectBufferOffset]; + } + void insertDebugSignpost(const char* _string) { [m_obj insertDebugSignpost:@(_string)]; @@ -527,6 +594,11 @@ namespace bgfx { namespace mtl return [m_obj newTextureViewWithPixelFormat:_pixelFormat]; } + id<MTLTexture> newTextureViewWithPixelFormat(MTLPixelFormat _pixelFormat, MTLTextureType _textureType, NSRange _levelRange, NSRange _sliceRange) + { + return [m_obj newTextureViewWithPixelFormat:_pixelFormat textureType:_textureType levels:_levelRange slices:_sliceRange]; + } + //properties uint32_t width() const { @@ -538,6 +610,11 @@ namespace bgfx { namespace mtl return (uint32_t)m_obj.height; } + uint32_t arrayLength() const + { + return (uint32_t)m_obj.arrayLength; + } + MTLPixelFormat pixelFormat() const { return m_obj.pixelFormat; @@ -567,6 +644,7 @@ namespace bgfx { namespace mtl //descriptors //NOTE: [class new] is same as [[class alloc] init] typedef MTLRenderPipelineDescriptor* RenderPipelineDescriptor; + typedef MTLComputePipelineReflection* ComputePipelineReflection; inline RenderPipelineDescriptor newRenderPipelineDescriptor() { @@ -683,7 +761,7 @@ namespace bgfx { namespace mtl typename HashMap::iterator it = m_hashMap.find(_id); if (it != m_hashMap.end() ) { - MTL_RELEASE(it->second); + release(it->second); m_hashMap.erase(it); } } @@ -712,13 +790,8 @@ namespace bgfx { namespace mtl { BufferMtl() : m_flags(BGFX_BUFFER_NONE) - , m_dynamic(false) - , m_bufferIndex(0) + , m_dynamic(NULL) { - for (uint32_t ii = 0; ii < MTL_MAX_FRAMES_IN_FLIGHT; ++ii) - { - m_buffers[ii] = NULL; - } } void create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride = 0, bool _vertex = false); @@ -726,23 +799,21 @@ namespace bgfx { namespace mtl void destroy() { - for (uint32_t ii = 0; ii < MTL_MAX_FRAMES_IN_FLIGHT; ++ii) + MTL_RELEASE(m_ptr); + + if (NULL != m_dynamic) { - MTL_RELEASE(m_buffers[ii]); + BX_DELETE(g_allocator, m_dynamic); + m_dynamic = NULL; } - - m_dynamic = false; } - Buffer getBuffer() const { return m_buffers[m_bufferIndex]; } - uint32_t m_size; uint16_t m_flags; + bool m_vertex; - bool m_dynamic; - private: - uint8_t m_bufferIndex; - Buffer m_buffers[MTL_MAX_FRAMES_IN_FLIGHT]; + Buffer m_ptr; + uint8_t* m_dynamic; }; typedef BufferMtl IndexBufferMtl; @@ -754,9 +825,9 @@ namespace bgfx { namespace mtl { } - void create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint16_t _flags); + void create(uint32_t _size, void* _data, VertexLayoutHandle _layoutHandle, uint16_t _flags); - VertexDeclHandle m_decl; + VertexLayoutHandle m_layoutHandle; }; @@ -776,22 +847,17 @@ namespace bgfx { namespace mtl Function m_function; uint32_t m_hash; + uint16_t m_numThreads[3]; }; + struct PipelineStateMtl; + struct ProgramMtl { ProgramMtl() : m_vsh(NULL) , m_fsh(NULL) - , m_vshConstantBuffer(NULL) - , m_fshConstantBuffer(NULL) - , m_vshConstantBufferSize(0) - , m_vshConstantBufferAlignmentMask(0) - , m_fshConstantBufferSize(0) - , m_fshConstantBufferAlignmentMask(0) - , m_samplerCount(0) - , m_numPredefined(0) - , m_processedUniforms(false) + , m_computePS(NULL) { } @@ -804,29 +870,77 @@ namespace bgfx { namespace mtl const ShaderMtl* m_vsh; const ShaderMtl* m_fsh; + + PipelineStateMtl* m_computePS; + }; + + struct PipelineStateMtl + { + PipelineStateMtl() + : m_vshConstantBuffer(NULL) + , m_fshConstantBuffer(NULL) + , m_vshConstantBufferSize(0) + , m_vshConstantBufferAlignment(0) + , m_fshConstantBufferSize(0) + , m_fshConstantBufferAlignment(0) + , m_numPredefined(0) + , m_rps(NULL) + , m_cps(NULL) + { + m_numThreads[0] = 1; + m_numThreads[1] = 1; + m_numThreads[2] = 1; + for(uint32_t i=0; i<BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++i) + m_bindingTypes[i] = 0; + } + + ~PipelineStateMtl() + { + if (NULL != m_vshConstantBuffer) + { + UniformBuffer::destroy(m_vshConstantBuffer); + m_vshConstantBuffer = NULL; + } + + if (NULL != m_fshConstantBuffer) + { + UniformBuffer::destroy(m_fshConstantBuffer); + m_fshConstantBuffer = NULL; + } + + release(m_rps); + release(m_cps); + } + UniformBuffer* m_vshConstantBuffer; UniformBuffer* m_fshConstantBuffer; uint32_t m_vshConstantBufferSize; - uint32_t m_vshConstantBufferAlignmentMask; + uint32_t m_vshConstantBufferAlignment; uint32_t m_fshConstantBufferSize; - uint32_t m_fshConstantBufferAlignmentMask; + uint32_t m_fshConstantBufferAlignment; - struct SamplerInfo + enum { - uint32_t m_index; - bgfx::UniformHandle m_uniform; - bool m_fragment; + BindToVertexShader = 1 << 0, + BindToFragmentShader = 1 << 1, }; + uint8_t m_bindingTypes[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; - SamplerInfo m_samplers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; - uint32_t m_samplerCount; + uint16_t m_numThreads[3]; PredefinedUniform m_predefined[PredefinedUniform::Count*2]; uint8_t m_numPredefined; - bool m_processedUniforms; + + RenderPipelineState m_rps; + ComputePipelineState m_cps; }; + void release(PipelineStateMtl* _ptr) + { + BX_DELETE(g_allocator, _ptr); + } + struct TextureMtl { enum Enum @@ -847,14 +961,32 @@ namespace bgfx { namespace mtl , m_depth(0) , m_numMips(0) { + for(uint32_t ii = 0; ii < BX_COUNTOF(m_ptrMips); ++ii) + { + m_ptrMips[ii] = NULL; + } } void create(const Memory* _mem, uint64_t _flags, uint8_t _skip); void destroy() { - MTL_RELEASE(m_ptr); + if (0 == (m_flags & BGFX_SAMPLER_INTERNAL_SHARED)) + { + MTL_RELEASE(m_ptr); + } MTL_RELEASE(m_ptrStencil); + for (uint32_t ii = 0; ii < m_numMips; ++ii) + { + MTL_RELEASE(m_ptrMips[ii]); + } + } + + void overrideInternal(uintptr_t _ptr) + { + destroy(); + m_flags |= BGFX_SAMPLER_INTERNAL_SHARED; + m_ptr = id<MTLTexture>(_ptr); } void update( @@ -872,11 +1004,15 @@ namespace bgfx { namespace mtl , bool _vertex , bool _fragment , uint32_t _flags = BGFX_SAMPLER_INTERNAL_DEFAULT + , uint8_t _mip = UINT8_MAX ); + Texture getTextureMipLevel(int _mip); + Texture m_ptr; Texture m_ptrMsaa; Texture m_ptrStencil; // for emulating packed depth/stencil formats - only for iOS8... + Texture m_ptrMips[14]; SamplerState m_sampler; uint64_t m_flags; uint32_t m_width; @@ -895,6 +1031,7 @@ namespace bgfx { namespace mtl SwapChainMtl() : m_metalLayer(nil) , m_drawable(nil) + , m_drawableTexture(nil) , m_backBufferColorMsaa() , m_backBufferDepth() , m_backBufferStencil() @@ -905,22 +1042,26 @@ namespace bgfx { namespace mtl ~SwapChainMtl(); void init(void* _nwh); - void resize(FrameBufferMtl &_frameBuffer, uint32_t _width, uint32_t _height, uint32_t _flags); + void resize(FrameBufferMtl &_frameBuffer, uint32_t _width, uint32_t _height, uint32_t _flags, uint32_t _maximumDrawableCount); - id<CAMetalDrawable> currentDrawable(); + id <MTLTexture> currentDrawableTexture(); CAMetalLayer* m_metalLayer; id <CAMetalDrawable> m_drawable; + id <MTLTexture> m_drawableTexture; Texture m_backBufferColorMsaa; Texture m_backBufferDepth; Texture m_backBufferStencil; uint32_t m_maxAnisotropy; + void* m_nwh; }; struct FrameBufferMtl { FrameBufferMtl() - : m_denseIdx(UINT16_MAX) + : m_swapChain(NULL) + , m_nwh(NULL) + , m_denseIdx(UINT16_MAX) , m_pixelFormatHash(0) , m_num(0) { @@ -939,7 +1080,10 @@ namespace bgfx { namespace mtl void postReset(); uint16_t destroy(); + void resolve(); + SwapChainMtl* m_swapChain; + void* m_nwh; uint32_t m_width; uint32_t m_height; uint16_t m_denseIdx; @@ -948,6 +1092,8 @@ namespace bgfx { namespace mtl TextureHandle m_colorHandle[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; TextureHandle m_depthHandle; + Attachment m_colorAttachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS-1]; + Attachment m_depthAttachment; uint8_t m_num; // number of color handles }; @@ -975,7 +1121,7 @@ namespace bgfx { namespace mtl int m_releaseWriteIndex; int m_releaseReadIndex; typedef stl::vector<NSObject*> ResourceArray; - ResourceArray m_release[MTL_MAX_FRAMES_IN_FLIGHT]; + ResourceArray m_release[BGFX_CONFIG_MAX_FRAME_LATENCY]; }; struct TimerQueryMtl @@ -987,15 +1133,33 @@ namespace bgfx { namespace mtl void init(); void shutdown(); + uint32_t begin(uint32_t _resultIdx, uint32_t _frameNum); + void end(uint32_t _idx); void addHandlers(CommandBuffer& _commandBuffer); bool get(); + struct Result + { + void reset() + { + m_begin = 0; + m_end = 0; + m_pending = 0; + m_frameNum = 0; + } + + uint64_t m_begin; + uint64_t m_end; + uint32_t m_pending; + uint32_t m_frameNum; // TODO: implement (currently stays 0) + }; + uint64_t m_begin; uint64_t m_end; uint64_t m_elapsed; uint64_t m_frequency; - uint64_t m_result[4*2]; + Result m_result[4*2]; bx::RingBufferControl m_control; }; |