Plasma Engine  2.0
Loading...
Searching...
No Matches
RenderContext.h
1#pragma once
2
3#include <Core/ResourceManager/Resource.h>
4#include <Foundation/Containers/Map.h>
5#include <Foundation/Math/Rect.h>
6#include <Foundation/Strings/String.h>
7#include <RendererCore/Declarations.h>
8#include <RendererCore/Pipeline/ViewData.h>
9#include <RendererCore/RenderContext/Implementation/RenderContextStructs.h>
10#include <RendererCore/Shader/ConstantBufferStorage.h>
11#include <RendererCore/Shader/ShaderStageBinary.h>
12#include <RendererCore/ShaderCompiler/PermutationGenerator.h>
13#include <RendererCore/Textures/Texture2DResource.h>
14#include <RendererCore/Textures/Texture3DResource.h>
15#include <RendererCore/Textures/TextureCubeResource.h>
16#include <RendererFoundation/CommandEncoder/CommandEncoder.h>
17#include <RendererFoundation/Device/Device.h>
18#include <RendererFoundation/Shader/Shader.h>
19#include <RendererFoundation/Shader/ShaderUtils.h>
20
21#include <RendererCore/../../../Data/Base/Shaders/Common/GlobalConstants.h>
22
24
26// plRenderContext
28
29class PL_RENDERERCORE_DLL plRenderContext
30{
31private:
32 plRenderContext(plGALCommandEncoder* pCommandEncoder);
34 friend class plMemoryUtils;
35
36 static plRenderContext* s_pDefaultInstance;
37 static plGALCommandEncoder* s_pCommandEncoder;
38 static plHybridArray<plRenderContext*, 4> s_Instances;
39
40public:
41 static plRenderContext* GetDefaultInstance();
42 static plRenderContext* CreateInstance(plGALCommandEncoder* pCommandEncoder);
43 static void DestroyInstance(plRenderContext* pRenderer);
44
45public:
47 {
48 Statistics();
49 void Reset();
50
51 plUInt32 m_uiFailedDrawcalls;
52 };
53
54 Statistics GetAndResetStatistics();
55
56 void BeginRendering(const plGALRenderingSetup& renderingSetup, const plRectFloat& viewport, const char* szName = "", bool bStereoRendering = false);
57 void EndRendering();
58
59 void BeginCompute(const char* szName = "");
60 void EndCompute();
61
62 // Helper class to automatically end rendering or compute on scope exit
63 template <int ScopeType>
65 {
66 PL_DISALLOW_COPY_AND_ASSIGN(CommandEncoderScope);
67
68 public:
69 PL_ALWAYS_INLINE ~CommandEncoderScope()
70 {
71 if constexpr (ScopeType == 0)
72 m_RenderContext.EndRendering();
73 else
74 m_RenderContext.EndCompute();
75
76 if (m_pCommandsScope != nullptr)
77 {
78 plGALDevice::GetDefaultDevice()->EndCommands(m_pCommandsScope);
79 }
80 }
81
82 PL_ALWAYS_INLINE plGALCommandEncoder* operator->() { return m_pGALCommandEncoder; }
83 PL_ALWAYS_INLINE operator const plGALCommandEncoder*() { return m_pGALCommandEncoder; }
84
85 private:
86 friend class plRenderContext;
87
88 PL_ALWAYS_INLINE CommandEncoderScope(plRenderContext& renderContext, plGALCommandEncoder* pCommandsScope)
89 : m_RenderContext(renderContext)
90 , m_pCommandsScope(pCommandsScope)
91 {
92 m_pGALCommandEncoder = renderContext.GetCommandEncoder();
93 }
94
95 plRenderContext& m_RenderContext;
96 plGALCommandEncoder* m_pCommandsScope;
97 plGALCommandEncoder* m_pGALCommandEncoder;
98 };
99
101 PL_ALWAYS_INLINE static RenderingScope BeginRenderingScope(const plRenderViewContext& viewContext, const plGALRenderingSetup& renderingSetup, const char* szName = "", bool bStereoRendering = false)
102 {
103 viewContext.m_pRenderContext->BeginRendering(renderingSetup, viewContext.m_pViewData->m_ViewPortRect, szName, bStereoRendering);
104 return RenderingScope(*viewContext.m_pRenderContext, nullptr);
105 }
106
107 PL_ALWAYS_INLINE static RenderingScope BeginCommandsAndRenderingScope(const plRenderViewContext& viewContext, const plGALRenderingSetup& renderingSetup, const char* szName, bool bStereoRendering = false)
108 {
109 plGALCommandEncoder* pCommandEncoder = plGALDevice::GetDefaultDevice()->BeginCommands(szName);
110 viewContext.m_pRenderContext->BeginRendering(renderingSetup, viewContext.m_pViewData->m_ViewPortRect, "", bStereoRendering);
111 return RenderingScope(*viewContext.m_pRenderContext, pCommandEncoder);
112 }
113
114 using ComputeScope = CommandEncoderScope<1>;
115 PL_ALWAYS_INLINE static ComputeScope BeginComputeScope(const plRenderViewContext& viewContext, const char* szName = "")
116 {
117 viewContext.m_pRenderContext->BeginCompute(szName);
118 return ComputeScope(*viewContext.m_pRenderContext, nullptr);
119 }
120
121 PL_ALWAYS_INLINE static ComputeScope BeginCommandsAndComputeScope(const plRenderViewContext& viewContext, const char* szName)
122 {
123 plGALCommandEncoder* pCommandEncoder = plGALDevice::GetDefaultDevice()->BeginCommands(szName);
124
125 viewContext.m_pRenderContext->BeginCompute();
126 return ComputeScope(*viewContext.m_pRenderContext, pCommandEncoder);
127 }
128
129 PL_ALWAYS_INLINE plGALCommandEncoder* GetCommandEncoder()
130 {
131 PL_ASSERT_DEBUG(m_pGALCommandEncoder != nullptr, "Outside of BeginCommands / EndCommands scope of the device");
132 return m_pGALCommandEncoder;
133 }
134
135 // Member Functions
136 void SetShaderPermutationVariable(const char* szName, const plTempHashedString& sValue);
137 void SetShaderPermutationVariable(const plHashedString& sName, const plHashedString& sValue);
138
139 void BindMaterial(const plMaterialResourceHandle& hMaterial);
140
141 void BindTexture2D(const plTempHashedString& sSlotName, const plTexture2DResourceHandle& hTexture, plResourceAcquireMode acquireMode = plResourceAcquireMode::AllowLoadingFallback);
142 void BindTexture3D(const plTempHashedString& sSlotName, const plTexture3DResourceHandle& hTexture, plResourceAcquireMode acquireMode = plResourceAcquireMode::AllowLoadingFallback);
143 void BindTextureCube(const plTempHashedString& sSlotName, const plTextureCubeResourceHandle& hTexture, plResourceAcquireMode acquireMode = plResourceAcquireMode::AllowLoadingFallback);
144
145 void BindTexture2D(const plTempHashedString& sSlotName, plGALTextureResourceViewHandle hResourceView);
146 void BindTexture3D(const plTempHashedString& sSlotName, plGALTextureResourceViewHandle hResourceView);
147 void BindTextureCube(const plTempHashedString& sSlotName, plGALTextureResourceViewHandle hResourceView);
148
150 void BindUAV(const plTempHashedString& sSlotName, plGALTextureUnorderedAccessViewHandle hUnorderedAccessViewHandle);
151 void BindUAV(const plTempHashedString& sSlotName, plGALBufferUnorderedAccessViewHandle hUnorderedAccessViewHandle);
152
153 void BindSamplerState(const plTempHashedString& sSlotName, plGALSamplerStateHandle hSamplerSate);
154
155 void BindBuffer(const plTempHashedString& sSlotName, plGALBufferResourceViewHandle hResourceView);
156
157 void BindConstantBuffer(const plTempHashedString& sSlotName, plGALBufferHandle hConstantBuffer);
158 void BindConstantBuffer(const plTempHashedString& sSlotName, plConstantBufferStorageHandle hConstantBufferStorage);
159
164 void SetPushConstants(const plTempHashedString& sSlotName, plArrayPtr<const plUInt8> data);
165
170 template <typename T>
171 PL_ALWAYS_INLINE void SetPushConstants(const plTempHashedString& sSlotName, const T& constants)
172 {
173 SetPushConstants(sSlotName, plArrayPtr<const plUInt8>(reinterpret_cast<const plUInt8*>(&constants), sizeof(T)));
174 }
175
179 void BindShader(const plShaderResourceHandle& hShader, plBitflags<plShaderBindFlags> flags = plShaderBindFlags::Default);
180
181 void BindMeshBuffer(const plDynamicMeshBufferResourceHandle& hDynamicMeshBuffer);
182 void BindMeshBuffer(const plMeshBufferResourceHandle& hMeshBuffer);
183 void BindMeshBuffer(plGALBufferHandle hVertexBuffer, plGALBufferHandle hIndexBuffer, const plVertexDeclarationInfo* pVertexDeclarationInfo, plGALPrimitiveTopology::Enum topology, plUInt32 uiPrimitiveCount, plGALBufferHandle hVertexBuffer2 = {}, plGALBufferHandle hVertexBuffer3 = {}, plGALBufferHandle hVertexBuffer4 = {});
184 PL_ALWAYS_INLINE void BindNullMeshBuffer(plGALPrimitiveTopology::Enum topology, plUInt32 uiPrimitiveCount)
185 {
186 BindMeshBuffer(plGALBufferHandle(), plGALBufferHandle(), nullptr, topology, uiPrimitiveCount);
187 }
188
189 plResult DrawMeshBuffer(plUInt32 uiPrimitiveCount = 0xFFFFFFFF, plUInt32 uiFirstPrimitive = 0, plUInt32 uiInstanceCount = 1);
190
191 plResult Dispatch(plUInt32 uiThreadGroupCountX, plUInt32 uiThreadGroupCountY = 1, plUInt32 uiThreadGroupCountZ = 1);
192 plResult DispatchIndirect(plGALBufferHandle hIndirectArgumentBuffer, plUInt32 uiArgumentOffsetInBytes);
193
194 plResult ApplyContextStates(bool bForce = false);
195 void ResetContextState();
196
197 plGlobalConstants& WriteGlobalConstants();
198 const plGlobalConstants& ReadGlobalConstants() const;
199
205 void SetDefaultTextureFilter(plTextureFilterSetting::Enum filter);
206
208 plTextureFilterSetting::Enum GetDefaultTextureFilter() const { return m_DefaultTextureFilter; }
209
215 plTextureFilterSetting::Enum GetSpecificTextureFilter(plTextureFilterSetting::Enum configuration) const;
216
218 void SetAllowAsyncShaderLoading(bool bAllow);
219
221 bool GetAllowAsyncShaderLoading();
222
223
224 // Static Functions
225public:
226 // Constant buffer storage handling
227 template <typename T>
228 PL_ALWAYS_INLINE static plConstantBufferStorageHandle CreateConstantBufferStorage()
229 {
230 return CreateConstantBufferStorage(sizeof(T));
231 }
232
233 template <typename T>
234 PL_FORCE_INLINE static plConstantBufferStorageHandle CreateConstantBufferStorage(plConstantBufferStorage<T>*& out_pStorage)
235 {
237 plConstantBufferStorageHandle hStorage = CreateConstantBufferStorage(sizeof(T), pStorage);
238 out_pStorage = static_cast<plConstantBufferStorage<T>*>(pStorage);
239 return hStorage;
240 }
241
242 PL_FORCE_INLINE static plConstantBufferStorageHandle CreateConstantBufferStorage(plUInt32 uiSizeInBytes)
243 {
245 return CreateConstantBufferStorage(uiSizeInBytes, pStorage);
246 }
247
248 static plConstantBufferStorageHandle CreateConstantBufferStorage(plUInt32 uiSizeInBytes, plConstantBufferStorageBase*& out_pStorage);
249 static void DeleteConstantBufferStorage(plConstantBufferStorageHandle hStorage);
250
251 template <typename T>
252 PL_FORCE_INLINE static bool TryGetConstantBufferStorage(plConstantBufferStorageHandle hStorage, plConstantBufferStorage<T>*& out_pStorage)
253 {
254 plConstantBufferStorageBase* pStorage = nullptr;
255 bool bResult = TryGetConstantBufferStorage(hStorage, pStorage);
256 out_pStorage = static_cast<plConstantBufferStorage<T>*>(pStorage);
257 return bResult;
258 }
259
260 static bool TryGetConstantBufferStorage(plConstantBufferStorageHandle hStorage, plConstantBufferStorageBase*& out_pStorage);
261
262 template <typename T>
263 PL_FORCE_INLINE static T* GetConstantBufferData(plConstantBufferStorageHandle hStorage)
264 {
265 plConstantBufferStorage<T>* pStorage = nullptr;
266 if (TryGetConstantBufferStorage(hStorage, pStorage))
267 {
268 return &(pStorage->GetDataForWriting());
269 }
270
271 return nullptr;
272 }
273
274 // Default sampler state
276
277private:
278 PL_MAKE_SUBSYSTEM_STARTUP_FRIEND(RendererCore, RendererContext);
279
280 static void LoadBuiltinShader(plShaderUtils::plBuiltinShaderType type, plShaderUtils::plBuiltinShader& out_shader);
281 static void RegisterImmutableSamplers();
282 static void OnEngineStartup();
283 static void OnEngineShutdown();
284 static void GALStaticDeviceEventHandler(const plGALDeviceEvent& e);
285
286private:
287 Statistics m_Statistics;
289 plShaderResourceHandle m_hActiveShader;
290 plGALShaderHandle m_hActiveGALShader;
291
292 plHashTable<plHashedString, plHashedString> m_PermutationVariables;
293 plMaterialResourceHandle m_hNewMaterial;
294 plMaterialResourceHandle m_hMaterial;
295
296 plShaderPermutationResourceHandle m_hActiveShaderPermutation;
297
298 plBitflags<plShaderBindFlags> m_ShaderBindFlags;
299
300 plGALBufferHandle m_hVertexBuffers[4];
301 plGALBufferHandle m_hIndexBuffer;
302 const plVertexDeclarationInfo* m_pVertexDeclarationInfo;
303 plGALPrimitiveTopology::Enum m_Topology;
304 plUInt32 m_uiMeshBufferPrimitiveCount;
305 plEnum<plTextureFilterSetting> m_DefaultTextureFilter;
306 bool m_bAllowAsyncShaderLoading;
307 bool m_bStereoRendering = false;
308
313
315
318 plGALSamplerStateHandle m_hFallbackSampler;
319
320 struct BoundConstantBuffer
321 {
322 PL_DECLARE_POD_TYPE();
323
324 BoundConstantBuffer() = default;
325 BoundConstantBuffer(plGALBufferHandle hConstantBuffer)
326 : m_hConstantBuffer(hConstantBuffer)
327 {
328 }
329 BoundConstantBuffer(plConstantBufferStorageHandle hConstantBufferStorage)
330 : m_hConstantBufferStorage(hConstantBufferStorage)
331 {
332 }
333
334 plGALBufferHandle m_hConstantBuffer;
335 plConstantBufferStorageHandle m_hConstantBufferStorage;
336 };
337
338 plHashTable<plUInt64, BoundConstantBuffer> m_BoundConstantBuffers;
339
340 plConstantBufferStorageHandle m_hGlobalConstantBufferStorage;
341 plConstantBufferStorageHandle m_hPushConstantsStorage;
342
343 struct ShaderVertexDecl
344 {
345 plGALShaderHandle m_hShader;
346 plUInt32 m_uiVertexDeclarationHash;
347
348 PL_FORCE_INLINE bool operator<(const ShaderVertexDecl& rhs) const
349 {
350 if (m_hShader < rhs.m_hShader)
351 return true;
352 if (rhs.m_hShader < m_hShader)
353 return false;
354 return m_uiVertexDeclarationHash < rhs.m_uiVertexDeclarationHash;
355 }
356
357 PL_FORCE_INLINE bool operator==(const ShaderVertexDecl& rhs) const
358 {
359 return (m_hShader == rhs.m_hShader && m_uiVertexDeclarationHash == rhs.m_uiVertexDeclarationHash);
360 }
361 };
362
363 static plResult BuildVertexDeclaration(plGALShaderHandle hShader, const plVertexDeclarationInfo& decl, plGALVertexDeclarationHandle& out_Declaration);
364
365 static plMap<ShaderVertexDecl, plGALVertexDeclarationHandle> s_GALVertexDeclarations;
366
367 static plMutex s_ConstantBufferStorageMutex;
369 static plMap<plUInt32, plDynamicArray<plConstantBufferStorageBase*>> s_FreeConstantBufferStorage;
370
371private: // Per Renderer States
372 plGALCommandEncoder* m_pGALCommandEncoder = nullptr;
373 plEventSubscriptionID m_GALdeviceEventsId = 0;
374 bool m_bRendering = false;
375 bool m_bCompute = false;
376
377 // Member Functions
378 void UploadConstants();
379
380 void SetShaderPermutationVariableInternal(const plHashedString& sName, const plHashedString& sValue);
381 void BindShaderInternal(const plShaderResourceHandle& hShader, plBitflags<plShaderBindFlags> flags);
382 plShaderPermutationResource* ApplyShaderState();
383 plMaterialResource* ApplyMaterialState();
384 void ApplyConstantBufferBindings(const plGALShader* pShader);
385 void ApplyTextureBindings(const plGALShader* pShader);
386 void ApplyUAVBindings(const plGALShader* pShader);
387 void ApplySamplerBindings(const plGALShader* pShader);
388 void ApplyBufferBindings(const plGALShader* pShader);
389};
This class encapsulates an array and it's size. It is recommended to use this class instead of plain ...
Definition ArrayPtr.h:37
Definition ConstantBufferStorage.h:8
Definition ConstantBufferStorage.h:54
Definition ConstantBufferStorage.h:34
Definition RendererFoundationDLL.h:418
Definition RendererFoundationDLL.h:432
Definition RendererFoundationDLL.h:446
Definition CommandEncoder.h:11
plGALCommandEncoder * BeginCommands(const char *szName)
Begin recording GPU commands on the returned command encoder.
Definition Device.cpp:183
void EndCommands(plGALCommandEncoder *pCommandEncoder)
Stop recording commands on the command encoder.
Definition Device.cpp:212
Definition RendererFoundationDLL.h:481
Definition RendererFoundationDLL.h:404
Definition Shader.h:7
Definition RendererFoundationDLL.h:425
Definition RendererFoundationDLL.h:439
Definition RendererFoundationDLL.h:488
Definition HashTable.h:333
This class is optimized to take nearly no memory (sizeof(void*)) and to allow very fast checks whethe...
Definition HashedString.h:25
A hybrid array uses in-place storage to handle the first few elements without any allocation....
Definition HybridArray.h:12
Definition IdTable.h:171
Definition Map.h:408
Definition MaterialResource.h:59
This class provides functions to work on raw memory.
Definition MemoryUtils.h:26
Provides a simple mechanism for mutual exclusion to prevent multiple threads from accessing a shared ...
Definition Mutex.h:13
Definition RenderContext.h:65
Definition RenderContext.h:30
PL_ALWAYS_INLINE void SetPushConstants(const plTempHashedString &sSlotName, const T &constants)
Definition RenderContext.h:171
plTextureFilterSetting::Enum GetDefaultTextureFilter() const
Returns the texture filter mode that is used by default for textures.
Definition RenderContext.h:208
Definition ShaderPermutationResource.h:18
A class to use together with plHashedString for quick comparisons with temporary strings that need no...
Definition HashedString.h:151
The plBitflags class allows you to work with type-safe bitflags.
Definition Bitflags.h:82
A custom enum implementation that allows to define the underlying storage type to control its memory ...
Definition Enum.h:37
Type for important GAL events.
Definition Descriptors.h:253
Definition RenderTargetSetup.h:44
Definition Descriptors.h:118
Definition RenderContext.h:47
Definition Declarations.h:51
Definition RenderWorld.h:24
Default enum for returning failure or success, instead of using a bool.
Definition Types.h:54
Definition ShaderUtils.h:54
Definition MeshBufferResource.h:24