Cogs.Core
EffectsCommon.h
1#pragma once
2
3#include "../Common.h"
4#include "../IEffects.h"
5
6#include "ResourcePointer.h"
7#include "ResourceMap.h"
8
9#include "Foundation/StringView.h"
10
11#include <memory>
12#include <unordered_map>
13
14#ifdef _WIN32
15#include <d3dcommon.h>
16#else
17namespace Cogs
18{
19 struct IUnknown
20 {
21 void AddRef() {}
22 int Release() { return 0; }
23 };
24
25 struct ID3DBlob : public IUnknown
26 {
27 };
28}
30#endif
31
32#ifdef COGS_VULKAN
33#include "../Vulkan/CommonVK.h"
34#else
35using VkShaderModule = intptr_t;
36#endif
37
38namespace Cogs
39{
40 const static uint8_t NoBinding = 0xFF;
41
42#ifdef COGSRENDERING_GFX_ANNOTATE
43 StringView tryToName(const StringView filename);
44#endif
45
46 struct StringId
47 {
48 StringId(const StringView & str) : id(Cogs::hash(str))
49 {
50#ifdef _DEBUG
51 name = std::string(str);
52#endif
53 }
54 StringId(const char * str) : StringId(StringView(str)) {}
55
56 operator size_t() { return id; }
57
58 size_t id = 0;
59#ifdef _DEBUG
60 std::string name;
61#endif
62 };
63
65 {
66 std::unordered_map<size_t, uint16_t> variables;
67
68 BufferHandle buffer;
69 std::vector<uint8_t> memoryBuffer;
70
71 std::vector<size_t> offsets;
72 std::vector<size_t> sizes;
73
74 std::string name;
75 uint32_t size = 0;
76
77 uint32_t slot = 0;
78 uint32_t binding = 0;
79 uint32_t index = 0;
80 bool dirty = false;
81 bool manual = false;
82 };
83
85 {
86 std::string semantic;
87 uint32_t index = 0;
88 uint32_t reg = 0;
89 };
90
92 {
93 std::unordered_map<size_t, uint32_t> slots;
94 std::vector<ShaderConstantBuffer> constantBuffers;
95
96 std::vector<InputAttribute> inputAttributes;
97
98 std::unordered_map<size_t, uint32_t> samplers;
99 std::unordered_map<size_t, uint32_t> textures;
100
101 std::unordered_map<size_t, uint32_t> bufferUAVs;
102 std::unordered_map<size_t, uint32_t> bufferSRVs;
103
104 uint32_t srvSlots = 0;
105 };
106
107 struct Shader
108 {
109 ResourcePointer<ID3DBlob> byteCode; // Shader Compiler
110 ResourcePointer<IUnknown> shader; // D3D
111 VkShaderModule shaderModule = 0; // Vulkan
112 ShaderHandle shaderHandle; // OpenGL20
113 ShaderReflectionInfo reflection;
114 };
115
117 {
118 ShaderConstantBuffer * buffer;
119 size_t offset;
120 size_t size;
121 };
122
124 {
125 std::vector<ConstantBufferVariable> variables;
126 };
127
129 {
130 enum EShaderType : uint32_t
131 {
132 VertexShader = 0,
133 HullShader = 1,
134 DomainShader = 2,
135 GeometryShader = 3,
136 PixelShader = 4,
137 ComputeShader = 5,
138 LastShaderType = PixelShader,
139 NumShaderTypes = PixelShader + 1,
140 NumShaderSlots = ComputeShader + 1,
141 };
142 };
143
144 struct SlotType
145 {
146 enum ESlotType : uint32_t
147 {
148 CBV = 0,
149 SRV = 1,
150 Sampler = 2,
151 UAV = 3,
152 NumSlotTypes = UAV + 1
153 };
154 };
155
156 struct Bindings
157 {
158 uint32_t values[ShaderType::NumShaderTypes];
159 uint32_t rangeIndex[ShaderType::NumShaderTypes];
160 };
161
163 {
164 Bindings slots[SlotType::NumSlotTypes];
165 };
166
167 struct RootSignature : public Signature
168 {
169
170 };
171
173 {
174
175 };
176
177 struct Effect
178 {
179 Effect() :
180 vertexShader(shaders[ShaderType::VertexShader]),
181 hullShader(shaders[ShaderType::HullShader]),
182 domainShader(shaders[ShaderType::DomainShader]),
183 geometryShader(shaders[ShaderType::GeometryShader]),
184 pixelShader(shaders[ShaderType::PixelShader]),
185 computeShader(shaders[ShaderType::ComputeShader])
186 {
187
188 }
189
190 Effect & operator=(const Effect & other)
191 {
192 for (size_t i = 0; i < ShaderType::NumShaderSlots; ++i) {
193 shaders[i] = other.shaders[i];
194 }
195
196 effectVariables = other.effectVariables;
197 signature = other.signature;
198
199 return *this;
200 }
201
202 Effect & operator=(Effect && other) noexcept
203 {
204 for (size_t i = 0; i < ShaderType::NumShaderSlots; ++i) {
205 shaders[i] = std::move(other.shaders[i]);
206 }
207
208 effectVariables = std::move(other.effectVariables);
209 signature = std::move(other.signature);
210
211 return *this;
212 }
213
214 void buildSignature();
215
216 EffectSignature signature;
217
218 Shader shaders[ShaderType::NumShaderSlots];
219
220 std::unordered_map<size_t, EffectVariable> effectVariables;
221
222 Shader & vertexShader;
223 Shader & hullShader;
224 Shader & domainShader;
225 Shader & geometryShader;
226 Shader & pixelShader;
227 Shader & computeShader;
228 };
229
231 {
232 int64_t uavBindings;
233 int64_t srvBindings;
234 };
235
236 struct EffectsCommon : public IEffects
237 {
238 EffectHandle loadEffect(const EffectDescription & description) final;
239 EffectHandle loadEffectSource(const EffectDescription & description);
240 EffectHandle loadEffectContents(const EffectDescription & description, const EffectContents & contents);
241
244
245 EffectHandle loadEffect(const StringView & vsFileName, const StringView & psFileName, EffectFlags::EEffectFlags effectFlags = EffectFlags::None) final;
246 EffectHandle loadEffect(const StringView & vsFileName, const StringView & psFileName, const PreprocessorDefinitions & defines, EffectFlags::EEffectFlags effectFlags = EffectFlags::None) final;
247
248 EffectHandle loadEffectSource(const StringView & vsSource, const StringView & psSource, EffectFlags::EEffectFlags effectFlags = EffectFlags::None) final;
249 EffectHandle loadEffectSource(const StringView & vsSource, const StringView & psSource, const PreprocessorDefinitions & defines, EffectFlags::EEffectFlags effectFlags = EffectFlags::None) final;
250
251 EffectHandle loadEffectSource(const StringView & vsSource, const StringView & gsSource, const StringView & psSource, EffectFlags::EEffectFlags effectFlags = EffectFlags::None) final;
252 EffectHandle loadEffectSource(const StringView & vsSource, const StringView & gsSource, const StringView & psSource, const PreprocessorDefinitions & defines, EffectFlags::EEffectFlags effectFlags = EffectFlags::None) final;
253
254 EffectVariableHandle getEffectVariable(EffectHandle effectHandle, const StringView & name) override;
256 TextureBindingHandle getTextureBinding(EffectHandle effectHandle, const StringView & name, const unsigned int slot) override;
257 SamplerStateBindingHandle getSamplerStateBinding(EffectHandle effectHandle, const StringView & name, const unsigned int slot) override;
258 BufferBindingHandle getBufferBinding(EffectHandle effectHandle, const StringView & name) override;
259 void releaseBufferBinding(BufferBindingHandle bufferBindingHandle) override;
260
261 void setIOHandler(IIOHandler * handler) override { this->handler = handler; }
262 IIOHandler * getIOHandler() override { return handler; }
263
264 EffectHandle load(const ProcessedContent & vsSource,
265 const ProcessedContent & psSource,
266 const StringView & vsEntryPoint,
267 const StringView & psEntryPoint,
268 const EffectDescription & desc);
269
270 EffectHandle load(const ProcessedContent & vsSource,
271 const ProcessedContent & gsSource,
272 const ProcessedContent & psSource,
273 const StringView & vsEntryPoint,
274 const StringView & gsEntryPoint,
275 const StringView & psEntryPoint,
276 const EffectDescription & desc);
277
278 virtual EffectHandle load(const ProcessedContent & vsSource,
279 const ProcessedContent & hsSource,
280 const ProcessedContent & dsSource,
281 const ProcessedContent & gsSource,
282 const ProcessedContent & psSource,
283 const StringView & vsEntryPoint,
284 const StringView & hsEntryPoint,
285 const StringView & dsEntryPoint,
286 const StringView & gsEntryPoint,
287 const StringView & psEntryPoint,
288 const EffectDescription & desc) = 0;
289
290 void initialize(struct IBuffers * buffers);
291
293
295
296 IIOHandler * handler = nullptr;
297 std::unique_ptr<IIOHandler> defaultHandler;
298 struct IBuffers * buffers = nullptr;
299 };
300
301 template<typename StateVariableType, size_t Slots>
302 struct Binding
303 {
304 Binding() = default;
305
306 bool hasChanged() const
307 {
308 return changed != 0;
309 }
310
311 void setUnchanged()
312 {
313 changed = 0;
314 }
315
316 void setChanged()
317 {
318 changed = 0xFFFFFFFF;
319 }
320
321 void setChanged(size_t slot, StateVariableType variable, bool force = false)
322 {
323 if (variables[slot] == variable && !force) return;
324
325 ++numChanged;
326 variables[slot] = variable;
327 changed |= 1 << slot;
328 }
329
330 void setAnyChanged(StateVariableType && variable)
331 {
332 for (size_t i = 0; i < Slots; ++i) {
333 if (variables[i] == variable) {
334 setChanged(i, std::forward<StateVariableType &&>(variable), true);
335 }
336 }
337 }
338
339 bool getChanged(size_t slot) const
340 {
341 return (changed & (1 << slot)) != 0;
342 }
343
344 size_t size() const { return Slots; }
345
346 const StateVariableType & operator[](size_t index) const
347 {
348 return variables[index];
349 }
350
351 private:
352 StateVariableType variables[Slots] = { 0 };
353 uint32_t changed = 0xFFFFFFFF;
354 uint32_t numChanged = 0;
355 };
356
357 template<typename T, size_t Size>
358 inline void decode(int64_t handle, T(&slots)[Size])
359 {
360 uint64_t value = static_cast<uint64_t>(handle);
361
362 if ((value == 0) || (value == ~0ull)) {
363 value = ~0ull; // If NoHandle or IllegalHandle, all slots to NoSlot.
364 }
365
366 for (size_t i = 0; i < Size; ++i) {
367 slots[i] = (value >> (i * 8)) & 0xFF;
368 }
369 }
370
371 inline uint8_t decode(int64_t handle)
372 {
373 uint64_t value = static_cast<uint64_t>(handle);
374
375 if ((value == 0) || (value == ~0ull)) {
376 return NoBinding;
377 } else {
378 return static_cast<uint8_t>(value & 0xffu);
379 }
380 }
381
382}
Provides a weakly referenced view over the contents of a string.
Definition: StringView.h:24
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
Definition: HashFunctions.h:62
std::vector< PreprocessorDefinition > PreprocessorDefinitions
A set of preprocessor definitions.
Definition: IEffects.h:13
Contains an effect description used to load a single effect.
Definition: IEffects.h:55
EEffectFlags
Effect source flags.
Definition: IEffects.h:20
IIOHandler * getIOHandler() override
Gets the external I/O handler.
ConstantBufferBindingHandle getConstantBufferBinding(EffectHandle effectHandle, const StringView &name) override
Get a handle to a constant buffer binding, mapping how to bind a constant buffer to the given effect.
BufferBindingHandle getBufferBinding(EffectHandle effectHandle, const StringView &name) override
Get a handle to a buffer binding.
SamplerStateBindingHandle getSamplerStateBinding(EffectHandle effectHandle, const StringView &name, const unsigned int slot) override
Get a handle to a sampler state object binding, mapping how to bind the sampler state to the given ef...
void releaseBufferBinding(BufferBindingHandle bufferBindingHandle) override
Release a handle to a buffer binding.
EffectVariableHandle getEffectVariable(EffectHandle effectHandle, const StringView &name) override
Get a handle to the variable with the given name in the effect with the given effectHandle.
TextureBindingHandle getTextureBinding(EffectHandle effectHandle, const StringView &name, const unsigned int slot) override
Get a handle to a texture object binding, mapping how to bind textures to the given effect.
EffectHandle loadEffect(const EffectDescription &description) final
Load an effect from the given description.
void setIOHandler(IIOHandler *handler) override
Sets an external I/O handler to use for I/O operations.
Provides buffer management functionality.
Definition: IBuffers.h:13
Provides effects and shader management functionality.
Definition: IEffects.h:148
I/O handler.
Definition: IEffects.h:106