xref: /aosp_15_r20/external/skia/src/sksl/ir/SkSLModifiersDeclaration.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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