1/* 2 * Copyright 2017 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "GrMtlGpu.h" 9 10#include "GrMtlTexture.h" 11 12#if !__has_feature(objc_arc) 13#error This file must be compiled with Arc. Use -fobjc-arc flag 14#endif 15 16static bool get_feature_set(id<MTLDevice> device, MTLFeatureSet* featureSet) { 17 // Mac OSX 18#ifdef SK_BUILD_FOR_MAC 19 if ([device supportsFeatureSet:MTLFeatureSet_OSX_GPUFamily1_v2]) { 20 *featureSet = MTLFeatureSet_OSX_GPUFamily1_v2; 21 return true; 22 } 23 if ([device supportsFeatureSet:MTLFeatureSet_OSX_GPUFamily1_v1]) { 24 *featureSet = MTLFeatureSet_OSX_GPUFamily1_v1; 25 return true; 26 } 27#endif 28 29 // iOS Family group 3 30#ifdef SK_BUILD_FOR_IOS 31 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v2]) { 32 *featureSet = MTLFeatureSet_iOS_GPUFamily3_v2; 33 return true; 34 } 35 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily3_v1]) { 36 *featureSet = MTLFeatureSet_iOS_GPUFamily3_v1; 37 return true; 38 } 39 40 // iOS Family group 2 41 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v3]) { 42 *featureSet = MTLFeatureSet_iOS_GPUFamily2_v3; 43 return true; 44 } 45 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v2]) { 46 *featureSet = MTLFeatureSet_iOS_GPUFamily2_v2; 47 return true; 48 } 49 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily2_v1]) { 50 *featureSet = MTLFeatureSet_iOS_GPUFamily2_v1; 51 return true; 52 } 53 54 // iOS Family group 1 55 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v3]) { 56 *featureSet = MTLFeatureSet_iOS_GPUFamily1_v3; 57 return true; 58 } 59 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v2]) { 60 *featureSet = MTLFeatureSet_iOS_GPUFamily1_v2; 61 return true; 62 } 63 if ([device supportsFeatureSet:MTLFeatureSet_iOS_GPUFamily1_v1]) { 64 *featureSet = MTLFeatureSet_iOS_GPUFamily1_v1; 65 return true; 66 } 67#endif 68 // No supported feature sets were found 69 return false; 70} 71 72sk_sp<GrGpu> GrMtlGpu::Make(GrContext* context, const GrContextOptions& options, 73 id<MTLDevice> device, id<MTLCommandQueue> queue) { 74 if (!device || !queue) { 75 return nullptr; 76 } 77 MTLFeatureSet featureSet; 78 if (!get_feature_set(device, &featureSet)) { 79 return nullptr; 80 } 81 return sk_sp<GrGpu>(new GrMtlGpu(context, options, device, queue, featureSet)); 82} 83 84GrMtlGpu::GrMtlGpu(GrContext* context, const GrContextOptions& options, 85 id<MTLDevice> device, id<MTLCommandQueue> queue, MTLFeatureSet featureSet) 86 : INHERITED(context) 87 , fDevice(device) 88 , fQueue(queue) { 89 90 fMtlCaps.reset(new GrMtlCaps(options, fDevice, featureSet)); 91 fCaps = fMtlCaps; 92 93 MTLTextureDescriptor* txDesc = [[MTLTextureDescriptor alloc] init]; 94 txDesc.textureType = MTLTextureType3D; 95 txDesc.height = 64; 96 txDesc.width = 64; 97 txDesc.depth = 64; 98 txDesc.pixelFormat = MTLPixelFormatRGBA8Unorm; 99 txDesc.arrayLength = 1; 100 txDesc.mipmapLevelCount = 1; 101 id<MTLTexture> testTexture = [fDevice newTextureWithDescriptor:txDesc]; 102 // To get ride of unused var warning 103 int width = [testTexture width]; 104 SkDebugf("width: %d\n", width); 105 // Unused queue warning fix 106 SkDebugf("ptr to queue: %p\n", fQueue); 107} 108 109sk_sp<GrTexture> GrMtlGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, 110 const GrMipLevel texels[], int mipLevelCount) { 111 int mipLevels = !mipLevelCount ? 1 : mipLevelCount; 112 113 if (!fMtlCaps->isConfigTexturable(desc.fConfig)) { 114 return nullptr; 115 } 116 117 bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag); 118 if (renderTarget) { 119 // Current we don't have render target support 120 return nullptr; 121 } 122 123 sk_sp<GrMtlTexture> tex; 124 if (renderTarget) { 125 // Enable once we have render target support 126#if 0 127 tex = GrMtlTextureRenderTarget::CreateNewTextureRenderTarget(this, budgeted, 128 desc, mipLevels); 129#endif 130 } else { 131 tex = GrMtlTexture::CreateNewTexture(this, budgeted, desc, mipLevels); 132 } 133 134 if (!tex) { 135 return nullptr; 136 } 137 138 if (mipLevelCount) { 139 // Perform initial data upload here 140 } 141 142 if (desc.fFlags & kPerformInitialClear_GrSurfaceFlag) { 143 // Do initial clear of the texture 144 } 145 return tex; 146} 147