diff options
author | Greg Daniel <egdaniel@google.com> | 2017-07-31 10:45:52 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-07-31 15:03:22 +0000 |
commit | cebcb84739c261e729a054ff097adca32a1b537f (patch) | |
tree | 6b936450dc9b90357152c94e32d4c77bdba66042 /src/gpu/mtl/GrMtlCaps.mm | |
parent | 6bd729d8ebc98548fd92e081e1d1163bbc2ec815 (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.mm | 322 |
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; +} |