1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6
7namespace bs
8{
9 /** @addtogroup Material-Internal
10 * @{
11 */
12
13 /** Allows you to specify defines that can control shader compilation. */
14 class BS_CORE_EXPORT ShaderDefines
15 {
16 public:
17 /** Adds a new define with a floating point value. */
18 void set(const String& name, float value);
19
20 /** Adds a new define with an integer value. */
21 void set(const String& name, INT32 value);
22
23 /** Adds a new define with an integer value. */
24 void set(const String& name, UINT32 value);
25
26 /** Adds a new define with a string point value. */
27 void set(const String& name, const String& value);
28
29 /** Returns a list of all defines. */
30 UnorderedMap<String, String> getAll() const { return mDefines; }
31
32 /** Removes all defines. */
33 void clear() { mDefines.clear(); }
34
35 protected:
36 UnorderedMap<String, String> mDefines;
37 };
38
39 /**
40 * Contains information about a single variation of a Shader. Each variation can have a separate set of
41 * \#defines that control shader compilation.
42 */
43 class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Rendering) ShaderVariation : public IReflectable
44 {
45 public:
46 /** Possible types of a variation parameter. */
47 enum ParamType
48 {
49 Int,
50 UInt,
51 Float,
52 Bool
53 };
54
55 /** Name, type and value of a variation parameter. */
56 struct Param
57 {
58 Param()
59 :i(0), type(Int)
60 { }
61
62 Param(const String& name, INT32 val)
63 :i(val), name(name), type(Int)
64 { }
65
66 Param(const String& name, UINT32 val)
67 :ui(val), name(name), type(Int)
68 { }
69
70 Param(const String& name, float val)
71 :f(val), name(name), type(Float)
72 { }
73
74 Param(const String& name, bool val)
75 :i(val ? 1 : 0), name(name), type(Bool)
76 { }
77
78 union
79 {
80 INT32 i;
81 UINT32 ui;
82 float f;
83 };
84
85 StringID name;
86 ParamType type;
87 };
88
89 BS_SCRIPT_EXPORT()
90 ShaderVariation() = default;
91
92 /** Creates a new shader variation with the specified parameters. */
93 ShaderVariation(const SmallVector<Param, 4>& params);
94
95 /**
96 * Returns the value of a signed integer parameter with the specified name. Returns 0 if the parameter cannot be
97 * found.
98 */
99 BS_SCRIPT_EXPORT()
100 INT32 getInt(const StringID& name);
101
102 /**
103 * Returns the value of a unsigned integer parameter with the specified name. Returns 0 if the parameter cannot be
104 * found.
105 */
106 BS_SCRIPT_EXPORT()
107 UINT32 getUInt(const StringID& name);
108
109 /** Returns the value of a float parameter with the specified name. Returns 0 if the parameter cannot be found. */
110 BS_SCRIPT_EXPORT()
111 float getFloat(const StringID& name);
112
113 /**
114 * Returns the value of a boolean parameter with the specified name. Returns false if the parameter cannot be
115 * found.
116 */
117 BS_SCRIPT_EXPORT()
118 bool getBool(const StringID& name);
119
120 /**
121 * Sets the value of the parameter for the provided name. Any previous value for a parameter with the same name
122 * will be overwritten.
123 */
124 BS_SCRIPT_EXPORT()
125 void setInt(const StringID& name, INT32 value);
126
127 /**
128 * Sets the value of the parameter for the provided name. Any previous value for a parameter with the same name
129 * will be overwritten.
130 */
131 BS_SCRIPT_EXPORT()
132 void setUInt(const StringID& name, UINT32 value);
133
134 /**
135 * Sets the value of the parameter for the provided name. Any previous value for a parameter with the same name
136 * will be overwritten.
137 */
138 BS_SCRIPT_EXPORT()
139 void setFloat(const StringID& name, float value);
140
141 /**
142 * Sets the value of the parameter for the provided name. Any previous value for a parameter with the same name
143 * will be overwritten.
144 */
145 BS_SCRIPT_EXPORT()
146 void setBool(const StringID& name, bool value);
147
148 /** Registers a new parameter that controls the variation. */
149 void addParam(const Param& param) { mParams[param.name] = param; }
150
151 /** Removes a parameter with the specified name. */
152 BS_SCRIPT_EXPORT()
153 void removeParam(const StringID& paramName) { mParams.erase(paramName); }
154
155 /** Removes all parameters. */
156 BS_SCRIPT_EXPORT()
157 void clearParams() { mParams.clear(); }
158
159 /** Returns a list of names of all registered parameters. */
160 BS_SCRIPT_EXPORT(n:ParamNames,pr:getter)
161 Vector<String> getParamNames() const;
162
163 /**
164 * Checks if this variation matches some other variation.
165 *
166 * @param[in] other Other variation to compare it to.
167 * @param[in] exact When true both variations need to have the exact number of parameters with identical
168 * contents, equivalent to the equals operator. When false, only the subset of
169 * parameters present in @p other is used for comparison, while any extra parameters
170 * present in this object are ignored.
171 */
172 bool matches(const ShaderVariation& other, bool exact = true) const;
173
174 /** Returns all the variation parameters. */
175 const UnorderedMap<StringID, Param>& getParams() const { return mParams; }
176
177 bool operator==(const ShaderVariation& rhs) const;
178
179 /** Empty variation with no parameters. */
180 static const ShaderVariation EMPTY;
181
182 /**
183 * @name Internal
184 * @{
185 */
186
187 /** Converts all the variation parameters in a ShaderDefines object, that may be consumed by the shader compiler. */
188 ShaderDefines getDefines() const;
189
190 /**
191 * Returns a unique index of this variation, relative to all other variations registered in ShaderVariations object.
192 */
193 UINT32 getIdx() const { return mIdx; }
194
195 /** Assigns a unique index to the variation that can later be used for quick lookup. */
196 void setIdx(UINT32 idx) const { mIdx = idx; }
197
198 /** Enumerates all the fields in the type and executes the specified processor action for each field. */
199 template<class P>
200 void rttiEnumFields(P p)
201 {
202 p(mParams);
203 }
204
205 /** @} */
206 private:
207 friend class ShaderVariations;
208
209 UnorderedMap<StringID, Param> mParams;
210 mutable UINT32 mIdx = -1;
211
212 /************************************************************************/
213 /* RTTI */
214 /************************************************************************/
215
216 public:
217 friend class ShaderVariationRTTI;
218 static RTTITypeBase* getRTTIStatic();
219 RTTITypeBase* getRTTI() const override;
220 };
221
222 /** A container for all variations of a single Shader. */
223 class BS_CORE_EXPORT ShaderVariations
224 {
225 public:
226 /** Registers a new variation. */
227 void add(const ShaderVariation& variation);
228
229 /** Returns a variation at the specified index. Variations are indexed sequentially as they are added. */
230 const ShaderVariation& get(UINT32 idx) { return mVariations[idx]; }
231
232 /**
233 * Scans a list of stored variations and returns an index of a variation that has the same parameters as the
234 * provided one, or -1 if one is not found.
235 */
236 UINT32 find(const ShaderVariation& variation) const;
237
238 /** Returns a list of all variations. */
239 const SmallVector<ShaderVariation, 4>& getVariations() const { return mVariations; }
240
241 private:
242 SmallVector<ShaderVariation, 4> mVariations;
243 UINT32 mNextIdx = 0;
244 };
245
246 /** @} */
247}
248