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