Skip to content

UpdateBuffer size limit #367

Open
Open

Description

@mingweiLIU

Hi, I am trying to update a big buffer to the GPU with code:

Diligent::BufferDesc desc;
desc.Name = "InstanceBuffer";
desc.Usage = Diligent::USAGE_DYNAMIC;
desc.BindFlags = Diligent::BIND_VERTEX_BUFFER;
desc.CPUAccessFlags = Diligent::CPU_ACCESS_WRITE;
desc.Size = this->capacity * sizeof(InstanceData);
pDevice->CreateBuffer(desc, nullptr, &this->instanceBuffer);
……
Diligent::MapHelper<uint8_t> mapped(pContext, instanceBuffer, Diligent::MAP_WRITE, Diligent::MAP_FLAG_DISCARD);
memcpy(mapped, instanceData.data(), instanceData.size() * sizeof(InstanceData));

Here’s the situation:
The data size I need to upload each frame is about 32 MB (1000 × 1000 × 2 × sizeof(float4x4)). When I run the code, the MapHelper() call fails. I'm using Diligent Engine 2.5.6, and my code is based on the samples (inherited from SampleBase).

The issue only appears when rendering 1000×1000 objects. With 100×100 objects, everything works fine, so the frame seems ok.

  1. With Vulkan backend: the program crashes.
    2 With OpenGL backend: it rendered a mess (but does not crash immediately).
    I also tried increasing DynamicHeapSize to 64 MB in ModifyEngineInitInfo via EngineVkCI.DynamicHeapSize = 64 << 20. After that, it no longer crashes, but rendered a mess.

I’m wondering: Is there a size limitation for dynamic buffers (or the upload buffer) in Diligent? What is the best practice for uploading a large buffer (around 32 MB) to the GPU on a per‑frame basis?

Activity

  1. TheMostDiligent commented on Apr 3, 2026

    @TheMostDiligent
    Contributor

    Dynamic buffers are intended to upload small amounts of data. They are implemented differently in all backends, but in Direct3D11 there is a limit of 64 KB (65536 bytes), which should be used as the guiding limit.
    So dynamic buffers are absolutely not the right way to update large buffers.

    For your use case, you have to use USAGE_DEFAULT buffer. You can update in two ways:

    1. Use UpdateBuffer
    2. Create a USAGE_STAGING buffer, map it, write data and copy to default buffer. Since your buffer is large, this would be the better way as it avoids one copy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions