diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index b93059190..72ecec37f 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -22,11 +22,11 @@ // known metal shader generation issues: 03-raymarch: OSX10.11.3 nothing is visible ( depth/color swap in fragment output struct fixed this ) 14-shadowvolumes: in texture as stencil mode - columns/bunny are dark. in fs_shadowvolume_color_lighting SAMPLER2D(s_texStencil, 1) is - converted to "texture2d s_texStencil [[texture(0)]], sampler _mtlsmp_s_texStencil [[sampler(0)]]". Slot is 1 -> 0. + converted to "texture2d s_texStencil [[texture(0)]], sampler _mtlsmp_s_texStencil [[sampler(0)]]". Slot is 1 -> 0. 15-shadowmaps-simple: shader compilation error 16-shadowmaps: //problem with essl -> metal: SAMPLER2D(u_shadowMap0, 4); sampler index is lost. Shadowmap is set to slot 4, but metal shader uses sampler/texture slot 0. this could require changes outside of renderer_mtl? - packFloatToRGBA needs highp. currently it uses half. + packFloatToRGBA needs highp. currently it uses half. 24-nbody: no generated compute shaders for metal 27-terrain: shaderc generates invalid metal shader for vs_terrain_height_texture. vertex output: half4 gl_Position [[position]], should be float4 31-rsm: @@ -36,18 +36,18 @@ Known issues(driver problems??): OSX mac mini(late 2014), OSX10.11.3 : nanovg-rendering: color writemask off causes problem... - 03-raymarch: OSX nothing is visible ( depth/color order should be swapped in fragment output struct) - works fine with newer OSX + 03-raymarch: OSX nothing is visible ( depth/color order should be swapped in fragment output struct) + works fine with newer OSX iPad mini 2, iOS 8.1.1: 21-deferred: scissor not working properly - 26-occlusion: query doesn't work with two rendercommandencoders - Only on this device ( no problem on iPad Air 2 with iOS9.3.1) + 26-occlusion: query doesn't work with two rendercommandencoders + Only on this device ( no problem on iPad Air 2 with iOS9.3.1) TODOs: - framebufferMtl and TextureMtl resolve - FrameBufferMtl::postReset recreate framebuffer??? - renderpass load/resolve + renderpass load/resolve - capture with msaa: 07-callback - implement fb discard. problematic with multiple views that has same fb... - msaa color/depth/stencil is not saved. could have problem when we switch back to msaa framebuffer @@ -975,6 +975,8 @@ namespace bgfx { namespace mtl m_occlusionQuery.invalidate(_handle); } + void submitBlit(BlitState& _bs, uint16_t _view); + void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE; void blitSetup(TextVideoMemBlitter& _blitter) BX_OVERRIDE @@ -2974,6 +2976,87 @@ namespace bgfx { namespace mtl } } + void RendererContextMtl::submitBlit(BlitState& _bs, uint16_t _view) + { + if (0 != m_renderCommandEncoder) + { + m_renderCommandEncoder.endEncoding(); + m_renderCommandEncoder = 0; + } + + m_blitCommandEncoder = getBlitCommandEncoder(); + + while (_bs.hasItem(_view) ) + { + const BlitItem& blit = _bs.advance(); + + const TextureMtl& src = m_textures[blit.m_src.idx]; + const TextureMtl& dst = m_textures[blit.m_dst.idx]; + + uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX; + uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY; + uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ; + uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX; + uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY; + uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ; + uint32_t width = bx::uint32_min(srcWidth, dstWidth); + uint32_t height = bx::uint32_min(srcHeight, dstHeight); + uint32_t depth = bx::uint32_min(srcDepth, dstDepth); +#if BX_PLATFORM_OSX + bool readBack = !!(dst.m_flags & BGFX_TEXTURE_READ_BACK); +#endif // BX_PLATFORM_OSX + + if ( MTLTextureType3D == src.m_ptr.textureType()) + { + m_blitCommandEncoder.copyFromTexture( + src.m_ptr + , 0 + , 0 + , MTLOriginMake(blit.m_srcX, blit.m_srcY, blit.m_srcZ) + , MTLSizeMake(width, height, bx::uint32_imax(depth, 1)) + , dst.m_ptr + , 0 + , 0 + , MTLOriginMake(blit.m_dstX, blit.m_dstY, blit.m_dstZ) + ); +#if BX_PLATFORM_OSX + if (m_macOS11Runtime + && readBack) + { + m_blitCommandEncoder.synchronizeResource(dst.m_ptr); + } +#endif // BX_PLATFORM_OSX + } + else + { + m_blitCommandEncoder.copyFromTexture( + src.m_ptr + , blit.m_srcZ + , blit.m_srcMip + , MTLOriginMake(blit.m_srcX, blit.m_srcY, 0) + , MTLSizeMake(width, height, 1) + , dst.m_ptr + , blit.m_dstZ + , blit.m_dstMip + , MTLOriginMake(blit.m_dstX, blit.m_dstY, 0) + ); +#if BX_PLATFORM_OSX + if (m_macOS11Runtime + && readBack) + { + m_blitCommandEncoder.synchronizeTexture(dst.m_ptr, 0, blit.m_dstMip); + } +#endif // BX_PLATFORM_OSX + } + } + + if (0 != m_blitCommandEncoder) + { + m_blitCommandEncoder.endEncoding(); + m_blitCommandEncoder = 0; + } + } + void RendererContextMtl::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE { m_cmd.finish(false); @@ -3079,10 +3162,7 @@ namespace bgfx { namespace mtl uint16_t view = UINT16_MAX; FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS }; - BlitKey blitKey; - blitKey.decode(_render->m_blitKeys[0]); - uint16_t numBlitItems = _render->m_numBlitItems; - uint16_t blitItem = 0; + BlitState bs(_render); const uint64_t primType = 0; uint8_t primIndex = uint8_t(primType>>BGFX_STATE_PT_SHIFT); @@ -3170,62 +3250,7 @@ namespace bgfx { namespace mtl viewState.m_rect.m_width /= 2; } - const uint8_t blitView = SortKey::decodeView(encodedKey); - for (; blitItem < numBlitItems && blitKey.m_view <= blitView; blitItem++) - { - if (0 != m_renderCommandEncoder) - { - m_renderCommandEncoder.endEncoding(); - m_renderCommandEncoder = 0; - } - m_blitCommandEncoder = getBlitCommandEncoder(); - - const BlitItem& blit = _render->m_blitItem[blitItem]; - blitKey.decode(_render->m_blitKeys[blitItem+1]); - - const TextureMtl& src = m_textures[blit.m_src.idx]; - const TextureMtl& dst = m_textures[blit.m_dst.idx]; - - uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX; - uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY; - uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ; - uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX; - uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY; - uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ; - uint32_t width = bx::uint32_min(srcWidth, dstWidth); - uint32_t height = bx::uint32_min(srcHeight, dstHeight); - uint32_t depth = bx::uint32_min(srcDepth, dstDepth); -#if BX_PLATFORM_OSX - bool readBack = !!(dst.m_flags & BGFX_TEXTURE_READ_BACK); -#endif // BX_PLATFORM_OSX - - if ( MTLTextureType3D == src.m_ptr.textureType()) - { - m_blitCommandEncoder.copyFromTexture(src.m_ptr, 0, 0, MTLOriginMake(blit.m_srcX, blit.m_srcY, blit.m_srcZ), MTLSizeMake(width, height, bx::uint32_imax(depth, 1)), - dst.m_ptr, 0, 0, MTLOriginMake(blit.m_dstX, blit.m_dstY, blit.m_dstZ)); -#if BX_PLATFORM_OSX - if (m_macOS11Runtime &&readBack) { - m_blitCommandEncoder.synchronizeResource(dst.m_ptr); - } -#endif // BX_PLATFORM_OSX - } - else - { - m_blitCommandEncoder.copyFromTexture(src.m_ptr, blit.m_srcZ, blit.m_srcMip, MTLOriginMake(blit.m_srcX, blit.m_srcY, 0), MTLSizeMake(width, height, 1), - dst.m_ptr, blit.m_dstZ, blit.m_dstMip, MTLOriginMake(blit.m_dstX, blit.m_dstY, 0)); -#if BX_PLATFORM_OSX - if (m_macOS11Runtime && readBack) { - m_blitCommandEncoder.synchronizeTexture(dst.m_ptr, 0, blit.m_dstMip); - } -#endif // BX_PLATFORM_OSX - } - } - - if (0 != m_blitCommandEncoder) - { - m_blitCommandEncoder.endEncoding(); - m_blitCommandEncoder = 0; - } + submitBlit(bs, view); const Rect& scissorRect = _render->m_scissor[view]; viewHasScissor = !scissorRect.isZero(); @@ -3305,7 +3330,6 @@ namespace bgfx { namespace mtl } } - //TODO: optimize store actions use discard flag RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment; if (NULL != depthAttachment.texture) { @@ -3337,7 +3361,6 @@ namespace bgfx { namespace mtl desc.loadAction = MTLLoadActionLoad; } - //TODO: optimize store actions use discard flag RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment; if (NULL != depthAttachment.texture) { @@ -3768,11 +3791,13 @@ namespace bgfx { namespace mtl //invalidateCompute(); } + submitBlit(bs, BGFX_CONFIG_MAX_VIEWS); + if (0 < _render->m_num) { captureElapsed = -bx::getHPCounter(); capture(); - rce = m_renderCommandEncoder; //TODO: ugly, can create new encoder + rce = m_renderCommandEncoder; captureElapsed += bx::getHPCounter(); } }