{"record":{"id":"021d2af078b554d3","repo":"stride3d/stride","slug":"size-needs-to-be-a-multiple-of-constant-buffer-alignment","errorCode":null,"errorMessage":"size needs to be a multiple of constant buffer alignment ({constantBufferAlignment})","messagePattern":"size needs to be a multiple of constant buffer alignment \\((.+?)\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/BufferPool.cs","lineNumber":34,"sourceCode":"        private const bool UseBufferOffsets = false;\n#endif\n\n        private readonly int constantBufferAlignment;\n        public int Size;\n        public IntPtr Data;\n\n        private readonly GraphicsResourceAllocator allocator;\n        private Buffer constantBuffer;\n        private MappedResource mappedConstantBuffer;\n        private CommandList commandList;\n\n        private int bufferAllocationOffset;\n\n        internal BufferPool(GraphicsResourceAllocator allocator, GraphicsDevice graphicsDevice, int size)\n        {\n            constantBufferAlignment = graphicsDevice.ConstantBufferDataPlacementAlignment;\n            if (size % constantBufferAlignment != 0)\n                throw new ArgumentException($\"size needs to be a multiple of constant buffer alignment ({constantBufferAlignment})\", nameof(size));\n\n            this.allocator = allocator;\n\n            Size = size;\n\n#pragma warning disable 162 // Unreachable code detected\n            if (!UseBufferOffsets)\n                Data = Marshal.AllocHGlobal(size);\n#pragma warning disable 162 // Unreachable code detected\n\n            Reset();\n        }\n\n        public static BufferPool New(GraphicsResourceAllocator allocator, GraphicsDevice graphicsDevice, int size)\n        {\n            return new BufferPool(allocator, graphicsDevice, size);\n        }\n","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/BufferPool.cs#L16-L52","documentation":"BufferPool's internal constructor validates that the pool size is a multiple of the device's ConstantBufferDataPlacementAlignment, because buffers are carved into constant-buffer allocations at that alignment. A size that isn't a multiple would desynchronize the allocation offsets. Note the parameter is internal, so users usually hit this indirectly.","triggerScenarios":"Constructing (internally) a BufferPool with a size not divisible by graphicsDevice.ConstantBufferDataPlacementAlignment (commonly 16 or 256 bytes); platform changes (e.g. different GPU/vendor alignment) invalidating a hardcoded size.","commonSituations":"Code that hardcodes a pool size like 4096 on a device whose alignment is 256 is fine, but 4100 fails; per-platform alignment differences between desktop and mobile.","solutions":["Round the requested size up to the next multiple of graphicsDevice.ConstantBufferDataPlacementAlignment.","Compute sizes from the alignment instead of hardcoding them.","If you hit this via Stride internals, update Stride — historical versions had such issues in profiler/recorder code paths."],"exampleFix":"// before\nvar poolSize = 4100;\nnew BufferPool(allocator, device, poolSize); // throws\n// after\nvar align = device.ConstantBufferDataPlacementAlignment;\nvar poolSize = (4100 + align - 1) / align * align;","handlingStrategy":"validation","validationCode":"int align = device.ConstantBufferDataPlacementAlignment;\nsize = (size + align - 1) / align * align; // round up before constructing","typeGuard":"bool IsAlignedSize(int size, int alignment) => size % alignment == 0;","tryCatchPattern":"try { pool = new BufferPool(allocator, device, size); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"multiple of constant buffer alignment\"))\n{\n    var a = device.ConstantBufferDataPlacementAlignment;\n    pool = new BufferPool(allocator, device, (size + a - 1) / a * a);\n}","preventionTips":["Always derive sizes from ConstantBufferDataPlacementAlignment.","Never hardcode pool sizes.","Test on all target platforms whose alignment may differ."],"tags":["graphics","buffer","alignment","argument-validation"],"backgroundTag":"invalid-argument-value","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"}