Flutter Engine
The Flutter Engine
SkSLLayout.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 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
9
11#include "src/base/SkMathPriv.h"
15#include "src/sksl/SkSLString.h"
16
17namespace SkSL {
18
19std::string Layout::paddedDescription() const {
20 std::string result;
21 auto separator = SkSL::String::Separator();
23 result += separator() + "vulkan";
24 }
26 result += separator() + "metal";
27 }
29 result += separator() + "webgpu";
30 }
32 result += separator() + "direct3d";
33 }
35 result += separator() + "rgba8";
36 }
38 result += separator() + "rgba32f";
39 }
41 result += separator() + "r32f";
42 }
43 if (fLocation >= 0) {
44 result += separator() + "location = " + std::to_string(fLocation);
45 }
46 if (fOffset >= 0) {
47 result += separator() + "offset = " + std::to_string(fOffset);
48 }
49 if (fBinding >= 0) {
50 result += separator() + "binding = " + std::to_string(fBinding);
51 }
52 if (fTexture >= 0) {
53 result += separator() + "texture = " + std::to_string(fTexture);
54 }
55 if (fSampler >= 0) {
56 result += separator() + "sampler = " + std::to_string(fSampler);
57 }
58 if (fIndex >= 0) {
59 result += separator() + "index = " + std::to_string(fIndex);
60 }
61 if (fSet >= 0) {
62 result += separator() + "set = " + std::to_string(fSet);
63 }
64 if (fBuiltin >= 0) {
65 result += separator() + "builtin = " + std::to_string(fBuiltin);
66 }
67 if (fInputAttachmentIndex >= 0) {
68 result += separator() + "input_attachment_index = " + std::to_string(fInputAttachmentIndex);
69 }
71 result += separator() + "origin_upper_left";
72 }
74 result += separator() + "blend_support_all_equations";
75 }
77 result += separator() + "push_constant";
78 }
80 result += separator() + "color";
81 }
82 if (fLocalSizeX >= 0) {
83 result += separator() + "local_size_x = " + std::to_string(fLocalSizeX);
84 }
85 if (fLocalSizeY >= 0) {
86 result += separator() + "local_size_y = " + std::to_string(fLocalSizeY);
87 }
88 if (fLocalSizeZ >= 0) {
89 result += separator() + "local_size_z = " + std::to_string(fLocalSizeZ);
90 }
91 if (result.size() > 0) {
92 result = "layout (" + result + ") ";
93 }
94 return result;
95}
96
97std::string Layout::description() const {
98 std::string s = this->paddedDescription();
99 if (!s.empty()) {
100 s.pop_back();
101 }
102 return s;
103}
104
105bool Layout::checkPermittedLayout(const Context& context,
106 Position pos,
107 LayoutFlags permittedLayoutFlags) const {
108 static constexpr struct { LayoutFlag flag; const char* name; } kLayoutFlags[] = {
109 { LayoutFlag::kOriginUpperLeft, "origin_upper_left"},
110 { LayoutFlag::kPushConstant, "push_constant"},
111 { LayoutFlag::kBlendSupportAllEquations, "blend_support_all_equations"},
112 { LayoutFlag::kColor, "color"},
113 { LayoutFlag::kLocation, "location"},
114 { LayoutFlag::kOffset, "offset"},
115 { LayoutFlag::kBinding, "binding"},
116 { LayoutFlag::kTexture, "texture"},
117 { LayoutFlag::kSampler, "sampler"},
118 { LayoutFlag::kIndex, "index"},
119 { LayoutFlag::kSet, "set"},
120 { LayoutFlag::kBuiltin, "builtin"},
121 { LayoutFlag::kInputAttachmentIndex, "input_attachment_index"},
122 { LayoutFlag::kVulkan, "vulkan"},
123 { LayoutFlag::kMetal, "metal"},
124 { LayoutFlag::kWebGPU, "webgpu"},
125 { LayoutFlag::kDirect3D, "direct3d"},
126 { LayoutFlag::kRGBA8, "rgba8"},
127 { LayoutFlag::kRGBA32F, "rgba32f"},
128 { LayoutFlag::kR32F, "r32f"},
129 { LayoutFlag::kLocalSizeX, "local_size_x"},
130 { LayoutFlag::kLocalSizeY, "local_size_y"},
131 { LayoutFlag::kLocalSizeZ, "local_size_z"},
132 };
133
134 bool success = true;
135 LayoutFlags layoutFlags = fFlags;
136
137 LayoutFlags backendFlags = layoutFlags & LayoutFlag::kAllBackends;
138 if (SkPopCount(backendFlags.value()) > 1) {
139 context.fErrors->error(pos, "only one backend qualifier can be used");
140 success = false;
141 }
142
143 LayoutFlags pixelFormatFlags = layoutFlags & LayoutFlag::kAllPixelFormats;
144 if (SkPopCount(pixelFormatFlags.value()) > 1) {
145 context.fErrors->error(pos, "only one pixel format qualifier can be used");
146 success = false;
147 }
148
149 if ((layoutFlags & (LayoutFlag::kTexture | LayoutFlag::kSampler)) &&
150 layoutFlags & LayoutFlag::kBinding) {
151 context.fErrors->error(pos, "'binding' modifier cannot coexist with 'texture'/'sampler'");
152 success = false;
153 }
154 // The `texture` and `sampler` flags are only allowed when targeting Metal, WebGPU or Direct3D.
156 permittedLayoutFlags &= ~LayoutFlag::kTexture;
157 permittedLayoutFlags &= ~LayoutFlag::kSampler;
158 }
159 // The `push_constant` flag is only allowed when targeting Vulkan or WebGPU.
160 if (!(layoutFlags & (LayoutFlag::kVulkan | LayoutFlag::kWebGPU))) {
161 permittedLayoutFlags &= ~LayoutFlag::kPushConstant;
162 }
163 // The `set` flag is not allowed when explicitly targeting Metal.
164 if (layoutFlags & LayoutFlag::kMetal) {
165 permittedLayoutFlags &= ~LayoutFlag::kSet;
166 }
167
168 for (const auto& lf : kLayoutFlags) {
169 if (layoutFlags & lf.flag) {
170 if (!(permittedLayoutFlags & lf.flag)) {
171 context.fErrors->error(pos, "layout qualifier '" + std::string(lf.name) +
172 "' is not permitted here");
173 success = false;
174 }
175 layoutFlags &= ~lf.flag;
176 }
177 }
178 SkASSERT(layoutFlags == LayoutFlag::kNone);
179 return success;
180}
181
182bool Layout::operator==(const Layout& other) const {
183 return fFlags == other.fFlags &&
184 fLocation == other.fLocation &&
185 fOffset == other.fOffset &&
186 fBinding == other.fBinding &&
187 fTexture == other.fTexture &&
188 fSampler == other.fSampler &&
189 fIndex == other.fIndex &&
190 fSet == other.fSet &&
191 fBuiltin == other.fBuiltin &&
192 fInputAttachmentIndex == other.fInputAttachmentIndex &&
193 fLocalSizeX == other.fLocalSizeX &&
194 fLocalSizeY == other.fLocalSizeY &&
195 fLocalSizeZ == other.fLocalSizeZ;
196}
197
198} // namespace SkSL
SkPoint pos
#define SkASSERT(cond)
Definition: SkAssert.h:116
static int SkPopCount(uint32_t n)
Definition: SkMathPriv.h:136
struct MyStruct s
FlutterSemanticsFlag flag
GAsyncResult * result
std::string void void auto Separator()
Definition: SkSLString.h:30
LayoutFlag
Definition: SkSLLayout.h:20
SkEnumBitMask< SkSL::LayoutFlag > LayoutFlags
Definition: SkSLLayout.h:68
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
static SkString to_string(int n)
Definition: nanobench.cpp:119
LayoutFlags fFlags
Definition: SkSLLayout.h:112
std::string description() const
std::string paddedDescription() const
bool checkPermittedLayout(const Context &context, Position pos, LayoutFlags permittedLayoutFlags) const
int fInputAttachmentIndex
Definition: SkSLLayout.h:125
bool operator==(const Layout &other) const