Cogs.Core
ComputeTask.cpp
1#include "ComputeTask.h"
2
3#include "Rendering/ICapabilities.h"
4#include "Rendering/IContext.h"
5#include "Rendering/IEffects.h"
6#include "Rendering/IGraphicsDevice.h"
7
8#include "Foundation/Logging/Logger.h"
9#include "Resources/ShaderBuilderPostProcess.h"
10
11#include "Renderer/Renderer.h"
12
13#include <cassert>
14
15using namespace Cogs;
16
17namespace
18{
19 Cogs::Logging::Log logger = Cogs::Logging::getLogger("ComputeTask");
20}
21
22void Cogs::Core::ComputeTask::initialize(RenderTaskContext * context)
23{
24 EffectDescription desc = {};
25
26 for (auto & p : effectParameter.values) {
27 if (p.key == "definitions") {
28 for (auto & d : p.values) {
29 desc.definitions.push_back({ d.key, d.value });
30 }
31 }
32 else if (p.key == "source") {
33 desc.cs = p.value;
34 }
35 else if (p.key == "useVariables") {
36 // Handled in RenderTaskFactory.cpp
37 }
38 else if (p.key == "setVariables") {
39 // Handled in RenderTaskFactory.cpp
40 }
41 else if (p.key == "useComponentFields") {
42 // Handled in RenderTaskFactory.cpp
43 }
44 else if (p.key == "properties") {
45 // Handled in RenderTaskFactory.cpp
46 }
47 else if (p.key == "groups" && p.values.size() == 3) {
48 // Handled in RenderTaskFactory.cpp
49 }
50 else if (p.key == "options") {
51 // Handled in RenderTaskFactory.cpp
52 }
53 else{
54 LOG_WARNING(logger, "Unknown compute task pipeline section \"%s\"", p.key.c_str());
55 }
56 }
57
58 effect = context->renderer->getEffectCache().loadEffect(context, desc);
59}
60
61void Cogs::Core::ComputeTask::initialize(RenderTaskContext* context, const RenderTaskDefinition& taskDefinition) {
62 ProcessTask::initialize(context, taskDefinition);
63 EffectDescription desc = {};
64
65 for (auto& p : effectParameter.values) {
66 if (p.key == "definitions") {
67 for (auto& d : p.values) {
68 desc.definitions.push_back({ d.key, d.value });
69 }
70 }
71 else if (p.key == "source") {
72 desc.cs = p.value;
73 }
74 else if (p.key == "useVariables") {
75 // Handled in RenderTaskFactory.cpp
76 }
77 else if (p.key == "setVariables") {
78 // Handled in RenderTaskFactory.cpp
79 }
80 else if (p.key == "useComponentFields") {
81 // Handled in RenderTaskFactory.cpp
82 }
83 else if (p.key == "properties") {
84 // Handled in RenderTaskFactory.cpp
85 }
86 else if (p.key == "groups" && p.values.size() == 3) {
87 // Handled in RenderTaskFactory.cpp
88 }
89 else if (p.key == "options") {
90 // Handled in RenderTaskFactory.cpp
91 }
92 else{
93 LOG_WARNING(logger, "Unknown compute task pipeline section \"%s\"", p.key.c_str());
94 }
95 }
96
97 {
98 Cogs::GraphicsDeviceType graphicsDeviceType = context->renderer->getDevice()->getType();
99 bool success = false;
100 switch (graphicsDeviceType)
101 {
102#if 0
103
105 success = Cogs::Core::buildPostProcessEffectES3(context, desc, this);
106 break;
108 success = buildPostProcessEffectWebGPU(context, desc);
109 break;
110#endif
113 success = buildComputeEffect(context, desc, this);
114 break;
115 default:
116 break;
117 }
118 if (!success) {
119 LOG_ERROR(logger, "Failed to build post processing shader source");
120 }
121 }
122
123 effect = context->renderer->getEffectCache().loadEffect(context, desc);
124}
125
126void Cogs::Core::ComputeTask::cleanup(RenderTaskContext * context)
127{
128 ProcessTask::cleanup(context);
129}
130
132{
133 IEffects* effects = context->device->getEffects();
134
135 Cogs::ResourceStatus status = HandleIsValid(effect->handle) ? effects->checkEffect(effect->handle) : Cogs::ResourceStatus::Error;
136
137 if (status == Cogs::ResourceStatus::Error && effectStatus != Cogs::ResourceStatus::Error) {
138 LOG_ERROR(logger, "Invalid compute effect handle.");
139 }
140
141 effectStatus = status;
142 return effectStatus;
143}
144
145void Cogs::Core::ComputeTask::apply(RenderTaskContext * context)
146{
147 DynamicRenderInstrumentationScope(context->device->getImmediateContext(), SCOPE_RENDERING, "ComputeTask", (std::string("ComputeTask<") + name + ">::apply").c_str());
148
149 assert(effectStatus == Cogs::ResourceStatus::Ready);
150
151 auto device = context->renderer->getDevice();
152 auto deviceContext = device->getImmediateContext();
153
154 if(!device->getCapabilities()->getDeviceCapabilities().RenderPass){
155 // Reset render target to avoid input/output locks.
157 }
158
159 deviceContext->setEffect(effect->handle);
160
161 setProperties(context);
162
163 deviceContext->setSamplerState("linearSampler", 0, context->states->getSamplerState(SamplerState::DefaultState()));
164
165 uint32_t groups[3] = { 1, 1, 1 };
166
167 if (this->groups.expressions.size() == 3) {
168 for (size_t i = 0; i < 3; i++) {
169 groups[i] = this->scope->update(this->groups.expressions[i].second, 0);
170 }
171 }
172 else {
173 for (auto & ep : effectParameter.values) {
174 if (ep.key != "groups") continue;
175
176 for (uint32_t i = 0; i < 3; i++) {
177 groups[i] = static_cast<uint32_t>(ep.float3Value[i]);
178 }
179 }
180 }
181
182 if (groups[0] && groups[1] && groups[2]) {
183 deviceContext->dispatchCompute(groups[0], groups[1], groups[2]);
184 } else {
185 LOG_WARNING(logger, "Empty compute shader dimensions.");
186 }
187}
IGraphicsDevice * getDevice() override
Get the graphics device used by the renderer.
Definition: Renderer.h:46
virtual IEffects * getEffects()=0
Get a pointer to the effect management interface.
virtual IContext * getImmediateContext()=0
Get a pointer to the immediate context used to issue commands to the graphics device.
Log implementation class.
Definition: LogManager.h:140
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:181
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
GraphicsDeviceType
Contains types of graphics devices that may be supported.
Definition: Base.h:48
@ OpenGLES30
Graphics device using the OpenGLES 3.0 API.
@ Direct3D11
Graphics device using the Direct3D 11 API.
@ OpenGL20
Graphics device using OpenGL, supporting at least OpenGL 2.0.
@ WebGPU
Graphics device using the WebGPU API Backend.
ResourceStatus
Status of an asynchronously loaded resource, such as an effect or a pipeline.
Definition: Common.h:198
@ Error
The resource failed to load.
@ Ready
The resource has loaded successfully and is ready for use.
Cogs::ResourceStatus checkReady(RenderTaskContext *context) override
Check if the task is ready to be applied, e.g.
Contains an effect description used to load a single effect.
Definition: IEffects.h:62
static const Handle_t NoHandle
Represents a handle to nothing.
Definition: Common.h:78
virtual void setRenderTarget(const RenderTargetHandle handle, const DepthStencilHandle depthStencilHandle)=0
Sets the current render target and an associated depth stencil target.
Provides effects and shader management functionality.
Definition: IEffects.h:158
virtual ResourceStatus checkEffect(EffectHandle effectHandle)=0
Check the load status of the effect with the given effectHandle.
static SamplerState & DefaultState()
Constructs a sampler state initialized with the default values.
Definition: SamplerState.h:85