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 "Material/BsMaterial.h"
7#include "Material/BsShader.h"
8#include "Material/BsPass.h"
9
10namespace bs
11{
12 /** @addtogroup Implementation
13 * @{
14 */
15
16 /** Contains a set of GpuParams used for a single technique within a Material. */
17 template<bool Core>
18 class BS_CORE_EXPORT TGpuParamsSet
19 {
20 using GpuParamsType = CoreVariantType<GpuParams, Core>;
21 using MaterialParamsType = CoreVariantType<MaterialParams, Core>;
22 using ParamBlockPtrType = SPtr<CoreVariantType<GpuParamBlockBuffer, Core>>;
23 using TechniqueType = CoreVariantType<Technique, Core>;
24 using ShaderType = CoreVariantHandleType<Shader, Core>;
25 using PassType = CoreVariantType<Pass, Core>;
26 using GpuProgramPtrType = SPtr<CoreVariantType<GpuProgram, Core>>;
27 using ParamBlockType = CoreVariantType<GpuParamBlockBuffer, Core>;
28 using TextureType = CoreVariantHandleType<Texture, Core>;
29 using BufferType = SPtr<CoreVariantType<GpuBuffer, Core>>;
30 using SamplerStateType = SPtr<CoreVariantType<SamplerState, Core>>;
31 using GraphicsPipelineStateType = CoreVariantType<GraphicsPipelineState, Core>;
32 using ComputePipelineStateType = CoreVariantType<ComputePipelineState, Core>;
33
34 /** Binding location for a single GPU param block buffer. */
35 struct BlockBinding
36 {
37 UINT32 set;
38 UINT32 slot;
39 };
40
41 /** All bindings for GPU param block buffers, for a single pass. */
42 struct PassBlockBindings
43 {
44 BlockBinding bindings[GPT_COUNT];
45 };
46
47 /** Information about a parameter block buffer. */
48 struct BlockInfo
49 {
50 BlockInfo(const String& name, UINT32 set, UINT32 slot, const ParamBlockPtrType& buffer, bool shareable)
51 : name(name), set(set), slot(slot), buffer(buffer), shareable(shareable), allowUpdate(true), isUsed(true)
52 , passData(nullptr)
53 { }
54
55 String name;
56 UINT32 set;
57 UINT32 slot;
58 ParamBlockPtrType buffer;
59 bool shareable;
60 bool allowUpdate;
61 bool isUsed;
62
63 PassBlockBindings* passData;
64 };
65
66 /** Information about how a data parameter maps from a material parameter into a parameter block buffer. */
67 struct DataParamInfo
68 {
69 UINT32 paramIdx;
70 UINT32 blockIdx;
71 UINT32 offset;
72 UINT32 arrayStride;
73 };
74
75 /** Information about how an object parameter maps from a material parameter to a GPU stage slot. */
76 struct ObjectParamInfo
77 {
78 UINT32 paramIdx;
79 UINT32 slotIdx;
80 UINT32 setIdx;
81 };
82
83 /** Information about all object parameters for a specific GPU programmable stage. */
84 struct StageParamInfo
85 {
86 ObjectParamInfo* textures;
87 UINT32 numTextures;
88 ObjectParamInfo* loadStoreTextures;
89 UINT32 numLoadStoreTextures;
90 ObjectParamInfo* buffers;
91 UINT32 numBuffers;
92 ObjectParamInfo* samplerStates;
93 UINT32 numSamplerStates;
94 };
95
96 /** Information about all object parameters for a specific pass. */
97 struct PassParamInfo
98 {
99 StageParamInfo stages[GPT_COUNT];
100 };
101
102 public:
103 TGpuParamsSet() = default;
104 TGpuParamsSet(const SPtr<TechniqueType>& technique, const ShaderType& shader,
105 const SPtr<MaterialParamsType>& params);
106 ~TGpuParamsSet();
107
108 /**
109 * Returns a set of GPU parameters for the specified pass.
110 *
111 * @param[in] passIdx Pass in which to look the GPU program for in.
112 * @return GPU parameters object that can be used for setting parameters of all GPU programs
113 * in a pass. Returns null if pass doesn't exist.
114 */
115 SPtr<GpuParamsType> getGpuParams(UINT32 passIdx = 0);
116
117 /**
118 * Searches for a parameter block buffer with the specified name, and returns an index you can use for accessing it.
119 * Returns -1 if buffer was not found.
120 */
121 UINT32 getParamBlockBufferIndex(const String& name) const;
122
123 /**
124 * Assign a parameter block buffer with the specified index to all the relevant child GpuParams.
125 *
126 * @param[in] index Index of the buffer, as retrieved from getParamBlockBufferIndex().
127 * @param[in] paramBlock Parameter block to assign.
128 * @param[in] ignoreInUpdate If true the buffer will not be updated during the update() call. This is useful
129 * if the caller wishes to manually update the buffer contents externally, to prevent
130 * overwriting manually written data during update.
131 *
132 * @note
133 * Parameter block buffers can be used as quick way of setting multiple parameters on a material at once, or
134 * potentially sharing parameters between multiple materials. This reduces driver overhead as the parameters
135 * in the buffers need only be set once and then reused multiple times.
136 */
137 void setParamBlockBuffer(UINT32 index, const ParamBlockPtrType& paramBlock, bool ignoreInUpdate = false);
138
139 /**
140 * Assign a parameter block buffer with the specified name to all the relevant child GpuParams.
141 *
142 * @param[in] name Name of the buffer to set.
143 * @param[in] paramBlock Parameter block to assign.
144 * @param[in] ignoreInUpdate If true the buffer will not be updated during the update() call. This is useful
145 * if the caller wishes to manually update the buffer contents externally, to prevent
146 * overwriting manually written data during update.
147 *
148 * @note
149 * Parameter block buffers can be used as quick way of setting multiple parameters on a material at once, or
150 * potentially sharing parameters between multiple materials. This reduces driver overhead as the parameters
151 * in the buffers need only be set once and then reused multiple times.
152 */
153 void setParamBlockBuffer(const String& name, const ParamBlockPtrType& paramBlock, bool ignoreInUpdate = false);
154
155 /** Returns the number of passes the set contains the parameters for. */
156 UINT32 getNumPasses() const { return (UINT32)mPassParams.size(); }
157
158 /**
159 * Updates parameter data in this object from the provided material parameters object.
160 *
161 * @param[in] params Object containing the parameter data to update from. Layout of the object must match
162 * the object used for creating this object (be created for the same shader).
163 * @param[in] t Time to evaluate animated parameters at (if any).
164 * @param[in] updateAll Normally the system will track dirty parameters since the last call to this method,
165 * and only update the dirty ones. Set this to true if you want to force all parameters
166 * to update, regardless of their dirty state.
167 */
168 void update(const SPtr<MaterialParamsType>& params, float t = 0.0f, bool updateAll = false);
169
170 static const UINT32 NUM_STAGES;
171 private:
172 template<bool Core2> friend class TMaterial;
173
174 Vector<SPtr<GpuParamsType>> mPassParams;
175 Vector<BlockInfo> mBlocks;
176 Vector<DataParamInfo> mDataParamInfos;
177 PassParamInfo* mPassParamInfos;
178
179 UINT64 mParamVersion;
180 UINT8* mData;
181 };
182
183 /** Sim thread version of TGpuParamsSet<Core>. */
184 class BS_CORE_EXPORT GpuParamsSet : public TGpuParamsSet<false>
185 {
186 public:
187 GpuParamsSet() = default;
188 GpuParamsSet(const SPtr<Technique>& technique, const HShader& shader,
189 const SPtr<MaterialParams>& params)
190 :TGpuParamsSet(technique, shader, params)
191 { }
192 };
193
194 namespace ct
195 {
196 /** Core thread version of TGpuParamsSet<Core>. */
197 class BS_CORE_EXPORT GpuParamsSet : public TGpuParamsSet<true>
198 {
199 public:
200 GpuParamsSet() = default;
201 GpuParamsSet(const SPtr<Technique>& technique, const SPtr<Shader>& shader,
202 const SPtr<MaterialParams>& params)
203 :TGpuParamsSet(technique, shader, params)
204 { }
205 };
206 }
207
208 /** @} */
209}