Cogs.Core
PostProcessTask.cpp
1#include "PostProcessTask.h"
2#include "Resources/VertexFormats.h"
3
4#include "Context.h"
5#include "Renderer/Renderer.h"
6#include "Renderer/RenderTarget.h"
7#include "Systems/Core/CameraSystem.h"
8
9#include "Rendering/IBuffers.h"
10#include "Rendering/ICapabilities.h"
11#include "Rendering/IContext.h"
12#include "Rendering/IGraphicsDevice.h"
13
14#include "Resources/ShaderBuilderPostProcess.h"
15
16#include <glm/gtc/type_ptr.hpp>
17
18#include "Foundation/Logging/Logger.h"
19
20using namespace Cogs;
21
22namespace
23{
24 const char * names[] = {
25 "linearSampler",
26 "linearClampSampler",
27 "pointSampler",
28 "pointClampSampler",
29 };
30
31 Cogs::Logging::Log logger = Cogs::Logging::getLogger("PostProcessTask");
32}
33
34void Cogs::Core::PostProcessTask::initialize(RenderTaskContext* context)
35{
36 ProcessTask::initialize(context);
37}
38
39void Cogs::Core::PostProcessTask::initialize(RenderTaskContext * context, const RenderTaskDefinition& taskDefinition)
40{
41 ProcessTask::initialize(context, taskDefinition);
42
43 auto effects = context->device->getEffects();
44
45 EffectDescription desc = createEffectDesc(context);
46 desc.vs = "Engine/FullscreenV3T2VS.hlsl";
47
48 for (auto & p : effectParameter.values) {
49 if (p.key == "definitions") {
50 for (auto & d : p.values) {
51 desc.definitions.push_back({ d.key, d.value });
52 }
53 }
54 else if (p.key == "source") {
55 desc.ps = p.value;
56 }
57 else if (p.key == "useVariables") {
58 // Handled in RenderTaskFactory.cpp
59 }
60 else if (p.key == "setVariables") {
61 // Handled in RenderTaskFactory.cpp
62 }
63 else if (p.key == "useComponentFields") {
64 // Handled in RenderTaskFactory.cpp
65 }
66 else if (p.key == "properties") {
67 // Handled in RenderTaskFactory.cpp
68 }
69 else if (p.key == "groups" && p.values.size() == 3) {
70 // Handled in RenderTaskFactory.cpp
71 }
72 else if (p.key == "options") {
73 // Handled in RenderTaskFactory.cpp
74 }
75 else{
76 LOG_WARNING(logger, "Unknown post process task pipeline section \"%s\"", p.key.c_str());
77 }
78 }
79
80 {
81 Cogs::GraphicsDeviceType graphicsDeviceType = context->renderer->getDevice()->getType();
82 bool success;
83 switch (graphicsDeviceType)
84 {
86 success = Cogs::Core::buildPostProcessEffectES3(context, desc, this);
87 break;
89 success = buildPostProcessEffectWebGPU(context, desc, this);
90 break;
91 default:
92 success = buildPostProcessEffect(context, desc, this);
93 break;
94 }
95 if (!success) {
96 LOG_ERROR(logger, "Failed to build post processing shader source");
97 }
98 }
99
100 effect = context->renderer->getEffectCache().loadEffect(context, desc);
101
102 if (!HandleIsValid(effect->handle)) {
103 return;
104 }
105 auto * buffers = context->device->getBuffers();
106 inputLayout = buffers->loadInputLayout(&VertexFormats::Pos4f, 1, effect->handle);
107
108 for (size_t i = 0; i < 4; ++i) {
109 auto binding = effects->getSamplerStateBinding(effect->handle, names[i], 0);
110
111 if (HandleIsValid(binding)) {
112 samplerStateBindings[i] = binding;
113 samplerStates[i] = context->states->commonSamplerStates[i];
114 } else {
115 samplerStateBindings[i] = SamplerStateBindingHandle::NoHandle;
116 }
117 }
118}
119
120void Cogs::Core::PostProcessTask::apply(RenderTaskContext * context)
121{
122 if (scopeName.empty()) {
123 scopeName = std::string("PostProcessTask<") + name + ">::apply";
124 }
125
126 DynamicRenderInstrumentationScope(context->device->getImmediateContext(), SCOPE_RENDERING, "PostProcessTask", scopeName.c_str());
127
128 RenderTarget* renderTarget = output.get(RenderResourceType::RenderTarget)->renderTarget;
129
130 if (!renderTarget) {
131 return;
132 }
133
134 if (!HandleIsValid(effect->handle)) {
135 return;
136 }
137
138 auto deviceContext = context->device->getImmediateContext();
139 deviceContext->setEffect(effect->handle);
140
141 if(context->device->getCapabilities()->getDeviceCapabilities().RenderPass){
142 RenderPassInfo info;
143 info.renderTargetHandle = renderTarget->renderTargetHandle;
144 info.depthStencilHandle = renderTarget->depthTargetHandle;
145 {
146 uint32_t i = 0;
147 info.loadOp[i] = clearColor ? LoadOp::Clear : LoadOp::Load;
148 // info.storeOp[i] = writeColor ? StoreOp::Store : StoreOp::Discard;
149 info.storeOp[i] = StoreOp::Store; // We can't really do a discard even if we don't write the color cause that may mangle previous writes to the target.
150 glm::vec4 color;
151 if (clearToDefault) {
152 color = context->renderer->getBackgroundColor();
153 }
154 else{
155 color = renderTarget->getClearColor();
156 }
157 info.clearValue[i][0] = color[0];
158 info.clearValue[i][1] = color[1];
159 info.clearValue[i][2] = color[2];
160 info.clearValue[i][3] = color[3];
161 }
162 info.depthLoadOp = clearDepth ? LoadOp::Clear : LoadOp::Load;
163 info.depthStoreOp = writeDepth ? StoreOp::Store : StoreOp::Discard;
164 info.depthClearValue = context->renderer->getClearDepth();
165 // info.depthReadOnly = !writeDepth;
166 deviceContext->beginRenderPass(info);
167 }
168 else{
169 deviceContext->setRenderTarget(renderTarget->renderTargetHandle, renderTarget->depthTargetHandle);
170 if (clearColor) {
171 if (clearToDefault) {
172 deviceContext->clearRenderTarget(glm::value_ptr(context->renderer->getBackgroundColor()));
173 } else {
174 deviceContext->clearRenderTarget(glm::value_ptr(renderTarget->getClearColor()));
175 }
176 }
177 if (clearDepth) {
178 if (HandleIsValid(renderTarget->depthTargetHandle) || !HandleIsValid(renderTarget->renderTargetHandle)) {
179 deviceContext->clearDepth(context->renderer->getClearDepth());
180 }
181 }
182 }
183
184 if (viewportFromTarget) {
185 deviceContext->setViewport(0.0f, 0.0f, static_cast<float>(renderTarget->width), static_cast<float>(renderTarget->height));
186 }
187 else {
188 // Note: context->cameraData is set when updating engine buffers, so its value is from the last invocation.
189 deviceContext->setViewport(
190 context->cameraData->viewportOrigin.x, context->cameraData->viewportOrigin.y,
191 context->cameraData->viewportSize.x, context->cameraData->viewportSize.y
192 );
193 }
194
195 if (writeDepth && depthTest) {
196 deviceContext->setDepthStencilState(context->states->leqDepthStencilStateHandle);
197 } else if (writeDepth && !depthTest) {
198 deviceContext->setDepthStencilState(context->states->noTestDepthStencilStateHandle);
199 }
200 else if (!writeDepth && depthTest) {
201 deviceContext->setDepthStencilState(context->states->noWriteDepthStencilStateHandle);
202 }
203 else {
204 deviceContext->setDepthStencilState(context->states->noDepthStencilStateHandle);
205 }
206
207 deviceContext->setRasterizerState(context->states->defaultRasterizerStateHandle);
208
209 for (size_t i = 0; i < 4; ++i) {
210 if (HandleIsValid(samplerStateBindings[i])) {
211 deviceContext->setSamplerState(samplerStateBindings[i], samplerStates[i]);
212 }
213 }
214
215 setProperties(context);
216
217 if (!writeColor){
218 deviceContext->setBlendState(context->states->blendStates[size_t(BlendMode::Zero)].handle);
219 }
220
221 deviceContext->setVertexBuffers(&context->states->fullScreenTriangle, 1);
222 deviceContext->setIndexBuffer(IndexBufferHandle::NoHandle);
223 deviceContext->setInputLayout(inputLayout);
224 deviceContext->draw(PrimitiveType::TriangleList, 0, 3);
225
226 if(context->device->getCapabilities()->getDeviceCapabilities().RenderPass){
227 deviceContext->endRenderPass();
228 }
229}
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.
@ Zero
Disable all color writes.
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.
@ WebGPU
Graphics device using the WebGPU API Backend.
@ TriangleList
List of triangles.
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