metal: Implement SDL_LockTexture for non-YUV textures.

This commit is contained in:
Alex Szpakowski 2018-12-18 14:23:05 -04:00
parent c0c8f2d703
commit ce8c716ada
1 changed files with 66 additions and 6 deletions

View File

@ -155,6 +155,9 @@ typedef struct METAL_ShaderPipelines
@property (nonatomic, assign) BOOL nv12; @property (nonatomic, assign) BOOL nv12;
@property (nonatomic, assign) size_t conversionBufferOffset; @property (nonatomic, assign) size_t conversionBufferOffset;
@property (nonatomic, assign) BOOL hasdata; @property (nonatomic, assign) BOOL hasdata;
@property (nonatomic, retain) id<MTLBuffer> lockedbuffer;
@property (nonatomic, assign) SDL_Rect lockedrect;
@end @end
@implementation METAL_TextureData @implementation METAL_TextureData
@ -783,16 +786,73 @@ METAL_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
static int static int
METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, void **pixels, int *pitch) const SDL_Rect * rect, void **pixels, int *pitch)
{ { @autoreleasepool {
return SDL_Unsupported(); // !!! FIXME: write me METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata;
if (texturedata.yuv || texturedata.nv12) {
/* FIXME: write me */
return SDL_Unsupported();
} }
*pitch = SDL_BYTESPERPIXEL(texture->format) * rect->w;
texturedata.lockedrect = *rect;
texturedata.lockedbuffer = [data.mtldevice newBufferWithLength:(*pitch)*rect->h options:MTLResourceStorageModeShared];
if (texturedata.lockedbuffer == nil) {
return SDL_OutOfMemory();
}
*pixels = [texturedata.lockedbuffer contents];
return 0;
}}
static void static void
METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{ { @autoreleasepool {
// !!! FIXME: write me METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata;
SDL_Rect rect = texturedata.lockedrect;
if (texturedata.lockedbuffer == nil) {
return;
} }
if (data.mtlcmdencoder != nil) {
[data.mtlcmdencoder endEncoding];
data.mtlcmdencoder = nil;
}
if (data.mtlcmdbuffer == nil) {
data.mtlcmdbuffer = [data.mtlcmdqueue commandBuffer];
}
id<MTLBlitCommandEncoder> blitcmd = [data.mtlcmdbuffer blitCommandEncoder];
[blitcmd copyFromBuffer:texturedata.lockedbuffer
sourceOffset:0
sourceBytesPerRow:SDL_BYTESPERPIXEL(texture->format) * rect.w
sourceBytesPerImage:0
sourceSize:MTLSizeMake(rect.w, rect.h, 1)
toTexture:texturedata.mtltexture
destinationSlice:0
destinationLevel:0
destinationOrigin:MTLOriginMake(rect.x, rect.y, 0)];
[blitcmd endEncoding];
[data.mtlcmdbuffer commit];
data.mtlcmdbuffer = nil;
#if !__has_feature(objc_arc)
[texturedata.lockedbuffer release];
#endif
texturedata.lockedbuffer = nil;
texturedata.hasdata = YES;
}}
static int static int
METAL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) METAL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
{ @autoreleasepool { { @autoreleasepool {