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
11namespace 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