mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2025-02-26 16:44:00 -05:00
Metal: Occlusion query WIP.
This commit is contained in:
parent
422fcf6052
commit
653bbea439
2 changed files with 790 additions and 701 deletions
|
@ -712,6 +712,29 @@ namespace bgfx { namespace mtl
|
|||
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
|
||||
|
||||
#endif // BGFX_CONFIG_RENDERER_METAL
|
||||
|
|
|
@ -348,8 +348,8 @@ namespace bgfx { namespace mtl
|
|||
|
||||
if (NULL != NSClassFromString(@"CAMetalLayer") )
|
||||
{
|
||||
//on iOS we need the layer as CAmetalLayer
|
||||
#if BX_PLATFORM_IOS
|
||||
{
|
||||
CAMetalLayer* metalLayer = (CAMetalLayer*)g_platformData.nwh;
|
||||
if (NULL == metalLayer
|
||||
|| ![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");
|
||||
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];
|
||||
m_metalLayer = [CAMetalLayer layer];
|
||||
[nsWindow.contentView setLayer:m_metalLayer];
|
||||
}
|
||||
#endif // BX_PLATFORM_*
|
||||
|
||||
m_device = (id<MTLDevice>)g_platformData.context;
|
||||
|
@ -401,8 +403,8 @@ namespace bgfx { namespace mtl
|
|||
m_uniformBufferFragmentOffset = 0;
|
||||
|
||||
g_caps.supported |= (0
|
||||
| BGFX_CAPS_TEXTURE_COMPARE_LEQUAL
|
||||
| BGFX_CAPS_TEXTURE_3D
|
||||
| BGFX_CAPS_TEXTURE_COMPARE_LEQUAL
|
||||
| BGFX_CAPS_INSTANCING
|
||||
| BGFX_CAPS_VERTEX_ATTRIB_HALF
|
||||
// | BGFX_CAPS_FRAGMENT_DEPTH
|
||||
|
@ -410,6 +412,9 @@ namespace bgfx { namespace mtl
|
|||
| BGFX_CAPS_COMPUTE
|
||||
| BGFX_CAPS_INDEX32
|
||||
| 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
|
||||
|
@ -483,11 +488,15 @@ namespace bgfx { namespace mtl
|
|||
bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1, "%3d ", ii);
|
||||
}
|
||||
|
||||
m_occlusionQuery.preReset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
m_occlusionQuery.postReset();
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii)
|
||||
{
|
||||
m_shaders[ii].destroy();
|
||||
|
@ -507,9 +516,10 @@ namespace bgfx { namespace mtl
|
|||
MTL_RELEASE(m_samplerDescriptor);
|
||||
|
||||
MTL_RELEASE(m_backBufferDepth);
|
||||
#if BX_PLATFORM_IOS
|
||||
if (BX_ENABLED(BX_PLATFORM_IOS) )
|
||||
{
|
||||
MTL_RELEASE(m_backBufferStencil);
|
||||
#endif // BX_PLATFORM_*
|
||||
}
|
||||
|
||||
MTL_RELEASE(m_uniformBuffer);
|
||||
MTL_RELEASE(m_commandQueue);
|
||||
|
@ -930,19 +940,7 @@ namespace bgfx { namespace mtl
|
|||
release(m_backBufferDepth);
|
||||
}
|
||||
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;
|
||||
#endif // 0
|
||||
|
||||
bx::HashMurmur2A murmur;
|
||||
murmur.begin();
|
||||
|
@ -964,14 +962,12 @@ namespace bgfx { namespace mtl
|
|||
|
||||
void setShaderUniform(uint8_t _flags, uint32_t _loc, const void* _val, uint32_t _numRegs)
|
||||
{
|
||||
if (_flags&BGFX_UNIFORM_FRAGMENTBIT)
|
||||
{
|
||||
memcpy(&((char*)m_uniformBuffer.contents())[m_uniformBufferFragmentOffset + _loc], _val, _numRegs*16);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&((char*)m_uniformBuffer.contents())[m_uniformBufferVertexOffset + _loc], _val, _numRegs*16);
|
||||
}
|
||||
uint32_t offset = 0 != (_flags&BGFX_UNIFORM_FRAGMENTBIT)
|
||||
? m_uniformBufferFragmentOffset
|
||||
: m_uniformBufferVertexOffset
|
||||
;
|
||||
uint8_t* dst = (uint8_t*)m_uniformBuffer.contents();
|
||||
memcpy(&dst[offset + _loc], _val, _numRegs*16);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
case UniformType::Mat3:
|
||||
case UniformType::Mat3|BGFX_UNIFORM_FRAGMENTBIT: \
|
||||
case UniformType::Mat3|BGFX_UNIFORM_FRAGMENTBIT:
|
||||
{
|
||||
float* value = (float*)data;
|
||||
for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9)
|
||||
|
@ -1066,7 +1062,7 @@ namespace bgfx { namespace mtl
|
|||
}
|
||||
}
|
||||
|
||||
void setFrameBuffer(mtl::RenderPassDescriptor renderPassDescriptor, FrameBufferHandle _fbh, bool _msaa = true)
|
||||
void setFrameBuffer(RenderPassDescriptor renderPassDescriptor, FrameBufferHandle _fbh, bool _msaa = true)
|
||||
{
|
||||
if (!isValid(_fbh) )
|
||||
{
|
||||
|
@ -1197,6 +1193,12 @@ namespace bgfx { namespace mtl
|
|||
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()
|
||||
{
|
||||
return m_backBufferDepth.width();
|
||||
|
@ -1215,6 +1217,8 @@ namespace bgfx { namespace mtl
|
|||
uint32_t m_backBufferPixelFormatHash;
|
||||
uint32_t m_maxAnisotropy;
|
||||
|
||||
OcclusionQueryMTL m_occlusionQuery;
|
||||
|
||||
Buffer m_uniformBuffer; //todo: use a pool of this
|
||||
uint32_t m_uniformBufferVertexOffset;
|
||||
uint32_t m_uniformBufferFragmentOffset;
|
||||
|
@ -2102,6 +2106,48 @@ namespace bgfx { namespace mtl
|
|||
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;
|
||||
_rce.setVisibilityResultMode(MTLVisibilityResultModeBoolean, _handle.idx);
|
||||
}
|
||||
|
||||
void OcclusionQueryMTL::end(RenderCommandEncoder& _rce)
|
||||
{
|
||||
Query& query = m_query[m_control.m_current];
|
||||
_rce.setVisibilityResultMode(MTLVisibilityResultModeDisabled, query.m_handle.idx);
|
||||
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
|
||||
{
|
||||
BX_UNUSED(_clearQuad);
|
||||
|
@ -2179,7 +2225,7 @@ namespace bgfx { namespace mtl
|
|||
PrimInfo prim = s_primInfo[primIndex];
|
||||
|
||||
ProgramMtl* currentProgram = NULL;
|
||||
mtl::RenderCommandEncoder rce;
|
||||
RenderCommandEncoder rce;
|
||||
|
||||
bool wasCompute = false;
|
||||
bool viewHasScissor = false;
|
||||
|
@ -2193,6 +2239,8 @@ namespace bgfx { namespace mtl
|
|||
uint32_t statsNumIndices = 0;
|
||||
uint32_t statsKeyType[2] = {};
|
||||
|
||||
m_occlusionQuery.resolve(_render);
|
||||
|
||||
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
|
||||
{
|
||||
bool viewRestart = false;
|
||||
|
@ -2258,7 +2306,8 @@ namespace bgfx { namespace mtl
|
|||
viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect;
|
||||
Clear& clr = _render->m_clear[view];
|
||||
|
||||
mtl::RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor();
|
||||
RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor();
|
||||
renderPassDescriptor.visibilityResultBuffer = m_occlusionQuery.m_buffer;
|
||||
|
||||
//todo: check FB size
|
||||
uint32_t width = getBufferWidth();
|
||||
|
@ -2370,6 +2419,14 @@ namespace bgfx { namespace mtl
|
|||
|
||||
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;
|
||||
uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags;
|
||||
currentState.m_stateFlags = newFlags;
|
||||
|
@ -2484,12 +2541,12 @@ namespace bgfx { namespace mtl
|
|||
bool constantsChanged = draw.m_constBegin < draw.m_constEnd;
|
||||
rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_constBegin, draw.m_constEnd);
|
||||
|
||||
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 ||
|
||||
currentState.m_vertexBuffer.idx != draw.m_vertexBuffer.idx ||
|
||||
currentState.m_vertexDecl.idx != draw.m_vertexDecl.idx ||
|
||||
currentState.m_instanceDataStride != draw.m_instanceDataStride ||
|
||||
( (blendFactor != draw.m_rgba) && !!(newFlags & BGFX_STATE_BLEND_INDEPENDENT) ) )
|
||||
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
|
||||
|| currentState.m_vertexBuffer.idx != draw.m_vertexBuffer.idx
|
||||
|| currentState.m_vertexDecl.idx != draw.m_vertexDecl.idx
|
||||
|| currentState.m_instanceDataStride != draw.m_instanceDataStride
|
||||
|| ( (blendFactor != draw.m_rgba) && !!(newFlags & BGFX_STATE_BLEND_INDEPENDENT) ) )
|
||||
{
|
||||
programIdx = key.m_program;
|
||||
currentState.m_vertexDecl = draw.m_vertexDecl;
|
||||
|
@ -2591,8 +2648,7 @@ namespace bgfx { namespace mtl
|
|||
if (currentState.m_vertexBuffer.idx != draw.m_vertexBuffer.idx
|
||||
|| currentState.m_startVertex != draw.m_startVertex
|
||||
|| 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_startVertex = draw.m_startVertex;
|
||||
|
@ -2635,6 +2691,11 @@ namespace bgfx { namespace mtl
|
|||
uint32_t numPrimsRendered = 0;
|
||||
uint32_t numDrawIndirect = 0;
|
||||
|
||||
if (hasOcclusionQuery)
|
||||
{
|
||||
m_occlusionQuery.begin(rce, _render, draw.m_occlusionQuery);
|
||||
}
|
||||
|
||||
if (isValid(draw.m_indirectBuffer) )
|
||||
{
|
||||
// TODO: indirect draw
|
||||
|
@ -2677,6 +2738,11 @@ namespace bgfx { namespace mtl
|
|||
}
|
||||
}
|
||||
|
||||
if (hasOcclusionQuery)
|
||||
{
|
||||
m_occlusionQuery.end(rce);
|
||||
}
|
||||
|
||||
statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
|
||||
statsNumPrimsRendered[primIndex] += numPrimsRendered;
|
||||
statsNumInstances[primIndex] += numInstances;
|
||||
|
|
Loading…
Reference in a new issue