Line data Source code
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_LAYOUT
9 : #define SKSL_LAYOUT
10 :
11 : #include "SkSLUtil.h"
12 :
13 : namespace SkSL {
14 :
15 : /**
16 : * Represents a layout block appearing before a variable declaration, as in:
17 : *
18 : * layout (location = 0) int x;
19 : */
20 : struct Layout {
21 : enum Primitive {
22 : kUnspecified_Primitive = -1,
23 : kPoints_Primitive,
24 : kLines_Primitive,
25 : kLineStrip_Primitive,
26 : kLinesAdjacency_Primitive,
27 : kTriangles_Primitive,
28 : kTriangleStrip_Primitive,
29 : kTrianglesAdjacency_Primitive
30 : };
31 :
32 : // These are used by images in GLSL. We only support a subset of what GL supports.
33 : enum class Format {
34 : kUnspecified = -1,
35 : kRGBA32F,
36 : kR32F,
37 : kRGBA16F,
38 : kR16F,
39 : kRGBA8,
40 : kR8,
41 : kRGBA8I,
42 : kR8I,
43 : };
44 :
45 0 : static const char* FormatToStr(Format format) {
46 0 : switch (format) {
47 0 : case Format::kUnspecified: return "";
48 0 : case Format::kRGBA32F: return "rgba32f";
49 0 : case Format::kR32F: return "r32f";
50 0 : case Format::kRGBA16F: return "rgba16f";
51 0 : case Format::kR16F: return "r16f";
52 0 : case Format::kRGBA8: return "rgba8";
53 0 : case Format::kR8: return "r8";
54 0 : case Format::kRGBA8I: return "rgba8i";
55 0 : case Format::kR8I: return "r8i";
56 : }
57 0 : ABORT("Unexpected format");
58 : return "";
59 : }
60 :
61 0 : static bool ReadFormat(String str, Format* format) {
62 0 : if (str == "rgba32f") {
63 0 : *format = Format::kRGBA32F;
64 0 : return true;
65 0 : } else if (str == "r32f") {
66 0 : *format = Format::kR32F;
67 0 : return true;
68 0 : } else if (str == "rgba16f") {
69 0 : *format = Format::kRGBA16F;
70 0 : return true;
71 0 : } else if (str == "r16f") {
72 0 : *format = Format::kR16F;
73 0 : return true;
74 0 : } else if (str == "rgba8") {
75 0 : *format = Format::kRGBA8;
76 0 : return true;
77 0 : } else if (str == "r8") {
78 0 : *format = Format::kR8;
79 0 : return true;
80 0 : } else if (str == "rgba8i") {
81 0 : *format = Format::kRGBA8I;
82 0 : return true;
83 0 : } else if (str == "r8i") {
84 0 : *format = Format::kR8I;
85 0 : return true;
86 : }
87 0 : return false;
88 : }
89 :
90 0 : Layout(int location, int offset, int binding, int index, int set, int builtin,
91 : int inputAttachmentIndex, bool originUpperLeft, bool overrideCoverage,
92 : bool blendSupportAllEquations, Format format, bool pushconstant, Primitive primitive,
93 : int maxVertices, int invocations)
94 0 : : fLocation(location)
95 : , fOffset(offset)
96 : , fBinding(binding)
97 : , fIndex(index)
98 : , fSet(set)
99 : , fBuiltin(builtin)
100 : , fInputAttachmentIndex(inputAttachmentIndex)
101 : , fOriginUpperLeft(originUpperLeft)
102 : , fOverrideCoverage(overrideCoverage)
103 : , fBlendSupportAllEquations(blendSupportAllEquations)
104 : , fFormat(format)
105 : , fPushConstant(pushconstant)
106 : , fPrimitive(primitive)
107 : , fMaxVertices(maxVertices)
108 0 : , fInvocations(invocations) {}
109 :
110 0 : Layout()
111 0 : : fLocation(-1)
112 : , fOffset(-1)
113 : , fBinding(-1)
114 : , fIndex(-1)
115 : , fSet(-1)
116 : , fBuiltin(-1)
117 : , fInputAttachmentIndex(-1)
118 : , fOriginUpperLeft(false)
119 : , fOverrideCoverage(false)
120 : , fBlendSupportAllEquations(false)
121 : , fFormat(Format::kUnspecified)
122 : , fPushConstant(false)
123 : , fPrimitive(kUnspecified_Primitive)
124 : , fMaxVertices(-1)
125 0 : , fInvocations(-1) {}
126 :
127 0 : String description() const {
128 0 : String result;
129 0 : String separator;
130 0 : if (fLocation >= 0) {
131 0 : result += separator + "location = " + to_string(fLocation);
132 0 : separator = ", ";
133 : }
134 0 : if (fOffset >= 0) {
135 0 : result += separator + "offset = " + to_string(fOffset);
136 0 : separator = ", ";
137 : }
138 0 : if (fBinding >= 0) {
139 0 : result += separator + "binding = " + to_string(fBinding);
140 0 : separator = ", ";
141 : }
142 0 : if (fIndex >= 0) {
143 0 : result += separator + "index = " + to_string(fIndex);
144 0 : separator = ", ";
145 : }
146 0 : if (fSet >= 0) {
147 0 : result += separator + "set = " + to_string(fSet);
148 0 : separator = ", ";
149 : }
150 0 : if (fBuiltin >= 0) {
151 0 : result += separator + "builtin = " + to_string(fBuiltin);
152 0 : separator = ", ";
153 : }
154 0 : if (fInputAttachmentIndex >= 0) {
155 0 : result += separator + "input_attachment_index = " + to_string(fBuiltin);
156 0 : separator = ", ";
157 : }
158 0 : if (fOriginUpperLeft) {
159 0 : result += separator + "origin_upper_left";
160 0 : separator = ", ";
161 : }
162 0 : if (fOverrideCoverage) {
163 0 : result += separator + "override_coverage";
164 0 : separator = ", ";
165 : }
166 0 : if (fBlendSupportAllEquations) {
167 0 : result += separator + "blend_support_all_equations";
168 0 : separator = ", ";
169 : }
170 0 : if (Format::kUnspecified != fFormat) {
171 0 : result += separator + FormatToStr(fFormat);
172 0 : separator = ", ";
173 : }
174 0 : if (fPushConstant) {
175 0 : result += separator + "push_constant";
176 0 : separator = ", ";
177 : }
178 0 : switch (fPrimitive) {
179 : case kPoints_Primitive:
180 0 : result += separator + "points";
181 0 : separator = ", ";
182 0 : break;
183 : case kLines_Primitive:
184 0 : result += separator + "lines";
185 0 : separator = ", ";
186 0 : break;
187 : case kLineStrip_Primitive:
188 0 : result += separator + "line_strip";
189 0 : separator = ", ";
190 0 : break;
191 : case kLinesAdjacency_Primitive:
192 0 : result += separator + "lines_adjacency";
193 0 : separator = ", ";
194 0 : break;
195 : case kTriangles_Primitive:
196 0 : result += separator + "triangles";
197 0 : separator = ", ";
198 0 : break;
199 : case kTriangleStrip_Primitive:
200 0 : result += separator + "triangle_strip";
201 0 : separator = ", ";
202 0 : break;
203 : case kTrianglesAdjacency_Primitive:
204 0 : result += separator + "triangles_adjacency";
205 0 : separator = ", ";
206 0 : break;
207 : case kUnspecified_Primitive:
208 0 : break;
209 : }
210 0 : if (fMaxVertices >= 0) {
211 0 : result += separator + "max_vertices = " + to_string(fMaxVertices);
212 0 : separator = ", ";
213 : }
214 0 : if (fInvocations >= 0) {
215 0 : result += separator + "invocations = " + to_string(fInvocations);
216 0 : separator = ", ";
217 : }
218 0 : if (result.size() > 0) {
219 0 : result = "layout (" + result + ")";
220 : }
221 0 : return result;
222 : }
223 :
224 0 : bool operator==(const Layout& other) const {
225 0 : return fLocation == other.fLocation &&
226 0 : fOffset == other.fOffset &&
227 0 : fBinding == other.fBinding &&
228 0 : fIndex == other.fIndex &&
229 0 : fSet == other.fSet &&
230 0 : fBuiltin == other.fBuiltin &&
231 0 : fInputAttachmentIndex == other.fInputAttachmentIndex &&
232 0 : fOriginUpperLeft == other.fOriginUpperLeft &&
233 0 : fOverrideCoverage == other.fOverrideCoverage &&
234 0 : fBlendSupportAllEquations == other.fBlendSupportAllEquations &&
235 0 : fFormat == other.fFormat &&
236 0 : fPrimitive == other.fPrimitive &&
237 0 : fMaxVertices == other.fMaxVertices &&
238 0 : fInvocations == other.fInvocations;
239 : }
240 :
241 : bool operator!=(const Layout& other) const {
242 : return !(*this == other);
243 : }
244 :
245 : int fLocation;
246 : int fOffset;
247 : int fBinding;
248 : int fIndex;
249 : int fSet;
250 : // builtin comes from SPIR-V and identifies which particular builtin value this object
251 : // represents.
252 : int fBuiltin;
253 : // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a
254 : // corresponding attachment on the subpass in which the shader is being used.
255 : int fInputAttachmentIndex;
256 : bool fOriginUpperLeft;
257 : bool fOverrideCoverage;
258 : bool fBlendSupportAllEquations;
259 : Format fFormat;
260 : bool fPushConstant;
261 : Primitive fPrimitive;
262 : int fMaxVertices;
263 : int fInvocations;
264 : };
265 :
266 : } // namespace
267 :
268 : #endif
|