aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/mtl/GrMtlCaps.mm
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2017-07-31 10:45:52 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-07-31 15:03:22 +0000
commitcebcb84739c261e729a054ff097adca32a1b537f (patch)
tree6b936450dc9b90357152c94e32d4c77bdba66042 /src/gpu/mtl/GrMtlCaps.mm
parent6bd729d8ebc98548fd92e081e1d1163bbc2ec815 (diff)
Add caps files for metal
Bug: skia: Change-Id: I8e7488320d4237cf67d6ebeaad319d3de75b67e6 Reviewed-on: https://skia-review.googlesource.com/27741 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Diffstat (limited to 'src/gpu/mtl/GrMtlCaps.mm')
-rw-r--r--src/gpu/mtl/GrMtlCaps.mm322
1 files changed, 322 insertions, 0 deletions
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
new file mode 100644
index 0000000000..29e28cff03
--- /dev/null
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrMtlCaps.h"
+
+#include "GrShaderCaps.h"
+
+GrMtlCaps::GrMtlCaps(const GrContextOptions& contextOptions, const id<MTLDevice> device,
+ MTLFeatureSet featureSet)
+ : INHERITED(contextOptions) {
+ fShaderCaps.reset(new GrShaderCaps(contextOptions));
+
+ this->initFeatureSet(featureSet);
+ this->initGrCaps(device);
+ this->initShaderCaps();
+ this->initConfigTable();
+
+ this->applyOptionsOverrides(contextOptions);
+ fShaderCaps->applyOptionsOverrides(contextOptions);
+}
+
+void GrMtlCaps::initFeatureSet(MTLFeatureSet featureSet) {
+ // Mac OSX
+#ifdef SK_BUILD_FOR_MAC
+ if (MTLFeatureSet_OSX_GPUFamily1_v2 == featureSet) {
+ fPlatform = Platform::kMac;
+ fFamilyGroup = 1;
+ fVersion = 2;
+ return;
+ }
+ if (MTLFeatureSet_OSX_GPUFamily1_v1 == featureSet) {
+ fPlatform = Platform::kMac;
+ fFamilyGroup = 1;
+ fVersion = 1;
+ return;
+ }
+#endif
+
+ // iOS Family group 3
+#ifdef SK_BUILD_FOR_IOS
+ if (MTLFeatureSet_iOS_GPUFamily3_v2 == featureSet) {
+ fPlatform = Platform::kIOS;
+ fFamilyGroup = 3;
+ fVersion = 2;
+ return;
+ }
+ if (MTLFeatureSet_iOS_GPUFamily3_v1 == featureSet) {
+ fPlatform = Platform::kIOS;
+ fFamilyGroup = 3;
+ fVersion = 1;
+ return;
+ }
+
+ // iOS Family group 2
+ if (MTLFeatureSet_iOS_GPUFamily2_v3 == featureSet) {
+ fPlatform = Platform::kIOS;
+ fFamilyGroup = 2;
+ fVersion = 3;
+ return;
+ }
+ if (MTLFeatureSet_iOS_GPUFamily2_v2 == featureSet) {
+ fPlatform = Platform::kIOS;
+ fFamilyGroup = 2;
+ fVersion = 2;
+ return;
+ }
+ if (MTLFeatureSet_iOS_GPUFamily2_v1 == featureSet) {
+ fPlatform = Platform::kIOS;
+ fFamilyGroup = 2;
+ fVersion = 1;
+ return;
+ }
+
+ // iOS Family group 1
+ if (MTLFeatureSet_iOS_GPUFamily1_v3 == featureSet) {
+ fPlatform = Platform::kIOS;
+ fFamilyGroup = 1;
+ fVersion = 3;
+ return;
+ }
+ if (MTLFeatureSet_iOS_GPUFamily1_v2 == featureSet) {
+ fPlatform = Platform::kIOS;
+ fFamilyGroup = 1;
+ fVersion = 2;
+ return;
+ }
+ if (MTLFeatureSet_iOS_GPUFamily1_v1 == featureSet) {
+ fPlatform = Platform::kIOS;
+ fFamilyGroup = 1;
+ fVersion = 1;
+ return;
+ }
+#endif
+ // No supported feature sets were found
+ SkFAIL("Requested an unsupported feature set");
+}
+
+void GrMtlCaps::initGrCaps(const id<MTLDevice> device) {
+ // Max vertex attribs is the same on all devices
+ fMaxVertexAttributes = 31;
+
+ // RenderTarget and Texture size
+ if (this->isMac()) {
+ fMaxRenderTargetSize = 16384;
+ } else {
+ if (3 == fFamilyGroup) {
+ fMaxRenderTargetSize = 16384;
+ } else {
+ // Family group 1 and 2 support 8192 for version 2 and above, 4096 for v1
+ if (1 == fVersion) {
+ fMaxRenderTargetSize = 4096;
+ } else {
+ fMaxRenderTargetSize = 8192;
+ }
+ }
+ }
+ fMaxTextureSize = fMaxRenderTargetSize;
+
+ // Init sample counts. All devices support 1 (i.e. 0 in skia).
+ fSampleCounts.push(0);
+ for (auto sampleCnt : {2, 4, 8}) {
+ if ([device supportsTextureSampleCount:sampleCnt]) {
+ fSampleCounts.push(sampleCnt);
+ }
+ }
+
+ // Starting with the assumption that there isn't a reason to not map small buffers.
+ fBufferMapThreshold = 0;
+
+ // Buffers are always fully mapped.
+ fMapBufferFlags = kCanMap_MapFlag;
+
+ fOversizedStencilSupport = true;
+
+ // Looks like there is a field called rasterSampleCount labeled as beta in the Metal docs. This
+ // may be what we eventually need here, but it has no description.
+ fSampleShadingSupport = false;
+
+ fSRGBSupport = true; // always available in Metal
+ fSRGBWriteControl = false;
+ fMipMapSupport = true; // always available in Metal
+ fNPOTTextureTileSupport = true; // always available in Metal
+ fDiscardRenderTargetSupport = true;
+
+ fReuseScratchTextures = true; // Assuming this okay
+
+ fTextureBarrierSupport = false; // Need to figure out if we can do this
+
+ fSampleLocationsSupport = false;
+ fMultisampleDisableSupport = false;
+
+ if (this->isMac() || 3 == fFamilyGroup) {
+ fInstanceAttribSupport = true;
+ }
+
+ fUsesMixedSamples = false;
+ fGpuTracingSupport = false;
+
+ fUseDrawInsteadOfClear = false;
+ fFenceSyncSupport = true; // always available in Metal
+ fCrossContextTextureSupport = false;
+
+ fMaxColorSampleCount = 4; // minimum required by spec
+ fMaxStencilSampleCount = 4; // minimum required by spec
+}
+
+int GrMtlCaps::getSampleCount(int requestedCount, GrPixelConfig config) const {
+ int count = fSampleCounts.count();
+ SkASSERT(count > 0); // We always add 0 as a valid sample count
+ if (!this->isConfigRenderable(config, true)) {
+ return 0;
+ }
+
+ for (int i = 0; i < count; ++i) {
+ if (fSampleCounts[i] >= requestedCount) {
+ return fSampleCounts[i];
+ }
+ }
+ return fSampleCounts[count-1];
+}
+
+void GrMtlCaps::initShaderCaps() {
+ GrShaderCaps* shaderCaps = fShaderCaps.get();
+
+ // fConfigOutputSwizzle will default to RGBA so we only need to set it for alpha only config.
+ for (int i = 0; i < kGrPixelConfigCnt; ++i) {
+ GrPixelConfig config = static_cast<GrPixelConfig>(i);
+ if (GrPixelConfigIsAlphaOnly(config)) {
+ shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RRRR();
+ shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
+ } else {
+ if (kGray_8_GrPixelConfig == config) {
+ shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RRRA();
+ } else {
+ shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RGBA();
+ }
+ }
+ }
+
+ // Setting this true with the assumption that this cap will eventually mean we support varying
+ // percisions and not just via modifiers.
+ shaderCaps->fUsesPrecisionModifiers = true;
+ shaderCaps->fFlatInterpolationSupport = true;
+
+ shaderCaps->fShaderDerivativeSupport = true;
+ shaderCaps->fGeometryShaderSupport = false;
+
+ if ((this->isMac() && fVersion >= 2) ||
+ (this->isIOS() && ((1 == fFamilyGroup && 4 == fVersion) ||
+ (2 == fFamilyGroup && 4 == fVersion) ||
+ (3 == fFamilyGroup && 3 == fVersion)))) {
+ shaderCaps->fDualSourceBlendingSupport = true;
+ }
+
+ if (this->isIOS()) {
+ shaderCaps->fFBFetchSupport = true;
+ shaderCaps->fFBFetchNeedsCustomOutput = true; // ??
+ shaderCaps->fFBFetchColorName = ""; // Somehow add [[color(0)]] to arguments to frag shader
+ }
+ shaderCaps->fDstReadInShaderSupport = shaderCaps->fFBFetchSupport;
+
+ shaderCaps->fIntegerSupport = true;
+ shaderCaps->fTexelBufferSupport = false;
+ shaderCaps->fTexelFetchSupport = false;
+ shaderCaps->fVertexIDSupport = false;
+ shaderCaps->fImageLoadStoreSupport = false;
+ shaderCaps->fShaderPrecisionVaries = false; // ???
+
+ // Metal uses IEEE float and half floats so using those values here.
+ for (int s = 0; s < kGrShaderTypeCount; ++s) {
+ auto& highp = shaderCaps->fFloatPrecisions[s][kHigh_GrSLPrecision];
+ highp.fLogRangeLow = highp.fLogRangeHigh = 127;
+ highp.fBits = 23;
+
+ auto& mediump = shaderCaps->fFloatPrecisions[s][kMedium_GrSLPrecision];
+ mediump.fLogRangeLow = mediump.fLogRangeHigh = 15;
+ mediump.fBits = 10;
+
+ shaderCaps->fFloatPrecisions[s][kLow_GrSLPrecision] = mediump;
+ }
+ shaderCaps->initSamplerPrecisionTable();
+
+ shaderCaps->fMaxVertexSamplers =
+ shaderCaps->fMaxFragmentSamplers = 16;
+ // For now just cap at the per stage max. If we hit this limit we can come back to adjust this
+ shaderCaps->fMaxCombinedSamplers = shaderCaps->fMaxVertexSamplers;
+}
+
+void GrMtlCaps::initConfigTable() {
+ ConfigInfo* info;
+ // Alpha_8 uses R8Unorm
+ info = &fConfigTable[kAlpha_8_GrPixelConfig];
+ info->fFlags = ConfigInfo::kAllFlags;
+
+ // Gray_8 uses R8Unorm
+ info = &fConfigTable[kGray_8_GrPixelConfig];
+ info->fFlags = ConfigInfo::kAllFlags;
+
+ // RGB_565 uses B5G6R5Unorm, even though written opposite this format packs how we want
+ info = &fConfigTable[kRGB_565_GrPixelConfig];
+ if (this->isMac()) {
+ info->fFlags = 0;
+ } else {
+ info->fFlags = ConfigInfo::kAllFlags;
+ }
+
+ // RGBA_4444 uses ABGR4Unorm
+ info = &fConfigTable[kRGBA_4444_GrPixelConfig];
+ if (this->isMac()) {
+ info->fFlags = 0;
+ } else {
+ info->fFlags = ConfigInfo::kAllFlags;
+ }
+
+ // RGBA_8888 uses RGBA8Unorm
+ info = &fConfigTable[kRGBA_8888_GrPixelConfig];
+ info->fFlags = ConfigInfo::kAllFlags;
+
+ // BGRA_8888 uses BGRA8Unorm
+ info = &fConfigTable[kBGRA_8888_GrPixelConfig];
+ info->fFlags = ConfigInfo::kAllFlags;
+
+ // SRGBA_8888 uses RGBA8Unorm_sRGB
+ info = &fConfigTable[kSRGBA_8888_GrPixelConfig];
+ info->fFlags = ConfigInfo::kAllFlags;
+
+ // SBGRA_8888 uses BGRA8Unorm_sRGB
+ info = &fConfigTable[kSBGRA_8888_GrPixelConfig];
+ info->fFlags = ConfigInfo::kAllFlags;
+
+ // RGBA_8888_sint uses RGBA8Sint
+ info = &fConfigTable[kRGBA_8888_sint_GrPixelConfig];
+ info->fFlags = ConfigInfo::kMSAA_Flag;
+
+ // RGBA_float uses RGBA32Float
+ info = &fConfigTable[kRGBA_float_GrPixelConfig];
+ if (this->isMac()) {
+ info->fFlags = ConfigInfo::kAllFlags;
+ } else {
+ info->fFlags = 0;
+ }
+
+ // RG_float uses RG32Float
+ info = &fConfigTable[kRG_float_GrPixelConfig];
+ if (this->isMac()) {
+ info->fFlags = ConfigInfo::kAllFlags;
+ } else {
+ info->fFlags = ConfigInfo::kRenderable_Flag;
+ }
+
+ // Alpha_half uses R16Float
+ info = &fConfigTable[kAlpha_half_GrPixelConfig];
+ info->fFlags = ConfigInfo::kAllFlags;
+
+ // RGBA_half uses RGBA16Float
+ info = &fConfigTable[kRGBA_half_GrPixelConfig];
+ info->fFlags = ConfigInfo::kAllFlags;
+}