Cogs.Core
RenderResources.cpp
1#include "RenderResources.h"
2#include "Renderer.h"
3#include "Context.h"
4
5#include "MemoryContext.h"
6
7#include "Resources/Mesh.h"
8#include "Resources/Texture.h"
9
10#include "RenderTexture.h"
11#include "RenderTarget.h"
12#include "RenderMesh.h"
13#include "RenderEffect.h"
14#include "RenderMaterial.h"
15#include "RenderMaterialInstance.h"
16#include "RenderList.h"
17#include "RenderBuffer.h"
18
19#include "Foundation/Collections/Pool.h"
20#include "Foundation/Logging/Logger.h"
21#include "Foundation/Platform/Threads.h"
22
23#include "Rendering/ITextures.h"
24
25namespace
26{
27 Cogs::Logging::Log logger = Cogs::Logging::getLogger("RenderResources");
28}
29
30using namespace Cogs;
31using namespace Cogs::Core;
32
33namespace Cogs
34{
35 namespace Core
36 {
38 {
40 renderMeshes(1024, 1024, allocator, MemBlockType::RenderResourceStorage),
41 renderTextures(1024, 1024, allocator, MemBlockType::RenderResourceStorage),
42 renderEffects(1024, 1024, allocator, MemBlockType::RenderResourceStorage),
43 renderMaterials(128, 128, allocator, MemBlockType::RenderResourceStorage),
44 renderMaterialInstances(1024, 1024, allocator, MemBlockType::RenderResourceStorage),
45 renderTargets(128, 128, allocator, MemBlockType::RenderResourceStorage),
46 renderLists(128, 128, allocator, MemBlockType::RenderResourceStorage),
47 renderBuffers(128, 128, allocator, MemBlockType::RenderResourceStorage)
48 {}
49
50 Mutex renderMeshMutex;
55 Collections::Pool<RenderMaterialInstance> renderMaterialInstances;
59 };
60 }
61}
62
63Cogs::Core::RenderResources::RenderResources(Context * context) :
64 storage(std::make_unique<RenderResourceStorage>(context->memory->resourceAllocator))
65{
66
67}
68
69Cogs::Core::RenderResources::~RenderResources()
70{
71}
72
73std::string Cogs::Core::RenderResources::getReport() const
74{
75 if(storage) {
76 size_t meshes, textures, effects, materials, materialinstances, targets, lists, buffers;
77 {
78 LockGuard guard(storage->renderMeshMutex);
79 meshes = storage->renderMeshes.size();
80 textures = storage->renderTextures.size();
81 effects = storage->renderEffects.size();
82 materials = storage->renderMaterials.size();
83 materialinstances = storage->renderMaterialInstances.size();
84 targets = storage->renderTargets.size();
85 lists = storage->renderLists.size();
86 buffers = storage->renderBuffers.size();
87 }
88 char buf[1024];
89 auto rv = std::snprintf(buf, sizeof(buf), "msh=%zu, tex=%zu, eff=%zu mat=%3zu, mit=%zu, trg=%3zu, lst=%zu, buf=%zu",
90 meshes, textures, effects, materials, materialinstances, targets, lists, buffers);
91 if (0 <= rv && static_cast<size_t>(rv) < sizeof(buf)) {
92 return std::string(buf);
93 }
94 }
95 return std::string();
96}
97
98
99void Cogs::Core::RenderResources::initialize(Context * context, Renderer * renderer)
100{
101 this->context = context;
102 this->renderer = renderer;
103 device = renderer->getDevice();
104 renderStates = &renderer->getRenderStates();
105}
106
107void Cogs::Core::RenderResources::cleanup(Context * /*context*/)
108{
109 //TODO: Perform shutdown validation.
110}
111
112RenderTarget * Cogs::Core::RenderResources::createRenderTarget()
113{
114 auto renderTarget = storage->renderTargets.create();
115 renderTarget->type = RenderResourceType::RenderTarget;
116 return renderTarget;
117}
118
119RenderTexture * Cogs::Core::RenderResources::createRenderTexture()
120{
121 auto renderTexture = storage->renderTextures.create();
122 renderTexture->type = RenderResourceType::RenderTexture;
123 return renderTexture;
124}
125
126RenderList * Cogs::Core::RenderResources::createRenderList()
127{
128 auto renderList = storage->renderLists.create();
129 renderList->type = RenderResourceType::RenderList;
130 return renderList;
131}
132
133RenderBuffer * Cogs::Core::RenderResources::createRenderBuffer()
134{
135 auto renderBuffer = storage->renderBuffers.create();
136 renderBuffer->type = RenderResourceType::RenderBuffer;
137 return renderBuffer;
138}
139
140Cogs::Core::RenderMesh * Cogs::Core::RenderResources::createRenderMesh()
141{
142 LockGuard lock(storage->renderMeshMutex);
143
144 auto renderMesh = storage->renderMeshes.create();
145 renderMesh->type = RenderResourceType::Unknown;
146 return renderMesh;
147}
148
149void Cogs::Core::RenderResources::destroyRenderMesh(RenderMesh * renderMesh)
150{
151 LockGuard lock(storage->renderMeshMutex);
152
153 storage->renderMeshes.destroy(renderMesh);
154}
155
156uint32_t Cogs::Core::RenderResources::getRenderHandle(RenderMesh * renderMesh)
157{
158 return storage->renderMeshes.getHandle(renderMesh);
159}
160
161RenderMesh * Cogs::Core::RenderResources::getRenderMesh(uint32_t handle)
162{
163 LockGuard lock(storage->renderMeshMutex);
164
165 return storage->renderMeshes[handle];
166}
167
168void Cogs::Core::RenderResources::updateResource(RenderResource * resource)
169{
170 switch (resource->type)
171 {
172 case RenderResourceType::RenderTarget:
173 static_cast<RenderTarget *>(resource)->update(renderer);
174 break;
175 case RenderResourceType::RenderTexture:
176 static_cast<RenderTexture *>(resource)->update(renderer);
177 break;
178 case RenderResourceType::RenderBuffer:
179 static_cast<RenderBuffer *>(resource)->update(renderer);
180 break;
181 default:
182 break;
183 }
184}
185
186void Cogs::Core::RenderResources::releaseResource(RenderResource * resource)
187{
188 switch (resource->type)
189 {
190 case RenderResourceType::RenderTarget:
191 static_cast<RenderTarget *>(resource)->release(renderer);
192 break;
193 case RenderResourceType::RenderTexture:
194 static_cast<RenderTexture *>(resource)->release(renderer);
195 break;
196 case RenderResourceType::RenderBuffer:
197 static_cast<RenderBuffer *>(resource)->release(renderer);
198 break;
199 default:
200 break;
201 }
202}
203
204void Cogs::Core::RenderResources::destroyResource(RenderResource * resource)
205{
206 switch (resource->type)
207 {
208 case RenderResourceType::RenderTarget:
209 storage->renderTargets.destroy(static_cast<RenderTarget *>(resource));
210 break;
211 case RenderResourceType::RenderTexture:
212 storage->renderTextures.destroy(reinterpret_cast<RenderTexture *>(resource));
213 break;
214 case RenderResourceType::RenderBuffer:
215 storage->renderBuffers.destroy(reinterpret_cast<RenderBuffer *>(resource));
216 break;
217 case RenderResourceType::RenderList:
218 storage->renderLists.destroy(reinterpret_cast<RenderList *>(resource));
219 break;
220 default:
221 break;
222 }
223}
224
225RenderEffect * Cogs::Core::RenderResources::getRenderEffect(const EffectHandle & effect)
226{
227 auto effectResource = effect.resolve();
228
229 if (!effectResource || !effectResource->hasAttachedResource()) return nullptr;
230
231 return (RenderEffect *)effectResource->getAttachedResource();
232}
233
234RenderMaterial * Cogs::Core::RenderResources::getRenderMaterial(const Material * material)
235{
236 if (!material || !material->hasAttachedResource()) return nullptr;
237
238 return (RenderMaterial *)material->getAttachedResource();
239}
240
241RenderMaterialInstance * Cogs::Core::RenderResources::getRenderMaterialInstance(const MaterialInstance * materialInstance)
242{
243 if (!materialInstance || !materialInstance->hasAttachedResource()) return nullptr;
244
245 return (RenderMaterialInstance *)materialInstance->getAttachedResource();
246}
247
248RenderMaterial * Cogs::Core::RenderResources::getRenderMaterial(const MaterialHandle & material)
249{
250 return getRenderMaterial(material.resolve());
251}
252
253RenderMaterialInstance * Cogs::Core::RenderResources::getRenderMaterialInstance(const MaterialInstanceHandle & materialInstance)
254{
255 return getRenderMaterialInstance(materialInstance.resolve());
256}
257
258RenderTexture * Cogs::Core::RenderResources::getRenderTexture(const TextureHandle & texture)
259{
260 auto textureResource = texture.resolve();
261
262 if (!textureResource || !textureResource->hasAttachedResource()) return nullptr;
263
264 return (RenderTexture *)textureResource->getAttachedResource();
265}
266
267RenderMesh * Cogs::Core::RenderResources::getRenderMesh(const MeshHandle & mesh)
268{
269 LockGuard lock(storage->renderMeshMutex);
270
271 auto meshResource = mesh.resolve();
272
273 if (!meshResource || !meshResource->hasAttachedResource()) return nullptr;
274
275 return (RenderMesh *)meshResource->getAttachedResource();
276}
277
278namespace Cogs::Core
279{
280 template<typename Handle, typename Resource>
281 Resource * createGpuResource(const Handle & handle, Collections::Pool<Resource> & resources, RenderResources * /*renderResources*/)
282 {
283 auto resource = handle.resolve();
284
285 if (!resource->hasAttachedResource()) {
286 auto renderResource = resources.create();
287 resource->attachResource(renderResource);
288 renderResource->setResource(resource);
289 renderResource->setName(resource->getName());
290 }
291
292 return static_cast<Resource *>(resource->getAttachedResource());
293 }
294}
295
296ActivationResult Cogs::Core::RenderResources::updateResource(const MeshHandle & meshHandle)
297{
298 LockGuard lock(storage->renderMeshMutex);
299 auto gpuResource = createGpuResource<MeshHandle, RenderMesh>(meshHandle, storage->renderMeshes, this);
300 return gpuResource->update(meshHandle.resolve(), device, this);
301}
302
303ActivationResult Cogs::Core::RenderResources::updateResource(const TextureHandle & textureHandle)
304{
305 auto gpuResource = createGpuResource<TextureHandle, RenderTexture>(textureHandle, storage->renderTextures, this);
306 return gpuResource->update(textureHandle.resolve(), device, this);
307}
308
309ActivationResult Cogs::Core::RenderResources::updateResource(const EffectHandle & effectHandle)
310{
311 auto gpuResource = createGpuResource<EffectHandle, RenderEffect>(effectHandle, storage->renderEffects, this);
312 return gpuResource->update(effectHandle.resolve(), device, this);
313}
314
315Cogs::Core::ActivationResult Cogs::Core::RenderResources::updateResource(const MaterialHandle & materialHandle)
316{
317 auto gpuResource = createGpuResource<MaterialHandle, RenderMaterial>(materialHandle, storage->renderMaterials, this);
318 return gpuResource->update(materialHandle.resolve(), device, this, renderStates);
319}
320
321Cogs::Core::ActivationResult Cogs::Core::RenderResources::updateResource(const MaterialInstanceHandle & materialInstanceHandle)
322{
323 auto gpuResource = createGpuResource<MaterialInstanceHandle, RenderMaterialInstance>(materialInstanceHandle, storage->renderMaterialInstances, this);
324 return gpuResource->update(materialInstanceHandle.resolve(), device, this, renderStates);
325}
326
327namespace Cogs::Core
328{
329 template<typename RenderResourceType>
330 RenderResource * releaseGpuResource(ResourceBase * resource, Renderer * renderer)
331 {
332 auto renderResource = (RenderResourceType *)resource->getAttachedResource();
333 if (renderResource) {
334 renderResource->release(renderer);
335 resource->attachResource(nullptr);
337 }
338 return renderResource;
339 }
340}
341
342void Cogs::Core::RenderResources::releaseResource(Texture * texture)
343{
344 if (auto renderResource = releaseGpuResource<RenderTexture>(texture, renderer)) {
345 storage->renderTextures.destroy((RenderTexture *)renderResource);
346 }
347 if (!texture->isProxy() && texture->ownsExternalTexture.value) {
348 if (texture->externalHandle) {
349 device->getTextures()->releaseNativeTexture(texture->externalHandle);
350 texture->externalHandle = 0;
351 }
352 }
353}
354
355void Cogs::Core::RenderResources::releaseResource(Mesh * mesh)
356{
357 LockGuard lock(storage->renderMeshMutex);
358
359 if (auto renderResource = releaseGpuResource<RenderMesh>(mesh, renderer)) {
360 storage->renderMeshes.destroy((RenderMesh *)renderResource);
361 }
362}
363
364void Cogs::Core::RenderResources::releaseResource(Material * material)
365{
366 if (auto renderResource = releaseGpuResource<RenderMaterial>(material, renderer)) {
367 storage->renderMaterials.destroy((RenderMaterial *)renderResource);
368 }
369}
370
371void Cogs::Core::RenderResources::releaseResource(MaterialInstance * materialInstance)
372{
373 if (auto renderResource = releaseGpuResource<RenderMaterialInstance>(materialInstance, renderer)) {
374 storage->renderMaterialInstances.destroy((RenderMaterialInstance *)renderResource);
375 }
376}
377
378void Cogs::Core::RenderResources::releaseResource(Effect * effect)
379{
380 if (auto renderResource = releaseGpuResource<RenderEffect>(effect, renderer)) {
381 storage->renderEffects.destroy((RenderEffect *)renderResource);
382 }
383}
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
Contains render resources used by the renderer.
Core renderer system.
Definition: Renderer.h:28
RenderStates & getRenderStates() override
Get the reference to the RenderStates structure.
Definition: Renderer.h:68
IGraphicsDevice * getDevice() override
Get the graphics device used by the renderer.
Definition: Renderer.h:45
Log implementation class.
Definition: LogManager.h:139
Base allocator implementation.
Definition: Allocator.h:30
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
@ Resident
The resource is loaded onto the GPU.
ActivationResult
Defines results for resource activation.
Definition: ResourceBase.h:14
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
STL namespace.
Pool used to store elements of ElementType.
Definition: Pool.h:17
ElementType * create(ARGS &&... args)
Allocate and initialize a new element from the pool passing any arguments to the constructor of the n...
Definition: Pool.h:69
Effect resources contain data to control the shader stages of the GPU pipeline.
Definition: Effect.h:24
Material instances represent a specialized Material combined with state for all its buffers and prope...
Material resources define the how of geometry rendering (the what is defined by Mesh and Texture reso...
Definition: Material.h:82
Meshes contain streams of vertex data in addition to index data and options defining geometry used fo...
Definition: Mesh.h:265
Base class for engine resources.
Definition: ResourceBase.h:107
void unsetFlag(ResourceFlags flag)
Unset the given flag.
Definition: ResourceBase.h:236
void attachResource(RenderResource *attachment)
Attach the given GPU resource to the resource.
Definition: ResourceBase.h:261
RenderResource * getAttachedResource() const
Get the attached resource.
Definition: ResourceBase.h:275
bool hasAttachedResource() const
Check if the resource has an attachment.
Definition: ResourceBase.h:268
ResourceType * resolve() const
Resolve the handle, returning a pointer to the actual resource.
Texture resources contain raster bitmap data to use for texturing.
Definition: Texture.h:91