metal: set max texture size based on device capability.
authorAlex Szpakowski <slime73@gmail.com>
Sun, 07 Jan 2018 22:00:37 -0400
changeset 1182143bba409e6d2
parent 11820 3086a1942192
child 11822 3f32b61fd611
metal: set max texture size based on device capability.
src/render/metal/SDL_render_metal.m
     1.1 --- a/src/render/metal/SDL_render_metal.m	Sun Jan 07 16:57:32 2018 -0400
     1.2 +++ b/src/render/metal/SDL_render_metal.m	Sun Jan 07 22:00:37 2018 -0400
     1.3 @@ -33,6 +33,7 @@
     1.4  #else
     1.5  #include "../../video/uikit/SDL_uikitmetalview.h"
     1.6  #endif
     1.7 +#include <Availability.h>
     1.8  #import <Metal/Metal.h>
     1.9  #import <QuartzCore/CAMetalLayer.h>
    1.10  
    1.11 @@ -88,27 +89,18 @@
    1.12  SDL_RenderDriver METAL_RenderDriver = {
    1.13      METAL_CreateRenderer,
    1.14      {
    1.15 -     "metal",
    1.16 -     (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
    1.17 -     6,
    1.18 -     {
    1.19 -         SDL_PIXELFORMAT_ARGB8888,
    1.20 -         SDL_PIXELFORMAT_ABGR8888,
    1.21 -         SDL_PIXELFORMAT_YV12,
    1.22 -         SDL_PIXELFORMAT_IYUV,
    1.23 -         SDL_PIXELFORMAT_NV12,
    1.24 -         SDL_PIXELFORMAT_NV21
    1.25 -     },
    1.26 -
    1.27 -     // !!! FIXME: how do you query Metal for this?
    1.28 -     // (the weakest GPU supported by Metal on iOS has 4k texture max, and
    1.29 -     //  other models might be 2x or 4x more. On macOS, it's 16k across the
    1.30 -     //  board right now.)
    1.31 -#ifdef __MACOSX__
    1.32 -     16384, 16384
    1.33 -#else
    1.34 -     4096, 4096
    1.35 -#endif
    1.36 +        "metal",
    1.37 +        (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
    1.38 +        6,
    1.39 +        {
    1.40 +            SDL_PIXELFORMAT_ARGB8888,
    1.41 +            SDL_PIXELFORMAT_ABGR8888,
    1.42 +            SDL_PIXELFORMAT_YV12,
    1.43 +            SDL_PIXELFORMAT_IYUV,
    1.44 +            SDL_PIXELFORMAT_NV12,
    1.45 +            SDL_PIXELFORMAT_NV21
    1.46 +        },
    1.47 +    0, 0,
    1.48      }
    1.49  };
    1.50  
    1.51 @@ -467,9 +459,10 @@
    1.52  
    1.53  static SDL_Renderer *
    1.54  METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
    1.55 -{
    1.56 +{ @autoreleasepool {
    1.57      SDL_Renderer *renderer = NULL;
    1.58      METAL_RenderData *data = NULL;
    1.59 +    id<MTLDevice> mtldevice = nil;
    1.60      SDL_SysWMinfo syswm;
    1.61  
    1.62      SDL_VERSION(&syswm.version);
    1.63 @@ -487,24 +480,22 @@
    1.64          return NULL;
    1.65      }
    1.66  
    1.67 +    // !!! FIXME: MTLCopyAllDevices() can find other GPUs on macOS...
    1.68 +    mtldevice = MTLCreateSystemDefaultDevice();
    1.69 +
    1.70 +    if (mtldevice == nil) {
    1.71 +        SDL_free(renderer);
    1.72 +        SDL_SetError("Failed to obtain Metal device");
    1.73 +        return NULL;
    1.74 +    }
    1.75 +
    1.76 +    // !!! FIXME: error checking on all of this.
    1.77      data = [[METAL_RenderData alloc] init];
    1.78  
    1.79      renderer->driverdata = (void*)CFBridgingRetain(data);
    1.80      renderer->window = window;
    1.81  
    1.82  #ifdef __MACOSX__
    1.83 -    id<MTLDevice> mtldevice = MTLCreateSystemDefaultDevice();  // !!! FIXME: MTLCopyAllDevices() can find other GPUs...
    1.84 -    if (mtldevice == nil) {
    1.85 -        SDL_free(renderer);
    1.86 -#if !__has_feature(objc_arc)
    1.87 -        [data release];
    1.88 -#endif
    1.89 -        SDL_SetError("Failed to obtain Metal device");
    1.90 -        return NULL;
    1.91 -    }
    1.92 -
    1.93 -    // !!! FIXME: error checking on all of this.
    1.94 -
    1.95      NSView *view = Cocoa_Mtl_AddMetalView(window);
    1.96      CAMetalLayer *layer = (CAMetalLayer *)[view layer];
    1.97  
    1.98 @@ -657,6 +648,40 @@
    1.99          renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
   1.100      }
   1.101  
   1.102 +    /* https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf */
   1.103 +    int maxtexsize = 4096;
   1.104 +#if defined(__MACOSX__)
   1.105 +    maxtexsize = 16384;
   1.106 +#elif defined(__TVOS__)
   1.107 +#ifdef __TVOS_11_0
   1.108 +    if ([mtldevice supportsFeatureSet:MTLFeatureSet_tvOS_GPUFamily2_v1]) {
   1.109 +        maxtexsize = 16384;
   1.110 +    } else
   1.111 +#endif
   1.112 +    {
   1.113 +        maxtexsize = 8192;
   1.114 +    }
   1.115 +#else
   1.116 +#ifdef __IPHONE_11_0
   1.117 +    if ([mtldevice supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily4_v1]) {
   1.118 +        maxtexsize = 16384;
   1.119 +    } else
   1.120 +#endif
   1.121 +#ifdef __IPHONE_10_0
   1.122 +    if ([mtldevice supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v1]) {
   1.123 +        maxtexsize = 16384;
   1.124 +    } else
   1.125 +#endif
   1.126 +    if ([mtldevice supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v2] || [mtldevice supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v2]) {
   1.127 +        maxtexsize = 8192;
   1.128 +    } else {
   1.129 +        maxtexsize = 4096;
   1.130 +    }
   1.131 +#endif
   1.132 +
   1.133 +    renderer->info.max_texture_width = maxtexsize;
   1.134 +    renderer->info.max_texture_height = maxtexsize;
   1.135 +
   1.136  #if !__has_feature(objc_arc)
   1.137      [mtlcmdqueue release];
   1.138      [mtllibrary release];
   1.139 @@ -666,13 +691,11 @@
   1.140      [mtlbufconstants release];
   1.141      [view release];
   1.142      [data release];
   1.143 -#ifdef __MACOSX__
   1.144      [mtldevice release];
   1.145  #endif
   1.146 -#endif
   1.147  
   1.148      return renderer;
   1.149 -}
   1.150 +}}
   1.151  
   1.152  static void
   1.153  METAL_ActivateRenderCommandEncoder(SDL_Renderer * renderer, MTLLoadAction load)
   1.154 @@ -1297,17 +1320,15 @@
   1.155          float c = cosf(rads), s = sinf(rads);
   1.156          SDL_memset(transform, 0, sizeof(transform));
   1.157  
   1.158 -        // matrix multiplication carried out on paper:
   1.159 -        // |1     x+c| |c -s    |
   1.160 -        // |  1   y+c| |s  c    |
   1.161 -        // |    1    | |     1  |
   1.162 -        // |        1| |       1|
   1.163 -        //     move      rotate
   1.164          transform[10] = transform[15] = 1.0f;
   1.165 +
   1.166 +        /* Rotation */
   1.167          transform[0]  = c;
   1.168          transform[1]  = s;
   1.169          transform[4]  = -s;
   1.170          transform[5]  = c;
   1.171 +
   1.172 +        /* Translation */
   1.173          transform[12] = dstrect->x + center->x;
   1.174          transform[13] = dstrect->y + center->y;
   1.175      }