Reduce duplicate GPU buffer uploads (#3577)

Co-authored-by: “Malcolm <“mtoon@atlasprogramming.com”>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
AtlasProgramming
2025-06-25 16:09:11 -04:00
committed by GitHub
parent 753b7ae795
commit 779b893468
4 changed files with 24 additions and 3 deletions

View File

@@ -103,15 +103,22 @@ void BufferResource::update(const void* newData, std::size_t updateSize, std::si
// Until we can be sure that the buffer is not still in use to render the
// previous frame, replace it with a new buffer instead of updating it.
auto& device = context.getBackend().getDevice();
const uint8_t* newBufferSource = nullptr;
std::unique_ptr<uint8_t[]> tempBuffer;
const bool updateIsEntireBuffer = (offset == 0 && updateSize == size);
// If the entire buffer is being updated, make sure it's changed
if (updateIsEntireBuffer) {
if (memcmp(buffer->contents(), newData, updateSize) == 0) {
return;
}
}
auto& device = context.getBackend().getDevice();
// `[MTLBuffer contents]` may involve memory mapping and/or synchronization. If the entire
// buffer is being replaced, avoid accessing the old one by creating the new buffer directly
// from the given data. If it's just being updated, apply the update to a local buffer to
// avoid needing to access the new buffer.
const bool updateIsEntireBuffer = (offset == 0 && updateSize == size);
if (updateIsEntireBuffer) {
newBufferSource = static_cast<const uint8_t*>(newData);
} else {

View File

@@ -223,7 +223,7 @@ void Drawable::draw(PaintParameters& parameters) const {
mbgl::util::hash(getColorMode().hash(), impl->vertexDescHash));
}
if (impl->pipelineState) {
encoder->setRenderPipelineState(impl->pipelineState.get());
renderPass.setRenderPipelineState(impl->pipelineState);
} else {
assert(!"Failed to create render pipeline state");
return;

View File

@@ -66,6 +66,7 @@ void RenderPass::endEncoding() {
}
void RenderPass::resetState() {
currentPipelineState.reset();
currentDepthStencilState.reset();
currentStencilReferenceValue = 0;
for (int i = 0; i < maxBinds; ++i) {
@@ -193,6 +194,14 @@ void RenderPass::setFragmentSamplerState(const MTLSamplerStatePtr& state, int32_
}
}
/// Set the render pipeline state
void RenderPass::setRenderPipelineState(const MTLRenderPipelineStatePtr& pipelineState) {
if (pipelineState != currentPipelineState) {
currentPipelineState = pipelineState;
encoder->setRenderPipelineState(currentPipelineState.get());
}
}
void RenderPass::setCullMode(const MTL::CullMode mode) {
if (mode != currentCullMode) {
encoder->setCullMode(mode);