metal: fixed render target support.
authorRyan C. Gordon <icculus@icculus.org>
Sat, 09 Dec 2017 03:28:23 -0500
changeset 11750e2a349c9dd30
parent 11749 799404c93d48
child 11751 f5a8e41ac249
metal: fixed render target support.
src/render/metal/SDL_render_metal.m
     1.1 --- a/src/render/metal/SDL_render_metal.m	Sat Dec 09 03:27:52 2017 -0500
     1.2 +++ b/src/render/metal/SDL_render_metal.m	Sat Dec 09 03:28:23 2017 -0500
     1.3 @@ -359,7 +359,7 @@
     1.4          data.mtlpassdesc.colorAttachments[0].loadAction = MTLLoadActionDontCare;
     1.5          data.mtlcmdbuffer = [data.mtlcmdqueue commandBuffer];
     1.6          data.mtlcmdencoder = [data.mtlcmdbuffer renderCommandEncoderWithDescriptor:data.mtlpassdesc];
     1.7 -        data.mtlcmdencoder.label = @"SDL metal renderer frame";
     1.8 +        data.mtlcmdencoder.label = @"SDL metal renderer start of frame";
     1.9  
    1.10          // Set up our current renderer state for the next frame...
    1.11          METAL_UpdateViewport(renderer);
    1.12 @@ -401,7 +401,15 @@
    1.13  
    1.14      MTLTextureDescriptor *mtltexdesc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:mtlpixfmt
    1.15                                              width:(NSUInteger)texture->w height:(NSUInteger)texture->h mipmapped:NO];
    1.16 -
    1.17 + 
    1.18 +    if (texture->access == SDL_TEXTUREACCESS_TARGET) {
    1.19 +        mtltexdesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
    1.20 +    } else {
    1.21 +        mtltexdesc.usage = MTLTextureUsageShaderRead;
    1.22 +    }
    1.23 +    //mtltexdesc.resourceOptions = MTLResourceCPUCacheModeDefaultCache | MTLResourceStorageModeManaged;
    1.24 +    //mtltexdesc.storageMode = MTLStorageModeManaged;
    1.25 +    
    1.26      id<MTLTexture> mtltexture = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
    1.27      if (mtltexture == nil) {
    1.28          return SDL_SetError("Texture allocation failed");
    1.29 @@ -453,8 +461,22 @@
    1.30  { @autoreleasepool {
    1.31      METAL_ActivateRenderer(renderer);
    1.32      METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
    1.33 -    id<MTLTexture> mtltexture = texture ? (__bridge id<MTLTexture>) texture->driverdata : nil;
    1.34 +
    1.35 +    // commit the current command buffer, so that any work on a render target
    1.36 +    //  will be available to the next one we're about to queue up.
    1.37 +    [data.mtlcmdencoder endEncoding];
    1.38 +    [data.mtlcmdbuffer commit];
    1.39 +
    1.40 +    id<MTLTexture> mtltexture = texture ? (__bridge id<MTLTexture>) texture->driverdata : data.mtlbackbuffer.texture;
    1.41      data.mtlpassdesc.colorAttachments[0].texture = mtltexture;
    1.42 +    // !!! FIXME: this can be MTLLoadActionDontCare for textures (not the backbuffer) if SDL doesn't guarantee the texture contents should survive.
    1.43 +    data.mtlpassdesc.colorAttachments[0].loadAction = MTLLoadActionLoad;
    1.44 +    data.mtlcmdbuffer = [data.mtlcmdqueue commandBuffer];
    1.45 +    data.mtlcmdencoder = [data.mtlcmdbuffer renderCommandEncoderWithDescriptor:data.mtlpassdesc];
    1.46 +    data.mtlcmdencoder.label = texture ? @"SDL metal renderer render texture" : @"SDL metal renderer backbuffer";
    1.47 +
    1.48 +    // The higher level will reset the viewport and scissor after this call returns.
    1.49 +
    1.50      return 0;
    1.51  }}
    1.52  
    1.53 @@ -511,8 +533,8 @@
    1.54  
    1.55      MTLViewport viewport;  // RenderClear ignores the viewport state, though, so reset that.
    1.56      viewport.originX = viewport.originY = 0.0;
    1.57 -    viewport.width = data.mtlbackbuffer.texture.width;
    1.58 -    viewport.height = data.mtlbackbuffer.texture.height;
    1.59 +    viewport.width = data.mtlpassdesc.colorAttachments[0].texture.width;
    1.60 +    viewport.height = data.mtlpassdesc.colorAttachments[0].texture.height;
    1.61      viewport.znear = 0.0;
    1.62      viewport.zfar = 1.0;
    1.63