From 08894e1422a545d916312054e8290a2b79b828b3 Mon Sep 17 00:00:00 2001 From: Attila Kocsis Date: Sat, 9 Feb 2019 20:55:23 +0100 Subject: [PATCH] buffer update with blit --- src/renderer_mtl.h | 30 +++--- src/renderer_mtl.mm | 246 +++++++++++++++++++++----------------------- 2 files changed, 131 insertions(+), 145 deletions(-) diff --git a/src/renderer_mtl.h b/src/renderer_mtl.h index e33371759..864bad31a 100644 --- a/src/renderer_mtl.h +++ b/src/renderer_mtl.h @@ -140,6 +140,11 @@ namespace bgfx { namespace mtl { return (uint32_t)m_obj.length; } + + void setLabel(const char* _label) + { + [m_obj setLabel:@(_label)]; + } MTL_CLASS_END MTL_CLASS(CommandBuffer) @@ -767,13 +772,8 @@ namespace bgfx { namespace mtl { BufferMtl() : m_flags(BGFX_BUFFER_NONE) - , m_dynamic(false) - , m_bufferIndex(0) + , m_dynamic(NULL) { - for (uint32_t ii = 0; ii < MTL_MAX_FRAMES_IN_FLIGHT; ++ii) - { - m_buffers[ii] = NULL; - } } void create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride = 0, bool _vertex = false); @@ -781,23 +781,21 @@ namespace bgfx { namespace mtl void destroy() { - for (uint32_t ii = 0; ii < MTL_MAX_FRAMES_IN_FLIGHT; ++ii) + MTL_RELEASE(m_ptr); + + if (m_dynamic) { - MTL_RELEASE(m_buffers[ii]); + BX_DELETE(g_allocator, m_dynamic); + m_dynamic = NULL; } - - m_dynamic = false; } - Buffer getBuffer() const { return m_buffers[m_bufferIndex]; } - uint32_t m_size; uint16_t m_flags; + bool m_vertex; - bool m_dynamic; - private: - uint8_t m_bufferIndex; - Buffer m_buffers[MTL_MAX_FRAMES_IN_FLIGHT]; + Buffer m_ptr; + uint8_t* m_dynamic; }; typedef BufferMtl IndexBufferMtl; diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index 02a5247bf..c89d95c99 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -1024,7 +1024,7 @@ namespace bgfx { namespace mtl switch (_handle.type) { case Handle::IndexBuffer: -// m_indexBuffers[_handle.idx].m_ptr.setLabel(_name); + m_indexBuffers[_handle.idx].m_ptr.setLabel(_name); break; case Handle::Shader: @@ -1036,7 +1036,7 @@ namespace bgfx { namespace mtl break; case Handle::VertexBuffer: -// m_vertexBuffers[_handle.idx].m_ptr.setLabel(_name); + m_vertexBuffers[_handle.idx].m_ptr.setLabel(_name); break; default: @@ -1051,87 +1051,7 @@ namespace bgfx { namespace mtl void blitSetup(TextVideoMemBlitter& _blitter) override { - RenderCommandEncoder rce = m_renderCommandEncoder; - - uint32_t width = m_resolution.width; - uint32_t height = m_resolution.height; - - FrameBufferHandle fbh = BGFX_INVALID_HANDLE; - - if (NULL == rce - || m_renderCommandEncoderFrameBufferHandle.idx != kInvalidHandle) - { - if (m_renderCommandEncoder) - { - m_renderCommandEncoder.endEncoding(); - } - - RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor(); - - setFrameBuffer(renderPassDescriptor, fbh); - - renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionLoad; - renderPassDescriptor.colorAttachments[0].storeAction = - NULL != renderPassDescriptor.colorAttachments[0].resolveTexture - ? MTLStoreActionMultisampleResolve - : 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); - MTLScissorRect rc = { 0,0,width,height }; - rce.setScissorRect(rc); - rce.setCullMode(MTLCullModeNone); - - uint64_t state = 0 - | BGFX_STATE_WRITE_RGB - | BGFX_STATE_WRITE_A - | BGFX_STATE_DEPTH_TEST_ALWAYS - ; - - setDepthStencilState(state); - - PipelineStateMtl* pso = getPipelineState( - state - , 0 - , fbh - , _blitter.m_vb->decl - , _blitter.m_program - , 0 - ); - rce.setRenderPipelineState(pso->m_rps); - - const uint32_t vertexUniformBufferSize = pso->m_vshConstantBufferSize; - const uint32_t fragmentUniformBufferSize = pso->m_fshConstantBufferSize; - - if (vertexUniformBufferSize) - { - m_uniformBufferVertexOffset = BX_ALIGN_MASK(m_uniformBufferVertexOffset, pso->m_vshConstantBufferAlignmentMask); - rce.setVertexBuffer(m_uniformBuffer, m_uniformBufferVertexOffset, 0); - } - - m_uniformBufferFragmentOffset = m_uniformBufferVertexOffset + vertexUniformBufferSize; - - if (0 != fragmentUniformBufferSize) - { - m_uniformBufferFragmentOffset = BX_ALIGN_MASK(m_uniformBufferFragmentOffset, pso->m_fshConstantBufferAlignmentMask); - rce.setFragmentBuffer(m_uniformBuffer, m_uniformBufferFragmentOffset, 0); - } - - float proj[16]; - bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f, 0.0f, false); - - PredefinedUniform& predefined = pso->m_predefined[0]; - uint8_t flags = predefined.m_type; - setShaderUniform(flags, predefined.m_loc, proj, 4); - - m_textures[_blitter.m_texture.idx].commit(0, false, true); + BX_UNUSED(_blitter); } void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) override @@ -1141,7 +1061,7 @@ namespace bgfx { namespace mtl { m_indexBuffers [_blitter.m_ib->handle.idx].update( 0 - , _numIndices*2 + , bx::strideAlign(_numIndices*2, 4) , _blitter.m_ib->data , true ); @@ -1151,15 +1071,88 @@ namespace bgfx { namespace mtl , _blitter.m_vb->data , true ); + + endEncoding(); + + uint32_t width = m_resolution.width; + uint32_t height = m_resolution.height; + + FrameBufferHandle fbh = BGFX_INVALID_HANDLE; + + RenderPassDescriptor renderPassDescriptor = newRenderPassDescriptor(); + + setFrameBuffer(renderPassDescriptor, fbh); + + renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionLoad; + renderPassDescriptor.colorAttachments[0].storeAction = + NULL != renderPassDescriptor.colorAttachments[0].resolveTexture + ? MTLStoreActionMultisampleResolve + : MTLStoreActionStore + ; + + RenderCommandEncoder 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); + MTLScissorRect rc = { 0,0,width,height }; + rce.setScissorRect(rc); + rce.setCullMode(MTLCullModeNone); + + uint64_t state = 0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_WRITE_A + | BGFX_STATE_DEPTH_TEST_ALWAYS + ; + + setDepthStencilState(state); + + PipelineStateMtl* pso = getPipelineState( + state + , 0 + , fbh + , _blitter.m_vb->decl + , _blitter.m_program + , 0 + ); + rce.setRenderPipelineState(pso->m_rps); + + const uint32_t vertexUniformBufferSize = pso->m_vshConstantBufferSize; + const uint32_t fragmentUniformBufferSize = pso->m_fshConstantBufferSize; + + if (vertexUniformBufferSize) + { + m_uniformBufferVertexOffset = BX_ALIGN_MASK(m_uniformBufferVertexOffset, pso->m_vshConstantBufferAlignmentMask); + rce.setVertexBuffer(m_uniformBuffer, m_uniformBufferVertexOffset, 0); + } + + m_uniformBufferFragmentOffset = m_uniformBufferVertexOffset + vertexUniformBufferSize; + + if (0 != fragmentUniformBufferSize) + { + m_uniformBufferFragmentOffset = BX_ALIGN_MASK(m_uniformBufferFragmentOffset, pso->m_fshConstantBufferAlignmentMask); + rce.setFragmentBuffer(m_uniformBuffer, m_uniformBufferFragmentOffset, 0); + } + + float proj[16]; + bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f, 0.0f, false); + + PredefinedUniform& predefined = pso->m_predefined[0]; + uint8_t flags = predefined.m_type; + setShaderUniform(flags, predefined.m_loc, proj, 4); + + m_textures[_blitter.m_texture.idx].commit(0, false, true); VertexBufferMtl& vb = m_vertexBuffers[_blitter.m_vb->handle.idx]; - m_renderCommandEncoder.setVertexBuffer(vb.getBuffer(), 0, 1); + m_renderCommandEncoder.setVertexBuffer(vb.m_ptr, 0, 1); m_renderCommandEncoder.drawIndexedPrimitives( MTLPrimitiveTypeTriangle , _numIndices , MTLIndexTypeUInt16 - , m_indexBuffers[_blitter.m_ib->handle.idx].getBuffer() + , m_indexBuffers[_blitter.m_ib->handle.idx].m_ptr , 0 , 1 ); @@ -1559,7 +1552,7 @@ namespace bgfx { namespace mtl const VertexBufferMtl& vb = m_vertexBuffers[_clearQuad.m_vb.idx]; m_renderCommandEncoder.setCullMode(MTLCullModeNone); - m_renderCommandEncoder.setVertexBuffer(vb.getBuffer(), 0, 1); + m_renderCommandEncoder.setVertexBuffer(vb.m_ptr, 0, 1); m_renderCommandEncoder.drawPrimitives(MTLPrimitiveTypeTriangleStrip, 0, 4, 1); } @@ -2207,6 +2200,8 @@ namespace bgfx { namespace mtl { if (NULL == m_blitCommandEncoder) { + endEncoding(); + if (NULL == m_commandBuffer) { m_commandBuffer = m_cmd.alloc(); @@ -2232,6 +2227,11 @@ namespace bgfx { namespace mtl m_computeCommandEncoder = 0; } + if (0 != m_blitCommandEncoder) + { + m_blitCommandEncoder.endEncoding(); + m_blitCommandEncoder = 0; + } } Device m_device; @@ -2484,58 +2484,46 @@ namespace bgfx { namespace mtl void BufferMtl::create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride, bool _vertex) { - BX_UNUSED(_stride, _vertex); - + BX_UNUSED(_stride); + m_size = _size; m_flags = _flags; - m_dynamic = (NULL == _data); + m_vertex = _vertex; if (NULL == _data) { - for (uint32_t ii = 0; ii < MTL_MAX_FRAMES_IN_FLIGHT; ++ii) - { - m_buffers[ii] = s_renderMtl->m_device.newBufferWithLength(_size, 0); - } + m_ptr = s_renderMtl->m_device.newBufferWithLength(_size, 0); } else { - m_buffers[0] = s_renderMtl->m_device.newBufferWithBytes(_data, _size, 0); + m_ptr = s_renderMtl->m_device.newBufferWithBytes(_data, _size, 0); } } void BufferMtl::update(uint32_t _offset, uint32_t _size, void* _data, bool _discard) { - BX_UNUSED(_discard); + BlitCommandEncoder bce = s_renderMtl->getBlitCommandEncoder(); - if (m_dynamic - && _discard) + if (!m_vertex && !_discard) { - m_bufferIndex = (m_bufferIndex + 1) % MTL_MAX_FRAMES_IN_FLIGHT; - bx::memCopy( (uint8_t*)getBuffer().contents() + _offset, _data, _size); - } - else if (NULL != s_renderMtl->m_renderCommandEncoder) - { - s_renderMtl->m_cmd.release(m_buffers[m_bufferIndex]); + if ( m_dynamic == NULL ) + { + m_dynamic = (uint8_t*)BX_ALLOC(g_allocator, m_size); + } - if (_offset == 0 - && _size == m_size) - { - m_buffers[m_bufferIndex] = s_renderMtl->m_device.newBufferWithBytes(_data, _size, 0); - } - else - { - const void* oldContent = m_buffers[m_bufferIndex].contents(); - m_buffers[m_bufferIndex] = s_renderMtl->m_device.newBufferWithBytes(oldContent, m_size, 0); - bx::memCopy( (uint8_t*)m_buffers[m_bufferIndex].contents() + _offset, _data, _size); - } + bx::memCopy(m_dynamic + _offset, _data, _size); + uint32_t start = _offset & 4; + uint32_t end = bx::strideAlign(_offset + _size, 4); + + Buffer temp = s_renderMtl->m_device.newBufferWithBytes(m_dynamic, end - start, 0); + bce.copyFromBuffer(temp, 0, m_ptr, start, end - start); + s_renderMtl->m_cmd.release(temp); } else { - BlitCommandEncoder bce = s_renderMtl->getBlitCommandEncoder(); - Buffer temp = s_renderMtl->m_device.newBufferWithBytes(_data, _size, 0); - bce.copyFromBuffer(temp, 0, getBuffer(), _offset, _size); - release(temp); + bce.copyFromBuffer(temp, 0, m_ptr, _offset, _size); + s_renderMtl->m_cmd.release(temp); } } @@ -3570,13 +3558,13 @@ namespace bgfx { namespace mtl if (0 < _render->m_iboffset) { TransientIndexBuffer* ib = _render->m_transientIb; - m_indexBuffers[ib->handle.idx].update(0, _render->m_iboffset, ib->data, true); + m_indexBuffers[ib->handle.idx].update(0, bx::strideAlign(_render->m_iboffset,4), ib->data, true); } if (0 < _render->m_vboffset) { TransientVertexBuffer* vb = _render->m_transientVb; - m_vertexBuffers[vb->handle.idx].update(0, _render->m_vboffset, vb->data, true); + m_vertexBuffers[vb->handle.idx].update(0, bx::strideAlign(_render->m_vboffset,4), vb->data, true); } _render->sort(); @@ -3934,7 +3922,7 @@ namespace bgfx { namespace mtl ? m_indexBuffers[bind.m_idx] : m_vertexBuffers[bind.m_idx] ; - m_computeCommandEncoder.setBuffer(buffer.getBuffer(), 0, stage + 1); + m_computeCommandEncoder.setBuffer(buffer.m_ptr, 0, stage + 1); } break; } @@ -3955,7 +3943,7 @@ namespace bgfx { namespace mtl uint32_t args = compute.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE; for (uint32_t ii = 0; ii < numDrawIndirect; ++ii) { - m_computeCommandEncoder.dispatchThreadgroupsWithIndirectBuffer(vb.getBuffer(), args, threadsPerGroup); + m_computeCommandEncoder.dispatchThreadgroupsWithIndirectBuffer(vb.m_ptr, args, threadsPerGroup); args += BGFX_CONFIG_DRAW_INDIRECT_STRIDE; } } @@ -4174,7 +4162,7 @@ namespace bgfx { namespace mtl ); const uint32_t offset = draw.m_stream[idx].m_startVertex * stride; - rce.setVertexBuffer(vb.getBuffer(), offset, idx+1); + rce.setVertexBuffer(vb.m_ptr, offset, idx+1); } currentState.m_numVertices = numVertices; @@ -4212,7 +4200,7 @@ namespace bgfx { namespace mtl if (isValid(draw.m_instanceDataBuffer) ) { const VertexBufferMtl& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx]; - rce.setVertexBuffer(inst.getBuffer(), draw.m_instanceDataOffset, numStreams+1); + rce.setVertexBuffer(inst.m_ptr, draw.m_instanceDataOffset, numStreams+1); } programChanged = @@ -4327,7 +4315,7 @@ namespace bgfx { namespace mtl for (uint32_t ii = 0; ii < numDrawIndirect; ++ii) { - rce.drawIndexedPrimitives(prim.m_type,indexType, ib.getBuffer(), 0, vb.getBuffer(), (draw.m_startIndirect + ii )* BGFX_CONFIG_DRAW_INDIRECT_STRIDE); + rce.drawIndexedPrimitives(prim.m_type,indexType, ib.m_ptr, 0, vb.m_ptr, (draw.m_startIndirect + ii )* BGFX_CONFIG_DRAW_INDIRECT_STRIDE); } } else @@ -4338,7 +4326,7 @@ namespace bgfx { namespace mtl ; for (uint32_t ii = 0; ii < numDrawIndirect; ++ii) { - rce.drawPrimitives(prim.m_type,vb.getBuffer(), (draw.m_startIndirect + ii) * BGFX_CONFIG_DRAW_INDIRECT_STRIDE); + rce.drawPrimitives(prim.m_type,vb.m_ptr, (draw.m_startIndirect + ii) * BGFX_CONFIG_DRAW_INDIRECT_STRIDE); } } } @@ -4357,7 +4345,7 @@ namespace bgfx { namespace mtl numInstances = draw.m_numInstances; numPrimsRendered = numPrimsSubmitted*draw.m_numInstances; - rce.drawIndexedPrimitives(prim.m_type, numIndices, indexType, ib.getBuffer(), 0, draw.m_numInstances); + rce.drawIndexedPrimitives(prim.m_type, numIndices, indexType, ib.m_ptr, 0, draw.m_numInstances); } else if (prim.m_min <= draw.m_numIndices) { @@ -4367,7 +4355,7 @@ namespace bgfx { namespace mtl numInstances = draw.m_numInstances; numPrimsRendered = numPrimsSubmitted*draw.m_numInstances; - rce.drawIndexedPrimitives(prim.m_type, numIndices, indexType, ib.getBuffer(), draw.m_startIndex * indexSize,numInstances); + rce.drawIndexedPrimitives(prim.m_type, numIndices, indexType, ib.m_ptr, draw.m_startIndex * indexSize,numInstances); } } else