• 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         kColor_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     };
36 
LayoutLayout37     Layout(int flags, int location, int offset, int binding, int index, int set, int builtin,
38            int inputAttachmentIndex)
39     : fFlags(flags)
40     , fLocation(location)
41     , fOffset(offset)
42     , fBinding(binding)
43     , fIndex(index)
44     , fSet(set)
45     , fBuiltin(builtin)
46     , fInputAttachmentIndex(inputAttachmentIndex) {}
47 
LayoutLayout48     Layout()
49     : fFlags(0)
50     , fLocation(-1)
51     , fOffset(-1)
52     , fBinding(-1)
53     , fIndex(-1)
54     , fSet(-1)
55     , fBuiltin(-1)
56     , fInputAttachmentIndex(-1) {}
57 
builtinLayout58     static Layout builtin(int builtin) {
59         Layout result;
60         result.fBuiltin = builtin;
61         return result;
62     }
63 
descriptionLayout64     std::string description() const {
65         std::string result;
66         auto separator = [firstSeparator = true]() mutable -> std::string {
67             if (firstSeparator) {
68                 firstSeparator = false;
69                 return "";
70             } else {
71                 return ", ";
72             }};
73         if (fLocation >= 0) {
74             result += separator() + "location = " + std::to_string(fLocation);
75         }
76         if (fOffset >= 0) {
77             result += separator() + "offset = " + std::to_string(fOffset);
78         }
79         if (fBinding >= 0) {
80             result += separator() + "binding = " + std::to_string(fBinding);
81         }
82         if (fIndex >= 0) {
83             result += separator() + "index = " + std::to_string(fIndex);
84         }
85         if (fSet >= 0) {
86             result += separator() + "set = " + std::to_string(fSet);
87         }
88         if (fBuiltin >= 0) {
89             result += separator() + "builtin = " + std::to_string(fBuiltin);
90         }
91         if (fInputAttachmentIndex >= 0) {
92             result += separator() + "input_attachment_index = " +
93                       std::to_string(fInputAttachmentIndex);
94         }
95         if (fFlags & kOriginUpperLeft_Flag) {
96             result += separator() + "origin_upper_left";
97         }
98         if (fFlags & kBlendSupportAllEquations_Flag) {
99             result += separator() + "blend_support_all_equations";
100         }
101         if (fFlags & kPushConstant_Flag) {
102             result += separator() + "push_constant";
103         }
104         if (fFlags & kColor_Flag) {
105             result += separator() + "color";
106         }
107         if (result.size() > 0) {
108             result = "layout (" + result + ")";
109         }
110         return result;
111     }
112 
113     bool operator==(const Layout& other) const {
114         return fFlags                == other.fFlags &&
115                fLocation             == other.fLocation &&
116                fOffset               == other.fOffset &&
117                fBinding              == other.fBinding &&
118                fIndex                == other.fIndex &&
119                fSet                  == other.fSet &&
120                fBuiltin              == other.fBuiltin &&
121                fInputAttachmentIndex == other.fInputAttachmentIndex;
122     }
123 
124     bool operator!=(const Layout& other) const {
125         return !(*this == other);
126     }
127 
128     int fFlags;
129     int fLocation;
130     int fOffset;
131     int fBinding;
132     int fIndex;
133     int fSet;
134     // builtin comes from SPIR-V and identifies which particular builtin value this object
135     // represents.
136     int fBuiltin;
137     // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a
138     // corresponding attachment on the subpass in which the shader is being used.
139     int fInputAttachmentIndex;
140 };
141 
142 }  // namespace SkSL
143 
144 #endif
145