{"record":{"id":"353bea281c7ee557","repo":"stride3d/stride","slug":"d3d12-staging-buffers-can-t-be-created-with-initial-data","errorCode":null,"errorMessage":"D3D12: Staging buffers can't be created with initial data.","messagePattern":"D3D12: Staging buffers can't be created with initial data\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs","lineNumber":187,"sourceCode":"            if (bufferFlags.HasFlag(BufferFlags.ShaderResource))\n                desiredResourceState |= ResourceStates.PixelShaderResource | ResourceStates.NonPixelShaderResource;\n\n            if (bufferFlags.HasFlag(BufferFlags.StructuredBuffer))\n            {\n                if (bufferDescription.StructureByteStride <= 0)\n                    throw new ArgumentException(\"Element size cannot be less or equal 0 for structured buffer\");\n            }\n\n            if (bufferFlags.HasFlag(BufferFlags.ArgumentBuffer))\n                desiredResourceState |= ResourceStates.IndirectArgument;\n\n            var heapType = HeapType.Default;\n            IsHostVisibleHeap = false;\n            if (Usage == GraphicsResourceUsage.Staging)\n            {\n                // Per our own definition of staging resource (read-back only)\n                if (hasInitData)\n                    throw new InvalidOperationException(\"D3D12: Staging buffers can't be created with initial data.\");\n\n                heapType = HeapType.Readback;\n                desiredResourceState = ResourceStates.CopyDest;\n                IsHostVisibleHeap = true;\n            }\n            else if (Usage == GraphicsResourceUsage.Dynamic)\n            {\n                heapType = HeapType.Upload;\n                desiredResourceState = ResourceStates.GenericRead;\n                IsHostVisibleHeap = true;\n            }\n\n            // TODO: D3D12: Move to a global allocator in bigger committed resources\n            var heap = new HeapProperties { Type = heapType };\n\n            var initialResourceState = heapType != HeapType.Default ? desiredResourceState : ResourceStates.Common;\n\n            // If the resource must be initialized with data, it is initially in the state","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs#L169-L205","documentation":"Thrown in Buffer.Recreate on D3D12 when a buffer with GraphicsResourceUsage.Staging is created together with initial data. Stride defines staging resources as read-back only (HeapType.Readback with CopyDest state), so providing initData contradicts that contract and the library throws InvalidOperationException.","triggerScenarios":"Calling Buffer.New / setData-style constructors with Usage = GraphicsResourceUsage.Staging and non-empty init data, e.g. new Buffer(device, initialBytes, size, BufferFlags.None, GraphicsResourceUsage.Staging).","commonSituations":"Trying to pre-fill a read-back/staging buffer instead of creating an upload buffer, porting D3D11 code where staging with initial data was tolerated, or writing a GPU-readback helper that also seeds the buffer.","solutions":["Create the staging buffer without initial data and use a Copy staging/upload pattern: copy from a Default/Upload buffer, then read back.","Switch Usage to Dynamic or Default if you need the buffer pre-populated with data.","If data must start on the GPU, create an upload buffer with the data and CopyResource/CopyBufferRegion into the read-back buffer."],"exampleFix":"// before\nvar buf = new Buffer(device, initData, size, BufferFlags.None, GraphicsResourceUsage.Staging);\n// after\nvar buf = new Buffer(device, size, BufferFlags.None, GraphicsResourceUsage.Staging); // then CopyCommandList.Copy into it","handlingStrategy":"validation","validationCode":"if (usage == GraphicsResourceUsage.Staging && hasInitData)\n    throw new InvalidOperationException(\"Staging buffers are read-back only; do not pass initial data.\");","typeGuard":"static bool IsStagingWithInitData(Buffer b, bool hasInitData) => b.Usage == GraphicsResourceUsage.Staging && hasInitData;","tryCatchPattern":"try { buf = new Buffer(device, initData, size, flags, GraphicsResourceUsage.Staging); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Staging\")) { buf = new Buffer(device, size, flags, GraphicsResourceUsage.Staging); }","preventionTips":["Treat Staging buffers as read-back only; seed data via a separate upload/Default buffer plus Copy.","Use Dynamic or Default usage whenever initial data is required.","Centralize buffer creation so usage/init-data combinations are checked in one place."],"tags":["graphics","direct3d12","buffer","staging","invalid-usage"],"backgroundTag":"conflicting-config-options","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}