GraphicsBuffer LockBufferForWrite

Hey everyone, I’ve been trying to figure out how to correctly use the graphics buffer LockBufferForWrite as well as UnlockBufferAfterWrite, I’ve been reading the documentation and I’m following everything it says to do, only calling each function one time per frame yet I’m getting the error

LockBufferForWrite: Multiple uploads in flight for buffer 0000022E24D608B8 (bufferHandle: 6372) of size 160016.
Falling back to slow path.
LockBufferForWrite() should not be called while a buffer has pending/active D3D11 commands - note that these commands can span multiple frames.
If you need to write to a buffer once per frame, consider utilizing double or triple buffering, cycling the target buffer each frame.

The QualitySettings.MaxQueuedFrames is set to 2, and I’ve tried using up to 6 buffers in my script in order to try and avoid that message to no avail

Here’s the code I’m using in order to write directly to the graphics buffer.
The JobHandle has Complete called on it after it returns it and before the PostManualUpdate is called. If anyone has any ideas I’d really appreciate some help since I’ve been stuck on this for a few days now.

private JobHandle CreateProceduralLineMeshThreaded()
 {

     GenerateVertices verts = new GenerateVertices();
     verts.points = points;
     verts.vertices = vertexBuffer[currentBuffer].LockBufferForWrite<float2>(0, (pointCount - 1) * 2);
     verts.halfThickness = thickness / 2f;
     verts.scale = new float2(transform.localScale.x, transform.localScale.y);
     JobHandle handle = verts.Schedule(pointCount - 1, 32);

     GenerateTriangles tris = new GenerateTriangles();
     tris.vertices = verts.vertices;
     tris.indices = trisBuffer[currentBuffer].LockBufferForWrite<int>(0, ((pointCount * 2) - 6) * 3);// pointCount * 6);
     JobHandle handleTwo = tris.Schedule((pointCount * 2) - 6, 16, handle);

     return handleTwo;

 }
public void PostManualUpdate()
    {

        Profiler.BeginSample("Set Mesh Data");

        vertexBuffer[currentBuffer].UnlockBufferAfterWrite<float2>((pointCount - 1) * 2);// (pointCount * 2);
        trisBuffer[currentBuffer].UnlockBufferAfterWrite<int>(((pointCount * 2) - 6) * 3);// (pointCount * 6);

        Profiler.EndSample();

        //Graphics.RenderMesh(in rParams, mesh, 0, Matrix4x4.TRS(transform.position, transform.rotation, transform.localScale));
        rp = new RenderParams(new Material(Shader.Find("Unlit/CustomUnlitLine")));
        rp.worldBounds = new Bounds(transform.position, new Vector3(100, 100, 25)); // use tighter bounds
        rp.shadowCastingMode = ShadowCastingMode.Off;
        rp.receiveShadows = false;

        rp.matProps = new MaterialPropertyBlock();
        rp.layer = gameObject.layer;

        rp.matProps.SetBuffer("Positions", vertexBuffer[currentBuffer]);
        rp.matProps.SetMatrix("ObjectToWorld", Matrix4x4.Translate(transform.position));
        rp.matProps.SetColor("lineColor", color);

        commandData[0].indexCountPerInstance = (uint)(((pointCount * 2) - 6) * 3);
        commandData[0].baseVertexIndex = 0;
        commandData[0].startIndex = 0;
        commandData[0].instanceCount = 1;
        commandBuf[currentBuffer].SetData(commandData);

        Graphics.RenderPrimitivesIndexedIndirect(in rp, MeshTopology.Triangles, trisBuffer[currentBuffer], commandBuf[currentBuffer]);

        currentBuffer++;

        if (currentBuffer >= bufferCount)
        {
            currentBuffer = 0;
        }

    }

I’m attempting a similar thing with similar results. Except for me I only see a few logs of those every so often, which matches their message that sometimes commands can span many frames.

However my issue is that as soon as I use the buffers to directly reference GPU memory I see a horrible cost in the CPU waiting on the GPU

Have you guys ever solved this problem. LockBufferForWrite documentation is not helping much.

I also got a little problem with the error itself:

If you need to write to a buffer once per frame, consider utilizing double or triple buffering, cycling the target buffer each frame.

What If I’m writing more than once per frame ? I don’t need to utilize more buffers ? :wink:

Should it be not

If you need to write to a buffer during every frame

If you are writing more than once per frame you are doing something wrong.

What this means is that you write to the CPU copy as many times as you like, but you should only upload to the GPU once per frame as a max.

Btw one thing I noticed since implmenting this is that performance is great for D3D12 but its significantly slower for 11. Anyone noticed the same?