mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-25 09:08:22 -05:00
Merge branch 'master' of cane:bkaradzic/bgfx
This commit is contained in:
commit
0184074392
6 changed files with 857 additions and 740 deletions
1
3rdparty/ocornut-imgui/imgui.cpp
vendored
1
3rdparty/ocornut-imgui/imgui.cpp
vendored
|
@ -2259,6 +2259,7 @@ static void AddDrawListToRenderList(ImVector<ImDrawList*>& out_render_list, ImDr
|
||||||
// If this assert triggers because you are drawing lots of stuff manually, A) workaround by calling BeginChild()/EndChild() to put your draw commands in multiple draw lists, B) #define ImDrawIdx to a 'unsigned int' in imconfig.h and render accordingly.
|
// If this assert triggers because you are drawing lots of stuff manually, A) workaround by calling BeginChild()/EndChild() to put your draw commands in multiple draw lists, B) #define ImDrawIdx to a 'unsigned int' in imconfig.h and render accordingly.
|
||||||
const unsigned long long int max_vtx_idx = (unsigned long long int)1L << (sizeof(ImDrawIdx)*8);
|
const unsigned long long int max_vtx_idx = (unsigned long long int)1L << (sizeof(ImDrawIdx)*8);
|
||||||
IM_ASSERT((unsigned long long int)draw_list->_VtxCurrentIdx <= max_vtx_idx);
|
IM_ASSERT((unsigned long long int)draw_list->_VtxCurrentIdx <= max_vtx_idx);
|
||||||
|
(void)max_vtx_idx;
|
||||||
|
|
||||||
GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size;
|
GImGui->IO.MetricsRenderVertices += draw_list->VtxBuffer.Size;
|
||||||
GImGui->IO.MetricsRenderIndices += draw_list->IdxBuffer.Size;
|
GImGui->IO.MetricsRenderIndices += draw_list->IdxBuffer.Size;
|
||||||
|
|
|
@ -508,6 +508,8 @@ struct OcornutImguiContext
|
||||||
m_wm->DockWith(w3, w0, ImGuiWM::E_DOCK_ORIENTATION_BOTTOM);
|
m_wm->DockWith(w3, w0, ImGuiWM::E_DOCK_ORIENTATION_BOTTOM);
|
||||||
}
|
}
|
||||||
#endif // 0
|
#endif // 0
|
||||||
|
|
||||||
|
ImGui::NewFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy()
|
void destroy()
|
||||||
|
|
|
@ -867,6 +867,12 @@ namespace bgfx
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame::blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, TextureHandle _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth)
|
void Frame::blit(uint8_t _id, TextureHandle _dst, uint8_t _dstMip, uint16_t _dstX, uint16_t _dstY, uint16_t _dstZ, TextureHandle _src, uint8_t _srcMip, uint16_t _srcX, uint16_t _srcY, uint16_t _srcZ, uint16_t _width, uint16_t _height, uint16_t _depth)
|
||||||
|
{
|
||||||
|
BX_WARN(m_numBlitItems < BGFX_CONFIG_MAX_BLIT_ITEMS
|
||||||
|
, "Exceed number of available blit items per frame. BGFX_CONFIG_MAX_BLIT_ITEMS is %d. Skipping blit."
|
||||||
|
, BGFX_CONFIG_MAX_BLIT_ITEMS
|
||||||
|
);
|
||||||
|
if (m_numBlitItems < BGFX_CONFIG_MAX_BLIT_ITEMS)
|
||||||
{
|
{
|
||||||
uint16_t item = m_numBlitItems++;
|
uint16_t item = m_numBlitItems++;
|
||||||
|
|
||||||
|
@ -890,6 +896,7 @@ namespace bgfx
|
||||||
key.m_item = item;
|
key.m_item = item;
|
||||||
m_blitKeys[item] = key.encode();
|
m_blitKeys[item] = key.encode();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Frame::sort()
|
void Frame::sort()
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
# ifndef BGFX_CONFIG_RENDERER_METAL
|
# ifndef BGFX_CONFIG_RENDERER_METAL
|
||||||
# define BGFX_CONFIG_RENDERER_METAL (0 \
|
# define BGFX_CONFIG_RENDERER_METAL (0 \
|
||||||
|| BX_PLATFORM_IOS \
|
|| BX_PLATFORM_IOS \
|
||||||
|| BX_PLATFORM_OSX \
|
|| (BX_PLATFORM_OSX >= 101100) \
|
||||||
? 1 : 0)
|
? 1 : 0)
|
||||||
# endif // BGFX_CONFIG_RENDERER_METAL
|
# endif // BGFX_CONFIG_RENDERER_METAL
|
||||||
|
|
||||||
|
|
|
@ -712,6 +712,29 @@ namespace bgfx { namespace mtl
|
||||||
uint8_t m_num; // number of color handles
|
uint8_t m_num; // number of color handles
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OcclusionQueryMTL
|
||||||
|
{
|
||||||
|
OcclusionQueryMTL()
|
||||||
|
: m_control(BX_COUNTOF(m_query) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void postReset();
|
||||||
|
void preReset();
|
||||||
|
void begin(RenderCommandEncoder& _rce, Frame* _render, OcclusionQueryHandle _handle);
|
||||||
|
void end(RenderCommandEncoder& _rce);
|
||||||
|
void resolve(Frame* _render, bool _wait = false);
|
||||||
|
|
||||||
|
struct Query
|
||||||
|
{
|
||||||
|
OcclusionQueryHandle m_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
Buffer m_buffer;
|
||||||
|
Query m_query[BGFX_CONFIG_MAX_OCCUSION_QUERIES];
|
||||||
|
bx::RingBufferControl m_control;
|
||||||
|
};
|
||||||
|
|
||||||
} /* namespace metal */ } // namespace bgfx
|
} /* namespace metal */ } // namespace bgfx
|
||||||
|
|
||||||
#endif // BGFX_CONFIG_RENDERER_METAL
|
#endif // BGFX_CONFIG_RENDERER_METAL
|
||||||
|
|
|
@ -348,8 +348,8 @@ namespace bgfx { namespace mtl
|
||||||
|
|
||||||
if (NULL != NSClassFromString(@"CAMetalLayer") )
|
if (NULL != NSClassFromString(@"CAMetalLayer") )
|
||||||
{
|
{
|
||||||
//on iOS we need the layer as CAmetalLayer
|
|
||||||
#if BX_PLATFORM_IOS
|
#if BX_PLATFORM_IOS
|
||||||
|
{
|
||||||
CAMetalLayer* metalLayer = (CAMetalLayer*)g_platformData.nwh;
|
CAMetalLayer* metalLayer = (CAMetalLayer*)g_platformData.nwh;
|
||||||
if (NULL == metalLayer
|
if (NULL == metalLayer
|
||||||
|| ![metalLayer isKindOfClass:NSClassFromString(@"CAMetalLayer")])
|
|| ![metalLayer isKindOfClass:NSClassFromString(@"CAMetalLayer")])
|
||||||
|
@ -357,14 +357,16 @@ namespace bgfx { namespace mtl
|
||||||
BX_WARN(NULL != m_device, "Unable to create Metal device. Please set platform data window to a CAMetalLayer");
|
BX_WARN(NULL != m_device, "Unable to create Metal device. Please set platform data window to a CAMetalLayer");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_metalLayer = metalLayer;
|
|
||||||
#elif BX_PLATFORM_OSX
|
|
||||||
// create and set metalLayer
|
|
||||||
NSWindow* nsWindow = (NSWindow*)g_platformData.nwh;
|
|
||||||
|
|
||||||
|
m_metalLayer = metalLayer;
|
||||||
|
}
|
||||||
|
#elif BX_PLATFORM_OSX
|
||||||
|
{
|
||||||
|
NSWindow* nsWindow = (NSWindow*)g_platformData.nwh;
|
||||||
[nsWindow.contentView setWantsLayer:YES];
|
[nsWindow.contentView setWantsLayer:YES];
|
||||||
m_metalLayer = [CAMetalLayer layer];
|
m_metalLayer = [CAMetalLayer layer];
|
||||||
[nsWindow.contentView setLayer:m_metalLayer];
|
[nsWindow.contentView setLayer:m_metalLayer];
|
||||||
|
}
|
||||||
#endif // BX_PLATFORM_*
|
#endif // BX_PLATFORM_*
|
||||||
|
|
||||||
m_device = (id<MTLDevice>)g_platformData.context;
|
m_device = (id<MTLDevice>)g_platformData.context;
|
||||||
|
@ -401,8 +403,8 @@ namespace bgfx { namespace mtl
|
||||||
m_uniformBufferFragmentOffset = 0;
|
m_uniformBufferFragmentOffset = 0;
|
||||||
|
|
||||||
g_caps.supported |= (0
|
g_caps.supported |= (0
|
||||||
| BGFX_CAPS_TEXTURE_COMPARE_LEQUAL
|
|
||||||
| BGFX_CAPS_TEXTURE_3D
|
| BGFX_CAPS_TEXTURE_3D
|
||||||
|
| BGFX_CAPS_TEXTURE_COMPARE_LEQUAL
|
||||||
| BGFX_CAPS_INSTANCING
|
| BGFX_CAPS_INSTANCING
|
||||||
| BGFX_CAPS_VERTEX_ATTRIB_HALF
|
| BGFX_CAPS_VERTEX_ATTRIB_HALF
|
||||||
// | BGFX_CAPS_FRAGMENT_DEPTH
|
// | BGFX_CAPS_FRAGMENT_DEPTH
|
||||||
|
@ -410,6 +412,9 @@ namespace bgfx { namespace mtl
|
||||||
| BGFX_CAPS_COMPUTE
|
| BGFX_CAPS_COMPUTE
|
||||||
| BGFX_CAPS_INDEX32
|
| BGFX_CAPS_INDEX32
|
||||||
| BGFX_CAPS_DRAW_INDIRECT
|
| BGFX_CAPS_DRAW_INDIRECT
|
||||||
|
// | BGFX_CAPS_TEXTURE_BLIT
|
||||||
|
// | BGFX_CAPS_TEXTURE_READ_BACK
|
||||||
|
| BGFX_CAPS_OCCLUSION_QUERY
|
||||||
);
|
);
|
||||||
|
|
||||||
g_caps.maxTextureSize = 2048; //ASK: real caps width/height: 4096, but max depth(3D) size is only: 2048
|
g_caps.maxTextureSize = 2048; //ASK: real caps width/height: 4096, but max depth(3D) size is only: 2048
|
||||||
|
@ -483,11 +488,15 @@ namespace bgfx { namespace mtl
|
||||||
bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1, "%3d ", ii);
|
bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1, "%3d ", ii);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_occlusionQuery.preReset();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown()
|
void shutdown()
|
||||||
{
|
{
|
||||||
|
m_occlusionQuery.postReset();
|
||||||
|
|
||||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii)
|
for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii)
|
||||||
{
|
{
|
||||||
m_shaders[ii].destroy();
|
m_shaders[ii].destroy();
|
||||||
|
@ -507,9 +516,10 @@ namespace bgfx { namespace mtl
|
||||||
MTL_RELEASE(m_samplerDescriptor);
|
MTL_RELEASE(m_samplerDescriptor);
|
||||||
|
|
||||||
MTL_RELEASE(m_backBufferDepth);
|
MTL_RELEASE(m_backBufferDepth);
|
||||||
#if BX_PLATFORM_IOS
|
if (BX_ENABLED(BX_PLATFORM_IOS) )
|
||||||
|
{
|
||||||
MTL_RELEASE(m_backBufferStencil);
|
MTL_RELEASE(m_backBufferStencil);
|
||||||
#endif // BX_PLATFORM_*
|
}
|
||||||
|
|
||||||
MTL_RELEASE(m_uniformBuffer);
|
MTL_RELEASE(m_uniformBuffer);
|
||||||
MTL_RELEASE(m_commandQueue);
|
MTL_RELEASE(m_commandQueue);
|
||||||
|
@ -930,19 +940,7 @@ namespace bgfx { namespace mtl
|
||||||
release(m_backBufferDepth);
|
release(m_backBufferDepth);
|
||||||
}
|
}
|
||||||
m_backBufferDepth = m_device.newTextureWithDescriptor(m_textureDescriptor);
|
m_backBufferDepth = m_device.newTextureWithDescriptor(m_textureDescriptor);
|
||||||
|
|
||||||
#if 0
|
|
||||||
m_textureDescriptor.pixelFormat = MTLPixelFormatStencil8;
|
|
||||||
|
|
||||||
if (NULL != m_backBufferStencil)
|
|
||||||
{
|
|
||||||
release(m_backBufferStencil);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_backBufferStencil = m_device.newTextureWithDescriptor(m_textureDescriptor);
|
|
||||||
#else
|
|
||||||
m_backBufferStencil = m_backBufferDepth;
|
m_backBufferStencil = m_backBufferDepth;
|
||||||
#endif // 0
|
|
||||||
|
|
||||||
bx::HashMurmur2A murmur;
|
bx::HashMurmur2A murmur;
|
||||||
murmur.begin();
|
murmur.begin();
|
||||||
|
@ -964,14 +962,12 @@ namespace bgfx { namespace mtl
|
||||||
|
|
||||||
void setShaderUniform(uint8_t _flags, uint32_t _loc, const void* _val, uint32_t _numRegs)
|
void setShaderUniform(uint8_t _flags, uint32_t _loc, const void* _val, uint32_t _numRegs)
|
||||||
{
|
{
|
||||||
if (_flags&BGFX_UNIFORM_FRAGMENTBIT)
|
uint32_t offset = 0 != (_flags&BGFX_UNIFORM_FRAGMENTBIT)
|
||||||
{
|
? m_uniformBufferFragmentOffset
|
||||||
memcpy(&((char*)m_uniformBuffer.contents())[m_uniformBufferFragmentOffset + _loc], _val, _numRegs*16);
|
: m_uniformBufferVertexOffset
|
||||||
}
|
;
|
||||||
else
|
uint8_t* dst = (uint8_t*)m_uniformBuffer.contents();
|
||||||
{
|
memcpy(&dst[offset + _loc], _val, _numRegs*16);
|
||||||
memcpy(&((char*)m_uniformBuffer.contents())[m_uniformBufferVertexOffset + _loc], _val, _numRegs*16);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setShaderUniform4f(uint8_t _flags, uint32_t _loc, const void* _val, uint32_t _numRegs)
|
void setShaderUniform4f(uint8_t _flags, uint32_t _loc, const void* _val, uint32_t _numRegs)
|
||||||
|
@ -1026,7 +1022,7 @@ namespace bgfx { namespace mtl
|
||||||
switch ( (uint32_t)type)
|
switch ( (uint32_t)type)
|
||||||
{
|
{
|
||||||
case UniformType::Mat3:
|
case UniformType::Mat3:
|
||||||
case UniformType::Mat3|BGFX_UNIFORM_FRAGMENTBIT: \
|
case UniformType::Mat3|BGFX_UNIFORM_FRAGMENTBIT:
|
||||||
{
|
{
|
||||||
float* value = (float*)data;
|
float* value = (float*)data;
|
||||||
for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9)
|
for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9)
|
||||||
|
@ -1066,15 +1062,18 @@ namespace bgfx { namespace mtl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFrameBuffer(mtl::RenderPassDescriptor renderPassDescriptor, FrameBufferHandle _fbh, bool _msaa = true)
|
void clearQuad(ClearQuad& _clearQuad, const Rect& _rect, const Clear& _clear, const float _palette[][4])
|
||||||
|
{
|
||||||
|
BX_UNUSED(_clearQuad, _rect, _clear, _palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFrameBuffer(RenderPassDescriptor renderPassDescriptor, FrameBufferHandle _fbh, bool _msaa = true)
|
||||||
{
|
{
|
||||||
if (!isValid(_fbh) )
|
if (!isValid(_fbh) )
|
||||||
{
|
{
|
||||||
renderPassDescriptor.colorAttachments[0].texture = m_drawable.texture;
|
renderPassDescriptor.colorAttachments[0].texture = m_drawable.texture;
|
||||||
renderPassDescriptor.depthAttachment.texture = m_backBufferDepth;
|
renderPassDescriptor.depthAttachment.texture = m_backBufferDepth;
|
||||||
renderPassDescriptor.stencilAttachment.texture = m_backBufferStencil;
|
renderPassDescriptor.stencilAttachment.texture = m_backBufferStencil;
|
||||||
|
|
||||||
//todo: set resolve textures
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1086,15 +1085,13 @@ namespace bgfx { namespace mtl
|
||||||
renderPassDescriptor.colorAttachments[ii].texture = texture.m_ptr;
|
renderPassDescriptor.colorAttachments[ii].texture = texture.m_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isValid(frameBuffer.m_depthHandle))
|
if (isValid(frameBuffer.m_depthHandle) )
|
||||||
{
|
{
|
||||||
const TextureMtl& texture = m_textures[frameBuffer.m_depthHandle.idx];
|
const TextureMtl& texture = m_textures[frameBuffer.m_depthHandle.idx];
|
||||||
renderPassDescriptor.depthAttachment.texture = texture.m_ptr;
|
renderPassDescriptor.depthAttachment.texture = texture.m_ptr;
|
||||||
renderPassDescriptor.stencilAttachment.texture = texture.m_ptrStencil;
|
renderPassDescriptor.stencilAttachment.texture = texture.m_ptrStencil;
|
||||||
//TODO: stencilAttachment should be the same if packed/depth stencil format is used
|
//TODO: stencilAttachment should be the same if packed/depth stencil format is used
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: set resolve textures
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fbh = _fbh;
|
m_fbh = _fbh;
|
||||||
|
@ -1104,8 +1101,10 @@ namespace bgfx { namespace mtl
|
||||||
void setDepthStencilState(uint64_t _state, uint64_t _stencil = 0)
|
void setDepthStencilState(uint64_t _state, uint64_t _stencil = 0)
|
||||||
{
|
{
|
||||||
_state &= BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK;
|
_state &= BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK;
|
||||||
|
|
||||||
uint32_t fstencil = unpackStencil(0, _stencil);
|
uint32_t fstencil = unpackStencil(0, _stencil);
|
||||||
uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
|
uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;
|
||||||
|
|
||||||
_stencil &= packStencil(~BGFX_STENCIL_FUNC_REF_MASK, BGFX_STENCIL_MASK);
|
_stencil &= packStencil(~BGFX_STENCIL_FUNC_REF_MASK, BGFX_STENCIL_MASK);
|
||||||
|
|
||||||
bx::HashMurmur2A murmur;
|
bx::HashMurmur2A murmur;
|
||||||
|
@ -1170,6 +1169,7 @@ namespace bgfx { namespace mtl
|
||||||
{
|
{
|
||||||
_flags &= BGFX_TEXTURE_SAMPLER_BITS_MASK;
|
_flags &= BGFX_TEXTURE_SAMPLER_BITS_MASK;
|
||||||
SamplerState sampler = m_samplerStateCache.find(_flags);
|
SamplerState sampler = m_samplerStateCache.find(_flags);
|
||||||
|
|
||||||
if (NULL == sampler)
|
if (NULL == sampler)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1197,6 +1197,12 @@ namespace bgfx { namespace mtl
|
||||||
return sampler;
|
return sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isVisible(Frame* _render, OcclusionQueryHandle _handle, bool _visible)
|
||||||
|
{
|
||||||
|
m_occlusionQuery.resolve(_render);
|
||||||
|
return _visible == (0 != _render->m_occlusion[_handle.idx]);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t getBufferWidth()
|
uint32_t getBufferWidth()
|
||||||
{
|
{
|
||||||
return m_backBufferDepth.width();
|
return m_backBufferDepth.width();
|
||||||
|
@ -1215,6 +1221,8 @@ namespace bgfx { namespace mtl
|
||||||
uint32_t m_backBufferPixelFormatHash;
|
uint32_t m_backBufferPixelFormatHash;
|
||||||
uint32_t m_maxAnisotropy;
|
uint32_t m_maxAnisotropy;
|
||||||
|
|
||||||
|
OcclusionQueryMTL m_occlusionQuery;
|
||||||
|
|
||||||
Buffer m_uniformBuffer; //todo: use a pool of this
|
Buffer m_uniformBuffer; //todo: use a pool of this
|
||||||
uint32_t m_uniformBufferVertexOffset;
|
uint32_t m_uniformBufferVertexOffset;
|
||||||
uint32_t m_uniformBufferFragmentOffset;
|
uint32_t m_uniformBufferFragmentOffset;
|
||||||
|
@ -1255,7 +1263,7 @@ namespace bgfx { namespace mtl
|
||||||
id <CAMetalDrawable> m_drawable;
|
id <CAMetalDrawable> m_drawable;
|
||||||
CommandBuffer m_commandBuffer;
|
CommandBuffer m_commandBuffer;
|
||||||
RenderCommandEncoder m_renderCommandEncoder;
|
RenderCommandEncoder m_renderCommandEncoder;
|
||||||
};
|
};
|
||||||
|
|
||||||
static RendererContextMtl* s_renderMtl;
|
static RendererContextMtl* s_renderMtl;
|
||||||
|
|
||||||
|
@ -2102,6 +2110,50 @@ namespace bgfx { namespace mtl
|
||||||
return denseIdx;
|
return denseIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OcclusionQueryMTL::postReset()
|
||||||
|
{
|
||||||
|
MTL_RELEASE(m_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OcclusionQueryMTL::preReset()
|
||||||
|
{
|
||||||
|
m_buffer = s_renderMtl->m_device.newBufferWithLength(BX_COUNTOF(m_query) * 8, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OcclusionQueryMTL::begin(RenderCommandEncoder& _rce, Frame* _render, OcclusionQueryHandle _handle)
|
||||||
|
{
|
||||||
|
while (0 == m_control.reserve(1) )
|
||||||
|
{
|
||||||
|
resolve(_render, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Query& query = m_query[m_control.m_current];
|
||||||
|
query.m_handle = _handle;
|
||||||
|
uint32_t offset = _handle.idx * 8;
|
||||||
|
_rce.setVisibilityResultMode(MTLVisibilityResultModeBoolean, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OcclusionQueryMTL::end(RenderCommandEncoder& _rce)
|
||||||
|
{
|
||||||
|
Query& query = m_query[m_control.m_current];
|
||||||
|
uint32_t offset = query.m_handle.idx * 8;
|
||||||
|
_rce.setVisibilityResultMode(MTLVisibilityResultModeDisabled, offset);
|
||||||
|
m_control.commit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OcclusionQueryMTL::resolve(Frame* _render, bool _wait)
|
||||||
|
{
|
||||||
|
BX_UNUSED(_wait);
|
||||||
|
while (0 != m_control.available() )
|
||||||
|
{
|
||||||
|
Query& query = m_query[m_control.m_read];
|
||||||
|
|
||||||
|
uint64_t result = ( (uint64_t*)m_buffer.contents() )[query.m_handle.idx];
|
||||||
|
_render->m_occlusion[query.m_handle.idx] = 0 < result;
|
||||||
|
m_control.consume(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RendererContextMtl::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE
|
void RendererContextMtl::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE
|
||||||
{
|
{
|
||||||
BX_UNUSED(_clearQuad);
|
BX_UNUSED(_clearQuad);
|
||||||
|
@ -2179,7 +2231,7 @@ namespace bgfx { namespace mtl
|
||||||
PrimInfo prim = s_primInfo[primIndex];
|
PrimInfo prim = s_primInfo[primIndex];
|
||||||
|
|
||||||
ProgramMtl* currentProgram = NULL;
|
ProgramMtl* currentProgram = NULL;
|
||||||
mtl::RenderCommandEncoder rce;
|
RenderCommandEncoder rce;
|
||||||
|
|
||||||
bool wasCompute = false;
|
bool wasCompute = false;
|
||||||
bool viewHasScissor = false;
|
bool viewHasScissor = false;
|
||||||
|
@ -2193,6 +2245,8 @@ namespace bgfx { namespace mtl
|
||||||
uint32_t statsNumIndices = 0;
|
uint32_t statsNumIndices = 0;
|
||||||
uint32_t statsKeyType[2] = {};
|
uint32_t statsKeyType[2] = {};
|
||||||
|
|
||||||
|
m_occlusionQuery.resolve(_render);
|
||||||
|
|
||||||
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
|
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
|
||||||
{
|
{
|
||||||
bool viewRestart = false;
|
bool viewRestart = false;
|
||||||
|
@ -2227,9 +2281,9 @@ namespace bgfx { namespace mtl
|
||||||
view = key.m_view;
|
view = key.m_view;
|
||||||
programIdx = invalidHandle;
|
programIdx = invalidHandle;
|
||||||
|
|
||||||
|
|
||||||
viewRestart = ( (BGFX_VIEW_STEREO == (_render->m_viewFlags[view] & BGFX_VIEW_STEREO) ) );
|
viewRestart = ( (BGFX_VIEW_STEREO == (_render->m_viewFlags[view] & BGFX_VIEW_STEREO) ) );
|
||||||
viewRestart &= hmdEnabled;
|
viewRestart &= hmdEnabled;
|
||||||
|
|
||||||
if (viewRestart)
|
if (viewRestart)
|
||||||
{
|
{
|
||||||
if (0 == restartState)
|
if (0 == restartState)
|
||||||
|
@ -2247,6 +2301,7 @@ namespace bgfx { namespace mtl
|
||||||
}
|
}
|
||||||
|
|
||||||
viewState.m_rect = _render->m_rect[view];
|
viewState.m_rect = _render->m_rect[view];
|
||||||
|
|
||||||
if (viewRestart)
|
if (viewRestart)
|
||||||
{
|
{
|
||||||
viewState.m_rect.m_x = eye * (viewState.m_rect.m_width+1)/2;
|
viewState.m_rect.m_x = eye * (viewState.m_rect.m_width+1)/2;
|
||||||
|
@ -2258,7 +2313,8 @@ namespace bgfx { namespace mtl
|
||||||
viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect;
|
viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect;
|
||||||
Clear& clr = _render->m_clear[view];
|
Clear& clr = _render->m_clear[view];
|
||||||
|
|
||||||
mtl::RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor();
|
RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor();
|
||||||
|
renderPassDescriptor.visibilityResultBuffer = m_occlusionQuery.m_buffer;
|
||||||
|
|
||||||
//todo: check FB size
|
//todo: check FB size
|
||||||
uint32_t width = getBufferWidth();
|
uint32_t width = getBufferWidth();
|
||||||
|
@ -2272,9 +2328,10 @@ namespace bgfx { namespace mtl
|
||||||
setFrameBuffer(renderPassDescriptor, fbh);
|
setFrameBuffer(renderPassDescriptor, fbh);
|
||||||
|
|
||||||
RenderPassColorAttachmentDescriptor colorAttachment0 = renderPassDescriptor.colorAttachments[0];
|
RenderPassColorAttachmentDescriptor colorAttachment0 = renderPassDescriptor.colorAttachments[0];
|
||||||
if (BGFX_CLEAR_COLOR & clr.m_flags)
|
|
||||||
|
if (0 != (BGFX_CLEAR_COLOR & clr.m_flags) )
|
||||||
{
|
{
|
||||||
if (BGFX_CLEAR_COLOR_USE_PALETTE & 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[0]);
|
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* rgba = _render->m_colorPalette[index];
|
||||||
|
@ -2282,7 +2339,7 @@ namespace bgfx { namespace mtl
|
||||||
const float gg = rgba[1];
|
const float gg = rgba[1];
|
||||||
const float bb = rgba[2];
|
const float bb = rgba[2];
|
||||||
const float aa = rgba[3];
|
const float aa = rgba[3];
|
||||||
colorAttachment0.clearColor = MTLClearColorMake(rr,gg,bb,aa);
|
colorAttachment0.clearColor = MTLClearColorMake(rr, gg, bb, aa);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2290,20 +2347,25 @@ namespace bgfx { namespace mtl
|
||||||
float gg = clr.m_index[1]*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 bb = clr.m_index[2]*1.0f/255.0f;
|
||||||
float aa = clr.m_index[3]*1.0f/255.0f;
|
float aa = clr.m_index[3]*1.0f/255.0f;
|
||||||
colorAttachment0.clearColor = MTLClearColorMake(rr,gg,bb,aa);
|
colorAttachment0.clearColor = MTLClearColorMake(rr, gg, bb, aa);
|
||||||
}
|
}
|
||||||
|
|
||||||
colorAttachment0.loadAction = MTLLoadActionClear;
|
colorAttachment0.loadAction = MTLLoadActionClear;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
colorAttachment0.loadAction = MTLLoadActionLoad;
|
colorAttachment0.loadAction = MTLLoadActionLoad;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: optimize store actions use discard flag
|
//TODO: optimize store actions use discard flag
|
||||||
RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment;
|
RenderPassDepthAttachmentDescriptor depthAttachment = renderPassDescriptor.depthAttachment;
|
||||||
if (NULL != depthAttachment.texture)
|
if (NULL != depthAttachment.texture)
|
||||||
{
|
{
|
||||||
depthAttachment.clearDepth = clr.m_depth;
|
depthAttachment.clearDepth = clr.m_depth;
|
||||||
depthAttachment.loadAction = (BGFX_CLEAR_DEPTH & clr.m_flags) ? MTLLoadActionClear : MTLLoadActionLoad;
|
depthAttachment.loadAction = 0 != (BGFX_CLEAR_DEPTH & clr.m_flags)
|
||||||
|
? MTLLoadActionClear
|
||||||
|
: MTLLoadActionLoad
|
||||||
|
;
|
||||||
depthAttachment.storeAction = MTLStoreActionStore;
|
depthAttachment.storeAction = MTLStoreActionStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2311,7 +2373,10 @@ namespace bgfx { namespace mtl
|
||||||
if (NULL != stencilAttachment.texture)
|
if (NULL != stencilAttachment.texture)
|
||||||
{
|
{
|
||||||
stencilAttachment.clearStencil = clr.m_stencil;
|
stencilAttachment.clearStencil = clr.m_stencil;
|
||||||
stencilAttachment.loadAction = (BGFX_CLEAR_STENCIL & clr.m_flags) ? MTLLoadActionClear : MTLLoadActionLoad;
|
stencilAttachment.loadAction = 0 != (BGFX_CLEAR_STENCIL & clr.m_flags)
|
||||||
|
? MTLLoadActionClear
|
||||||
|
: MTLLoadActionLoad
|
||||||
|
;
|
||||||
stencilAttachment.storeAction = MTLStoreActionStore;
|
stencilAttachment.storeAction = MTLStoreActionStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2319,6 +2384,7 @@ namespace bgfx { namespace mtl
|
||||||
{
|
{
|
||||||
m_renderCommandEncoder.endEncoding();
|
m_renderCommandEncoder.endEncoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
rce = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor);
|
rce = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor);
|
||||||
m_renderCommandEncoder = rce;
|
m_renderCommandEncoder = rce;
|
||||||
MTL_RELEASE(renderPassDescriptor);
|
MTL_RELEASE(renderPassDescriptor);
|
||||||
|
@ -2332,8 +2398,10 @@ namespace bgfx { namespace mtl
|
||||||
|
|
||||||
if (BX_ENABLED(BGFX_CONFIG_DEBUG_MTL) )
|
if (BX_ENABLED(BGFX_CONFIG_DEBUG_MTL) )
|
||||||
{
|
{
|
||||||
if (item != 1) //ASK: better check ? I don't get the whole restart thing
|
if (item != 1)
|
||||||
|
{
|
||||||
rce.popDebugGroup();
|
rce.popDebugGroup();
|
||||||
|
}
|
||||||
|
|
||||||
rce.pushDebugGroup(s_viewName[view]);
|
rce.pushDebugGroup(s_viewName[view]);
|
||||||
}
|
}
|
||||||
|
@ -2347,14 +2415,13 @@ namespace bgfx { namespace mtl
|
||||||
vp.zfar = 1.0f;
|
vp.zfar = 1.0f;
|
||||||
rce.setViewport(vp);
|
rce.setViewport(vp);
|
||||||
|
|
||||||
if (BGFX_CLEAR_NONE != (clr.m_flags & BGFX_CLEAR_MASK) && !fullscreenRect)
|
if (BGFX_CLEAR_NONE != (clr.m_flags & BGFX_CLEAR_MASK)
|
||||||
{ //TODO: fallback to clear with quad
|
&& !fullscreenRect)
|
||||||
//clearQuad(_clearQuad, viewState.m_rect, clr, _render->m_colorPalette);
|
{
|
||||||
|
clearQuad(_clearQuad, viewState.m_rect, clr, _render->m_colorPalette);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: iscompute
|
|
||||||
|
|
||||||
bool resetState = viewChanged || wasCompute;
|
bool resetState = viewChanged || wasCompute;
|
||||||
|
|
||||||
if (wasCompute)
|
if (wasCompute)
|
||||||
|
@ -2370,6 +2437,14 @@ namespace bgfx { namespace mtl
|
||||||
|
|
||||||
const RenderDraw& draw = renderItem.draw;
|
const RenderDraw& draw = renderItem.draw;
|
||||||
|
|
||||||
|
const bool hasOcclusionQuery = 0 != (draw.m_stateFlags & BGFX_STATE_INTERNAL_OCCLUSION_QUERY);
|
||||||
|
if (isValid(draw.m_occlusionQuery)
|
||||||
|
&& !hasOcclusionQuery
|
||||||
|
&& !isVisible(_render, draw.m_occlusionQuery, 0 != (draw.m_submitFlags&BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) ) )
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const uint64_t newFlags = draw.m_stateFlags;
|
const uint64_t newFlags = draw.m_stateFlags;
|
||||||
uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags;
|
uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags;
|
||||||
currentState.m_stateFlags = newFlags;
|
currentState.m_stateFlags = newFlags;
|
||||||
|
@ -2484,12 +2559,12 @@ namespace bgfx { namespace mtl
|
||||||
bool constantsChanged = draw.m_constBegin < draw.m_constEnd;
|
bool constantsChanged = draw.m_constBegin < draw.m_constEnd;
|
||||||
rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_constBegin, draw.m_constEnd);
|
rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_constBegin, draw.m_constEnd);
|
||||||
|
|
||||||
if (key.m_program != programIdx ||
|
if (key.m_program != programIdx
|
||||||
(BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE|BGFX_STATE_BLEND_INDEPENDENT|BGFX_STATE_MSAA) & changedFlags ||
|
|| (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE|BGFX_STATE_BLEND_INDEPENDENT|BGFX_STATE_MSAA) & changedFlags
|
||||||
currentState.m_vertexBuffer.idx != draw.m_vertexBuffer.idx ||
|
|| currentState.m_vertexBuffer.idx != draw.m_vertexBuffer.idx
|
||||||
currentState.m_vertexDecl.idx != draw.m_vertexDecl.idx ||
|
|| currentState.m_vertexDecl.idx != draw.m_vertexDecl.idx
|
||||||
currentState.m_instanceDataStride != draw.m_instanceDataStride ||
|
|| currentState.m_instanceDataStride != draw.m_instanceDataStride
|
||||||
( (blendFactor != draw.m_rgba) && !!(newFlags & BGFX_STATE_BLEND_INDEPENDENT) ) )
|
|| ( (blendFactor != draw.m_rgba) && !!(newFlags & BGFX_STATE_BLEND_INDEPENDENT) ) )
|
||||||
{
|
{
|
||||||
programIdx = key.m_program;
|
programIdx = key.m_program;
|
||||||
currentState.m_vertexDecl = draw.m_vertexDecl;
|
currentState.m_vertexDecl = draw.m_vertexDecl;
|
||||||
|
@ -2532,14 +2607,14 @@ namespace bgfx { namespace mtl
|
||||||
uint32_t vertexUniformBufferSize = program.m_vshConstantBufferSize;
|
uint32_t vertexUniformBufferSize = program.m_vshConstantBufferSize;
|
||||||
uint32_t fragmentUniformBufferSize = program.m_fshConstantBufferSize;
|
uint32_t fragmentUniformBufferSize = program.m_fshConstantBufferSize;
|
||||||
|
|
||||||
if (vertexUniformBufferSize )
|
if (vertexUniformBufferSize)
|
||||||
{
|
{
|
||||||
m_uniformBufferVertexOffset = BX_ALIGN_MASK(m_uniformBufferVertexOffset, program.m_vshConstantBufferAlignmentMask);
|
m_uniformBufferVertexOffset = BX_ALIGN_MASK(m_uniformBufferVertexOffset, program.m_vshConstantBufferAlignmentMask);
|
||||||
rce.setVertexBuffer(m_uniformBuffer, m_uniformBufferVertexOffset, 0);
|
rce.setVertexBuffer(m_uniformBuffer, m_uniformBufferVertexOffset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_uniformBufferFragmentOffset = m_uniformBufferVertexOffset + vertexUniformBufferSize;
|
m_uniformBufferFragmentOffset = m_uniformBufferVertexOffset + vertexUniformBufferSize;
|
||||||
if (fragmentUniformBufferSize )
|
if (fragmentUniformBufferSize)
|
||||||
{
|
{
|
||||||
m_uniformBufferFragmentOffset = BX_ALIGN_MASK(m_uniformBufferFragmentOffset, program.m_fshConstantBufferAlignmentMask);
|
m_uniformBufferFragmentOffset = BX_ALIGN_MASK(m_uniformBufferFragmentOffset, program.m_fshConstantBufferAlignmentMask);
|
||||||
rce.setFragmentBuffer(m_uniformBuffer, m_uniformBufferFragmentOffset, 0);
|
rce.setFragmentBuffer(m_uniformBuffer, m_uniformBufferFragmentOffset, 0);
|
||||||
|
@ -2591,8 +2666,7 @@ namespace bgfx { namespace mtl
|
||||||
if (currentState.m_vertexBuffer.idx != draw.m_vertexBuffer.idx
|
if (currentState.m_vertexBuffer.idx != draw.m_vertexBuffer.idx
|
||||||
|| currentState.m_startVertex != draw.m_startVertex
|
|| currentState.m_startVertex != draw.m_startVertex
|
||||||
|| currentState.m_instanceDataBuffer.idx != draw.m_instanceDataBuffer.idx
|
|| currentState.m_instanceDataBuffer.idx != draw.m_instanceDataBuffer.idx
|
||||||
|| currentState.m_instanceDataOffset != draw.m_instanceDataOffset
|
|| currentState.m_instanceDataOffset != draw.m_instanceDataOffset)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
currentState.m_vertexBuffer = draw.m_vertexBuffer;
|
currentState.m_vertexBuffer = draw.m_vertexBuffer;
|
||||||
currentState.m_startVertex = draw.m_startVertex;
|
currentState.m_startVertex = draw.m_startVertex;
|
||||||
|
@ -2635,6 +2709,11 @@ namespace bgfx { namespace mtl
|
||||||
uint32_t numPrimsRendered = 0;
|
uint32_t numPrimsRendered = 0;
|
||||||
uint32_t numDrawIndirect = 0;
|
uint32_t numDrawIndirect = 0;
|
||||||
|
|
||||||
|
if (hasOcclusionQuery)
|
||||||
|
{
|
||||||
|
m_occlusionQuery.begin(rce, _render, draw.m_occlusionQuery);
|
||||||
|
}
|
||||||
|
|
||||||
if (isValid(draw.m_indirectBuffer) )
|
if (isValid(draw.m_indirectBuffer) )
|
||||||
{
|
{
|
||||||
// TODO: indirect draw
|
// TODO: indirect draw
|
||||||
|
@ -2677,6 +2756,11 @@ namespace bgfx { namespace mtl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasOcclusionQuery)
|
||||||
|
{
|
||||||
|
m_occlusionQuery.end(rce);
|
||||||
|
}
|
||||||
|
|
||||||
statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
|
statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
|
||||||
statsNumPrimsRendered[primIndex] += numPrimsRendered;
|
statsNumPrimsRendered[primIndex] += numPrimsRendered;
|
||||||
statsNumInstances[primIndex] += numInstances;
|
statsNumInstances[primIndex] += numInstances;
|
||||||
|
|
Loading…
Reference in a new issue