metal fixes
added cpu/gpu timer fixed handling iOS device orientation change fixed BGFX_DEBUG_IFH rendering acquire drawable just before needed added sampler comparison where available
This commit is contained in:
parent
661accb206
commit
c1cd627cb7
@ -83,6 +83,11 @@ namespace bgfx { namespace mtl
|
||||
[m_obj commit];
|
||||
}
|
||||
|
||||
void addScheduledHandler(mtlCallback _cb, void* _data)
|
||||
{
|
||||
[m_obj addScheduledHandler:^(id <MTLCommandBuffer>){ _cb(_data); }];
|
||||
}
|
||||
|
||||
void addCompletedHandler(mtlCallback _cb, void* _data)
|
||||
{
|
||||
[m_obj addCompletedHandler:^(id <MTLCommandBuffer>){ _cb(_data); }];
|
||||
@ -757,6 +762,27 @@ namespace bgfx { namespace mtl
|
||||
TextureHandle m_depthHandle;
|
||||
uint8_t m_num; // number of color handles
|
||||
};
|
||||
|
||||
struct TimerQueryMtl
|
||||
{
|
||||
TimerQueryMtl()
|
||||
: m_control(4)
|
||||
{
|
||||
}
|
||||
|
||||
void init();
|
||||
void shutdown();
|
||||
void addHandlers(CommandBuffer& _commandBuffer);
|
||||
bool get();
|
||||
|
||||
uint64_t m_begin;
|
||||
uint64_t m_end;
|
||||
uint64_t m_elapsed;
|
||||
uint64_t m_frequency;
|
||||
|
||||
uint64_t m_result[4*2];
|
||||
bx::RingBufferControl m_control;
|
||||
};
|
||||
|
||||
struct OcclusionQueryMTL
|
||||
{
|
||||
|
@ -38,17 +38,28 @@ Known issues(driver problems??):
|
||||
Only on this device ( no problem on iPad Air 2 with iOS9.3.1)
|
||||
|
||||
TODOs:
|
||||
- iOS device orientation change is not handled properly
|
||||
|
||||
22-windows: todo support multiple windows
|
||||
|
||||
- optimization: remove sync points, merge views with same fb and no clear.
|
||||
13-stencil and 16-shadowmaps are very inefficient. every view stores/loads backbuffer data
|
||||
multithreading with multiple commandbuffer
|
||||
- texture blit support: 08-update, 09-hdr
|
||||
- texture read_back: 09-hdr
|
||||
- texture msaa: 09-hdr
|
||||
- backbuffer msaa: 06-bump, 07-callback, 13-stencil, 19-oit, 21-deferred, 28-wireframe
|
||||
- textureMtl::commit set only vertex/fragment stage
|
||||
- FrameBufferMtl::postReset recreate framebuffer???
|
||||
- implement fb discard. problematic with multiple views that has same fb...
|
||||
- remove sync points at texture/mesh update
|
||||
- merge views with same fb and no fullscreen clear
|
||||
- capture: 07-callback
|
||||
|
||||
- finish savescreenshot with screenshotbegin/end
|
||||
|
||||
- support multiple windows: 22-windows
|
||||
- multithreading with multiple commandbuffer
|
||||
|
||||
- compute and drawindirect: 24-nbody (needs comnpute shaders)
|
||||
|
||||
INFO:
|
||||
- 15-shadowmaps-simple (example needs modification mtxCrop znew = z * 0.5 + 0.5 is not needed ) could be hacked in shader too
|
||||
|
||||
ASK:
|
||||
BGFX_RESET_FLIP_AFTER_RENDER on low level renderers should be true?
|
||||
Do I have absolutely need to send result to screen at flip or can I do it in submit?
|
||||
*/
|
||||
@ -126,7 +137,6 @@ namespace bgfx { namespace mtl
|
||||
},
|
||||
|
||||
//Uint10
|
||||
//TODO: normalized only
|
||||
{
|
||||
{ MTLVertexFormatInvalid, MTLVertexFormatUInt1010102Normalized },
|
||||
{ MTLVertexFormatInvalid, MTLVertexFormatUInt1010102Normalized },
|
||||
@ -197,7 +207,7 @@ namespace bgfx { namespace mtl
|
||||
|
||||
static const MTLCompareFunction s_cmpFunc[] =
|
||||
{
|
||||
MTLCompareFunctionAlways, //TODO: depth disable?
|
||||
MTLCompareFunctionAlways,
|
||||
MTLCompareFunctionLess,
|
||||
MTLCompareFunctionLessEqual,
|
||||
MTLCompareFunctionEqual,
|
||||
@ -416,7 +426,7 @@ namespace bgfx { namespace mtl
|
||||
}
|
||||
m_uniformBufferVertexOffset = 0;
|
||||
m_uniformBufferFragmentOffset = 0;
|
||||
|
||||
|
||||
const char* vshSource =
|
||||
"using namespace metal;\n"
|
||||
"struct xlatMtlShaderOutput { float4 gl_Position [[position]]; float2 v_texcoord0; }; \n"
|
||||
@ -434,7 +444,6 @@ namespace bgfx { namespace mtl
|
||||
" fragment half4 xlatMtlMain (xlatMtlShaderInput _mtl_i[[stage_in]], texture2d<float> s_texColor [[texture(0)]], sampler _mtlsmp_s_texColor [[sampler(0)]] ) \n"
|
||||
" { return half4(s_texColor.sample(_mtlsmp_s_texColor, _mtl_i.v_texcoord0)); } \n";
|
||||
|
||||
//TODO: use binary format
|
||||
Library lib = m_device.newLibraryWithSource(vshSource);
|
||||
if (NULL != lib)
|
||||
{
|
||||
@ -587,6 +596,7 @@ namespace bgfx { namespace mtl
|
||||
}
|
||||
|
||||
m_occlusionQuery.preReset();
|
||||
m_gpuTimer.init();
|
||||
|
||||
g_internalData.context = m_device;
|
||||
return true;
|
||||
@ -595,6 +605,7 @@ namespace bgfx { namespace mtl
|
||||
void shutdown()
|
||||
{
|
||||
m_occlusionQuery.postReset();
|
||||
m_gpuTimer.shutdown();
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii)
|
||||
{
|
||||
@ -863,7 +874,7 @@ namespace bgfx { namespace mtl
|
||||
BX_FREE(g_allocator, data);
|
||||
|
||||
m_commandBuffer = m_commandQueue.commandBuffer();
|
||||
retain(m_commandBuffer); // keep alive to be useable at 'flip'
|
||||
retain(m_commandBuffer); //NOTE: keep alive to be useable at 'flip'
|
||||
}
|
||||
|
||||
void updateViewName(uint8_t _id, const char* _name) BX_OVERRIDE
|
||||
@ -905,8 +916,24 @@ namespace bgfx { namespace mtl
|
||||
//}
|
||||
|
||||
FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
|
||||
//TODO: change to default framebuffer - we need a new encoder for this!
|
||||
//setFrameBuffer(fbh, false);
|
||||
|
||||
if ( NULL == rce || m_renderCommandEncoderFrameBufferHandle.idx != invalidHandle )
|
||||
{
|
||||
if ( m_renderCommandEncoder )
|
||||
m_renderCommandEncoder.endEncoding();
|
||||
|
||||
RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor();
|
||||
|
||||
setFrameBuffer(renderPassDescriptor, fbh);
|
||||
|
||||
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionLoad;
|
||||
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||
|
||||
rce = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor);
|
||||
m_renderCommandEncoder = rce;
|
||||
m_renderCommandEncoderFrameBufferHandle = fbh;
|
||||
MTL_RELEASE(renderPassDescriptor);
|
||||
}
|
||||
|
||||
MTLViewport viewport = { 0.0f, 0.0f, (float)width, (float)height, 0.0f, 1.0f};
|
||||
rce.setViewport(viewport);
|
||||
@ -976,15 +1003,17 @@ namespace bgfx { namespace mtl
|
||||
|
||||
void flip(HMD& /*_hmd*/) BX_OVERRIDE
|
||||
{
|
||||
if (NULL == m_drawable
|
||||
|| NULL == m_commandBuffer)
|
||||
if (NULL == m_commandBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Present and commit the command buffer
|
||||
m_commandBuffer.presentDrawable(m_drawable);
|
||||
MTL_RELEASE(m_drawable);
|
||||
if ( NULL != m_drawable)
|
||||
{
|
||||
m_commandBuffer.presentDrawable(m_drawable);
|
||||
MTL_RELEASE(m_drawable);
|
||||
}
|
||||
|
||||
m_commandBuffer.addCompletedHandler(commandBufferFinishedCallback, this);
|
||||
|
||||
@ -1019,25 +1048,26 @@ namespace bgfx { namespace mtl
|
||||
? 16
|
||||
: 1
|
||||
;
|
||||
|
||||
//TODO: _resolution has wrong dimensions, using m_drawable.texture size now
|
||||
if (NULL == m_drawable.texture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t width = (uint32_t)m_drawable.texture.width;
|
||||
uint32_t height = (uint32_t)m_drawable.texture.height;
|
||||
|
||||
|
||||
//TODO: there should be a way to specify if backbuffer needs stencil/depth.
|
||||
//TODO: support msaa
|
||||
if (NULL == m_backBufferDepth
|
||||
|| width != m_backBufferDepth.width()
|
||||
|| height != m_backBufferDepth.height()
|
||||
|| m_resolution.m_width != _resolution.m_width
|
||||
|| m_resolution.m_height != _resolution.m_height
|
||||
|| m_resolution.m_flags != _resolution.m_flags)
|
||||
const uint32_t maskFlags = ~(0
|
||||
| BGFX_RESET_HMD_RECENTER
|
||||
| BGFX_RESET_MAXANISOTROPY
|
||||
| BGFX_RESET_DEPTH_CLAMP
|
||||
| BGFX_RESET_SUSPEND
|
||||
);
|
||||
|
||||
if (m_resolution.m_width != _resolution.m_width
|
||||
|| m_resolution.m_height != _resolution.m_height
|
||||
|| (m_resolution.m_flags&maskFlags) != (_resolution.m_flags&maskFlags) )
|
||||
{
|
||||
m_metalLayer.drawableSize = CGSizeMake(_resolution.m_width, _resolution.m_height);
|
||||
m_metalLayer.pixelFormat = (m_resolution.m_flags & BGFX_RESET_SRGB_BACKBUFFER)
|
||||
? MTLPixelFormatBGRA8Unorm_sRGB
|
||||
: MTLPixelFormatBGRA8Unorm
|
||||
;
|
||||
|
||||
m_resolution = _resolution;
|
||||
m_resolution.m_flags &= ~BGFX_RESET_INTERNAL_FORCE;
|
||||
|
||||
@ -1047,10 +1077,9 @@ namespace bgfx { namespace mtl
|
||||
m_textureDescriptor.pixelFormat = MTLPixelFormatDepth32Float_Stencil8;
|
||||
else
|
||||
m_textureDescriptor.pixelFormat = MTLPixelFormatDepth32Float;
|
||||
//todo: create separate stencil buffer
|
||||
|
||||
m_textureDescriptor.width = width;
|
||||
m_textureDescriptor.height = height;
|
||||
m_textureDescriptor.width = _resolution.m_width;
|
||||
m_textureDescriptor.height = _resolution.m_height;
|
||||
m_textureDescriptor.depth = 1;
|
||||
m_textureDescriptor.mipmapLevelCount = 1;
|
||||
m_textureDescriptor.sampleCount = 1;
|
||||
@ -1080,7 +1109,7 @@ namespace bgfx { namespace mtl
|
||||
bx::HashMurmur2A murmur;
|
||||
murmur.begin();
|
||||
murmur.add(1);
|
||||
murmur.add((uint32_t)m_drawable.texture.pixelFormat);
|
||||
murmur.add((uint32_t)m_metalLayer.pixelFormat);
|
||||
murmur.add((uint32_t)m_backBufferDepth.pixelFormat());
|
||||
murmur.add((uint32_t)m_backBufferStencil.pixelFormat());
|
||||
m_backBufferPixelFormatHash = murmur.end();
|
||||
@ -1090,7 +1119,7 @@ namespace bgfx { namespace mtl
|
||||
m_frameBuffers[ii].postReset();
|
||||
}
|
||||
|
||||
m_textVideoMem.resize(false, width, height);
|
||||
m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height);
|
||||
m_textVideoMem.clear();
|
||||
}
|
||||
}
|
||||
@ -1206,7 +1235,7 @@ namespace bgfx { namespace mtl
|
||||
{
|
||||
if (!isValid(_fbh) )
|
||||
{
|
||||
renderPassDescriptor.colorAttachments[0].texture = ((NULL != m_screenshotTarget) ? m_screenshotTarget.m_obj : m_drawable.texture);
|
||||
renderPassDescriptor.colorAttachments[0].texture = ((NULL != m_screenshotTarget) ? m_screenshotTarget.m_obj : currentDrawable().texture);
|
||||
renderPassDescriptor.depthAttachment.texture = m_backBufferDepth;
|
||||
renderPassDescriptor.stencilAttachment.texture = m_backBufferStencil;
|
||||
}
|
||||
@ -1321,11 +1350,12 @@ namespace bgfx { namespace mtl
|
||||
m_samplerDescriptor.normalizedCoordinates = TRUE;
|
||||
m_samplerDescriptor.maxAnisotropy = m_maxAnisotropy;
|
||||
|
||||
//TODO: I haven't found how to specify this. Comparison function can be specified in shader.
|
||||
// On OSX this can be specified. There is no support for this on iOS right now.
|
||||
//const uint32_t cmpFunc = (_flags&BGFX_TEXTURE_COMPARE_MASK)>>BGFX_TEXTURE_COMPARE_SHIFT;
|
||||
//const uint8_t filter = 0 == cmpFunc ? 0 : D3D11_COMPARISON_FILTERING_BIT;
|
||||
//m_samplerDescriptor.comparisonFunc = 0 == cmpFunc ? D3D11_COMPARISON_NEVER : s_cmpFunc[cmpFunc];
|
||||
//NOTE: Comparison function can be specified in shader on all metal hw.
|
||||
if ( m_macOS11Runtime || [m_device supportsFeatureSet:(MTLFeatureSet)4/*MTLFeatureSet_iOS_GPUFamily3_v1*/])
|
||||
{
|
||||
const uint32_t cmpFunc = (_flags&BGFX_TEXTURE_COMPARE_MASK)>>BGFX_TEXTURE_COMPARE_SHIFT;
|
||||
m_samplerDescriptor.compareFunction = 0 == cmpFunc ? MTLCompareFunctionNever : s_cmpFunc[cmpFunc];
|
||||
}
|
||||
|
||||
sampler = m_device.newSamplerStateWithDescriptor(m_samplerDescriptor);
|
||||
m_samplerStateCache.add(_flags, sampler);
|
||||
@ -1372,8 +1402,24 @@ namespace bgfx { namespace mtl
|
||||
return m_blitCommandEncoder;
|
||||
}
|
||||
|
||||
id<CAMetalDrawable> currentDrawable()
|
||||
{
|
||||
if (m_drawable == nil)
|
||||
{
|
||||
m_drawable = m_metalLayer.nextDrawable;
|
||||
#if BX_PLATFORM_IOS
|
||||
retain(m_drawable); // keep alive to be useable at 'flip'
|
||||
#endif
|
||||
}
|
||||
|
||||
return m_drawable;
|
||||
}
|
||||
|
||||
|
||||
Device m_device;
|
||||
OcclusionQueryMTL m_occlusionQuery;
|
||||
TimerQueryMtl m_gpuTimer;
|
||||
|
||||
Device m_device;
|
||||
CommandQueue m_commandQueue;
|
||||
CAMetalLayer* m_metalLayer;
|
||||
Texture m_backBufferDepth;
|
||||
@ -1385,7 +1431,7 @@ namespace bgfx { namespace mtl
|
||||
bool m_macOS11Runtime;
|
||||
bool m_hasPixelFormatDepth32Float_Stencil8;
|
||||
|
||||
OcclusionQueryMTL m_occlusionQuery;
|
||||
|
||||
|
||||
bx::Semaphore m_framesSemaphore;
|
||||
|
||||
@ -1436,10 +1482,11 @@ namespace bgfx { namespace mtl
|
||||
ShaderMtl m_screenshotBlitProgramFsh;
|
||||
ProgramMtl m_screenshotBlitProgram;
|
||||
|
||||
CommandBuffer m_commandBuffer;
|
||||
CommandBuffer m_prevCommandBuffer;
|
||||
BlitCommandEncoder m_blitCommandEncoder;
|
||||
RenderCommandEncoder m_renderCommandEncoder;
|
||||
CommandBuffer m_commandBuffer;
|
||||
CommandBuffer m_prevCommandBuffer;
|
||||
BlitCommandEncoder m_blitCommandEncoder;
|
||||
RenderCommandEncoder m_renderCommandEncoder;
|
||||
FrameBufferHandle m_renderCommandEncoderFrameBufferHandle;
|
||||
};
|
||||
|
||||
static RendererContextMtl* s_renderMtl;
|
||||
@ -1676,7 +1723,7 @@ namespace bgfx { namespace mtl
|
||||
|
||||
if (!isValid(_fbHandle) )
|
||||
{
|
||||
pd.colorAttachments[0].pixelFormat = s_renderMtl->m_drawable.texture.pixelFormat;
|
||||
pd.colorAttachments[0].pixelFormat = s_renderMtl->currentDrawable().texture.pixelFormat;
|
||||
pd.depthAttachmentPixelFormat = s_renderMtl->m_backBufferDepth.m_obj.pixelFormat;
|
||||
pd.stencilAttachmentPixelFormat = s_renderMtl->m_backBufferStencil.m_obj.pixelFormat;
|
||||
}
|
||||
@ -1697,11 +1744,11 @@ namespace bgfx { namespace mtl
|
||||
pd.depthAttachmentPixelFormat = texture.m_ptr.m_obj.pixelFormat;
|
||||
if (NULL != texture.m_ptrStencil)
|
||||
{
|
||||
pd.stencilAttachmentPixelFormat = MTLPixelFormatInvalid; //texture.m_ptrStencil.m_obj.pixelFormat;
|
||||
pd.stencilAttachmentPixelFormat = texture.m_ptrStencil.m_obj.pixelFormat;
|
||||
}
|
||||
|
||||
if ( texture.m_textureFormat == TextureFormat::D24S8)
|
||||
pd.stencilAttachmentPixelFormat = texture.m_ptr.m_obj.pixelFormat;
|
||||
// if ( texture.m_textureFormat == TextureFormat::D24S8)
|
||||
// pd.stencilAttachmentPixelFormat = texture.m_ptr.m_obj.pixelFormat;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1791,7 +1838,7 @@ namespace bgfx { namespace mtl
|
||||
BX_TRACE("attrib:%s format: %d offset:%d", s_attribName[attr], (int)vertexDesc.attributes[loc].format, (int)vertexDesc.attributes[loc].offset);
|
||||
}
|
||||
else
|
||||
{ // missing attribute: using dummy attribute with smallest possible size
|
||||
{ // NOTE: missing attribute: using dummy attribute with smallest possible size
|
||||
vertexDesc.attributes[loc].format = MTLVertexFormatUChar2;
|
||||
vertexDesc.attributes[loc].bufferIndex = 1;
|
||||
vertexDesc.attributes[loc].offset = 0;
|
||||
@ -2237,7 +2284,6 @@ namespace bgfx { namespace mtl
|
||||
{
|
||||
const TextureMtl& texture = s_renderMtl->m_textures[handle.idx];
|
||||
|
||||
//TODO: separate stencil buffer? or just use packed depth/stencil (which is not available on iOS8)
|
||||
if (isDepth( (TextureFormat::Enum)texture.m_textureFormat) )
|
||||
{
|
||||
m_depthHandle = handle;
|
||||
@ -2261,7 +2307,7 @@ namespace bgfx { namespace mtl
|
||||
}
|
||||
const TextureMtl& depthTexture = s_renderMtl->m_textures[m_depthHandle.idx];
|
||||
murmur.add((uint32_t)depthTexture.m_ptr.pixelFormat());
|
||||
murmur.add((uint32_t)MTLPixelFormatInvalid); //stencil
|
||||
murmur.add((uint32_t)(NULL != depthTexture.m_ptrStencil ? depthTexture.m_ptrStencil.pixelFormat() : MTLPixelFormatInvalid));
|
||||
|
||||
m_pixelFormatHash = murmur.end();
|
||||
}
|
||||
@ -2290,6 +2336,51 @@ namespace bgfx { namespace mtl
|
||||
return denseIdx;
|
||||
}
|
||||
|
||||
void TimerQueryMtl::init()
|
||||
{
|
||||
m_frequency = bx::getHPFrequency();
|
||||
}
|
||||
|
||||
void TimerQueryMtl::shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
static void setTimestamp(void* _data)
|
||||
{
|
||||
*((int64_t*)_data) = bx::getHPCounter();
|
||||
}
|
||||
|
||||
void TimerQueryMtl::addHandlers(CommandBuffer& _commandBuffer)
|
||||
{
|
||||
while (0 == m_control.reserve(1) )
|
||||
{
|
||||
m_control.consume(1);
|
||||
}
|
||||
|
||||
uint32_t offset = m_control.m_current * 2 + 0;
|
||||
|
||||
_commandBuffer.addScheduledHandler(setTimestamp, &m_result[offset]);
|
||||
_commandBuffer.addCompletedHandler(setTimestamp, &m_result[offset+1]);
|
||||
m_control.commit(1);
|
||||
}
|
||||
|
||||
bool TimerQueryMtl::get()
|
||||
{
|
||||
if (0 != m_control.available() )
|
||||
{
|
||||
uint32_t offset = m_control.m_read * 2;
|
||||
m_begin = m_result[offset+0];
|
||||
m_end = m_result[offset+1];
|
||||
m_elapsed = m_end - m_begin;
|
||||
|
||||
m_control.consume(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OcclusionQueryMTL::postReset()
|
||||
{
|
||||
MTL_RELEASE(m_buffer);
|
||||
@ -2343,6 +2434,11 @@ namespace bgfx { namespace mtl
|
||||
m_commandBuffer = m_commandQueue.commandBuffer();
|
||||
retain(m_commandBuffer); // keep alive to be useable at 'flip'
|
||||
}
|
||||
|
||||
int64_t elapsed = -bx::getHPCounter();
|
||||
int64_t captureElapsed = 0;
|
||||
|
||||
m_gpuTimer.addHandlers(m_commandBuffer);
|
||||
|
||||
if ( m_blitCommandEncoder )
|
||||
{
|
||||
@ -2350,19 +2446,14 @@ namespace bgfx { namespace mtl
|
||||
m_blitCommandEncoder = 0;
|
||||
}
|
||||
|
||||
|
||||
//TODO: acquire CAMetalDrawable just before we really need it. When we are using an encoder with target metalLayer's texture
|
||||
m_drawable = m_metalLayer.nextDrawable;
|
||||
#if BX_PLATFORM_IOS
|
||||
retain(m_drawable); // keep alive to be useable at 'flip'
|
||||
#endif
|
||||
|
||||
updateResolution(_render->m_resolution);
|
||||
|
||||
if ( m_saveScreenshot )
|
||||
{
|
||||
if ( m_screenshotTarget )
|
||||
{
|
||||
if ( m_screenshotTarget.width() != m_drawable.texture.width ||
|
||||
m_screenshotTarget.height() != m_drawable.texture.height )
|
||||
if ( m_screenshotTarget.width() != m_resolution.m_width ||
|
||||
m_screenshotTarget.height() != m_resolution.m_height )
|
||||
{
|
||||
MTL_RELEASE(m_screenshotTarget);
|
||||
}
|
||||
@ -2371,13 +2462,13 @@ namespace bgfx { namespace mtl
|
||||
if ( NULL == m_screenshotTarget)
|
||||
{
|
||||
m_textureDescriptor.textureType = MTLTextureType2D;
|
||||
m_textureDescriptor.pixelFormat = m_drawable.texture.pixelFormat;
|
||||
m_textureDescriptor.width = m_drawable.texture.width;
|
||||
m_textureDescriptor.height = m_drawable.texture.height;
|
||||
m_textureDescriptor.pixelFormat = m_metalLayer.pixelFormat;
|
||||
m_textureDescriptor.width = m_resolution.m_width;
|
||||
m_textureDescriptor.height = m_resolution.m_height;
|
||||
m_textureDescriptor.depth = 1;
|
||||
m_textureDescriptor.mipmapLevelCount = 1;
|
||||
m_textureDescriptor.sampleCount = m_drawable.texture.sampleCount;
|
||||
m_textureDescriptor.arrayLength = m_drawable.texture.arrayLength;
|
||||
m_textureDescriptor.sampleCount = 1;
|
||||
m_textureDescriptor.arrayLength = 1;
|
||||
if ( m_iOS9Runtime || m_macOS11Runtime )
|
||||
{
|
||||
m_textureDescriptor.cpuCacheMode = MTLCPUCacheModeDefaultCache;
|
||||
@ -2400,16 +2491,7 @@ namespace bgfx { namespace mtl
|
||||
m_uniformBufferVertexOffset = 0;
|
||||
m_uniformBufferFragmentOffset = 0;
|
||||
|
||||
updateResolution(_render->m_resolution);
|
||||
|
||||
int64_t elapsed = -bx::getHPCounter();
|
||||
int64_t captureElapsed = 0;
|
||||
|
||||
if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
|
||||
{
|
||||
//TODO
|
||||
//m_gpuTimer.begin();
|
||||
}
|
||||
|
||||
if (0 < _render->m_iboffset)
|
||||
{
|
||||
@ -2443,8 +2525,6 @@ namespace bgfx { namespace mtl
|
||||
uint16_t view = UINT16_MAX;
|
||||
FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS };
|
||||
|
||||
//ASK: why should we use this? It changes topology, so possible renders a big mess, doesn't it?
|
||||
//const uint64_t primType = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;
|
||||
const uint64_t primType = 0;
|
||||
uint8_t primIndex = uint8_t(primType>>BGFX_STATE_PT_SHIFT);
|
||||
PrimInfo prim = s_primInfo[primIndex];
|
||||
@ -2642,6 +2722,7 @@ namespace bgfx { namespace mtl
|
||||
|
||||
rce = m_commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor);
|
||||
m_renderCommandEncoder = rce;
|
||||
m_renderCommandEncoderFrameBufferHandle = fbh;
|
||||
MTL_RELEASE(renderPassDescriptor);
|
||||
|
||||
rce.setTriangleFillMode(wireframe? MTLTriangleFillModeLines : MTLTriangleFillModeFill);
|
||||
@ -2771,7 +2852,6 @@ namespace bgfx { namespace mtl
|
||||
| BGFX_STATE_CULL_MASK
|
||||
| BGFX_STATE_ALPHA_REF_MASK
|
||||
| BGFX_STATE_PT_MASK
|
||||
// | BGFX_STATE_POINT_SIZE_MASK
|
||||
) & changedFlags)
|
||||
{
|
||||
if (BGFX_STATE_CULL_MASK & changedFlags)
|
||||
@ -3042,34 +3122,47 @@ namespace bgfx { namespace mtl
|
||||
|
||||
int64_t now = bx::getHPCounter();
|
||||
elapsed += now;
|
||||
|
||||
|
||||
static int64_t last = now;
|
||||
|
||||
Stats& perfStats = _render->m_perfStats;
|
||||
perfStats.cpuTimeBegin = last;
|
||||
|
||||
int64_t frameTime = now - last;
|
||||
last = now;
|
||||
|
||||
|
||||
static int64_t min = frameTime;
|
||||
static int64_t max = frameTime;
|
||||
min = min > frameTime ? frameTime : min;
|
||||
max = max < frameTime ? frameTime : max;
|
||||
min = bx::int64_min(min, frameTime);
|
||||
max = bx::int64_max(max, frameTime);
|
||||
|
||||
static uint32_t maxGpuLatency = 0;
|
||||
static double maxGpuElapsed = 0.0f;
|
||||
double elapsedGpuMs = 0.0;
|
||||
|
||||
do
|
||||
{
|
||||
double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency);
|
||||
elapsedGpuMs = m_gpuTimer.m_elapsed * toGpuMs;
|
||||
maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed;
|
||||
}
|
||||
while (m_gpuTimer.get() );
|
||||
|
||||
maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1);
|
||||
|
||||
const int64_t timerFreq = bx::getHPFrequency();
|
||||
|
||||
perfStats.cpuTimeEnd = now;
|
||||
perfStats.cpuTimerFreq = timerFreq;
|
||||
perfStats.gpuTimeBegin = m_gpuTimer.m_begin;
|
||||
perfStats.gpuTimeEnd = m_gpuTimer.m_end;
|
||||
perfStats.gpuTimerFreq = m_gpuTimer.m_frequency;
|
||||
|
||||
rce.setTriangleFillMode(MTLTriangleFillModeFill);
|
||||
if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )
|
||||
{
|
||||
rce.pushDebugGroup("debugstats");
|
||||
|
||||
static uint32_t maxGpuLatency = 0;
|
||||
static double maxGpuElapsed = 0.0f;
|
||||
// double elapsedGpuMs = 0.0;
|
||||
|
||||
// m_gpuTimer.end();
|
||||
//
|
||||
// while (m_gpuTimer.get() )
|
||||
// {
|
||||
// double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency);
|
||||
// elapsedGpuMs = m_gpuTimer.m_elapsed * toGpuMs;
|
||||
// maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed;
|
||||
// }
|
||||
// maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1);
|
||||
|
||||
TextVideoMem& tvm = m_textVideoMem;
|
||||
|
||||
static int64_t next = now;
|
||||
@ -3146,6 +3239,7 @@ namespace bgfx { namespace mtl
|
||||
}
|
||||
|
||||
blit(this, _textVideoMemBlitter, tvm);
|
||||
rce = m_renderCommandEncoder; //TODO: ugly, blit can create encoder
|
||||
|
||||
rce.popDebugGroup();
|
||||
}
|
||||
@ -3154,18 +3248,20 @@ namespace bgfx { namespace mtl
|
||||
rce.pushDebugGroup("debugtext");
|
||||
|
||||
blit(this, _textVideoMemBlitter, _render->m_textVideoMem);
|
||||
rce = m_renderCommandEncoder; //TODO: ugly, blit can create encoder
|
||||
|
||||
rce.popDebugGroup();
|
||||
}
|
||||
|
||||
rce.endEncoding();
|
||||
m_renderCommandEncoder = 0;
|
||||
m_renderCommandEncoderFrameBufferHandle.idx = invalidHandle;
|
||||
|
||||
|
||||
if ( m_screenshotTarget )
|
||||
{
|
||||
RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor();
|
||||
renderPassDescriptor.colorAttachments[0].texture = m_drawable.texture;
|
||||
renderPassDescriptor.colorAttachments[0].texture = currentDrawable().texture;
|
||||
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||
renderPassDescriptor.depthAttachment.texture = m_backBufferDepth;
|
||||
renderPassDescriptor.stencilAttachment.texture = m_backBufferStencil;
|
||||
|
Loading…
Reference in New Issue
Block a user