blob: 22f6a6de8ff6e6570814ebeb110e35a1d44fa856 [file] [log] [blame]
bsalomondc47ff72015-05-26 12:16:59 -07001
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
12GrShaderCaps::GrShaderCaps() {
13 fShaderDerivativeSupport = false;
14 fGeometryShaderSupport = false;
15 fPathRenderingSupport = false;
16 fDstReadInShaderSupport = false;
17 fDualSourceBlendingSupport = false;
18 fMixedSamplesSupport = false;
vbuzinov3e77ba92015-09-30 23:02:06 -070019 fProgrammableSampleLocationsSupport = false;
bsalomondc47ff72015-05-26 12:16:59 -070020 fShaderPrecisionVaries = false;
21}
22
23static 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
35static 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
47SkString GrShaderCaps::dump() const {
48 SkString r;
49 static const char* gNY[] = { "NO", "YES" };
vbuzinov3e77ba92015-09-30 23:02:06 -070050 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("Mixed Samples Support : %s\n", gNY[fMixedSamplesSupport]);
56 r.appendf("Programmable Sample Locations Support : %s\n", gNY[fProgrammableSampleLocationsSupport]);
bsalomondc47ff72015-05-26 12:16:59 -070057
vbuzinov3e77ba92015-09-30 23:02:06 -070058 r.appendf("Shader Float Precisions (varies: %s) :\n", gNY[fShaderPrecisionVaries]);
bsalomondc47ff72015-05-26 12:16:59 -070059
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
cdalton6fd158e2015-05-27 15:08:33 -070078void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
79 fDualSourceBlendingSupport = fDualSourceBlendingSupport && !options.fSuppressDualSourceBlending;
egdanielb7e7d572015-11-04 04:23:53 -080080 this->onApplyOptionsOverrides(options);
bsalomon4ee6bd82015-05-27 13:23:23 -070081}
82
bsalomondc47ff72015-05-26 12:16:59 -070083///////////////////////////////////////////////////////////////////////////////
84
85GrCaps::GrCaps(const GrContextOptions& options) {
86 fMipMapSupport = false;
87 fNPOTTextureTileSupport = false;
88 fTwoSidedStencilSupport = false;
89 fStencilWrapOpsSupport = false;
90 fDiscardRenderTargetSupport = false;
91 fReuseScratchTextures = true;
robertphillips1b8e1b52015-06-24 06:54:10 -070092 fReuseScratchBuffers = true;
bsalomondc47ff72015-05-26 12:16:59 -070093 fGpuTracingSupport = false;
94 fCompressedTexSubImageSupport = false;
95 fOversizedStencilSupport = false;
96 fTextureBarrierSupport = false;
joshualitt58001552015-06-26 12:46:36 -070097 fSupportsInstancedDraws = false;
egdaniel51c8d402015-08-06 10:54:13 -070098 fFullClearIsFree = false;
bsalomon7dea7b72015-08-19 08:26:51 -070099 fMustClearUploadedBufferData = false;
bsalomondc47ff72015-05-26 12:16:59 -0700100
101 fUseDrawInsteadOfClear = false;
102
103 fBlendEquationSupport = kBasic_BlendEquationSupport;
cdalton1dd05422015-06-12 09:01:18 -0700104 fAdvBlendEqBlacklist = 0;
105
bsalomondc47ff72015-05-26 12:16:59 -0700106 fMapBufferFlags = kNone_MapFlags;
107
egdanielff1d5472015-09-10 08:37:20 -0700108 fMaxRenderTargetSize = 1;
109 fMaxTextureSize = 1;
bsalomondc47ff72015-05-26 12:16:59 -0700110 fMaxSampleCount = 0;
111
112 memset(fConfigRenderSupport, 0, sizeof(fConfigRenderSupport));
113 memset(fConfigTextureSupport, 0, sizeof(fConfigTextureSupport));
114
115 fSupressPrints = options.fSuppressPrints;
116 fDrawPathMasksToCompressedTextureSupport = options.fDrawPathToCompressedTexture;
joshualitt7224c862015-05-29 06:46:47 -0700117 fGeometryBufferMapThreshold = options.fGeometryBufferMapThreshold;
joshualitt83bc2292015-06-18 14:18:02 -0700118 fUseDrawInsteadOfPartialRenderTargetWrite = options.fUseDrawInsteadOfPartialRenderTargetWrite;
robertphillips63926682015-08-20 09:39:02 -0700119
120 fPreferVRAMUseOverFlushes = true;
bsalomondc47ff72015-05-26 12:16:59 -0700121}
122
bsalomon4ee6bd82015-05-27 13:23:23 -0700123void GrCaps::applyOptionsOverrides(const GrContextOptions& options) {
124 fMaxTextureSize = SkTMin(fMaxTextureSize, options.fMaxTextureSizeOverride);
bsalomon8c07b7a2015-11-02 11:36:52 -0800125 // 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 }
egdanielb7e7d572015-11-04 04:23:53 -0800131 this->onApplyOptionsOverrides(options);
bsalomon4ee6bd82015-05-27 13:23:23 -0700132}
133
bsalomondc47ff72015-05-26 12:16:59 -0700134static 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
154SkString 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]);
robertphillips1b8e1b52015-06-24 06:54:10 -0700163 r.appendf("Reuse Scratch Buffers : %s\n", gNY[fReuseScratchBuffers]);
bsalomondc47ff72015-05-26 12:16:59 -0700164 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]);
joshualitt58001552015-06-26 12:46:36 -0700168 r.appendf("Supports instanced draws : %s\n", gNY[fSupportsInstancedDraws]);
egdaniel51c8d402015-08-06 10:54:13 -0700169 r.appendf("Full screen clear is free : %s\n", gNY[fFullClearIsFree]);
bsalomon7dea7b72015-08-19 08:26:51 -0700170 r.appendf("Must clear buffer memory : %s\n", gNY[fMustClearUploadedBufferData]);
bsalomondc47ff72015-05-26 12:16:59 -0700171 r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]);
joshualitt83bc2292015-06-18 14:18:02 -0700172 r.appendf("Draw Instead of TexSubImage [workaround] : %s\n",
173 gNY[fUseDrawInsteadOfPartialRenderTargetWrite]);
robertphillips63926682015-08-20 09:39:02 -0700174 r.appendf("Prefer VRAM Use over flushes [workaround] : %s\n", gNY[fPreferVRAMUseOverFlushes]);
175
cdalton1dd05422015-06-12 09:01:18 -0700176 if (this->advancedBlendEquationSupport()) {
177 r.appendf("Advanced Blend Equation Blacklist : 0x%x\n", fAdvBlendEqBlacklist);
178 }
bsalomondc47ff72015-05-26 12:16:59 -0700179
180 r.appendf("Max Texture Size : %d\n", fMaxTextureSize);
bsalomondc47ff72015-05-26 12:16:59 -0700181 r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize);
182 r.appendf("Max Sample Count : %d\n", fMaxSampleCount);
183
184 static const char* kBlendEquationSupportNames[] = {
185 "Basic",
186 "Advanced",
187 "Advanced Coherent",
188 };
189 GR_STATIC_ASSERT(0 == kBasic_BlendEquationSupport);
190 GR_STATIC_ASSERT(1 == kAdvanced_BlendEquationSupport);
191 GR_STATIC_ASSERT(2 == kAdvancedCoherent_BlendEquationSupport);
192 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kBlendEquationSupportNames) == kLast_BlendEquationSupport + 1);
193
194 r.appendf("Blend Equation Support : %s\n",
195 kBlendEquationSupportNames[fBlendEquationSupport]);
196 r.appendf("Map Buffer Support : %s\n",
197 map_flags_to_string(fMapBufferFlags).c_str());
198
199 static const char* kConfigNames[] = {
200 "Unknown", // kUnknown_GrPixelConfig
201 "Alpha8", // kAlpha_8_GrPixelConfig,
202 "Index8", // kIndex_8_GrPixelConfig,
203 "RGB565", // kRGB_565_GrPixelConfig,
204 "RGBA444", // kRGBA_4444_GrPixelConfig,
205 "RGBA8888", // kRGBA_8888_GrPixelConfig,
206 "BGRA8888", // kBGRA_8888_GrPixelConfig,
207 "SRGBA8888",// kSRGBA_8888_GrPixelConfig,
208 "ETC1", // kETC1_GrPixelConfig,
209 "LATC", // kLATC_GrPixelConfig,
210 "R11EAC", // kR11_EAC_GrPixelConfig,
211 "ASTC12x12",// kASTC_12x12_GrPixelConfig,
212 "RGBAFloat",// kRGBA_float_GrPixelConfig
213 "AlphaHalf",// kAlpha_half_GrPixelConfig
214 "RGBAHalf", // kRGBA_half_GrPixelConfig
215 };
216 GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig);
217 GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig);
218 GR_STATIC_ASSERT(2 == kIndex_8_GrPixelConfig);
219 GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig);
220 GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig);
221 GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig);
222 GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig);
223 GR_STATIC_ASSERT(7 == kSRGBA_8888_GrPixelConfig);
224 GR_STATIC_ASSERT(8 == kETC1_GrPixelConfig);
225 GR_STATIC_ASSERT(9 == kLATC_GrPixelConfig);
226 GR_STATIC_ASSERT(10 == kR11_EAC_GrPixelConfig);
227 GR_STATIC_ASSERT(11 == kASTC_12x12_GrPixelConfig);
228 GR_STATIC_ASSERT(12 == kRGBA_float_GrPixelConfig);
229 GR_STATIC_ASSERT(13 == kAlpha_half_GrPixelConfig);
230 GR_STATIC_ASSERT(14 == kRGBA_half_GrPixelConfig);
231 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt);
232
233 SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][0]);
234 SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][1]);
235
236 for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i) {
237 r.appendf("%s is renderable: %s, with MSAA: %s\n",
238 kConfigNames[i],
239 gNY[fConfigRenderSupport[i][0]],
240 gNY[fConfigRenderSupport[i][1]]);
241 }
242
243 SkASSERT(!fConfigTextureSupport[kUnknown_GrPixelConfig]);
244
245 for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i) {
246 r.appendf("%s is uploadable to a texture: %s\n",
247 kConfigNames[i],
248 gNY[fConfigTextureSupport[i]]);
249 }
250
251 return r;
252}