1#include "EffectCache.h"
4#include "Resources/ResourceStore.h"
5#include "Tasks/RenderTask.h"
6#include "Services/Variables.h"
8#include "Foundation/HashSequence.h"
9#include "Foundation/Platform/FileSystemWatcher.h"
10#include "Foundation/Platform/IO.h"
14 size_t getCode(EffectDescription & desc)
16 size_t hashValue =
hashSequence(desc.vs, desc.ps, desc.cs);
18 for (
const auto & def : desc.definitions) {
25 void changeSuffix(std::string& dst,
const std::string& from,
const std::string& to)
27 auto pos = dst.find(from);
28 if (pos == std::string::npos)
return;
29 dst.replace(pos, to.length(), to);
34void Cogs::Core::EffectCache::reload(RenderTaskContext * context)
36 for (
auto & p : effects) {
37 reload(context, &p.second);
41void Cogs::Core::EffectCache::reload(RenderTaskContext * context, CachedEffect * effect)
43 auto device = context->renderer->getDevice();
46 device->getEffects()->releaseEffect(effect->handle);
49 context->context->resourceStore->purge(
"Shaders/" + effect->description.vs);
50 context->context->resourceStore->purge(
"Shaders/" + effect->description.ps);
52 effect->handle = device->getEffects()->loadEffect(effect->description.vs, effect->description.ps);
57 const size_t code = getCode(desc);
59 auto it = effects.find(code);
61 if (it != effects.end() && it->second.usage) {
62 assert(it->second.description.vs == desc.vs);
63 assert(it->second.description.cs == desc.cs);
64 assert(it->second.description.ps == desc.ps);
70 if (!desc.cs.empty()) {
71 std::string cs = desc.cs;
72 switch (context->renderer->getDevice()->getType()) {
74 changeSuffix(cs,
".hlsl",
".wgsl");
79 handle = context->renderer->getDevice()->getEffects()->loadComputeEffect(cs, desc.definitions);
83 auto name = IO::stem(desc.ps);
86 effectDesc.
flags = context->renderer->getEffectFlags();
87 switch (context->renderer->getDevice()->getType()) {
91 changeSuffix(vs,
".hlsl",
".es30.glsl");
92 changeSuffix(ps,
".hlsl",
".es30.glsl");
100 changeSuffix(vs,
".hlsl",
".wgsl");
101 changeSuffix(ps,
".hlsl",
".wgsl");
111 effectDesc.
name = name;
114 handle = context->renderer->getDevice()->getEffects()->loadEffect(effectDesc);
117 CachedEffect effect = { desc, handle, 1 };
118 auto & cached = effects[code] = effect;
120 if (context->context->variables->get(
"resources.effects.autoReload",
false)) {
121 if (desc.vs.size()) {
122 context->context->watcher->watchFile(desc.vs, [&](
const FileSystemWatcher::Event&) { reload(context, &cached); });
124 if (desc.ps.size()) {
125 context->context->watcher->watchFile(desc.ps, [&](
const FileSystemWatcher::Event&) { reload(context, &cached); });
133void Cogs::Core::EffectCache::release(RenderTaskContext * context, CachedEffect * effect)
135 assert(effect->usage &&
"Effect already released.");
137 if (--effect->usage == 0) {
139 context->renderer->getDevice()->getEffects()->releaseEffect(effect->handle);
147 EffectDescription desc{};
148 desc.cs = cs.to_string();
149 return loadEffect(context, desc);
153Cogs::Core::CachedEffect * Cogs::Core::EffectCache::loadEffect(RenderTaskContext * context, StringView vs, StringView ps)
155 EffectDescription desc{};
156 desc.vs = vs.to_string();
157 desc.ps = ps.to_string();
159 return loadEffect(context, desc);
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
@ OpenGLES30
Graphics device using the OpenGLES 3.0 API.
@ WebGPU
Graphics device using the WebGPU API Backend.
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
constexpr size_t hashSequence(const T &t, const U &u)
Hash the last two items in a sequence of objects.
Contains an effect description used to load a single effect.
EffectFlags::EEffectFlags flags
Effect loading flags.
PreprocessorDefinitions definitions
Definitions.
StringView vertexShader
Vertex shader file name or source.
StringView name
Name of the effect. Used for tracking purposes, like naming shader dumps.
StringView pixelShader
Pixel shader file name or source.
EEffectFlags
Effect source flags.
@ WGSL
Effect source is WGSL.
@ GLSL
Effect source is GLSL.
static const Handle_t NoHandle
Represents a handle to nothing.