1 2 /* 3 * Copyright 2015 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 #include "GrCaps.h" 10 #include "GrContextOptions.h" 11 12 GrShaderCaps::GrShaderCaps() { 13 fShaderDerivativeSupport = false; 14 fGeometryShaderSupport = false; 15 fPathRenderingSupport = false; 16 fDstReadInShaderSupport = false; 17 fDualSourceBlendingSupport = false; 18 fIntegerSupport = false; 19 fShaderPrecisionVaries = false; 20 } 21 22 static const char* shader_type_to_string(GrShaderType type) { 23 switch (type) { 24 case kVertex_GrShaderType: 25 return "vertex"; 26 case kGeometry_GrShaderType: 27 return "geometry"; 28 case kFragment_GrShaderType: 29 return "fragment"; 30 } 31 return ""; 32 } 33 34 static const char* precision_to_string(GrSLPrecision p) { 35 switch (p) { 36 case kLow_GrSLPrecision: 37 return "low"; 38 case kMedium_GrSLPrecision: 39 return "medium"; 40 case kHigh_GrSLPrecision: 41 return "high"; 42 } 43 return ""; 44 } 45 46 SkString GrShaderCaps::dump() const { 47 SkString r; 48 static const char* gNY[] = { "NO", "YES" }; 49 r.appendf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]); 50 r.appendf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]); 51 r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]); 52 r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]); 53 r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]); 54 r.appendf("Integer Support : %s\n", gNY[fIntegerSupport]); 55 56 r.appendf("Shader Float Precisions (varies: %s):\n", gNY[fShaderPrecisionVaries]); 57 58 for (int s = 0; s < kGrShaderTypeCount; ++s) { 59 GrShaderType shaderType = static_cast<GrShaderType>(s); 60 r.appendf("\t%s:\n", shader_type_to_string(shaderType)); 61 for (int p = 0; p < kGrSLPrecisionCount; ++p) { 62 if (fFloatPrecisions[s][p].supported()) { 63 GrSLPrecision precision = static_cast<GrSLPrecision>(p); 64 r.appendf("\t\t%s: log_low: %d log_high: %d bits: %d\n", 65 precision_to_string(precision), 66 fFloatPrecisions[s][p].fLogRangeLow, 67 fFloatPrecisions[s][p].fLogRangeHigh, 68 fFloatPrecisions[s][p].fBits); 69 } 70 } 71 } 72 73 return r; 74 } 75 76 void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) { 77 fDualSourceBlendingSupport = fDualSourceBlendingSupport && !options.fSuppressDualSourceBlending; 78 this->onApplyOptionsOverrides(options); 79 } 80 81 /////////////////////////////////////////////////////////////////////////////// 82 83 GrCaps::GrCaps(const GrContextOptions& options) { 84 fMipMapSupport = false; 85 fNPOTTextureTileSupport = false; 86 fTwoSidedStencilSupport = false; 87 fStencilWrapOpsSupport = false; 88 fDiscardRenderTargetSupport = false; 89 fReuseScratchTextures = true; 90 fReuseScratchBuffers = true; 91 fGpuTracingSupport = false; 92 fCompressedTexSubImageSupport = false; 93 fOversizedStencilSupport = false; 94 fTextureBarrierSupport = false; 95 fUsesMixedSamples = false; 96 fSupportsInstancedDraws = false; 97 fFullClearIsFree = false; 98 fMustClearUploadedBufferData = false; 99 100 fUseDrawInsteadOfClear = false; 101 102 fBlendEquationSupport = kBasic_BlendEquationSupport; 103 fAdvBlendEqBlacklist = 0; 104 105 fMapBufferFlags = kNone_MapFlags; 106 107 fMaxRenderTargetSize = 1; 108 fMaxTextureSize = 1; 109 fMaxColorSampleCount = 0; 110 fMaxStencilSampleCount = 0; 111 fMaxRasterSamples = 0; 112 113 fSuppressPrints = options.fSuppressPrints; 114 fImmediateFlush = options.fImmediateMode; 115 fDrawPathMasksToCompressedTextureSupport = options.fDrawPathToCompressedTexture; 116 fGeometryBufferMapThreshold = options.fGeometryBufferMapThreshold; 117 fUseDrawInsteadOfPartialRenderTargetWrite = options.fUseDrawInsteadOfPartialRenderTargetWrite; 118 fUseDrawInsteadOfAllRenderTargetWrites = false; 119 120 fPreferVRAMUseOverFlushes = true; 121 } 122 123 void GrCaps::applyOptionsOverrides(const GrContextOptions& options) { 124 fMaxTextureSize = SkTMin(fMaxTextureSize, options.fMaxTextureSizeOverride); 125 // If the max tile override is zero, it means we should use the max texture size. 126 if (!options.fMaxTileSizeOverride || options.fMaxTileSizeOverride > fMaxTextureSize) { 127 fMaxTileSize = fMaxTextureSize; 128 } else { 129 fMaxTileSize = options.fMaxTileSizeOverride; 130 } 131 this->onApplyOptionsOverrides(options); 132 } 133 134 static SkString map_flags_to_string(uint32_t flags) { 135 SkString str; 136 if (GrCaps::kNone_MapFlags == flags) { 137 str = "none"; 138 } else { 139 SkASSERT(GrCaps::kCanMap_MapFlag & flags); 140 SkDEBUGCODE(flags &= ~GrCaps::kCanMap_MapFlag); 141 str = "can_map"; 142 143 if (GrCaps::kSubset_MapFlag & flags) { 144 str.append(" partial"); 145 } else { 146 str.append(" full"); 147 } 148 SkDEBUGCODE(flags &= ~GrCaps::kSubset_MapFlag); 149 } 150 SkASSERT(0 == flags); // Make sure we handled all the flags. 151 return str; 152 } 153 154 SkString GrCaps::dump() const { 155 SkString r; 156 static const char* gNY[] = {"NO", "YES"}; 157 r.appendf("MIP Map Support : %s\n", gNY[fMipMapSupport]); 158 r.appendf("NPOT Texture Tile Support : %s\n", gNY[fNPOTTextureTileSupport]); 159 r.appendf("Two Sided Stencil Support : %s\n", gNY[fTwoSidedStencilSupport]); 160 r.appendf("Stencil Wrap Ops Support : %s\n", gNY[fStencilWrapOpsSupport]); 161 r.appendf("Discard Render Target Support : %s\n", gNY[fDiscardRenderTargetSupport]); 162 r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]); 163 r.appendf("Reuse Scratch Buffers : %s\n", gNY[fReuseScratchBuffers]); 164 r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]); 165 r.appendf("Compressed Update Support : %s\n", gNY[fCompressedTexSubImageSupport]); 166 r.appendf("Oversized Stencil Support : %s\n", gNY[fOversizedStencilSupport]); 167 r.appendf("Texture Barrier Support : %s\n", gNY[fTextureBarrierSupport]); 168 r.appendf("Uses Mixed Samples : %s\n", gNY[fUsesMixedSamples]); 169 r.appendf("Supports instanced draws : %s\n", gNY[fSupportsInstancedDraws]); 170 r.appendf("Full screen clear is free : %s\n", gNY[fFullClearIsFree]); 171 r.appendf("Must clear buffer memory : %s\n", gNY[fMustClearUploadedBufferData]); 172 r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]); 173 r.appendf("Draw Instead of TexSubImage [workaround] : %s\n", 174 gNY[fUseDrawInsteadOfPartialRenderTargetWrite]); 175 r.appendf("Prefer VRAM Use over flushes [workaround] : %s\n", gNY[fPreferVRAMUseOverFlushes]); 176 177 if (this->advancedBlendEquationSupport()) { 178 r.appendf("Advanced Blend Equation Blacklist : 0x%x\n", fAdvBlendEqBlacklist); 179 } 180 181 r.appendf("Max Texture Size : %d\n", fMaxTextureSize); 182 r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize); 183 r.appendf("Max Color Sample Count : %d\n", fMaxColorSampleCount); 184 r.appendf("Max Stencil Sample Count : %d\n", fMaxStencilSampleCount); 185 r.appendf("Max Raster Samples : %d\n", fMaxRasterSamples); 186 187 static const char* kBlendEquationSupportNames[] = { 188 "Basic", 189 "Advanced", 190 "Advanced Coherent", 191 }; 192 GR_STATIC_ASSERT(0 == kBasic_BlendEquationSupport); 193 GR_STATIC_ASSERT(1 == kAdvanced_BlendEquationSupport); 194 GR_STATIC_ASSERT(2 == kAdvancedCoherent_BlendEquationSupport); 195 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kBlendEquationSupportNames) == kLast_BlendEquationSupport + 1); 196 197 r.appendf("Blend Equation Support : %s\n", 198 kBlendEquationSupportNames[fBlendEquationSupport]); 199 r.appendf("Map Buffer Support : %s\n", 200 map_flags_to_string(fMapBufferFlags).c_str()); 201 202 static const char* kConfigNames[] = { 203 "Unknown", // kUnknown_GrPixelConfig 204 "Alpha8", // kAlpha_8_GrPixelConfig, 205 "Index8", // kIndex_8_GrPixelConfig, 206 "RGB565", // kRGB_565_GrPixelConfig, 207 "RGBA444", // kRGBA_4444_GrPixelConfig, 208 "RGBA8888", // kRGBA_8888_GrPixelConfig, 209 "BGRA8888", // kBGRA_8888_GrPixelConfig, 210 "SRGBA8888",// kSRGBA_8888_GrPixelConfig, 211 "ETC1", // kETC1_GrPixelConfig, 212 "LATC", // kLATC_GrPixelConfig, 213 "R11EAC", // kR11_EAC_GrPixelConfig, 214 "ASTC12x12",// kASTC_12x12_GrPixelConfig, 215 "RGBAFloat",// kRGBA_float_GrPixelConfig 216 "AlphaHalf",// kAlpha_half_GrPixelConfig 217 "RGBAHalf", // kRGBA_half_GrPixelConfig 218 }; 219 GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig); 220 GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig); 221 GR_STATIC_ASSERT(2 == kIndex_8_GrPixelConfig); 222 GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig); 223 GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig); 224 GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig); 225 GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig); 226 GR_STATIC_ASSERT(7 == kSRGBA_8888_GrPixelConfig); 227 GR_STATIC_ASSERT(8 == kETC1_GrPixelConfig); 228 GR_STATIC_ASSERT(9 == kLATC_GrPixelConfig); 229 GR_STATIC_ASSERT(10 == kR11_EAC_GrPixelConfig); 230 GR_STATIC_ASSERT(11 == kASTC_12x12_GrPixelConfig); 231 GR_STATIC_ASSERT(12 == kRGBA_float_GrPixelConfig); 232 GR_STATIC_ASSERT(13 == kAlpha_half_GrPixelConfig); 233 GR_STATIC_ASSERT(14 == kRGBA_half_GrPixelConfig); 234 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt); 235 236 SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig, false)); 237 SkASSERT(!this->isConfigRenderable(kUnknown_GrPixelConfig, true)); 238 239 for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i) { 240 GrPixelConfig config = static_cast<GrPixelConfig>(i); 241 r.appendf("%s is renderable: %s, with MSAA: %s\n", 242 kConfigNames[i], 243 gNY[this->isConfigRenderable(config, false)], 244 gNY[this->isConfigRenderable(config, true)]); 245 } 246 247 SkASSERT(!this->isConfigTexturable(kUnknown_GrPixelConfig)); 248 249 for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i) { 250 GrPixelConfig config = static_cast<GrPixelConfig>(i); 251 r.appendf("%s is uploadable to a texture: %s\n", 252 kConfigNames[i], 253 gNY[this->isConfigTexturable(config)]); 254 } 255 256 return r; 257 } 258