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/BsRTTIType.h"
7#include "Private/RTTI/BsGpuProgramRTTI.h"
8#include "Material/BsPass.h"
9
10namespace bs
11{
12 /** @cond RTTI */
13 /** @addtogroup RTTI-Impl-Core
14 * @{
15 */
16
17 /** Helper class used for serialization of GPU_PROGRAM_DESC. */
18 struct SerializedGpuProgramData : GPU_PROGRAM_DESC, IReflectable
19 {
20 const SerializedGpuProgramData& operator=(const GPU_PROGRAM_DESC& desc)
21 {
22 source = desc.source;
23 entryPoint = desc.entryPoint;
24 language = desc.language;
25 type = desc.type;
26 requiresAdjacency = desc.requiresAdjacency;
27 bytecode = desc.bytecode;
28
29 return *this;
30 }
31
32 /************************************************************************/
33 /* RTTI */
34 /************************************************************************/
35 public:
36 friend class SerializedGpuProgramDataRTTI;
37 inline static RTTITypeBase* getRTTIStatic();
38 inline RTTITypeBase* getRTTI() const override;
39 };
40
41 class BS_CORE_EXPORT SerializedGpuProgramDataRTTI : public RTTIType<SerializedGpuProgramData, IReflectable, SerializedGpuProgramDataRTTI>
42 {
43 private:
44 BS_BEGIN_RTTI_MEMBERS
45 BS_RTTI_MEMBER_PLAIN(source, 0)
46 BS_RTTI_MEMBER_PLAIN(entryPoint, 1)
47 BS_RTTI_MEMBER_PLAIN(language, 2)
48 BS_RTTI_MEMBER_PLAIN(type, 3)
49 BS_RTTI_MEMBER_PLAIN(requiresAdjacency, 4)
50 BS_RTTI_MEMBER_REFLPTR(bytecode, 5)
51 BS_END_RTTI_MEMBERS
52
53 public:
54 const String& getRTTIName() override
55 {
56 static String name = "SerializedGpuProgramData";
57 return name;
58 }
59
60 UINT32 getRTTIId() override
61 {
62 return TID_SerializedGpuProgramData;
63 }
64
65 SPtr<IReflectable> newRTTIObject() override
66 {
67 return bs_shared_ptr_new<SerializedGpuProgramData>();
68 }
69 };
70
71 RTTITypeBase* SerializedGpuProgramData::getRTTIStatic()
72 {
73 return SerializedGpuProgramDataRTTI::instance();
74 }
75
76 RTTITypeBase* SerializedGpuProgramData::getRTTI() const
77 {
78 return getRTTIStatic();
79 }
80
81 class BS_CORE_EXPORT PassRTTI : public RTTIType<Pass, IReflectable, PassRTTI>
82 {
83 private:
84 BS_BEGIN_RTTI_MEMBERS
85 BS_RTTI_MEMBER_PLAIN_NAMED(blendStateDesc, mData.blendStateDesc, 0)
86 BS_RTTI_MEMBER_PLAIN_NAMED(rasterizerStateDesc, mData.rasterizerStateDesc, 1)
87 BS_RTTI_MEMBER_PLAIN_NAMED(depthStencilState, mData.depthStencilStateDesc, 2)
88
89 BS_RTTI_MEMBER_PLAIN_NAMED(stencilRefValue, mData.stencilRefValue, 9)
90 BS_END_RTTI_MEMBERS
91
92 SerializedGpuProgramData& getVertexProgramDesc(Pass* obj)
93 {
94 return mVertexProgramDesc;
95 }
96
97 void setVertexProgramDesc(Pass* obj, SerializedGpuProgramData& val)
98 {
99 obj->mData.vertexProgramDesc = val;
100 }
101
102 SerializedGpuProgramData& getFragmentProgramDesc(Pass* obj)
103 {
104 return mFragmentProgramDesc;
105 }
106
107 void setFragmentProgramDesc(Pass* obj, SerializedGpuProgramData& val)
108 {
109 obj->mData.fragmentProgramDesc = val;
110 }
111
112 SerializedGpuProgramData& getGeometryProgramDesc(Pass* obj)
113 {
114 return mGeometryProgramDesc;
115 }
116
117 void setGeometryProgramDesc(Pass* obj, SerializedGpuProgramData& val)
118 {
119 obj->mData.geometryProgramDesc = val;
120 }
121
122 SerializedGpuProgramData& getHullProgramDesc(Pass* obj)
123 {
124 return mHullProgramDesc;
125 }
126
127 void setHullProgramDesc(Pass* obj, SerializedGpuProgramData& val)
128 {
129 obj->mData.hullProgramDesc = val;
130 }
131
132 SerializedGpuProgramData& getDomainProgramDesc(Pass* obj)
133 {
134 return mDomainProgramDesc;
135 }
136
137 void setDomainProgramDesc(Pass* obj, SerializedGpuProgramData& val)
138 {
139 obj->mData.domainProgramDesc = val;
140 }
141
142 SerializedGpuProgramData& getComputeProgramDesc(Pass* obj)
143 {
144 return mComputeProgramDesc;
145 }
146
147 void setComputeProgramDesc(Pass* obj, SerializedGpuProgramData& val)
148 {
149 obj->mData.computeProgramDesc = val;
150 }
151 public:
152 PassRTTI()
153 {
154 addReflectableField("mVertexProgramDesc", 3, &PassRTTI::getVertexProgramDesc, &PassRTTI::setVertexProgramDesc);
155 addReflectableField("mFragmentProgramDesc", 4, &PassRTTI::getFragmentProgramDesc, &PassRTTI::setFragmentProgramDesc);
156 addReflectableField("mGeometryProgramDesc", 5, &PassRTTI::getGeometryProgramDesc, &PassRTTI::setGeometryProgramDesc);
157 addReflectableField("mHullProgramDesc", 6, &PassRTTI::getHullProgramDesc, &PassRTTI::setHullProgramDesc);
158 addReflectableField("mDomainProgramDesc", 7, &PassRTTI::getDomainProgramDesc, &PassRTTI::setDomainProgramDesc);
159 addReflectableField("mComputeProgramDesc", 8, &PassRTTI::getComputeProgramDesc, &PassRTTI::setComputeProgramDesc);
160 }
161
162 void onSerializationStarted(IReflectable* obj, SerializationContext* context) override
163 {
164 Pass* pass = static_cast<Pass*>(obj);
165
166 mVertexProgramDesc = pass->mData.vertexProgramDesc;
167 mFragmentProgramDesc = pass->mData.fragmentProgramDesc;
168 mGeometryProgramDesc = pass->mData.geometryProgramDesc;
169 mHullProgramDesc = pass->mData.hullProgramDesc;
170 mDomainProgramDesc = pass->mData.domainProgramDesc;
171 mComputeProgramDesc = pass->mData.computeProgramDesc;
172
173 auto initBytecode = [](const SPtr<GpuProgram>& prog, GPU_PROGRAM_DESC& desc)
174 {
175 if (prog)
176 {
177 prog->blockUntilCoreInitialized();
178 desc.bytecode = prog->getCore()->getBytecode();
179 }
180 };
181
182 const SPtr<GraphicsPipelineState>& graphicsPipeline = pass->getGraphicsPipelineState();
183 if(graphicsPipeline)
184 {
185 initBytecode(graphicsPipeline->getVertexProgram(), mVertexProgramDesc);
186 initBytecode(graphicsPipeline->getFragmentProgram(), mFragmentProgramDesc);
187 initBytecode(graphicsPipeline->getGeometryProgram(), mGeometryProgramDesc);
188 initBytecode(graphicsPipeline->getHullProgram(), mHullProgramDesc);
189 initBytecode(graphicsPipeline->getDomainProgram(), mDomainProgramDesc);
190 }
191
192 const SPtr<ComputePipelineState>& computePipeline = pass->getComputePipelineState();
193 if(computePipeline)
194 initBytecode(computePipeline->getProgram(), mComputeProgramDesc);
195 }
196
197 void onDeserializationEnded(IReflectable* obj, SerializationContext* context) override
198 {
199 Pass* pass = static_cast<Pass*>(obj);
200 pass->initialize();
201 }
202
203 const String& getRTTIName() override
204 {
205 static String name = "Pass";
206 return name;
207 }
208
209 UINT32 getRTTIId() override
210 {
211 return TID_Pass;
212 }
213
214 SPtr<IReflectable> newRTTIObject() override
215 {
216 return Pass::createEmpty();
217 }
218
219 private:
220 SerializedGpuProgramData mVertexProgramDesc;
221 SerializedGpuProgramData mFragmentProgramDesc;
222 SerializedGpuProgramData mGeometryProgramDesc;
223 SerializedGpuProgramData mHullProgramDesc;
224 SerializedGpuProgramData mDomainProgramDesc;
225 SerializedGpuProgramData mComputeProgramDesc;
226 };
227
228 /** @} */
229 /** @endcond */
230}
231