{"record":{"id":"ac82e15676feb3ff","repo":"stride3d/stride","slug":"the-length-of-the-destination-buffer-destlengthinbytes-bytes","errorCode":null,"errorMessage":"The length of the destination buffer ({destLengthInBytes} bytes) is not compatible with the expected largestSize ({mipMapSize} bytes) : Width * Height * Depth * sizeof(Format) largestSize in bytes","messagePattern":"The length of the destination buffer \\((.+?) bytes\\) is not compatible with the expected largestSize \\((.+?) bytes\\) : Width \\* Height \\* Depth \\* sizeof\\(Format\\) largestSize in bytes","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/Texture.cs","lineNumber":1249,"sourceCode":"        ///   at <paramref name=\"arrayIndex\"/> and <paramref name=\"mipLevel\"/>.\n        /// </exception>\n        public unsafe bool GetData<T>(CommandList commandList, Texture stagingTexture, Span<T> toData, int arrayIndex = 0, int mipLevel = 0, bool doNotWait = false) where T : unmanaged\n        {\n            ArgumentNullException.ThrowIfNull(stagingTexture);\n\n            // Get a description for the specified mip-level\n            ref readonly var mipmap = ref GetMipMapDescription(mipLevel);\n\n            int height = mipmap.HeightPacked;\n            int depth = mipmap.Depth;\n            int rowStride = mipmap.RowStride;\n            int textureDepthStride = mipmap.DepthStride;\n            int mipMapSize = mipmap.MipmapSize;\n\n            int destLengthInBytes = toData.Length * sizeof(T);\n\n            if (destLengthInBytes > mipMapSize)\n                throw new ArgumentException($\"The length of the destination buffer ({destLengthInBytes} bytes) is not compatible with \" +\n                    $\"the expected largestSize ({mipMapSize} bytes) : Width * Height * Depth * sizeof(Format) largestSize in bytes\");\n\n            // Copy the actual content of the texture to the staging Resource\n            if (!ReferenceEquals(this, stagingTexture))\n                commandList.Copy(this, stagingTexture);\n\n            int subResourceIndex = GetSubResourceIndex(arrayIndex, mipLevel);\n\n            // Map the staging Resource to CPU-accessible memory\n            var mappedResource = commandList.MapSubResource(stagingTexture, subResourceIndex, MapMode.Read, doNotWait);\n\n            // Box can be empty if `doNotWait` is true: Return false if empty\n            var box = mappedResource.DataBox;\n            if (box.IsEmpty)\n                return false;\n\n            // If depth == 1 (like for 1D, 2D, or Cube), then depthStride is not used\n            var boxDepthStride = Depth == 1 ? box.SlicePitch : textureDepthStride;","sourceCodeStart":1231,"sourceCodeEnd":1267,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/Texture.cs#L1231-L1267","documentation":"When reading texture data back (the GetData path copying from a staging texture), the destination buffer in bytes must not exceed the mip level's total size (Width * Height * Depth * sizeof(Format), i.e. MipmapSize). ArgumentException is thrown when destLengthInBytes > mipMapSize, meaning the buffer cannot correspond to this mip level.","triggerScenarios":"Calling GetData with a destination array larger than the mip level's MipmapSize (e.g. reusing a buffer sized for mip 0 to read mip 2, or an oversized generic scratch array).","commonSituations":"Reading individual mip levels into a shared scratch buffer sized for the largest mip; CPU readback of textures whose format size was estimated incorrectly.","solutions":["Allocate the destination buffer for the requested mip: width*height*depth * Format.SizeInBytes bytes.","Pass the correct mipLevel so mipMapSize matches the buffer you provide.","Slice a larger scratch buffer to the exact mip size before calling GetData."],"exampleFix":"// before\nvar big = new byte[width * height * 4]; // sized for mip 0\ntexture.GetData(commandList, big, mipLevel: 2); // throws: too large for mip 2\n// after\nvar mip = texture.GetMipMapDescription(2);\nvar buf = new byte[mip.Width * mip.Height * mip.Depth * texture.Format.SizeInBytes];\ntexture.GetData(commandList, buf, mipLevel: 2);","handlingStrategy":"validation","validationCode":"var mip = texture.GetMipMapDescription(mipLevel);\nint required = mip.MipmapSize;\nint provided = dest.Length * sizeof(T);\nif (provided > required)\n    throw new InvalidOperationException($\"Dest buffer {provided}B exceeds mip size {required}B\");","typeGuard":"static bool BufferFitsMip<T>(Texture t, T[] buf, int mipLevel) where T : unmanaged => buf.Length * sizeof(T) <= t.GetMipMapDescription(mipLevel).MipmapSize;","tryCatchPattern":"try { texture.GetData(commandList, dest, mipLevel: lvl); }\ncatch (ArgumentException ex)\n{\n    logger.LogError(ex, \"Buffer {Len}B incompatible with mip {Mip}\", dest.Length * sizeof(byte), lvl);\n    throw;\n}","preventionTips":["Size readback buffers from GetMipMapDescription(mipLevel).MipmapSize.","Slice shared scratch buffers to the exact mip size.","Unit-test readback per mip level."],"tags":["graphics","stride","readback","buffer-size"],"backgroundTag":"shape-mismatch","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}