• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "include/private/SkSLString.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 Flag {
22         kOriginUpperLeft_Flag            = 1 <<  0,
23         kPushConstant_Flag               = 1 <<  1,
24         kBlendSupportAllEquations_Flag   = 1 <<  2,
25         kSRGBUnpremul_Flag               = 1 <<  3,
26 
27         // These flags indicate if the qualifier appeared, regardless of the accompanying value.
28         kLocation_Flag                   = 1 <<  4,
29         kOffset_Flag                     = 1 <<  5,
30         kBinding_Flag                    = 1 <<  6,
31         kIndex_Flag                      = 1 <<  7,
32         kSet_Flag                        = 1 <<  8,
33         kBuiltin_Flag                    = 1 <<  9,
34         kInputAttachmentIndex_Flag       = 1 << 10,
35 #ifdef SKSL_EXT
36         kConstantId_Flag                 = 1 << 11,
37 #endif
38     };
39 
LayoutLayout40     Layout(int flags, int location, int offset, int binding, int index, int set, int builtin,
41            int inputAttachmentIndex)
42     : fFlags(flags)
43     , fLocation(location)
44     , fOffset(offset)
45     , fBinding(binding)
46     , fIndex(index)
47     , fSet(set)
48     , fBuiltin(builtin)
49     , fInputAttachmentIndex(inputAttachmentIndex) {}
50 
LayoutLayout51     Layout()
52     : fFlags(0)
53     , fLocation(-1)
54     , fOffset(-1)
55     , fBinding(-1)
56     , fIndex(-1)
57     , fSet(-1)
58     , fBuiltin(-1)
59     , fInputAttachmentIndex(-1) {}
60 
builtinLayout61     static Layout builtin(int builtin) {
62         Layout result;
63         result.fBuiltin = builtin;
64         return result;
65     }
66 
descriptionLayout67     String description() const {
68         String result;
69         auto separator = [firstSeparator = true]() mutable -> String {
70             if (firstSeparator) {
71                 firstSeparator = false;
72                 return "";
73             } else {
74                 return ", ";
75             }};
76         if (fLocation >= 0) {
77             result += separator() + "location = " + to_string(fLocation);
78         }
79         if (fOffset >= 0) {
80             result += separator() + "offset = " + to_string(fOffset);
81         }
82         if (fBinding >= 0) {
83             result += separator() + "binding = " + to_string(fBinding);
84         }
85         if (fIndex >= 0) {
86             result += separator() + "index = " + to_string(fIndex);
87         }
88         if (fSet >= 0) {
89             result += separator() + "set = " + to_string(fSet);
90         }
91         if (fBuiltin >= 0) {
92             result += separator() + "builtin = " + to_string(fBuiltin);
93         }
94         if (fInputAttachmentIndex >= 0) {
95             result += separator() + "input_attachment_index = " + to_string(fInputAttachmentIndex);
96         }
97         if (fFlags & kOriginUpperLeft_Flag) {
98             result += separator() + "origin_upper_left";
99         }
100         if (fFlags & kBlendSupportAllEquations_Flag) {
101             result += separator() + "blend_support_all_equations";
102         }
103         if (fFlags & kPushConstant_Flag) {
104             result += separator() + "push_constant";
105         }
106         if (fFlags & kSRGBUnpremul_Flag) {
107             result += separator() + "srgb_unpremul";
108         }
109 #ifdef SKSL_EXT
110         if (fFlags & kConstantId_Flag) {
111             result += separator() + "constant_id";
112         }
113 #endif
114         if (result.size() > 0) {
115             result = "layout (" + result + ")";
116         }
117         return result;
118     }
119 
120     bool operator==(const Layout& other) const {
121         return fFlags                == other.fFlags &&
122                fLocation             == other.fLocation &&
123                fOffset               == other.fOffset &&
124                fBinding              == other.fBinding &&
125                fIndex                == other.fIndex &&
126                fSet                  == other.fSet &&
127                fBuiltin              == other.fBuiltin &&
128 #ifdef SKSL_EXT
129                fConstantId           == other.fConstantId &&
130 #endif
131                fInputAttachmentIndex == other.fInputAttachmentIndex;
132     }
133 
134     bool operator!=(const Layout& other) const {
135         return !(*this == other);
136     }
137 
138     int fFlags;
139     int fLocation;
140     int fOffset;
141     int fBinding;
142     int fIndex;
143     int fSet;
144     // builtin comes from SPIR-V and identifies which particular builtin value this object
145     // represents.
146     int fBuiltin;
147     // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a
148     // corresponding attachment on the subpass in which the shader is being used.
149     int fInputAttachmentIndex;
150 #ifdef SKSL_EXT
151     int fConstantId = -1;
152 #endif
153 };
154 
155 }  // namespace SkSL
156 
157 #endif
158