blob: 324c00dd7acc9138faa8db8ea183afeb02689bc4 [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 Nicholas11d53972016-11-28 11:23:23 -05007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_LAYOUT
9#define SKSL_LAYOUT
10
Ethan Nicholas762466e2017-06-29 10:03:38 -040011#include "SkSLString.h"
Ethan Nicholas11d53972016-11-28 11:23:23 -050012#include "SkSLUtil.h"
13
ethannicholasb3058bd2016-07-01 08:22:01 -070014namespace SkSL {
15
16/**
17 * Represents a layout block appearing before a variable declaration, as in:
18 *
19 * layout (location = 0) int x;
20 */
21struct Layout {
Ethan Nicholas39204fd2017-11-27 13:12:30 -050022 enum Flag {
23 kOriginUpperLeft_Flag = 1 << 0,
24 kOverrideCoverage_Flag = 1 << 1,
25 kPushConstant_Flag = 1 << 2,
26 kBlendSupportAllEquations_Flag = 1 << 3,
27 kBlendSupportMultiply_Flag = 1 << 4,
28 kBlendSupportScreen_Flag = 1 << 5,
29 kBlendSupportOverlay_Flag = 1 << 6,
30 kBlendSupportDarken_Flag = 1 << 7,
31 kBlendSupportLighten_Flag = 1 << 8,
32 kBlendSupportColorDodge_Flag = 1 << 9,
33 kBlendSupportColorBurn_Flag = 1 << 10,
34 kBlendSupportHardLight_Flag = 1 << 11,
35 kBlendSupportSoftLight_Flag = 1 << 12,
36 kBlendSupportDifference_Flag = 1 << 13,
37 kBlendSupportExclusion_Flag = 1 << 14,
38 kBlendSupportHSLHue_Flag = 1 << 15,
39 kBlendSupportHSLSaturation_Flag = 1 << 16,
40 kBlendSupportHSLColor_Flag = 1 << 17,
Michael Ludwiga4275592018-08-31 10:52:47 -040041 kBlendSupportHSLLuminosity_Flag = 1 << 18,
42 kTracked_Flag = 1 << 19
Ethan Nicholas39204fd2017-11-27 13:12:30 -050043 };
44
Ethan Nicholas52cad152017-02-16 16:37:32 -050045 enum Primitive {
46 kUnspecified_Primitive = -1,
47 kPoints_Primitive,
48 kLines_Primitive,
49 kLineStrip_Primitive,
50 kLinesAdjacency_Primitive,
51 kTriangles_Primitive,
52 kTriangleStrip_Primitive,
53 kTrianglesAdjacency_Primitive
54 };
55
Ethan Nicholas11d53972016-11-28 11:23:23 -050056 // These are used by images in GLSL. We only support a subset of what GL supports.
57 enum class Format {
58 kUnspecified = -1,
59 kRGBA32F,
60 kR32F,
61 kRGBA16F,
62 kR16F,
63 kRGBA8,
64 kR8,
65 kRGBA8I,
66 kR8I,
67 };
68
Ethan Nicholas762466e2017-06-29 10:03:38 -040069 // used by SkSL processors
70 enum Key {
71 // field is not a key
72 kNo_Key,
73 // field is a key
74 kKey_Key,
75 // key is 0 or 1 depending on whether the matrix is an identity matrix
76 kIdentity_Key,
77 };
78
Ethan Nicholas11d53972016-11-28 11:23:23 -050079 static const char* FormatToStr(Format format) {
80 switch (format) {
81 case Format::kUnspecified: return "";
82 case Format::kRGBA32F: return "rgba32f";
83 case Format::kR32F: return "r32f";
84 case Format::kRGBA16F: return "rgba16f";
85 case Format::kR16F: return "r16f";
86 case Format::kRGBA8: return "rgba8";
87 case Format::kR8: return "r8";
88 case Format::kRGBA8I: return "rgba8i";
89 case Format::kR8I: return "r8i";
90 }
Ethan Nicholas0df1b042017-03-31 13:56:23 -040091 ABORT("Unexpected format");
Ethan Nicholas11d53972016-11-28 11:23:23 -050092 }
93
Ethan Nicholas0df1b042017-03-31 13:56:23 -040094 static bool ReadFormat(String str, Format* format) {
Ethan Nicholas11d53972016-11-28 11:23:23 -050095 if (str == "rgba32f") {
96 *format = Format::kRGBA32F;
97 return true;
98 } else if (str == "r32f") {
99 *format = Format::kR32F;
100 return true;
101 } else if (str == "rgba16f") {
102 *format = Format::kRGBA16F;
103 return true;
104 } else if (str == "r16f") {
105 *format = Format::kR16F;
106 return true;
107 } else if (str == "rgba8") {
108 *format = Format::kRGBA8;
109 return true;
110 } else if (str == "r8") {
111 *format = Format::kR8;
112 return true;
113 } else if (str == "rgba8i") {
114 *format = Format::kRGBA8I;
115 return true;
116 } else if (str == "r8i") {
117 *format = Format::kR8I;
118 return true;
119 }
120 return false;
121 }
ethannicholasb3058bd2016-07-01 08:22:01 -0700122
Ethan Nicholas39204fd2017-11-27 13:12:30 -0500123 Layout(int flags, int location, int offset, int binding, int index, int set, int builtin,
124 int inputAttachmentIndex, Format format, Primitive primitive, int maxVertices,
125 int invocations, String when, Key key, StringFragment ctype)
126 : fFlags(flags)
127 , fLocation(location)
Ethan Nicholas19671772016-11-28 16:30:17 -0500128 , fOffset(offset)
ethannicholasb3058bd2016-07-01 08:22:01 -0700129 , fBinding(binding)
130 , fIndex(index)
131 , fSet(set)
ethannicholasf789b382016-08-03 12:43:36 -0700132 , fBuiltin(builtin)
Greg Daniel64773e62016-11-22 09:44:03 -0500133 , fInputAttachmentIndex(inputAttachmentIndex)
ethannicholas8ac838d2016-11-22 08:39:36 -0800134 , fFormat(format)
Ethan Nicholas52cad152017-02-16 16:37:32 -0500135 , fPrimitive(primitive)
136 , fMaxVertices(maxVertices)
Ethan Nicholas762466e2017-06-29 10:03:38 -0400137 , fInvocations(invocations)
138 , fWhen(when)
Ethan Nicholasd608c092017-10-26 09:30:08 -0400139 , fKey(key)
140 , fCType(ctype) {}
Brian Salomon2a51de82016-11-16 12:06:01 -0500141
Greg Daniel64773e62016-11-22 09:44:03 -0500142 Layout()
Ethan Nicholas39204fd2017-11-27 13:12:30 -0500143 : fFlags(0)
144 , fLocation(-1)
Ethan Nicholas19671772016-11-28 16:30:17 -0500145 , fOffset(-1)
Brian Salomon2a51de82016-11-16 12:06:01 -0500146 , fBinding(-1)
147 , fIndex(-1)
148 , fSet(-1)
149 , fBuiltin(-1)
Greg Daniel64773e62016-11-22 09:44:03 -0500150 , fInputAttachmentIndex(-1)
Ethan Nicholas11d53972016-11-28 11:23:23 -0500151 , fFormat(Format::kUnspecified)
Ethan Nicholas52cad152017-02-16 16:37:32 -0500152 , fPrimitive(kUnspecified_Primitive)
153 , fMaxVertices(-1)
Ethan Nicholas762466e2017-06-29 10:03:38 -0400154 , fInvocations(-1)
155 , fKey(kNo_Key) {}
ethannicholasb3058bd2016-07-01 08:22:01 -0700156
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400157 String description() const {
158 String result;
159 String separator;
ethannicholasb3058bd2016-07-01 08:22:01 -0700160 if (fLocation >= 0) {
161 result += separator + "location = " + to_string(fLocation);
162 separator = ", ";
163 }
Ethan Nicholas19671772016-11-28 16:30:17 -0500164 if (fOffset >= 0) {
165 result += separator + "offset = " + to_string(fOffset);
166 separator = ", ";
167 }
ethannicholasb3058bd2016-07-01 08:22:01 -0700168 if (fBinding >= 0) {
169 result += separator + "binding = " + to_string(fBinding);
170 separator = ", ";
171 }
172 if (fIndex >= 0) {
173 result += separator + "index = " + to_string(fIndex);
174 separator = ", ";
175 }
176 if (fSet >= 0) {
177 result += separator + "set = " + to_string(fSet);
178 separator = ", ";
179 }
180 if (fBuiltin >= 0) {
181 result += separator + "builtin = " + to_string(fBuiltin);
182 separator = ", ";
183 }
Greg Daniel64773e62016-11-22 09:44:03 -0500184 if (fInputAttachmentIndex >= 0) {
z102.zhang937efc32018-08-17 11:15:27 +0800185 result += separator + "input_attachment_index = " + to_string(fInputAttachmentIndex);
Greg Daniel64773e62016-11-22 09:44:03 -0500186 separator = ", ";
187 }
Ethan Nicholas11d53972016-11-28 11:23:23 -0500188 if (Format::kUnspecified != fFormat) {
189 result += separator + FormatToStr(fFormat);
Brian Salomon2a51de82016-11-16 12:06:01 -0500190 separator = ", ";
191 }
Ethan Nicholas39204fd2017-11-27 13:12:30 -0500192 if (fFlags & kOriginUpperLeft_Flag) {
193 result += separator + "origin_upper_left";
194 separator = ", ";
195 }
196 if (fFlags & kOverrideCoverage_Flag) {
197 result += separator + "override_coverage";
198 separator = ", ";
199 }
200 if (fFlags & kBlendSupportAllEquations_Flag) {
201 result += separator + "blend_support_all_equations";
202 separator = ", ";
203 }
204 if (fFlags & kBlendSupportMultiply_Flag) {
205 result += separator + "blend_support_multiply";
206 separator = ", ";
207 }
208 if (fFlags & kBlendSupportScreen_Flag) {
209 result += separator + "blend_support_screen";
210 separator = ", ";
211 }
212 if (fFlags & kBlendSupportOverlay_Flag) {
213 result += separator + "blend_support_overlay";
214 separator = ", ";
215 }
216 if (fFlags & kBlendSupportDarken_Flag) {
217 result += separator + "blend_support_darken";
218 separator = ", ";
219 }
220 if (fFlags & kBlendSupportLighten_Flag) {
221 result += separator + "blend_support_lighten";
222 separator = ", ";
223 }
224 if (fFlags & kBlendSupportColorDodge_Flag) {
225 result += separator + "blend_support_colordodge";
226 separator = ", ";
227 }
228 if (fFlags & kBlendSupportColorBurn_Flag) {
229 result += separator + "blend_support_colorburn";
230 separator = ", ";
231 }
232 if (fFlags & kBlendSupportHardLight_Flag) {
233 result += separator + "blend_support_hardlight";
234 separator = ", ";
235 }
236 if (fFlags & kBlendSupportSoftLight_Flag) {
237 result += separator + "blend_support_softlight";
238 separator = ", ";
239 }
240 if (fFlags & kBlendSupportDifference_Flag) {
241 result += separator + "blend_support_difference";
242 separator = ", ";
243 }
244 if (fFlags & kBlendSupportExclusion_Flag) {
245 result += separator + "blend_support_exclusion";
246 separator = ", ";
247 }
248 if (fFlags & kBlendSupportHSLHue_Flag) {
249 result += separator + "blend_support_hsl_hue";
250 separator = ", ";
251 }
252 if (fFlags & kBlendSupportHSLSaturation_Flag) {
253 result += separator + "blend_support_hsl_saturation";
254 separator = ", ";
255 }
256 if (fFlags & kBlendSupportHSLColor_Flag) {
257 result += separator + "blend_support_hsl_color";
258 separator = ", ";
259 }
260 if (fFlags & kBlendSupportHSLLuminosity_Flag) {
261 result += separator + "blend_support_hsl_luminosity";
262 separator = ", ";
263 }
264 if (fFlags & kPushConstant_Flag) {
ethannicholas8ac838d2016-11-22 08:39:36 -0800265 result += separator + "push_constant";
266 separator = ", ";
267 }
Michael Ludwiga4275592018-08-31 10:52:47 -0400268 if (fFlags & kTracked_Flag) {
269 result += separator + "tracked";
270 separator = ", ";
271 }
Ethan Nicholas52cad152017-02-16 16:37:32 -0500272 switch (fPrimitive) {
273 case kPoints_Primitive:
274 result += separator + "points";
275 separator = ", ";
276 break;
277 case kLines_Primitive:
278 result += separator + "lines";
279 separator = ", ";
280 break;
281 case kLineStrip_Primitive:
282 result += separator + "line_strip";
283 separator = ", ";
284 break;
285 case kLinesAdjacency_Primitive:
286 result += separator + "lines_adjacency";
287 separator = ", ";
288 break;
289 case kTriangles_Primitive:
290 result += separator + "triangles";
291 separator = ", ";
292 break;
293 case kTriangleStrip_Primitive:
294 result += separator + "triangle_strip";
295 separator = ", ";
296 break;
297 case kTrianglesAdjacency_Primitive:
298 result += separator + "triangles_adjacency";
299 separator = ", ";
300 break;
301 case kUnspecified_Primitive:
302 break;
303 }
304 if (fMaxVertices >= 0) {
305 result += separator + "max_vertices = " + to_string(fMaxVertices);
306 separator = ", ";
307 }
308 if (fInvocations >= 0) {
309 result += separator + "invocations = " + to_string(fInvocations);
310 separator = ", ";
311 }
Ethan Nicholas762466e2017-06-29 10:03:38 -0400312 if (fWhen.size()) {
313 result += separator + "when = " + fWhen;
314 separator = ", ";
315 }
Ethan Nicholas9e1138d2016-11-21 10:39:35 -0500316 if (result.size() > 0) {
ethannicholasb3058bd2016-07-01 08:22:01 -0700317 result = "layout (" + result + ")";
318 }
Ethan Nicholas00543112018-07-31 09:44:36 -0400319 if (fKey) {
320 result += "/* key */";
321 }
ethannicholasb3058bd2016-07-01 08:22:01 -0700322 return result;
323 }
324
325 bool operator==(const Layout& other) const {
Ethan Nicholas39204fd2017-11-27 13:12:30 -0500326 return fFlags == other.fFlags &&
327 fLocation == other.fLocation &&
328 fOffset == other.fOffset &&
329 fBinding == other.fBinding &&
330 fIndex == other.fIndex &&
331 fSet == other.fSet &&
332 fBuiltin == other.fBuiltin &&
333 fInputAttachmentIndex == other.fInputAttachmentIndex &&
334 fFormat == other.fFormat &&
335 fPrimitive == other.fPrimitive &&
336 fMaxVertices == other.fMaxVertices &&
337 fInvocations == other.fInvocations;
ethannicholasb3058bd2016-07-01 08:22:01 -0700338 }
339
340 bool operator!=(const Layout& other) const {
341 return !(*this == other);
342 }
343
Ethan Nicholas39204fd2017-11-27 13:12:30 -0500344 int fFlags;
ethannicholasf789b382016-08-03 12:43:36 -0700345 int fLocation;
Ethan Nicholas19671772016-11-28 16:30:17 -0500346 int fOffset;
ethannicholasf789b382016-08-03 12:43:36 -0700347 int fBinding;
348 int fIndex;
349 int fSet;
Greg Daniel64773e62016-11-22 09:44:03 -0500350 // builtin comes from SPIR-V and identifies which particular builtin value this object
351 // represents.
ethannicholasf789b382016-08-03 12:43:36 -0700352 int fBuiltin;
Greg Daniel64773e62016-11-22 09:44:03 -0500353 // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a
354 // corresponding attachment on the subpass in which the shader is being used.
355 int fInputAttachmentIndex;
Ethan Nicholas11d53972016-11-28 11:23:23 -0500356 Format fFormat;
Ethan Nicholas52cad152017-02-16 16:37:32 -0500357 Primitive fPrimitive;
358 int fMaxVertices;
359 int fInvocations;
Ethan Nicholas762466e2017-06-29 10:03:38 -0400360 String fWhen;
361 Key fKey;
Ethan Nicholasd608c092017-10-26 09:30:08 -0400362 StringFragment fCType;
ethannicholasb3058bd2016-07-01 08:22:01 -0700363};
364
365} // namespace
366
367#endif