Cogs.Core
ComputeTask.cpp
1#include "ComputeTask.h"
2
3#include "Rendering/ICapabilities.h"
4#include "Rendering/IContext.h"
5#include "Rendering/IGraphicsDevice.h"
6
7#include "Foundation/Logging/Logger.h"
8#include "Resources/ShaderBuilderPostProcess.h"
9
10#include "Renderer/Renderer.h"
11
12using namespace Cogs;
13
14namespace
15{
16 Cogs::Logging::Log logger = Cogs::Logging::getLogger("ComputeTask");
17}
18
19void Cogs::Core::ComputeTask::initialize(RenderTaskContext * context)
20{
21 EffectDescription desc = {};
22
23 for (auto & p : effectParameter.values) {
24 if (p.key == "definitions") {
25 for (auto & d : p.values) {
26 desc.definitions.push_back({ d.key, d.value });
27 }
28 }
29 else if (p.key == "source") {
30 desc.cs = p.value;
31 }
32 else if (p.key == "useVariables") {
33 // Handled in RenderTaskFactory.cpp
34 }
35 else if (p.key == "setVariables") {
36 // Handled in RenderTaskFactory.cpp
37 }
38 else if (p.key == "useComponentFields") {
39 // Handled in RenderTaskFactory.cpp
40 }
41 else if (p.key == "properties") {
42 // Handled in RenderTaskFactory.cpp
43 }
44 else if (p.key == "groups" && p.values.size() == 3) {
45 // Handled in RenderTaskFactory.cpp
46 }
47 else if (p.key == "options") {
48 // Handled in RenderTaskFactory.cpp
49 }
50 else{
51 LOG_WARNING(logger, "Unknown compute task pipeline section \"%s\"", p.key.c_str());
52 }
53 }
54
55 effect = context->renderer->getEffectCache().loadEffect(context, desc);
56}
57
58void Cogs::Core::ComputeTask::initialize(RenderTaskContext* context, const RenderTaskDefinition& taskDefinition) {
59 ProcessTask::initialize(context, taskDefinition);
60 EffectDescription desc = {};
61
62 for (auto& p : effectParameter.values) {
63 if (p.key == "definitions") {
64 for (auto& d : p.values) {
65 desc.definitions.push_back({ d.key, d.value });
66 }
67 }
68 else if (p.key == "source") {
69 desc.cs = p.value;
70 }
71 else if (p.key == "useVariables") {
72 // Handled in RenderTaskFactory.cpp
73 }
74 else if (p.key == "setVariables") {
75 // Handled in RenderTaskFactory.cpp
76 }
77 else if (p.key == "useComponentFields") {
78 // Handled in RenderTaskFactory.cpp
79 }
80 else if (p.key == "properties") {
81 // Handled in RenderTaskFactory.cpp
82 }
83 else if (p.key == "groups" && p.values.size() == 3) {
84 // Handled in RenderTaskFactory.cpp
85 }
86 else if (p.key == "options") {
87 // Handled in RenderTaskFactory.cpp
88 }
89 else{
90 LOG_WARNING(logger, "Unknown compute task pipeline section \"%s\"", p.key.c_str());
91 }
92 }
93
94 {
95 Cogs::GraphicsDeviceType graphicsDeviceType = context->renderer->getDevice()->getType();
96 bool success = false;
97 switch (graphicsDeviceType)
98 {
99#if 0
100
102 success = Cogs::Core::buildPostProcessEffectES3(context, desc, this);
103 break;
105 success = buildPostProcessEffectWebGPU(context, desc);
106 break;
107#endif
110 success = buildComputeEffect(context, desc, this);
111 break;
112 default:
113 break;
114 }
115 if (!success) {
116 LOG_ERROR(logger, "Failed to build post processing shader source");
117 }
118 }
119
120 effect = context->renderer->getEffectCache().loadEffect(context, desc);
121}
122
123void Cogs::Core::ComputeTask::cleanup(RenderTaskContext * context)
124{
125 ProcessTask::cleanup(context);
126}
127
128void Cogs::Core::ComputeTask::apply(RenderTaskContext * context)
129{
130 DynamicRenderInstrumentationScope(context->device->getImmediateContext(), SCOPE_RENDERING, "ComputeTask", (std::string("ComputeTask<") + name + ">::apply").c_str());
131
132 if (!HandleIsValid(effect->handle)) {
133 LOG_ERROR(logger, "Invalid compute effect handle.");
134 return;
135 }
136
137 auto device = context->renderer->getDevice();
138 auto deviceContext = device->getImmediateContext();
139
140 if(!device->getCapabilities()->getDeviceCapabilities().RenderPass){
141 // Reset render target to avoid input/output locks.
142 deviceContext->setRenderTarget(RenderTargetHandle::NoHandle, DepthStencilHandle::NoHandle);
143 }
144
145 deviceContext->setEffect(effect->handle);
146
147 setProperties(context);
148
149 deviceContext->setSamplerState("linearSampler", 0, context->states->getSamplerState(SamplerState::DefaultState()));
150
151 uint32_t groups[3] = { 1, 1, 1 };
152
153 if (this->groups.expressions.size() == 3) {
154 for (size_t i = 0; i < 3; i++) {
155 groups[i] = this->scope->update(this->groups.expressions[i].second, 0);
156 }
157 }
158 else {
159 for (auto & ep : effectParameter.values) {
160 if (ep.key != "groups") continue;
161
162 for (uint32_t i = 0; i < 3; i++) {
163 groups[i] = static_cast<uint32_t>(ep.float3Value[i]);
164 }
165 }
166 }
167
168 if (groups[0] && groups[1] && groups[2]) {
169 deviceContext->dispatchCompute(groups[0], groups[1], groups[2]);
170 } else {
171 LOG_WARNING(logger, "Empty compute shader dimensions.");
172 }
173}
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.
Contains an effect description used to load a single effect.
Definition: IEffects.h:55
static const Handle_t NoHandle
Represents a handle to nothing.
Definition: Common.h:78
static SamplerState & DefaultState()
Constructs a sampler state initialized with the default values.
Definition: SamplerState.h:85