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 "Material/BsTechnique.h" |
4 | #include "Error/BsException.h" |
5 | #include "RenderAPI/BsRenderAPI.h" |
6 | #include "Renderer/BsRendererManager.h" |
7 | #include "Material/BsPass.h" |
8 | #include "Renderer/BsRenderer.h" |
9 | #include "Managers/BsGpuProgramManager.h" |
10 | #include "Private/RTTI/BsTechniqueRTTI.h" |
11 | |
12 | namespace bs |
13 | { |
14 | TechniqueBase::TechniqueBase(const String& language, const Vector<StringID>& tags, const ShaderVariation& variation) |
15 | :mLanguage(language), mTags(tags), mVariation(variation) |
16 | { |
17 | |
18 | } |
19 | |
20 | bool TechniqueBase::isSupported() const |
21 | { |
22 | if (ct::GpuProgramManager::instance().isLanguageSupported(mLanguage) || mLanguage == "Any" ) |
23 | return true; |
24 | |
25 | return false; |
26 | } |
27 | |
28 | bool TechniqueBase::hasTag(const StringID& tag) |
29 | { |
30 | for(auto& entry : mTags) |
31 | { |
32 | if (entry == tag) |
33 | return true; |
34 | } |
35 | |
36 | return false; |
37 | } |
38 | |
39 | template<bool Core> |
40 | TTechnique<Core>::TTechnique(const String& language, const Vector<StringID>& tags, |
41 | const ShaderVariation& variation, const Vector<SPtr<PassType>>& passes) |
42 | : TechniqueBase(language, tags, variation), mPasses(passes) |
43 | { } |
44 | |
45 | template<bool Core> |
46 | TTechnique<Core>::TTechnique() |
47 | : TechniqueBase("" , {}, ShaderVariation()) |
48 | { } |
49 | |
50 | template<bool Core> |
51 | SPtr<typename TTechnique<Core>::PassType> TTechnique<Core>::getPass(UINT32 idx) const |
52 | { |
53 | if (idx < 0 || idx >= (UINT32)mPasses.size()) |
54 | BS_EXCEPT(InvalidParametersException, "Index out of range: " + toString(idx)); |
55 | |
56 | return mPasses[idx]; |
57 | } |
58 | template<bool Core> |
59 | void TTechnique<Core>::compile() |
60 | { |
61 | for(auto& pass : mPasses) |
62 | pass->compile(); |
63 | } |
64 | |
65 | template class TTechnique < false > ; |
66 | template class TTechnique < true >; |
67 | |
68 | Technique::Technique(const String& language, const Vector<StringID>& tags, |
69 | const ShaderVariation& variation, const Vector<SPtr<Pass>>& passes) |
70 | :TTechnique(language, tags, variation, passes) |
71 | { } |
72 | |
73 | Technique::Technique() |
74 | : TTechnique() |
75 | { } |
76 | |
77 | SPtr<ct::Technique> Technique::getCore() const |
78 | { |
79 | return std::static_pointer_cast<ct::Technique>(mCoreSpecific); |
80 | } |
81 | |
82 | SPtr<ct::CoreObject> Technique::createCore() const |
83 | { |
84 | Vector<SPtr<ct::Pass>> passes; |
85 | for (auto& pass : mPasses) |
86 | passes.push_back(pass->getCore()); |
87 | |
88 | ct::Technique* technique = new(bs_alloc<ct::Technique>()) ct::Technique( |
89 | mLanguage, |
90 | mTags, |
91 | mVariation, |
92 | passes); |
93 | |
94 | SPtr<ct::Technique> techniquePtr = bs_shared_ptr<ct::Technique>(technique); |
95 | techniquePtr->_setThisPtr(techniquePtr); |
96 | |
97 | return techniquePtr; |
98 | } |
99 | |
100 | void Technique::getCoreDependencies(Vector<CoreObject*>& dependencies) |
101 | { |
102 | for (auto& pass : mPasses) |
103 | dependencies.push_back(pass.get()); |
104 | } |
105 | |
106 | SPtr<Technique> Technique::create(const String& language, const Vector<SPtr<Pass>>& passes) |
107 | { |
108 | Technique* technique = new (bs_alloc<Technique>()) Technique(language, {}, ShaderVariation(), passes); |
109 | SPtr<Technique> techniquePtr = bs_core_ptr<Technique>(technique); |
110 | techniquePtr->_setThisPtr(techniquePtr); |
111 | techniquePtr->initialize(); |
112 | |
113 | return techniquePtr; |
114 | } |
115 | |
116 | SPtr<Technique> Technique::create(const String& language, const Vector<StringID>& tags, |
117 | const ShaderVariation& variation, const Vector<SPtr<Pass>>& passes) |
118 | { |
119 | Technique* technique = new (bs_alloc<Technique>()) Technique(language, tags, variation, passes); |
120 | SPtr<Technique> techniquePtr = bs_core_ptr<Technique>(technique); |
121 | techniquePtr->_setThisPtr(techniquePtr); |
122 | techniquePtr->initialize(); |
123 | |
124 | return techniquePtr; |
125 | } |
126 | |
127 | SPtr<Technique> Technique::createEmpty() |
128 | { |
129 | Technique* technique = new (bs_alloc<Technique>()) Technique(); |
130 | SPtr<Technique> techniquePtr = bs_core_ptr<Technique>(technique); |
131 | techniquePtr->_setThisPtr(techniquePtr); |
132 | |
133 | return techniquePtr; |
134 | } |
135 | |
136 | RTTITypeBase* Technique::getRTTIStatic() |
137 | { |
138 | return TechniqueRTTI::instance(); |
139 | } |
140 | |
141 | RTTITypeBase* Technique::getRTTI() const |
142 | { |
143 | return Technique::getRTTIStatic(); |
144 | } |
145 | |
146 | namespace ct |
147 | { |
148 | Technique::Technique(const String& language, const Vector<StringID>& tags, const ShaderVariation& variation, |
149 | const Vector<SPtr<Pass>>& passes) |
150 | :TTechnique(language, tags, variation, passes) |
151 | { } |
152 | |
153 | SPtr<Technique> Technique::create(const String& language, const Vector<SPtr<Pass>>& passes) |
154 | { |
155 | Technique* technique = new (bs_alloc<Technique>()) Technique(language, {}, ShaderVariation(), passes); |
156 | SPtr<Technique> techniquePtr = bs_shared_ptr<Technique>(technique); |
157 | techniquePtr->_setThisPtr(techniquePtr); |
158 | techniquePtr->initialize(); |
159 | |
160 | return techniquePtr; |
161 | } |
162 | |
163 | SPtr<Technique> Technique::create(const String& language, const Vector<StringID>& tags, |
164 | const ShaderVariation& variation, const Vector<SPtr<Pass>>& passes) |
165 | { |
166 | Technique* technique = new (bs_alloc<Technique>()) Technique(language, tags, variation, passes); |
167 | SPtr<Technique> techniquePtr = bs_shared_ptr<Technique>(technique); |
168 | techniquePtr->_setThisPtr(techniquePtr); |
169 | techniquePtr->initialize(); |
170 | |
171 | return techniquePtr; |
172 | } |
173 | } |
174 | } |