buffer update with blit

This commit is contained in:
Attila Kocsis 2019-02-09 20:55:23 +01:00
parent c309921a1a
commit 08894e1422
2 changed files with 131 additions and 145 deletions

View File

@ -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;

View File

@ -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