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 | #include "BsShaderVariation.h" |
4 | #include "Private/RTTI/BsShaderVariationRTTI.h" |
5 | |
6 | namespace bs |
7 | { |
8 | void ShaderDefines::set(const String& name, float value) |
9 | { |
10 | mDefines[name] = toString(value); |
11 | } |
12 | |
13 | void ShaderDefines::set(const String& name, INT32 value) |
14 | { |
15 | mDefines[name] = toString(value); |
16 | } |
17 | |
18 | void ShaderDefines::set(const String& name, UINT32 value) |
19 | { |
20 | mDefines[name] = toString(value); |
21 | } |
22 | |
23 | void ShaderDefines::set(const String& name, const String& value) |
24 | { |
25 | mDefines[name] = value; |
26 | } |
27 | |
28 | const ShaderVariation ShaderVariation::EMPTY; |
29 | |
30 | ShaderVariation::ShaderVariation(const SmallVector<Param, 4>& params) |
31 | { |
32 | for (auto& entry : params) |
33 | mParams[entry.name] = entry; |
34 | } |
35 | |
36 | INT32 ShaderVariation::getInt(const StringID& name) |
37 | { |
38 | auto iterFind = mParams.find(name); |
39 | if (iterFind == mParams.end()) |
40 | return 0; |
41 | else |
42 | return iterFind->second.i; |
43 | } |
44 | |
45 | UINT32 ShaderVariation::getUInt(const StringID& name) |
46 | { |
47 | auto iterFind = mParams.find(name); |
48 | if (iterFind == mParams.end()) |
49 | return 0; |
50 | else |
51 | return iterFind->second.ui; |
52 | } |
53 | |
54 | float ShaderVariation::getFloat(const StringID& name) |
55 | { |
56 | auto iterFind = mParams.find(name); |
57 | if (iterFind == mParams.end()) |
58 | return 0.0f; |
59 | else |
60 | return iterFind->second.f; |
61 | } |
62 | |
63 | bool ShaderVariation::getBool(const StringID& name) |
64 | { |
65 | auto iterFind = mParams.find(name); |
66 | if (iterFind == mParams.end()) |
67 | return false; |
68 | else |
69 | return iterFind->second.i > 0 ? true : false; |
70 | } |
71 | |
72 | void ShaderVariation::setInt(const StringID& name, INT32 value) |
73 | { |
74 | addParam(Param(name, value)); |
75 | } |
76 | |
77 | void ShaderVariation::setUInt(const StringID& name, UINT32 value) |
78 | { |
79 | addParam(Param(name, value)); |
80 | } |
81 | |
82 | void ShaderVariation::setFloat(const StringID& name, float value) |
83 | { |
84 | addParam(Param(name, value)); |
85 | } |
86 | |
87 | void ShaderVariation::setBool(const StringID& name, bool value) |
88 | { |
89 | addParam(Param(name, value)); |
90 | } |
91 | |
92 | Vector<String> ShaderVariation::getParamNames() const |
93 | { |
94 | Vector<String> params; |
95 | params.reserve(mParams.size()); |
96 | |
97 | for(auto& entry : mParams) |
98 | params.push_back(entry.first); |
99 | |
100 | return params; |
101 | } |
102 | |
103 | ShaderDefines ShaderVariation::getDefines() const |
104 | { |
105 | ShaderDefines defines; |
106 | for (auto& entry : mParams) |
107 | { |
108 | switch (entry.second.type) |
109 | { |
110 | case Int: |
111 | case Bool: |
112 | defines.set(entry.first.c_str(), entry.second.i); |
113 | break; |
114 | case UInt: |
115 | defines.set(entry.first.c_str(), entry.second.ui); |
116 | break; |
117 | case Float: |
118 | defines.set(entry.first.c_str(), entry.second.f); |
119 | break; |
120 | } |
121 | } |
122 | |
123 | return defines; |
124 | } |
125 | |
126 | bool ShaderVariation::matches(const ShaderVariation& other, bool exact) const |
127 | { |
128 | for(auto& entry : other.mParams) |
129 | { |
130 | const auto iterFind = mParams.find(entry.first); |
131 | if(iterFind == mParams.end()) |
132 | return false; |
133 | |
134 | if(entry.second.i != iterFind->second.i) |
135 | return false; |
136 | } |
137 | |
138 | if(exact) |
139 | { |
140 | for (auto& entry : mParams) |
141 | { |
142 | const auto iterFind = other.mParams.find(entry.first); |
143 | if (iterFind == other.mParams.end()) |
144 | return false; |
145 | |
146 | if (entry.second.i != iterFind->second.i) |
147 | return false; |
148 | } |
149 | } |
150 | |
151 | return true; |
152 | } |
153 | |
154 | bool ShaderVariation::operator==(const ShaderVariation& rhs) const |
155 | { |
156 | return matches(rhs, true); |
157 | } |
158 | |
159 | void ShaderVariations::add(const ShaderVariation& variation) |
160 | { |
161 | variation.mIdx = mNextIdx++; |
162 | |
163 | mVariations.add(variation); |
164 | } |
165 | |
166 | UINT32 ShaderVariations::find(const ShaderVariation& variation) const |
167 | { |
168 | UINT32 idx = 0; |
169 | for(auto& entry : mVariations) |
170 | { |
171 | if(entry == variation) |
172 | return idx; |
173 | |
174 | idx++; |
175 | } |
176 | |
177 | return (UINT32)-1; |
178 | } |
179 | |
180 | RTTITypeBase* ShaderVariation::getRTTIStatic() |
181 | { |
182 | return ShaderVariationRTTI::instance(); |
183 | } |
184 | |
185 | RTTITypeBase* ShaderVariation::getRTTI() const |
186 | { |
187 | return ShaderVariation::getRTTIStatic(); |
188 | } |
189 | |
190 | // This is here to solve a linking issue on Clang 7. The destructor apparently either doesn't get implicitly |
191 | // instantiated. This means external libraries linking with bsf, using the same SmallVector template parameters will |
192 | // trigger an undefined reference linker error. And why doesn't the library instantiate it itself? Don't know, either |
193 | // a Clang issue or maybe even some part of the standard. |
194 | template SmallVector<ShaderVariation::Param, 4>::~SmallVector(); |
195 | } |