1 /*
2 * Copyright 2023 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 #include "src/sksl/ir/SkSLModifiersDeclaration.h"
9
10 #include "include/private/base/SkAssert.h"
11 #include "src/base/SkEnumBitMask.h"
12 #include "src/sksl/SkSLContext.h"
13 #include "src/sksl/SkSLErrorReporter.h"
14 #include "src/sksl/SkSLProgramSettings.h"
15 #include "src/sksl/ir/SkSLModifiers.h"
16
17 #include <cstdint>
18
19 namespace SkSL {
20
21 enum class ProgramKind : int8_t;
22
Convert(const Context & context,const Modifiers & modifiers)23 std::unique_ptr<ModifiersDeclaration> ModifiersDeclaration::Convert(const Context& context,
24 const Modifiers& modifiers) {
25 SkSL::ProgramKind kind = context.fConfig->fKind;
26 if (!ProgramConfig::IsFragment(kind) && !ProgramConfig::IsVertex(kind) &&
27 !ProgramConfig::IsCompute(kind)) {
28 context.fErrors->error(modifiers.fPosition,
29 "layout qualifiers are not allowed in this kind of program");
30 return nullptr;
31 }
32
33 if (modifiers.fLayout.fLocalSizeX >= 0 ||
34 modifiers.fLayout.fLocalSizeY >= 0 ||
35 modifiers.fLayout.fLocalSizeZ >= 0) {
36 if (modifiers.fLayout.fLocalSizeX == 0 ||
37 modifiers.fLayout.fLocalSizeY == 0 ||
38 modifiers.fLayout.fLocalSizeZ == 0) {
39 context.fErrors->error(modifiers.fPosition, "local size qualifiers cannot be zero");
40 return nullptr;
41 }
42 if (!ProgramConfig::IsCompute(kind)) {
43 context.fErrors->error(
44 modifiers.fPosition,
45 "local size layout qualifiers are only allowed in a compute program");
46 return nullptr;
47 }
48 if (modifiers.fFlags != ModifierFlag::kIn) {
49 context.fErrors->error(
50 modifiers.fPosition,
51 "local size layout qualifiers must be defined using an 'in' declaration");
52 return nullptr;
53 }
54 }
55
56 return ModifiersDeclaration::Make(context, modifiers);
57 }
58
Make(const Context & context,const Modifiers & modifiers)59 std::unique_ptr<ModifiersDeclaration> ModifiersDeclaration::Make(const Context& context,
60 const Modifiers& modifiers) {
61 [[maybe_unused]] SkSL::ProgramKind kind = context.fConfig->fKind;
62 SkASSERT(ProgramConfig::IsFragment(kind) || ProgramConfig::IsVertex(kind) ||
63 ProgramConfig::IsCompute(kind));
64
65 return std::make_unique<ModifiersDeclaration>(modifiers.fPosition,
66 modifiers.fLayout,
67 modifiers.fFlags);
68 }
69
70 } // namespace SkSL
71