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