mirror of
https://github.com/love2d/love.git
synced 2026-08-16 08:11:02 +02:00
Add sync and async texture and buffer readback APIs.
- Add imagedata = love.graphics.readbackTexture(texture, [slice, mipmap, x, y, w, h, [dest, destx, desty]]). - Add readback = love.graphics.readbackTextureAsync(texture, [slice, mipmap, x, y, w, h, [dest, destx, desty]]). - Add bytedata = love.graphics.readbackBuffer(buffer, [offset, size, [dest, destoffset]]). - Add readback = ove.graphics.readbackBufferAsync(buffer, [offset, size, [dest, destoffset]]). - Deprecate Texture:newImageData. The async variants return a new GraphicsReadback object. It has the following methods: - isComplete() - hasError() - wait() - getBufferData() - getImageData() - update() (called automatically every frame by love, not normally needed). Support notes: - readbackBuffer and readbackBufferAsync require buffer copying support. - readbackTexture with a render target (canvas) is always supported. readbackTexture with a non-render-target requires copy-texture-to-buffer support. - readbackTextureAsync with a render target requires copy-render-target-to-buffer support. readbackTextureAsync with a non-render-target requires copy-texture-to-buffer support.
This commit is contained in:
@@ -273,52 +273,6 @@ void Texture::generateMipmapsInternal()
|
||||
[encoder generateMipmapsForTexture:texture];
|
||||
}}
|
||||
|
||||
void Texture::readbackImageData(love::image::ImageData *imagedata, int slice, int mipmap, const Rect &rect)
|
||||
{ @autoreleasepool {
|
||||
auto gfx = Graphics::getInstance();
|
||||
|
||||
id<MTLBlitCommandEncoder> encoder = gfx->useBlitEncoder();
|
||||
|
||||
size_t rowSize = 0;
|
||||
if (isCompressed())
|
||||
rowSize = getPixelFormatCompressedBlockRowSize(format, rect.w);
|
||||
else
|
||||
rowSize = getPixelFormatUncompressedRowSize(format, rect.w);
|
||||
|
||||
// TODO: Verify this is correct for compressed formats at small sizes.
|
||||
// TODO: make sure this is consistent with the imagedata byte size?
|
||||
size_t sliceSize = getPixelFormatSliceSize(format, rect.w, rect.h);
|
||||
|
||||
int z = texType == TEXTURE_VOLUME ? slice : 0;
|
||||
|
||||
id<MTLBuffer> buffer = [gfx->device newBufferWithLength:sliceSize
|
||||
options:MTLResourceStorageModeShared];
|
||||
|
||||
MTLBlitOption options = MTLBlitOptionNone;
|
||||
if (isPixelFormatDepthStencil(format))
|
||||
options = MTLBlitOptionDepthFromDepthStencil;
|
||||
|
||||
[encoder copyFromTexture:texture
|
||||
sourceSlice:texType == TEXTURE_VOLUME ? 0 : slice
|
||||
sourceLevel:mipmap
|
||||
sourceOrigin:MTLOriginMake(rect.x, rect.y, z)
|
||||
sourceSize:MTLSizeMake(rect.w, rect.h, 1)
|
||||
toBuffer:buffer
|
||||
destinationOffset:0
|
||||
destinationBytesPerRow:rowSize
|
||||
destinationBytesPerImage:sliceSize
|
||||
options:options];
|
||||
|
||||
id<MTLCommandBuffer> cmd = gfx->getCommandBuffer();
|
||||
|
||||
gfx->submitBlitEncoder();
|
||||
gfx->submitCommandBuffer(Graphics::SUBMIT_STORE);
|
||||
|
||||
[cmd waitUntilCompleted];
|
||||
|
||||
memcpy(imagedata->getData(), buffer.contents, imagedata->getSize());
|
||||
}}
|
||||
|
||||
void Texture::copyFromBuffer(love::graphics::Buffer *source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect &rect)
|
||||
{ @autoreleasepool {
|
||||
id<MTLBlitCommandEncoder> encoder = Graphics::getInstance()->useBlitEncoder();
|
||||
|
||||
Reference in New Issue
Block a user