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 | #include "Reflection/BsIReflectable.h" |
7 | #include "CoreThread/BsCoreObject.h" |
8 | #include "Material/BsShaderVariation.h" |
9 | #include "String/BsStringID.h" |
10 | |
11 | namespace bs |
12 | { |
13 | /** @addtogroup Implementation |
14 | * @{ |
15 | */ |
16 | |
17 | /** Base class that is used for implementing both sim and core versions of Technique. */ |
18 | class BS_CORE_EXPORT TechniqueBase |
19 | { |
20 | public: |
21 | TechniqueBase(const String& language, const Vector<StringID>& tags, const ShaderVariation& variation); |
22 | virtual ~TechniqueBase() = default; |
23 | |
24 | /** Checks if this technique is supported based on current render and other systems. */ |
25 | bool isSupported() const; |
26 | |
27 | /** Checks if the technique has the specified tag. */ |
28 | bool hasTag(const StringID& tag); |
29 | |
30 | /** Checks if the technique has any tags. */ |
31 | UINT32 hasTags() const { return !mTags.empty(); } |
32 | |
33 | /** Returns a set of preprocessor defines used for compiling this particular technique. */ |
34 | const ShaderVariation& getVariation() const { return mVariation; } |
35 | |
36 | protected: |
37 | String mLanguage; |
38 | Vector<StringID> mTags; |
39 | ShaderVariation mVariation; |
40 | }; |
41 | |
42 | /** Templated class that is used for implementing both sim and core versions of Technique. */ |
43 | template<bool Core> |
44 | class BS_CORE_EXPORT TTechnique : public TechniqueBase |
45 | { |
46 | public: |
47 | using PassType = CoreVariantType<Pass, Core>; |
48 | |
49 | TTechnique(); |
50 | TTechnique(const String& language, const Vector<StringID>& tags, const ShaderVariation& variation, |
51 | const Vector<SPtr<PassType>>& passes); |
52 | virtual ~TTechnique() = default; |
53 | |
54 | /** Returns a pass with the specified index. */ |
55 | SPtr<PassType> getPass(UINT32 idx) const; |
56 | |
57 | /** Returns total number of passes. */ |
58 | UINT32 getNumPasses() const { return (UINT32)mPasses.size(); } |
59 | |
60 | /** Compiles all the passes in a technique. @see Pass::compile. */ |
61 | void compile(); |
62 | |
63 | protected: |
64 | Vector<SPtr<PassType>> mPasses; |
65 | }; |
66 | |
67 | /** @} */ |
68 | |
69 | /** @addtogroup Material |
70 | * @{ |
71 | */ |
72 | |
73 | /** |
74 | * Technique is a set of shading passes bindable to the GPU pipeline. Each technique can also have a set of properties |
75 | * that help the engine to determine which technique should be used under which circumstances (if more than one |
76 | * technique is available). |
77 | * |
78 | * @note |
79 | * Normally you want to have a separate technique for every render system and renderer your application supports. |
80 | * For example, if you are supporting DirectX11 and OpenGL you will want to have two techniques, one using HLSL based |
81 | * GPU programs, other using GLSL. Those techniques should try to mirror each other's end results. |
82 | */ |
83 | class BS_CORE_EXPORT Technique : public IReflectable, public CoreObject, public TTechnique<false> |
84 | { |
85 | public: |
86 | Technique(const String& language, const Vector<StringID>& tags, const ShaderVariation& variation, |
87 | const Vector<SPtr<Pass>>& passes); |
88 | |
89 | /** Retrieves an implementation of a technique usable only from the core thread. */ |
90 | SPtr<ct::Technique> getCore() const; |
91 | |
92 | /** |
93 | * Creates a new technique. |
94 | * |
95 | * @param[in] language Shading language used by the technique. The engine will not use this technique unless |
96 | * this language is supported by the render API. |
97 | * @param[in] passes A set of passes that define the technique. |
98 | * @return Newly creted technique. |
99 | */ |
100 | static SPtr<Technique> create(const String& language, const Vector<SPtr<Pass>>& passes); |
101 | |
102 | /** |
103 | * Creates a new technique. |
104 | * |
105 | * @param[in] language Shading language used by the technique. The engine will not use this technique unless |
106 | * this language is supported by the render API. |
107 | * @param[in] tags An optional set of tags that can be used for further identifying under which |
108 | * circumstances should a technique be used. |
109 | * @param[in] variation A set of preprocessor directives that were used for compiling this particular technique. |
110 | * Used for shaders that have multiple variations. |
111 | * @param[in] passes A set of passes that define the technique. |
112 | * @return Newly creted technique. |
113 | */ |
114 | static SPtr<Technique> create(const String& language, const Vector<StringID>& tags, |
115 | const ShaderVariation& variation, const Vector<SPtr<Pass>>& passes); |
116 | |
117 | protected: |
118 | /** @copydoc CoreObject::createCore */ |
119 | SPtr<ct::CoreObject> createCore() const override; |
120 | |
121 | /** @copydoc CoreObject::getCoreDependencies */ |
122 | void getCoreDependencies(Vector<CoreObject*>& dependencies) override; |
123 | |
124 | /** Creates a new technique but doesn't initialize it. */ |
125 | static SPtr<Technique> createEmpty(); |
126 | |
127 | private: |
128 | /************************************************************************/ |
129 | /* RTTI */ |
130 | /************************************************************************/ |
131 | |
132 | /** Serialization only constructor. */ |
133 | Technique(); |
134 | |
135 | public: |
136 | friend class TechniqueRTTI; |
137 | static RTTITypeBase* getRTTIStatic(); |
138 | RTTITypeBase* getRTTI() const override; |
139 | }; |
140 | |
141 | /** @} */ |
142 | |
143 | namespace ct |
144 | { |
145 | /** @addtogroup Material-Internal |
146 | * @{ |
147 | */ |
148 | |
149 | /** Core thread version of bs::Technique. */ |
150 | class BS_CORE_EXPORT Technique : public CoreObject, public TTechnique<true> |
151 | { |
152 | public: |
153 | Technique(const String& language, const Vector<StringID>& tags, |
154 | const ShaderVariation& variation, const Vector<SPtr<Pass>>& passes); |
155 | |
156 | /** @copydoc bs::Technique::create(const String&, const Vector<SPtr<Pass>>&) */ |
157 | static SPtr<Technique> create(const String& language, const Vector<SPtr<Pass>>& passes); |
158 | |
159 | /** |
160 | * @copydoc bs::Technique::create(const String&, const Vector<StringID>&, const ShaderVariation&, const Vector<SPtr<Pass>>&) |
161 | */ |
162 | static SPtr<Technique> create(const String& language, const Vector<StringID>& tags, |
163 | const ShaderVariation& variation, const Vector<SPtr<Pass>>& passes); |
164 | }; |
165 | |
166 | /** @} */ |
167 | } |
168 | } |
169 | |