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