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 "src/base/SkEnumBitMask.h" 12 13 #include <string> 14 15 namespace SkSL { 16 17 class Context; 18 class Position; 19 20 enum class LayoutFlag : int { 21 kNone = 0, 22 kAll = ~0, 23 24 kOriginUpperLeft = 1 << 0, 25 kPushConstant = 1 << 1, 26 kBlendSupportAllEquations = 1 << 2, 27 kColor = 1 << 3, 28 29 // These flags indicate if the qualifier appeared, regardless of the accompanying value. 30 kLocation = 1 << 4, 31 kOffset = 1 << 5, 32 kBinding = 1 << 6, 33 kTexture = 1 << 7, 34 kSampler = 1 << 8, 35 kIndex = 1 << 9, 36 kSet = 1 << 10, 37 kBuiltin = 1 << 11, 38 kInputAttachmentIndex = 1 << 12, 39 40 // These flags indicate the backend type; only one at most can be set. 41 kVulkan = 1 << 13, 42 kMetal = 1 << 14, 43 kWebGPU = 1 << 15, 44 kDirect3D = 1 << 16, 45 46 kAllBackends = kVulkan | kMetal | kWebGPU | kDirect3D, 47 48 // These flags indicate the pixel format; only one at most can be set. 49 // (https://www.khronos.org/opengl/wiki/Layout_Qualifier_(GLSL)#Image_formats) 50 kRGBA8 = 1 << 17, 51 kRGBA32F = 1 << 18, 52 kR32F = 1 << 19, 53 54 kAllPixelFormats = kRGBA8 | kRGBA32F | kR32F, 55 56 // The local invocation size of a compute program. 57 kLocalSizeX = 1 << 20, 58 kLocalSizeY = 1 << 21, 59 kLocalSizeZ = 1 << 22, 60 }; 61 62 } // namespace SkSL 63 64 SK_MAKE_BITMASK_OPS(SkSL::LayoutFlag); 65 66 namespace SkSL { 67 68 using LayoutFlags = SkEnumBitMask<SkSL::LayoutFlag>; 69 70 /** 71 * Represents a layout block appearing before a variable declaration, as in: 72 * 73 * layout (location = 0) int x; 74 */ 75 struct Layout { LayoutLayout76 Layout(LayoutFlags flags, int location, int offset, int binding, int index, int set, 77 int builtin, int inputAttachmentIndex) 78 : fFlags(flags) 79 , fLocation(location) 80 , fOffset(offset) 81 , fBinding(binding) 82 , fIndex(index) 83 , fSet(set) 84 , fBuiltin(builtin) 85 , fInputAttachmentIndex(inputAttachmentIndex) {} 86 87 constexpr Layout() = default; 88 builtinLayout89 static Layout builtin(int builtin) { 90 Layout result; 91 result.fBuiltin = builtin; 92 return result; 93 } 94 95 std::string description() const; 96 std::string paddedDescription() const; 97 98 /** 99 * Verifies that only permitted layout flags are included. Reports errors and returns false in 100 * the event of a violation. 101 */ 102 bool checkPermittedLayout(const Context& context, 103 Position pos, 104 LayoutFlags permittedLayoutFlags) const; 105 106 bool operator==(const Layout& other) const; 107 108 bool operator!=(const Layout& other) const { 109 return !(*this == other); 110 } 111 112 LayoutFlags fFlags = LayoutFlag::kNone; 113 int fLocation = -1; 114 int fOffset = -1; 115 int fBinding = -1; 116 int fTexture = -1; 117 int fSampler = -1; 118 int fIndex = -1; 119 int fSet = -1; 120 // builtin comes from SPIR-V and identifies which particular builtin value this object 121 // represents. 122 int fBuiltin = -1; 123 // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a 124 // corresponding attachment on the subpass in which the shader is being used. 125 int fInputAttachmentIndex = -1; 126 127 // The local invocation size dimensions of a compute program. 128 int fLocalSizeX = -1; 129 int fLocalSizeY = -1; 130 int fLocalSizeZ = -1; 131 }; 132 133 } // namespace SkSL 134 135 #endif 136