Cogs.Core
ResolveResourceTask.cpp
1#include "ResolveResourceTask.h"
2
3#include "ProcessTask.h"
4
5#include "Rendering/CommandGroupAnnotation.h"
6#include "Rendering/IBuffers.h"
7#include "Rendering/ICapabilities.h"
8#include "Rendering/IContext.h"
9#include "Rendering/IGraphicsDevice.h"
10#include "Rendering/ITextures.h"
11
12#include "Resources/VertexFormats.h"
13
14#include "Renderer/Renderer.h"
15#include "Renderer/RenderTarget.h"
16#include "Renderer/RenderTexture.h"
17
18#include "Platform/Instrumentation.h"
19
20using namespace Cogs;
21
22bool Cogs::Core::ResolveResourceTask::setupColorEffect(RenderTaskContext * context)
23{
25 desc.vs = "Engine/FullscreenV3T2VS.hlsl";
26 desc.ps = "PostProcess/ResolveColor.hlsl";
27 colorEffect = context->renderer->getEffectCache().loadEffect(context, desc);
28 if(!HandleIsValid(colorEffect->handle)){
29 return false;
30 }
31 IBuffers* buffers = context->device->getBuffers();
32 colorInputLayout = buffers->loadInputLayout(&VertexFormats::Pos4f, 1, colorEffect->handle);
33 IEffects* effects = context->device->getEffects();
34 colorTextureBinding = effects->getTextureBinding(colorEffect->handle, "colorTexture", 0);
35 return true;
36}
37bool Cogs::Core::ResolveResourceTask::setupDepthEffect(RenderTaskContext * context)
38{
40 desc.vs = "Engine/FullscreenV3T2VS.hlsl";
41 desc.ps = "PostProcess/ResolveDepth.hlsl";
42 depthEffect = context->renderer->getEffectCache().loadEffect(context, desc);
43 if(!HandleIsValid(depthEffect->handle)){
44 return false;
45 }
46 IBuffers* buffers = context->device->getBuffers();
47 depthInputLayout = buffers->loadInputLayout(&VertexFormats::Pos4f, 1, depthEffect->handle);
48 IEffects* effects = context->device->getEffects();
49 depthTextureBinding = effects->getTextureBinding(depthEffect->handle, "depthTexture", 0);
50 return true;
51}
52void Cogs::Core::ResolveResourceTask::resolveColorShader(RenderTaskContext * context,
53 RenderTexture * inputTexture,
54 RenderTexture * outputTexture)
55{
56 if(!colorEffect && !setupColorEffect(context)){
57 return;
58 }
59
60 IGraphicsDevice* device = context->device;
61 IContext* deviceContext = device->getImmediateContext();
62
63 CommandGroupAnnotation commandGroup(deviceContext, "ResolveResourceTask::ColorShader");
64 if(!outputTexture->resolveTarget){
65 RenderTexture* renderTexture = outputTexture;
66 RenderTarget* resolveTarget = context->resources->createRenderTarget();
67 resolveTarget->setName(outputTexture->getName() + " RT");
68 resolveTarget->textures.push_back(renderTexture);
69 resolveTarget->width = renderTexture->description.width;
70 resolveTarget->height = renderTexture->description.height;
71 resolveTarget->samples = renderTexture->description.samples;
72 resolveTarget->update(context->renderer);
73 renderTexture->resolveTarget = resolveTarget;
74 }
75
76 deviceContext->setEffect(colorEffect->handle);
77
78 RenderTarget* resolveTarget = outputTexture->resolveTarget;
79 assert(HandleIsValid(resolveTarget->renderTargetHandle));
80 if (device->getCapabilities()->getDeviceCapabilities().RenderPass) {
82 info.renderTargetHandle = resolveTarget->renderTargetHandle;
83 info.depthStencilHandle = DepthStencilHandle::NoHandle;
84 info.loadOp[0] = LoadOp::Clear;
85 info.storeOp[0] = StoreOp::Store;
86 info.depthLoadOp = LoadOp::Undefined;
87 info.depthStoreOp = StoreOp::Undefined;
88 info.depthClearValue = context->renderer->getClearDepth();
89 info.depthReadOnly = true;
90 deviceContext->beginRenderPass(info);
91 }
92 else{
93 deviceContext->setRenderTarget(resolveTarget->renderTargetHandle, DepthStencilHandle::NoHandle);
94 float vals[4] = {};
95 deviceContext->clearRenderTarget(vals);
96 }
97
98 deviceContext->setViewport(0.0f, 0.0f, static_cast<float>(resolveTarget->width), static_cast<float>(resolveTarget->height));
99
100 deviceContext->setDepthStencilState(context->states->noTestDepthStencilStateHandle);
101 deviceContext->setRasterizerState(context->states->defaultRasterizerStateHandle);
102 deviceContext->setBlendState(context->states->blendStates[size_t(BlendMode::None)].handle);
103
104 deviceContext->setTexture(colorTextureBinding, inputTexture->textureHandle);
105
106 deviceContext->setVertexBuffers(&context->states->fullScreenTriangle, 1);
108 deviceContext->setInputLayout(colorInputLayout);
109 deviceContext->draw(PrimitiveType::TriangleList, 0, 3);
110
111 if (device->getCapabilities()->getDeviceCapabilities().RenderPass) {
112 deviceContext->endRenderPass();
113 }
114}
115void Cogs::Core::ResolveResourceTask::resolveDepthShader(RenderTaskContext * context,
116 RenderTexture * inputTexture,
117 RenderTexture * outputTexture)
118{
119 if(!depthEffect && !setupDepthEffect(context)){
120 return;
121 }
122
123 IGraphicsDevice* device = context->device;
124 IContext* deviceContext = device->getImmediateContext();
125
126 CommandGroupAnnotation commandGroup(deviceContext, "ResolveResourceTask::DepthShader");
127 if(!outputTexture->resolveTarget){
128 RenderTexture* renderTexture = outputTexture;
129 RenderTarget* resolveTarget = context->resources->createRenderTarget();
130 resolveTarget->setName(outputTexture->getName() + " RT");
131 resolveTarget->depth = renderTexture;
132 resolveTarget->width = renderTexture->description.width;
133 resolveTarget->height = renderTexture->description.height;
134 resolveTarget->samples = renderTexture->description.samples;
135 resolveTarget->update(context->renderer);
136 renderTexture->resolveTarget = resolveTarget;
137 }
138
139 deviceContext->setEffect(depthEffect->handle);
140
141 RenderTarget* resolveTarget = outputTexture->resolveTarget;
142 assert(HandleIsValid(resolveTarget->depthTargetHandle));
143 if (device->getCapabilities()->getDeviceCapabilities().RenderPass) {
145 info.renderTargetHandle = RenderTargetHandle::NoHandle;
146 info.depthStencilHandle = resolveTarget->depthTargetHandle;
147 info.depthLoadOp = LoadOp::Clear;
148 info.depthStoreOp = StoreOp::Store;
149 info.depthClearValue = context->renderer->getClearDepth();
150 info.depthReadOnly = false;
151 deviceContext->beginRenderPass(info);
152 }
153 else{
154 deviceContext->setRenderTarget(RenderTargetHandle::NoHandle, resolveTarget->depthTargetHandle);
155 deviceContext->clearDepth(context->renderer->getClearDepth());
156 }
157
158 deviceContext->setViewport(0.0f, 0.0f, static_cast<float>(resolveTarget->width), static_cast<float>(resolveTarget->height));
159
160 deviceContext->setDepthStencilState(context->states->noTestDepthStencilStateHandle);
161 deviceContext->setRasterizerState(context->states->defaultRasterizerStateHandle);
162 deviceContext->setBlendState(context->states->blendStates[size_t(BlendMode::Zero)].handle);
163
164 deviceContext->setTexture(depthTextureBinding, inputTexture->textureHandle);
165
166 deviceContext->setVertexBuffers(&context->states->fullScreenTriangle, 1);
168 deviceContext->setInputLayout(depthInputLayout);
169 deviceContext->draw(PrimitiveType::TriangleList, 0, 3);
170
171 if (device->getCapabilities()->getDeviceCapabilities().RenderPass) {
172 deviceContext->endRenderPass();
173 }
174}
175
176void Cogs::Core::ResolveResourceTask::cleanup(RenderTaskContext * context)
177{
178 if(colorEffect) context->renderer->getEffectCache().release(context, colorEffect);
179 if(depthEffect) context->renderer->getEffectCache().release(context, depthEffect);
180}
181
182void Cogs::Core::ResolveResourceTask::apply(RenderTaskContext * context)
183{
184 RenderInstrumentationScope(context->device->getImmediateContext(), SCOPE_RENDERING, "ResolveResourceTask::apply");
185
186 RenderTexture* inputTexture = input.get(RenderResourceType::RenderTexture)->renderTexure;
187 RenderTexture* outputTexture = output.get(RenderResourceType::RenderTexture)->renderTexure;
188
189 IGraphicsDevice* device = context->device;
190 IContext* deviceContext = device->getImmediateContext();
191
192 if (!HandleIsValid(inputTexture->textureHandle)) return;
193
194 if(device->getType() != GraphicsDeviceType::OpenGLES30 &&
195 inputTexture->description.flags & TextureFlags::DepthBuffer){
196 resolveDepthShader(context, inputTexture, outputTexture);
197 }
198 else{
199 if (inputTexture->description.samples == 1) {
200 deviceContext->copyResource(outputTexture->textureHandle, inputTexture->textureHandle);
201 } else {
202 if(device->getType() == GraphicsDeviceType::WebGPU){
203 resolveColorShader(context, inputTexture, outputTexture);
204 }
205 else{
206 deviceContext->resolveResource(inputTexture->textureHandle, outputTexture->textureHandle);
207 }
208 }
209 }
210}
Represents a graphics device used to manage graphics resources and issue drawing commands.
virtual ICapabilities * getCapabilities()=0
Get a pointer to the capability management interface used to query the graphics device capability fla...
virtual IContext * getImmediateContext()=0
Get a pointer to the immediate context used to issue commands to the graphics device.
virtual GraphicsDeviceType getType() const
Get the type of the graphics device.
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
@ None
No blending enabled for opaque shapes, defaults to Blend for transparent shapes.
@ Zero
Disable all color writes.
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
@ OpenGLES30
Graphics device using the OpenGLES 3.0 API.
@ WebGPU
Graphics device using the WebGPU API Backend.
@ TriangleList
List of triangles.
RAII-helper for pushCommandGroupAnnotation/pushCommandGroupAnnotation.
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
Provides buffer management functionality.
Definition: IBuffers.h:13
virtual InputLayoutHandle loadInputLayout(const VertexFormatHandle *vertexFormats, const size_t count, EffectHandle effectHandle)=0
Loads a new input layout to map vertex flow between vertex buffers with the given vertexFormats to ef...
virtual const GraphicsDeviceCapabilities & getDeviceCapabilities() const
Gets the device capabilities in a structure.
Represents a graphics device context which can receive rendering commands.
Definition: IContext.h:43
virtual void setTexture(const StringView &name, unsigned int unit, TextureHandle textureHandle)=0
Sets the texture slot given by unit with the given name to contain the given texture.
virtual void setRasterizerState(const RasterizerStateHandle handle)=0
Set the current rasterizer state.
virtual void setBlendState(const BlendStateHandle handle, const float *constant=nullptr)=0
Set the current blend state.
virtual void setInputLayout(const InputLayoutHandle inputLayoutHandle)=0
Sets the current input layout.
virtual void clearRenderTarget(const float *value)=0
Clear the currently set render target to the given value (4 component floating point RGBA).
virtual void endRenderPass()=0
End a render pass.
virtual void setIndexBuffer(IndexBufferHandle bufferHandle, uint32_t stride=4, uint32_t offset=0)=0
Sets the current index buffer.
virtual void setDepthStencilState(const DepthStencilStateHandle handle)=0
Set the current depth stencil state.
virtual void resolveResource(TextureHandle source, TextureHandle destination)=0
Resolves the given source resource target into the given destination texture.
virtual void clearDepth(const float depth=1.0f)=0
Clear the currently set depth/stencil target to the given depth.
virtual void setViewport(const float x, const float y, const float width, const float height)=0
Sets the current viewport to the given location and dimensions.
virtual void draw(PrimitiveType primitiveType, const size_t startVertex, const size_t numVertexes)=0
Draws non-indexed, non-instanced primitives.
virtual void beginRenderPass(const RenderPassInfo &info)=0
Begin a render pass.
virtual void setVertexBuffers(const VertexBufferHandle *vertexBufferHandles, const size_t count, const uint32_t *strides, const uint32_t *offsets)=0
Sets the current vertex buffers.
virtual void setEffect(EffectHandle handle)=0
Set the current effect.
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:148
virtual TextureBindingHandle getTextureBinding(EffectHandle effectHandle, const StringView &name, const unsigned int slot)=0
Get a handle to a texture object binding, mapping how to bind textures to the given effect.
@ DepthBuffer
The texture can be used as a depth target and have depth buffer values written into.
Definition: Flags.h:122