blob: 75650e271d652dbaf53d88d47c99cdaa1277e7df [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
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 */
Ethan Nicholas11d53972016-11-28 11:23:23 -05007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_LAYOUT
9#define SKSL_LAYOUT
10
Ethan Nicholas11d53972016-11-28 11:23:23 -050011#include "SkString.h"
12#include "SkSLUtil.h"
13
ethannicholasb3058bd2016-07-01 08:22:01 -070014namespace SkSL {
15
16/**
17 * Represents a layout block appearing before a variable declaration, as in:
18 *
19 * layout (location = 0) int x;
20 */
21struct Layout {
Ethan Nicholas11d53972016-11-28 11:23:23 -050022 // These are used by images in GLSL. We only support a subset of what GL supports.
23 enum class Format {
24 kUnspecified = -1,
25 kRGBA32F,
26 kR32F,
27 kRGBA16F,
28 kR16F,
29 kRGBA8,
30 kR8,
31 kRGBA8I,
32 kR8I,
33 };
34
35 static const char* FormatToStr(Format format) {
36 switch (format) {
37 case Format::kUnspecified: return "";
38 case Format::kRGBA32F: return "rgba32f";
39 case Format::kR32F: return "r32f";
40 case Format::kRGBA16F: return "rgba16f";
41 case Format::kR16F: return "r16f";
42 case Format::kRGBA8: return "rgba8";
43 case Format::kR8: return "r8";
44 case Format::kRGBA8I: return "rgba8i";
45 case Format::kR8I: return "r8i";
46 }
47 SkFAIL("Unexpected format");
48 return "";
49 }
50
51 static bool ReadFormat(SkString str, Format* format) {
52 if (str == "rgba32f") {
53 *format = Format::kRGBA32F;
54 return true;
55 } else if (str == "r32f") {
56 *format = Format::kR32F;
57 return true;
58 } else if (str == "rgba16f") {
59 *format = Format::kRGBA16F;
60 return true;
61 } else if (str == "r16f") {
62 *format = Format::kR16F;
63 return true;
64 } else if (str == "rgba8") {
65 *format = Format::kRGBA8;
66 return true;
67 } else if (str == "r8") {
68 *format = Format::kR8;
69 return true;
70 } else if (str == "rgba8i") {
71 *format = Format::kRGBA8I;
72 return true;
73 } else if (str == "r8i") {
74 *format = Format::kR8I;
75 return true;
76 }
77 return false;
78 }
ethannicholasb3058bd2016-07-01 08:22:01 -070079
Ethan Nicholas19671772016-11-28 16:30:17 -050080 Layout(int location, int offset, int binding, int index, int set, int builtin,
81 int inputAttachmentIndex, bool originUpperLeft, bool overrideCoverage,
82 bool blendSupportAllEquations, Format format, bool pushconstant)
ethannicholasb3058bd2016-07-01 08:22:01 -070083 : fLocation(location)
Ethan Nicholas19671772016-11-28 16:30:17 -050084 , fOffset(offset)
ethannicholasb3058bd2016-07-01 08:22:01 -070085 , fBinding(binding)
86 , fIndex(index)
87 , fSet(set)
ethannicholasf789b382016-08-03 12:43:36 -070088 , fBuiltin(builtin)
Greg Daniel64773e62016-11-22 09:44:03 -050089 , fInputAttachmentIndex(inputAttachmentIndex)
ethannicholas5961bc92016-10-12 06:39:56 -070090 , fOriginUpperLeft(originUpperLeft)
91 , fOverrideCoverage(overrideCoverage)
Brian Salomon2a51de82016-11-16 12:06:01 -050092 , fBlendSupportAllEquations(blendSupportAllEquations)
ethannicholas8ac838d2016-11-22 08:39:36 -080093 , fFormat(format)
94 , fPushConstant(pushconstant) {}
Brian Salomon2a51de82016-11-16 12:06:01 -050095
Greg Daniel64773e62016-11-22 09:44:03 -050096 Layout()
Brian Salomon2a51de82016-11-16 12:06:01 -050097 : fLocation(-1)
Ethan Nicholas19671772016-11-28 16:30:17 -050098 , fOffset(-1)
Brian Salomon2a51de82016-11-16 12:06:01 -050099 , fBinding(-1)
100 , fIndex(-1)
101 , fSet(-1)
102 , fBuiltin(-1)
Greg Daniel64773e62016-11-22 09:44:03 -0500103 , fInputAttachmentIndex(-1)
Brian Salomon2a51de82016-11-16 12:06:01 -0500104 , fOriginUpperLeft(false)
105 , fOverrideCoverage(false)
106 , fBlendSupportAllEquations(false)
Ethan Nicholas11d53972016-11-28 11:23:23 -0500107 , fFormat(Format::kUnspecified)
ethannicholas8ac838d2016-11-22 08:39:36 -0800108 , fPushConstant(false) {}
ethannicholasb3058bd2016-07-01 08:22:01 -0700109
Ethan Nicholas9e1138d2016-11-21 10:39:35 -0500110 SkString description() const {
111 SkString result;
112 SkString separator;
ethannicholasb3058bd2016-07-01 08:22:01 -0700113 if (fLocation >= 0) {
114 result += separator + "location = " + to_string(fLocation);
115 separator = ", ";
116 }
Ethan Nicholas19671772016-11-28 16:30:17 -0500117 if (fOffset >= 0) {
118 result += separator + "offset = " + to_string(fOffset);
119 separator = ", ";
120 }
ethannicholasb3058bd2016-07-01 08:22:01 -0700121 if (fBinding >= 0) {
122 result += separator + "binding = " + to_string(fBinding);
123 separator = ", ";
124 }
125 if (fIndex >= 0) {
126 result += separator + "index = " + to_string(fIndex);
127 separator = ", ";
128 }
129 if (fSet >= 0) {
130 result += separator + "set = " + to_string(fSet);
131 separator = ", ";
132 }
133 if (fBuiltin >= 0) {
134 result += separator + "builtin = " + to_string(fBuiltin);
135 separator = ", ";
136 }
Greg Daniel64773e62016-11-22 09:44:03 -0500137 if (fInputAttachmentIndex >= 0) {
138 result += separator + "input_attachment_index = " + to_string(fBuiltin);
139 separator = ", ";
140 }
ethannicholasf789b382016-08-03 12:43:36 -0700141 if (fOriginUpperLeft) {
142 result += separator + "origin_upper_left";
143 separator = ", ";
144 }
ethannicholas5961bc92016-10-12 06:39:56 -0700145 if (fOverrideCoverage) {
146 result += separator + "override_coverage";
147 separator = ", ";
148 }
149 if (fBlendSupportAllEquations) {
150 result += separator + "blend_support_all_equations";
151 separator = ", ";
152 }
Ethan Nicholas11d53972016-11-28 11:23:23 -0500153 if (Format::kUnspecified != fFormat) {
154 result += separator + FormatToStr(fFormat);
Brian Salomon2a51de82016-11-16 12:06:01 -0500155 separator = ", ";
156 }
ethannicholas8ac838d2016-11-22 08:39:36 -0800157 if (fPushConstant) {
158 result += separator + "push_constant";
159 separator = ", ";
160 }
Ethan Nicholas9e1138d2016-11-21 10:39:35 -0500161 if (result.size() > 0) {
ethannicholasb3058bd2016-07-01 08:22:01 -0700162 result = "layout (" + result + ")";
163 }
164 return result;
165 }
166
167 bool operator==(const Layout& other) const {
ethannicholas5961bc92016-10-12 06:39:56 -0700168 return fLocation == other.fLocation &&
Ethan Nicholas19671772016-11-28 16:30:17 -0500169 fOffset == other.fOffset &&
ethannicholas5961bc92016-10-12 06:39:56 -0700170 fBinding == other.fBinding &&
171 fIndex == other.fIndex &&
172 fSet == other.fSet &&
173 fBuiltin == other.fBuiltin &&
Greg Daniel64773e62016-11-22 09:44:03 -0500174 fInputAttachmentIndex == other.fInputAttachmentIndex &&
ethannicholas5961bc92016-10-12 06:39:56 -0700175 fOriginUpperLeft == other.fOriginUpperLeft &&
176 fOverrideCoverage == other.fOverrideCoverage &&
Brian Salomon2a51de82016-11-16 12:06:01 -0500177 fBlendSupportAllEquations == other.fBlendSupportAllEquations &&
178 fFormat == other.fFormat;
ethannicholasb3058bd2016-07-01 08:22:01 -0700179 }
180
181 bool operator!=(const Layout& other) const {
182 return !(*this == other);
183 }
184
ethannicholasf789b382016-08-03 12:43:36 -0700185 int fLocation;
Ethan Nicholas19671772016-11-28 16:30:17 -0500186 int fOffset;
ethannicholasf789b382016-08-03 12:43:36 -0700187 int fBinding;
188 int fIndex;
189 int fSet;
Greg Daniel64773e62016-11-22 09:44:03 -0500190 // builtin comes from SPIR-V and identifies which particular builtin value this object
191 // represents.
ethannicholasf789b382016-08-03 12:43:36 -0700192 int fBuiltin;
Greg Daniel64773e62016-11-22 09:44:03 -0500193 // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a
194 // corresponding attachment on the subpass in which the shader is being used.
195 int fInputAttachmentIndex;
ethannicholasf789b382016-08-03 12:43:36 -0700196 bool fOriginUpperLeft;
ethannicholas5961bc92016-10-12 06:39:56 -0700197 bool fOverrideCoverage;
198 bool fBlendSupportAllEquations;
Ethan Nicholas11d53972016-11-28 11:23:23 -0500199 Format fFormat;
ethannicholas8ac838d2016-11-22 08:39:36 -0800200 bool fPushConstant;
ethannicholasb3058bd2016-07-01 08:22:01 -0700201};
202
203} // namespace
204
205#endif