blob: 60979bbd3007d2824e661b43b19771a1ae99e64a [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
2 * Copyright 2016 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 */
Ethan Nicholas0df1b042017-03-31 13:56:23 -04007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_UTIL
9#define SKSL_UTIL
10
Ethan Nicholas0df1b042017-03-31 13:56:23 -040011#include <cstdarg>
12#include <memory>
ethannicholasb3058bd2016-07-01 08:22:01 -070013#include "stdlib.h"
Ethan Nicholas0df1b042017-03-31 13:56:23 -040014#include "string.h"
ethannicholasb3058bd2016-07-01 08:22:01 -070015#include "assert.h"
Ethan Nicholas0df1b042017-03-31 13:56:23 -040016#include "SkSLString.h"
17#include "SkSLStringStream.h"
18
Brian Salomonc7fe0f72018-05-11 10:14:21 -040019#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
Ethan Nicholas7ef4b742016-11-11 15:16:46 -050020#include "GrContextOptions.h"
Brian Salomon94efbf52016-11-29 13:43:05 -050021#include "GrShaderCaps.h"
Ethan Nicholas0df1b042017-03-31 13:56:23 -040022#endif
23
24#ifdef SKSL_STANDALONE
25#if defined(_WIN32) || defined(__SYMBIAN32__)
26#define SKSL_BUILD_FOR_WIN
27#endif
28#else
29#ifdef SK_BUILD_FOR_WIN
30#define SKSL_BUILD_FOR_WIN
31#endif // SK_BUILD_FOR_WIN
32#endif // SKSL_STANDALONE
ethannicholasb3058bd2016-07-01 08:22:01 -070033
Brian Salomonc7fe0f72018-05-11 10:14:21 -040034class GrShaderCaps;
35
ethannicholasb3058bd2016-07-01 08:22:01 -070036namespace SkSL {
37
Brian Salomonc7fe0f72018-05-11 10:14:21 -040038#if defined(SKSL_STANDALONE) || !SK_SUPPORT_GPU
Ethan Nicholas0df1b042017-03-31 13:56:23 -040039
40// we're being compiled standalone, so we don't have access to caps...
41enum GrGLSLGeneration {
42 k110_GrGLSLGeneration,
43 k130_GrGLSLGeneration,
44 k140_GrGLSLGeneration,
45 k150_GrGLSLGeneration,
46 k330_GrGLSLGeneration,
47 k400_GrGLSLGeneration,
48 k420_GrGLSLGeneration,
49 k310es_GrGLSLGeneration,
50 k320es_GrGLSLGeneration,
51};
52
53#define SKSL_CAPS_CLASS StandaloneShaderCaps
54class StandaloneShaderCaps {
55public:
56 GrGLSLGeneration generation() const {
57 return k400_GrGLSLGeneration;
58 }
59
60 bool canUseMinAndAbsTogether() const {
61 return true;
62 }
63
64 bool mustForceNegatedAtanParamToFloat() const {
65 return false;
66 }
67
68 bool shaderDerivativeSupport() const {
69 return true;
70 }
71
72 bool usesPrecisionModifiers() const {
73 return true;
74 }
75
76 bool mustDeclareFragmentShaderOutput() const {
77 return true;
78 }
79
80 bool fbFetchSupport() const {
81 return true;
82 }
83
84 bool fbFetchNeedsCustomOutput() const {
85 return false;
86 }
87
Ethan Nicholas0df1b042017-03-31 13:56:23 -040088 bool dropsTileOnZeroDivide() const {
89 return false;
90 }
91
92 bool flatInterpolationSupport() const {
93 return true;
94 }
95
96 bool noperspectiveInterpolationSupport() const {
97 return true;
98 }
99
Robert Phillips7f861922018-01-30 13:13:42 +0000100 bool multisampleInterpolationSupport() const {
101 return true;
102 }
103
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400104 bool externalTextureSupport() const {
105 return true;
106 }
107
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400108 bool imageLoadStoreSupport() const {
109 return true;
110 }
111
112 bool mustEnableAdvBlendEqs() const {
113 return false;
114 }
115
116 bool mustEnableSpecificAdvBlendEqs() const {
117 return false;
118 }
119
120 bool canUseAnyFunctionInShader() const {
121 return false;
122 }
123
Chris Dalton47c8ed32017-11-15 18:27:09 -0700124 bool floatIs32Bits() const {
125 return true;
Ethan Nicholas762466e2017-06-29 10:03:38 -0400126 }
127
Ethan Nicholas07990de2017-07-18 09:47:43 -0400128 bool integerSupport() const {
129 return false;
130 }
131
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400132 const char* shaderDerivativeExtensionString() const {
133 return nullptr;
134 }
135
136 const char* fragCoordConventionsExtensionString() const {
137 return nullptr;
138 }
139
140 const char* imageLoadStoreExtensionString() const {
141 return nullptr;
142 }
143
Chris Dalton8fd79552018-01-11 00:46:14 -0500144 const char* geometryShaderExtensionString() const {
145 return nullptr;
146 }
147
Chris Dalton567d6f42017-10-06 13:13:32 -0600148 const char* gsInvocationsExtensionString() const {
149 return nullptr;
150 }
151
Brian Osman4b2f9152018-04-17 11:19:57 -0400152 const char* externalTextureExtensionString() const {
153 return nullptr;
154 }
155
Brian Osman061020e2018-04-17 14:22:15 -0400156 const char* secondExternalTextureExtensionString() const {
157 return nullptr;
158 }
159
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400160 const char* versionDeclString() const {
161 return "";
162 }
Ethan Nicholas7da6dfa2017-06-21 11:25:18 -0400163
Chris Dalton567d6f42017-10-06 13:13:32 -0600164 bool gsInvocationsSupport() const {
165 return true;
Ethan Nicholas7da6dfa2017-06-21 11:25:18 -0400166 }
Ethan Nicholas1af6d682017-08-08 16:42:13 -0400167
168 bool canUseFractForNegativeValues() const {
169 return true;
170 }
Brian Osmancd3261a2018-01-16 13:52:29 +0000171
172 bool canUseFragCoord() const {
173 return true;
174 }
Chris Dalton85fcfc52018-03-14 11:15:27 -0600175
176 bool incompleteShortIntPrecision() const {
177 return false;
178 }
Ethan Nicholas43f6d452018-04-13 16:53:07 -0400179
180 const char* fbFetchColorName() const {
181 return nullptr;
182 }
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400183};
184
185extern StandaloneShaderCaps standaloneCaps;
186
187#else
188
189#define SKSL_CAPS_CLASS GrShaderCaps
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500190// Various sets of caps for use in tests
Brian Salomonf1dd6772016-11-29 15:27:52 -0500191class ShaderCapsFactory {
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500192public:
Brian Salomon94efbf52016-11-29 13:43:05 -0500193 static sk_sp<GrShaderCaps> Default() {
194 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500195 result->fVersionDeclString = "#version 400";
196 result->fShaderDerivativeSupport = true;
197 return result;
198 }
199
Brian Salomon94efbf52016-11-29 13:43:05 -0500200 static sk_sp<GrShaderCaps> Version450Core() {
201 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500202 result->fVersionDeclString = "#version 450 core";
203 return result;
204 }
205
Brian Salomon94efbf52016-11-29 13:43:05 -0500206 static sk_sp<GrShaderCaps> Version110() {
207 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500208 result->fVersionDeclString = "#version 110";
209 result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration;
210 return result;
211 }
212
Brian Salomon94efbf52016-11-29 13:43:05 -0500213 static sk_sp<GrShaderCaps> UsesPrecisionModifiers() {
214 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500215 result->fVersionDeclString = "#version 400";
216 result->fUsesPrecisionModifiers = true;
217 return result;
218 }
219
Brian Salomon94efbf52016-11-29 13:43:05 -0500220 static sk_sp<GrShaderCaps> CannotUseMinAndAbsTogether() {
221 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500222 result->fVersionDeclString = "#version 400";
223 result->fCanUseMinAndAbsTogether = false;
224 return result;
225 }
226
Florin Malita3b30c4f2017-08-08 15:47:35 -0400227 static sk_sp<GrShaderCaps> CannotUseFractForNegativeValues() {
228 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
229 result->fVersionDeclString = "#version 400";
230 result->fCanUseFractForNegativeValues = false;
231 return result;
232 }
233
Brian Salomon94efbf52016-11-29 13:43:05 -0500234 static sk_sp<GrShaderCaps> MustForceNegatedAtanParamToFloat() {
235 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500236 result->fVersionDeclString = "#version 400";
237 result->fMustForceNegatedAtanParamToFloat = true;
238 return result;
239 }
240
Brian Salomon94efbf52016-11-29 13:43:05 -0500241 static sk_sp<GrShaderCaps> ShaderDerivativeExtensionString() {
242 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500243 result->fVersionDeclString = "#version 400";
244 result->fShaderDerivativeSupport = true;
245 result->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
Ethan Nicholas762466e2017-06-29 10:03:38 -0400246 result->fUsesPrecisionModifiers = true;
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500247 return result;
248 }
Ethan Nicholas3605ace2016-11-21 15:59:48 -0500249
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500250 static sk_sp<GrShaderCaps> FragCoordsOld() {
251 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
252 result->fVersionDeclString = "#version 110";
253 result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration;
254 result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
255 return result;
256 }
257
258 static sk_sp<GrShaderCaps> FragCoordsNew() {
259 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
260 result->fVersionDeclString = "#version 400";
261 result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
262 return result;
263 }
264
Chris Dalton8fd79552018-01-11 00:46:14 -0500265 static sk_sp<GrShaderCaps> GeometryShaderSupport() {
266 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
267 result->fVersionDeclString = "#version 400";
268 result->fGeometryShaderSupport = true;
269 result->fGSInvocationsSupport = true;
270 return result;
271 }
272
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600273 static sk_sp<GrShaderCaps> NoGSInvocationsSupport() {
Ethan Nicholas7da6dfa2017-06-21 11:25:18 -0400274 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
275 result->fVersionDeclString = "#version 400";
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600276 result->fGeometryShaderSupport = true;
277 result->fGSInvocationsSupport = false;
278 return result;
279 }
280
Chris Dalton8fd79552018-01-11 00:46:14 -0500281 static sk_sp<GrShaderCaps> GeometryShaderExtensionString() {
282 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
283 result->fVersionDeclString = "#version 310es";
284 result->fGeometryShaderSupport = true;
285 result->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
286 result->fGSInvocationsSupport = true;
287 return result;
288 }
289
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600290 static sk_sp<GrShaderCaps> GSInvocationsExtensionString() {
291 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
292 result->fVersionDeclString = "#version 400";
293 result->fGeometryShaderSupport = true;
294 result->fGSInvocationsSupport = true;
295 result->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
Ethan Nicholas7da6dfa2017-06-21 11:25:18 -0400296 return result;
297 }
298
Brian Salomon94efbf52016-11-29 13:43:05 -0500299 static sk_sp<GrShaderCaps> VariousCaps() {
300 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas3605ace2016-11-21 15:59:48 -0500301 result->fVersionDeclString = "#version 400";
302 result->fExternalTextureSupport = true;
303 result->fFBFetchSupport = false;
304 result->fDropsTileOnZeroDivide = true;
Ethan Nicholas3605ace2016-11-21 15:59:48 -0500305 result->fCanUseAnyFunctionInShader = false;
306 return result;
307 }
Brian Osmancd3261a2018-01-16 13:52:29 +0000308
309 static sk_sp<GrShaderCaps> CannotUseFragCoord() {
310 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
311 result->fVersionDeclString = "#version 400";
312 result->fCanUseFragCoord = false;
313 return result;
314 }
Chris Daltonc2d0dd62018-03-07 07:46:10 -0700315
316 static sk_sp<GrShaderCaps> IncompleteShortIntPrecision() {
317 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
318 result->fVersionDeclString = "#version 310es";
319 result->fUsesPrecisionModifiers = true;
320 result->fIncompleteShortIntPrecision = true;
321 return result;
322 }
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500323};
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400324#endif
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500325
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400326void write_stringstream(const StringStream& d, OutputStream& out);
ethannicholasb3058bd2016-07-01 08:22:01 -0700327
328#if _MSC_VER
329#define NORETURN __declspec(noreturn)
330#else
331#define NORETURN __attribute__((__noreturn__))
332#endif
ethannicholasb3058bd2016-07-01 08:22:01 -0700333
334NORETURN void sksl_abort();
335
336} // namespace
337
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400338#ifdef SKSL_STANDALONE
Ethan Nicholasd9d33c32018-06-12 11:05:59 -0400339#define SkASSERT(x)
340#define SkAssertResult(x) x
341#define SkDEBUGCODE(x)
ethannicholasb3058bd2016-07-01 08:22:01 -0700342#endif
343
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400344#define SKSL_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
345
346#if defined(__clang__) || defined(__GNUC__)
347#define SKSL_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
348#else
349#define SKSL_PRINTF_LIKE(A, B)
350#endif
351
352#define ABORT(...) (printf(__VA_ARGS__), sksl_abort())
353
ethannicholasb3058bd2016-07-01 08:22:01 -0700354#endif