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 #ifdef SKSL_EXT 36 kConstantId_Flag = 1 << 11, 37 #endif 38 }; 39 LayoutLayout40 Layout(int flags, int location, int offset, int binding, int index, int set, int builtin, 41 int inputAttachmentIndex) 42 : fFlags(flags) 43 , fLocation(location) 44 , fOffset(offset) 45 , fBinding(binding) 46 , fIndex(index) 47 , fSet(set) 48 , fBuiltin(builtin) 49 , fInputAttachmentIndex(inputAttachmentIndex) {} 50 LayoutLayout51 Layout() 52 : fFlags(0) 53 , fLocation(-1) 54 , fOffset(-1) 55 , fBinding(-1) 56 , fIndex(-1) 57 , fSet(-1) 58 , fBuiltin(-1) 59 , fInputAttachmentIndex(-1) {} 60 builtinLayout61 static Layout builtin(int builtin) { 62 Layout result; 63 result.fBuiltin = builtin; 64 return result; 65 } 66 descriptionLayout67 String description() const { 68 String result; 69 auto separator = [firstSeparator = true]() mutable -> String { 70 if (firstSeparator) { 71 firstSeparator = false; 72 return ""; 73 } else { 74 return ", "; 75 }}; 76 if (fLocation >= 0) { 77 result += separator() + "location = " + to_string(fLocation); 78 } 79 if (fOffset >= 0) { 80 result += separator() + "offset = " + to_string(fOffset); 81 } 82 if (fBinding >= 0) { 83 result += separator() + "binding = " + to_string(fBinding); 84 } 85 if (fIndex >= 0) { 86 result += separator() + "index = " + to_string(fIndex); 87 } 88 if (fSet >= 0) { 89 result += separator() + "set = " + to_string(fSet); 90 } 91 if (fBuiltin >= 0) { 92 result += separator() + "builtin = " + to_string(fBuiltin); 93 } 94 if (fInputAttachmentIndex >= 0) { 95 result += separator() + "input_attachment_index = " + to_string(fInputAttachmentIndex); 96 } 97 if (fFlags & kOriginUpperLeft_Flag) { 98 result += separator() + "origin_upper_left"; 99 } 100 if (fFlags & kBlendSupportAllEquations_Flag) { 101 result += separator() + "blend_support_all_equations"; 102 } 103 if (fFlags & kPushConstant_Flag) { 104 result += separator() + "push_constant"; 105 } 106 if (fFlags & kSRGBUnpremul_Flag) { 107 result += separator() + "srgb_unpremul"; 108 } 109 #ifdef SKSL_EXT 110 if (fFlags & kConstantId_Flag) { 111 result += separator() + "constant_id"; 112 } 113 #endif 114 if (result.size() > 0) { 115 result = "layout (" + result + ")"; 116 } 117 return result; 118 } 119 120 bool operator==(const Layout& other) const { 121 return fFlags == other.fFlags && 122 fLocation == other.fLocation && 123 fOffset == other.fOffset && 124 fBinding == other.fBinding && 125 fIndex == other.fIndex && 126 fSet == other.fSet && 127 fBuiltin == other.fBuiltin && 128 #ifdef SKSL_EXT 129 fConstantId == other.fConstantId && 130 #endif 131 fInputAttachmentIndex == other.fInputAttachmentIndex; 132 } 133 134 bool operator!=(const Layout& other) const { 135 return !(*this == other); 136 } 137 138 int fFlags; 139 int fLocation; 140 int fOffset; 141 int fBinding; 142 int fIndex; 143 int fSet; 144 // builtin comes from SPIR-V and identifies which particular builtin value this object 145 // represents. 146 int fBuiltin; 147 // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a 148 // corresponding attachment on the subpass in which the shader is being used. 149 int fInputAttachmentIndex; 150 #ifdef SKSL_EXT 151 int fConstantId = -1; 152 #endif 153 }; 154 155 } // namespace SkSL 156 157 #endif 158