1 /*
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  */
7 
8 #ifndef SKSL_UTIL
9 #define SKSL_UTIL
10 
11 #include <cstdarg>
12 #include <memory>
13 #include "stdlib.h"
14 #include "string.h"
15 #include "assert.h"
16 #include "SkSLString.h"
17 #include "SkSLStringStream.h"
18 
19 #ifndef SKSL_STANDALONE
20 #include "GrContextOptions.h"
21 #include "GrShaderCaps.h"
22 #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
33 
34 namespace SkSL {
35 
36 #ifdef SKSL_STANDALONE
37 
38 // we're being compiled standalone, so we don't have access to caps...
39 enum GrGLSLGeneration {
40     k110_GrGLSLGeneration,
41     k130_GrGLSLGeneration,
42     k140_GrGLSLGeneration,
43     k150_GrGLSLGeneration,
44     k330_GrGLSLGeneration,
45     k400_GrGLSLGeneration,
46     k420_GrGLSLGeneration,
47     k310es_GrGLSLGeneration,
48     k320es_GrGLSLGeneration,
49 };
50 
51 #define SKSL_CAPS_CLASS StandaloneShaderCaps
52 class StandaloneShaderCaps {
53 public:
generation()54     GrGLSLGeneration generation() const {
55         return k400_GrGLSLGeneration;
56     }
57 
canUseMinAndAbsTogether()58     bool canUseMinAndAbsTogether() const {
59         return true;
60     }
61 
mustForceNegatedAtanParamToFloat()62     bool mustForceNegatedAtanParamToFloat() const {
63         return false;
64     }
65 
shaderDerivativeSupport()66     bool shaderDerivativeSupport() const {
67         return true;
68     }
69 
usesPrecisionModifiers()70     bool usesPrecisionModifiers() const {
71         return true;
72     }
73 
mustDeclareFragmentShaderOutput()74     bool mustDeclareFragmentShaderOutput() const {
75         return true;
76     }
77 
fbFetchSupport()78     bool fbFetchSupport() const {
79         return true;
80     }
81 
fbFetchNeedsCustomOutput()82     bool fbFetchNeedsCustomOutput() const {
83         return false;
84     }
85 
dropsTileOnZeroDivide()86     bool dropsTileOnZeroDivide() const {
87         return false;
88     }
89 
flatInterpolationSupport()90     bool flatInterpolationSupport() const {
91         return true;
92     }
93 
noperspectiveInterpolationSupport()94     bool noperspectiveInterpolationSupport() const {
95         return true;
96     }
97 
multisampleInterpolationSupport()98     bool multisampleInterpolationSupport() const {
99         return true;
100     }
101 
externalTextureSupport()102     bool externalTextureSupport() const {
103         return true;
104     }
105 
texelFetchSupport()106     bool texelFetchSupport() const {
107         return true;
108     }
109 
imageLoadStoreSupport()110     bool imageLoadStoreSupport() const {
111         return true;
112     }
113 
mustEnableAdvBlendEqs()114     bool mustEnableAdvBlendEqs() const {
115         return false;
116     }
117 
mustEnableSpecificAdvBlendEqs()118     bool mustEnableSpecificAdvBlendEqs() const {
119         return false;
120     }
121 
canUseAnyFunctionInShader()122     bool canUseAnyFunctionInShader() const {
123         return false;
124     }
125 
floatIs32Bits()126     bool floatIs32Bits() const {
127         return true;
128     }
129 
integerSupport()130     bool integerSupport() const {
131         return false;
132     }
133 
shaderDerivativeExtensionString()134     const char* shaderDerivativeExtensionString() const {
135         return nullptr;
136     }
137 
fragCoordConventionsExtensionString()138     const char* fragCoordConventionsExtensionString() const {
139         return nullptr;
140     }
141 
imageLoadStoreExtensionString()142     const char* imageLoadStoreExtensionString() const {
143         return nullptr;
144     }
145 
geometryShaderExtensionString()146     const char* geometryShaderExtensionString() const {
147         return nullptr;
148     }
149 
gsInvocationsExtensionString()150     const char* gsInvocationsExtensionString() const {
151         return nullptr;
152     }
153 
versionDeclString()154     const char* versionDeclString() const {
155         return "";
156     }
157 
gsInvocationsSupport()158     bool gsInvocationsSupport() const {
159         return true;
160     }
161 
canUseFractForNegativeValues()162     bool canUseFractForNegativeValues() const {
163         return true;
164     }
165 
canUseFragCoord()166     bool canUseFragCoord() const {
167         return true;
168     }
169 };
170 
171 extern StandaloneShaderCaps standaloneCaps;
172 
173 #else
174 
175 #define SKSL_CAPS_CLASS GrShaderCaps
176 // Various sets of caps for use in tests
177 class ShaderCapsFactory {
178 public:
179     static sk_sp<GrShaderCaps> Default() {
180         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
181         result->fVersionDeclString = "#version 400";
182         result->fShaderDerivativeSupport = true;
183         return result;
184     }
185 
186     static sk_sp<GrShaderCaps> Version450Core() {
187         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
188         result->fVersionDeclString = "#version 450 core";
189         return result;
190     }
191 
192     static sk_sp<GrShaderCaps> Version110() {
193         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
194         result->fVersionDeclString = "#version 110";
195         result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration;
196         return result;
197     }
198 
199     static sk_sp<GrShaderCaps> UsesPrecisionModifiers() {
200         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
201         result->fVersionDeclString = "#version 400";
202         result->fUsesPrecisionModifiers = true;
203         return result;
204     }
205 
206     static sk_sp<GrShaderCaps> CannotUseMinAndAbsTogether() {
207         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
208         result->fVersionDeclString = "#version 400";
209         result->fCanUseMinAndAbsTogether = false;
210         return result;
211     }
212 
213     static sk_sp<GrShaderCaps> CannotUseFractForNegativeValues() {
214         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
215         result->fVersionDeclString = "#version 400";
216         result->fCanUseFractForNegativeValues = false;
217         return result;
218     }
219 
220     static sk_sp<GrShaderCaps> MustForceNegatedAtanParamToFloat() {
221         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
222         result->fVersionDeclString = "#version 400";
223         result->fMustForceNegatedAtanParamToFloat = true;
224         return result;
225     }
226 
227     static sk_sp<GrShaderCaps> ShaderDerivativeExtensionString() {
228         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
229         result->fVersionDeclString = "#version 400";
230         result->fShaderDerivativeSupport = true;
231         result->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
232         result->fUsesPrecisionModifiers = true;
233         return result;
234     }
235 
236     static sk_sp<GrShaderCaps> FragCoordsOld() {
237         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
238         result->fVersionDeclString = "#version 110";
239         result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration;
240         result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
241         return result;
242     }
243 
244     static sk_sp<GrShaderCaps> FragCoordsNew() {
245         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
246         result->fVersionDeclString = "#version 400";
247         result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
248         return result;
249     }
250 
251     static sk_sp<GrShaderCaps> GeometryShaderSupport() {
252         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
253         result->fVersionDeclString = "#version 400";
254         result->fGeometryShaderSupport = true;
255         result->fGSInvocationsSupport = true;
256         return result;
257     }
258 
259     static sk_sp<GrShaderCaps> NoGSInvocationsSupport() {
260         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
261         result->fVersionDeclString = "#version 400";
262         result->fGeometryShaderSupport = true;
263         result->fGSInvocationsSupport = false;
264         return result;
265     }
266 
267     static sk_sp<GrShaderCaps> GeometryShaderExtensionString() {
268         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
269         result->fVersionDeclString = "#version 310es";
270         result->fGeometryShaderSupport = true;
271         result->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
272         result->fGSInvocationsSupport = true;
273         return result;
274     }
275 
276     static sk_sp<GrShaderCaps> GSInvocationsExtensionString() {
277         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
278         result->fVersionDeclString = "#version 400";
279         result->fGeometryShaderSupport = true;
280         result->fGSInvocationsSupport = true;
281         result->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
282         return result;
283     }
284 
285     static sk_sp<GrShaderCaps> VariousCaps() {
286         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
287         result->fVersionDeclString = "#version 400";
288         result->fExternalTextureSupport = true;
289         result->fFBFetchSupport = false;
290         result->fDropsTileOnZeroDivide = true;
291         result->fTexelFetchSupport = true;
292         result->fCanUseAnyFunctionInShader = false;
293         return result;
294     }
295 
296     static sk_sp<GrShaderCaps> CannotUseFragCoord() {
297         sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
298         result->fVersionDeclString = "#version 400";
299         result->fCanUseFragCoord = false;
300         return result;
301     }
302 };
303 #endif
304 
305 void write_stringstream(const StringStream& d, OutputStream& out);
306 
307 #if _MSC_VER
308 #define NORETURN __declspec(noreturn)
309 #else
310 #define NORETURN __attribute__((__noreturn__))
311 #endif
312 
313 NORETURN void sksl_abort();
314 
315 } // namespace
316 
317 #ifdef SKSL_STANDALONE
318 #define ASSERT(x) (void)((x) || (ABORT("failed assert(%s): %s:%d\n", #x, __FILE__, __LINE__), 0))
319 #define ASSERT_RESULT(x) ASSERT(x)
320 #define SKSL_DEBUGCODE(x) x
321 #else
322 #define ASSERT SkASSERT
323 #define ASSERT_RESULT(x) SkAssertResult(x)
324 #define SKSL_DEBUGCODE(x) SkDEBUGCODE(x)
325 #endif
326 
327 #define SKSL_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
328 
329 #if defined(__clang__) || defined(__GNUC__)
330 #define SKSL_PRINTF_LIKE(A, B) __attribute__((format(printf, (A), (B))))
331 #else
332 #define SKSL_PRINTF_LIKE(A, B)
333 #endif
334 
335 #define ABORT(...) (printf(__VA_ARGS__), sksl_abort())
336 
337 #endif
338