diff --git a/examples/19-oit/oit.cpp b/examples/19-oit/oit.cpp index b9bbd0419..78c600331 100644 --- a/examples/19-oit/oit.cpp +++ b/examples/19-oit/oit.cpp @@ -410,6 +410,14 @@ class ExampleOIT : public entry::AppI | BGFX_STATE_MSAA ; + const uint64_t stateNoDepth = 0 + | BGFX_STATE_CULL_CW + | BGFX_STATE_RGB_WRITE + | BGFX_STATE_ALPHA_WRITE + | BGFX_STATE_DEPTH_TEST_ALWAYS + | BGFX_STATE_MSAA + ; + bgfx::ProgramHandle program = BGFX_INVALID_HANDLE; switch (m_mode) { @@ -428,7 +436,7 @@ class ExampleOIT : public entry::AppI program = m_wbSeparatePass; // Set render states. - bgfx::setState(state + bgfx::setState(stateNoDepth | BGFX_STATE_BLEND_FUNC_SEPARATE(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_INV_SRC_ALPHA) ); break; @@ -438,7 +446,7 @@ class ExampleOIT : public entry::AppI program = m_wbPass; // Set render states. - bgfx::setState(state + bgfx::setState(stateNoDepth | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE) | BGFX_STATE_BLEND_INDEPENDENT , 0 diff --git a/examples/21-deferred/fs_deferred_light.sc b/examples/21-deferred/fs_deferred_light.sc index 81f9ad259..425711577 100644 --- a/examples/21-deferred/fs_deferred_light.sc +++ b/examples/21-deferred/fs_deferred_light.sc @@ -56,11 +56,11 @@ vec3 calcLight(int _idx, vec3 _wpos, vec3 _normal, vec3 _view) float toClipSpaceDepth(float _depthTextureZ) { -#if BGFX_SHADER_LANGUAGE_HLSL +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL return _depthTextureZ; #else return _depthTextureZ * 2.0 - 1.0; -#endif // BGFX_SHADER_LANGUAGE_HLSL +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL } vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos) @@ -76,9 +76,9 @@ void main() float depth = toClipSpaceDepth(deviceDepth); vec3 clip = vec3(v_texcoord0 * 2.0 - 1.0, depth); -#if BGFX_SHADER_LANGUAGE_HLSL +#if BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL clip.y = -clip.y; -#endif // BGFX_SHADER_LANGUAGE_HLSL +#endif // BGFX_SHADER_LANGUAGE_HLSL || BGFX_SHADER_LANGUAGE_METAL vec3 wpos = clipToWorld(u_mtx, clip); vec3 view = mul(u_view, vec4(wpos, 0.0) ).xyz; diff --git a/examples/runtime/shaders/metal/fs_deferred_light.bin b/examples/runtime/shaders/metal/fs_deferred_light.bin index 89bc35bc2..e5a039689 100644 Binary files a/examples/runtime/shaders/metal/fs_deferred_light.bin and b/examples/runtime/shaders/metal/fs_deferred_light.bin differ diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index 1b977fa19..6f8e661af 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -1,5 +1,5 @@ /* - * Copyright 2011-2015 Attila Kocsis. All rights reserved. + * Copyright 2011-2016 Attila Kocsis. All rights reserved. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ @@ -21,40 +21,33 @@ #define UNIFORM_BUFFER_COUNT (3) /* - // metal shader generation issues: - 03-raymarch: nothing is visible ( should be swapped in fragment output struct) - 15-shadowmaps-simple: shader compilation error + // known metal shader generation issues: + 03-raymarch: OSX nothing is visible ( depth/color order should be swapped in fragment output struct) + 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. + 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 - //OSX issues: - 16-shadowmaps: framebuffer creation problems (iOS: PixelFormat MTLPixelFormatDepth32Float is not stencil renderable) - 18-ibl:color wheel is not visible - 19-oit: mrt independent does not work - 20-nanovg: nothing is visible - 21-deferred: only intermediate buffers are visible (iOS) - 22-windows: todo support multiple windows - 26-occlusion: view 2's clear should clear only its rect (not whole fb) (iOS, occlusion doesn't work) - 27-terrain: problem with sample in texture mode (iOS) +Known issues(driver problems??): + OSX mac mini(late 2014), OSX10.11.3 : nanovg-rendering: color writemask off causes problem... + iPad mini 2, iOS 8.1.1: 21-deferred: scissor not working properly + 26-occlusion: doesn't work with two rendercommandencoders, merge should fix this + +TODOs: + 07-callback, saveScreenshot should be implemented with one frame latency (using saveScreenshotBegin and End) + - iOS device orientation change is not handled properly + + 22-windows: todo support multiple windows + + - optimization: remove heavy sync, merge views with same fb and no clear. + 13-stencil and 16-shadowmaps are very inefficient. every view stores/loads backbuffer data + + - 15-shadowmaps-simple (example needs modification mtxCrop znew = z * 0.5 + 0.5 is not needed ) could be hacked in shader too -Known issues / TODOs: -- device orientation change is not handled properly -- 15-shadowmaps-simple (modified shaderc and example needs modification too, mtxCrop znew = z * 0.5 + 0.5 is not needed ) could be hacked in shader too - 21-deferred ( fs_deferred_light needed modification for metal (similar to BGFX_SHADER_LANGUAGE_HLSL ) - - 07-callback, saveScreenshot should be implemented with one frame latency (using saveScreenshotBegin and End) - -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? - Otherwise it works with hacking the slot. - -24-nbody - cannot generate compute shaders for metal - -- optimization... - - 13-stencil and 16-shadowmaps are very inefficient. every view stores/loads backbuffer data - BGFX_RESET_FLIP_AFTER_RENDER on low level renderers should be true? (crashes even with BGFX_RESET_FLIP_AFTER_RENDER because there is one rendering frame before reset). Do I have absolutely need to send result to View at flip or can I do it in submit? - */ namespace bgfx { namespace mtl @@ -1191,7 +1184,6 @@ namespace bgfx { namespace mtl if ( texture.m_textureFormat == TextureFormat::D24S8) renderPassDescriptor.stencilAttachment.texture = texture.m_ptr; - //TODO: stencilAttachment should be the same if packed/depth stencil format is used } } @@ -2156,6 +2148,11 @@ namespace bgfx { namespace mtl void TextureMtl::commit(uint8_t _stage, uint32_t _flags) { //TODO: vertex or fragment stage? + s_renderMtl->m_renderCommandEncoder.setVertexTexture(m_ptr, _stage); + s_renderMtl->m_renderCommandEncoder.setVertexSamplerState(0 == (BGFX_TEXTURE_INTERNAL_DEFAULT_SAMPLER & _flags) + ? s_renderMtl->getSamplerState(_flags) + : m_sampler, _stage); + s_renderMtl->m_renderCommandEncoder.setFragmentTexture(m_ptr, _stage); s_renderMtl->m_renderCommandEncoder.setFragmentSamplerState(0 == (BGFX_TEXTURE_INTERNAL_DEFAULT_SAMPLER & _flags) ? s_renderMtl->getSamplerState(_flags) @@ -2436,57 +2433,91 @@ namespace bgfx { namespace mtl fbh = _render->m_fb[view]; setFrameBuffer(renderPassDescriptor, fbh); - RenderPassColorAttachmentDescriptor colorAttachment0 = renderPassDescriptor.colorAttachments[0]; - - if (0 != (BGFX_CLEAR_COLOR & clr.m_flags) ) + if ( fullscreenRect) { - if (0 != (BGFX_CLEAR_COLOR_USE_PALETTE & clr.m_flags) ) + for(uint32_t ii = 0; ii < g_caps.maxFBAttachments; ++ii) { - uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, clr.m_index[0]); - const float* rgba = _render->m_colorPalette[index]; - const float rr = rgba[0]; - const float gg = rgba[1]; - const float bb = rgba[2]; - const float aa = rgba[3]; - colorAttachment0.clearColor = MTLClearColorMake(rr, gg, bb, aa); + MTLRenderPassColorAttachmentDescriptor* desc = renderPassDescriptor.colorAttachments[ii]; + + if ( desc.texture != NULL) + { + if (0 != (BGFX_CLEAR_COLOR & clr.m_flags) ) + { + if (0 != (BGFX_CLEAR_COLOR_USE_PALETTE & clr.m_flags) ) + { + uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, clr.m_index[ii]); + const float* rgba = _render->m_colorPalette[index]; + const float rr = rgba[0]; + const float gg = rgba[1]; + const float bb = rgba[2]; + const float aa = rgba[3]; + desc.clearColor = MTLClearColorMake(rr, gg, bb, aa); + } + else + { + float rr = clr.m_index[0]*1.0f/255.0f; + float gg = clr.m_index[1]*1.0f/255.0f; + float bb = clr.m_index[2]*1.0f/255.0f; + float aa = clr.m_index[3]*1.0f/255.0f; + desc.clearColor = MTLClearColorMake(rr, gg, bb, aa); + } + + desc.loadAction = MTLLoadActionClear; + } + else + { + desc.loadAction = MTLLoadActionLoad; + } + } } - else + + //TODO: optimize store actions use discard flag + RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment; + if (NULL != depthAttachment.texture) { - float rr = clr.m_index[0]*1.0f/255.0f; - float gg = clr.m_index[1]*1.0f/255.0f; - float bb = clr.m_index[2]*1.0f/255.0f; - float aa = clr.m_index[3]*1.0f/255.0f; - colorAttachment0.clearColor = MTLClearColorMake(rr, gg, bb, aa); + depthAttachment.clearDepth = clr.m_depth; + depthAttachment.loadAction = 0 != (BGFX_CLEAR_DEPTH & clr.m_flags) + ? MTLLoadActionClear + : MTLLoadActionLoad + ; + depthAttachment.storeAction = MTLStoreActionStore; + } + + RenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.stencilAttachment; + if (NULL != stencilAttachment.texture) + { + stencilAttachment.clearStencil = clr.m_stencil; + stencilAttachment.loadAction = 0 != (BGFX_CLEAR_STENCIL & clr.m_flags) + ? MTLLoadActionClear + : MTLLoadActionLoad + ; + stencilAttachment.storeAction = MTLStoreActionStore; } - - colorAttachment0.loadAction = MTLLoadActionClear; } else { - colorAttachment0.loadAction = MTLLoadActionLoad; - } - - //TODO: optimize store actions use discard flag - RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment; - if (NULL != depthAttachment.texture) - { - depthAttachment.clearDepth = clr.m_depth; - depthAttachment.loadAction = 0 != (BGFX_CLEAR_DEPTH & clr.m_flags) - ? MTLLoadActionClear - : MTLLoadActionLoad - ; - depthAttachment.storeAction = MTLStoreActionStore; - } - - RenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.stencilAttachment; - if (NULL != stencilAttachment.texture) - { - stencilAttachment.clearStencil = clr.m_stencil; - stencilAttachment.loadAction = 0 != (BGFX_CLEAR_STENCIL & clr.m_flags) - ? MTLLoadActionClear - : MTLLoadActionLoad - ; - stencilAttachment.storeAction = MTLStoreActionStore; + for(uint32_t ii = 0; ii < g_caps.maxFBAttachments; ++ii) + { + MTLRenderPassColorAttachmentDescriptor* desc = renderPassDescriptor.colorAttachments[ii]; + if ( desc.texture != NULL) + desc.loadAction = MTLLoadActionLoad; + } + + //TODO: optimize store actions use discard flag + RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment; + if (NULL != depthAttachment.texture) + { + depthAttachment.loadAction = MTLLoadActionLoad; + depthAttachment.storeAction = MTLStoreActionStore; + } + + RenderPassStencilAttachmentDescriptor stencilAttachment = renderPassDescriptor.stencilAttachment; + if (NULL != stencilAttachment.texture) + { + stencilAttachment.clearStencil = clr.m_stencil; + stencilAttachment.loadAction = MTLLoadActionLoad; + stencilAttachment.storeAction = MTLStoreActionStore; + } } if (0 != m_renderCommandEncoder)