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;
115 handle = context->renderer->getDevice()->getEffects()->loadEffect(effectDesc);
118 CachedEffect effect = { desc, handle, 1 };
119 auto & cached = effects[code] = effect;
121 if (context->context->watcher && context->context->variables->get(
"resources.effects.autoReload",
false)) {
122 if (desc.vs.size()) {
123 context->context->watcher->watchFile(desc.vs, [&](
const FileSystemWatcher::Event&) { reload(context, &cached); });
125 if (desc.ps.size()) {
126 context->context->watcher->watchFile(desc.ps, [&](
const FileSystemWatcher::Event&) { reload(context, &cached); });
134void Cogs::Core::EffectCache::release(RenderTaskContext * context, CachedEffect * effect)
136 assert(effect->usage &&
"Effect already released.");
138 if (--effect->usage == 0) {
140 context->renderer->getDevice()->getEffects()->releaseEffect(effect->handle);
148 EffectDescription desc{};
149 desc.cs = cs.to_string();
150 return loadEffect(context, desc);
154Cogs::Core::CachedEffect * Cogs::Core::EffectCache::loadEffect(RenderTaskContext * context, StringView vs, StringView ps)
156 EffectDescription desc{};
157 desc.vs = vs.to_string();
158 desc.ps = ps.to_string();
160 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.
BindGroupSetDescription bindGroupLayoutDesc
Optional bind-group layout metadata. Backends may use this instead of source introspection.
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.