1#include "MipLevelsTask.h"
3#include "Rendering/IGraphicsDevice.h"
4#include "Rendering/IBuffers.h"
5#include "Rendering/IContext.h"
6#include "Rendering/SamplerState.h"
7#include "Rendering/ITextures.h"
9#include "Renderer/RenderTarget.h"
10#include "Renderer/RenderTexture.h"
12#include "Resources/VertexFormats.h"
14#include "Utilities/Parsing.h"
20 struct MipLevelsParameter
22 glm::vec2 srcTexelSize;
23 glm::vec2 dstTexelSize;
29void Cogs::Core::MipLevelsTask::initialize(RenderTaskContext * context)
31 PostProcessTask::initialize(context);
32 if (effect ==
nullptr || !
HandleIsValid(effect->handle))
return;
34 auto device = context->renderer->getDevice();
35 auto effects = device->getEffects();
36 auto buffers = device->getBuffers();
39 parameterBufferBinding = effects->getConstantBufferBinding(effect->handle,
"MipLevelsParameter");
42void Cogs::Core::MipLevelsTask::cleanup(RenderTaskContext * context)
44 auto device = context->renderer->getDevice();
45 auto buffers = device->getBuffers();
46 buffers->releaseBuffer(parameterHandle);
47 PostProcessTask::cleanup(context);
50void Cogs::Core::MipLevelsTask::apply(RenderTaskContext * context)
52 DynamicRenderInstrumentationScope(context->device->getImmediateContext(), SCOPE_RENDERING,
"MipLevelsTask", (std::string(
"MipLevelsTask<") + name +
">::apply").c_str());
54 if (effect ==
nullptr || !
HandleIsValid(effect->handle))
return;
56 auto device = context->renderer->getDevice();
57 auto deviceContext = device->getImmediateContext();
58 auto effects = device->getEffects();
60 auto renderTarget = output.get(RenderResourceType::RenderTarget)->renderTarget;
61 auto targetSource = renderTarget->textures[0];
63 std::string targetSourceKey;
64 for (
auto & p : properties) {
65 if (p.definition->type == ParsedDataType::Texture2D) {
66 auto inputSource = input.get(p.definition->value);
68 if (inputSource->type == RenderResourceType::RenderTexture) {
69 tex = inputSource->renderTexure;
71 else if (inputSource->type == RenderResourceType::RenderTarget) {
72 tex = inputSource->renderTarget->textures[0];
75 targetSourceKey = p.definition->key;
80 size_t maxLevel = std::max(
size_t(1u), renderTarget->mipLevelViews.size());
81 if (sizes.size() != maxLevel || sizes[0].x != renderTarget->width || sizes[0].y != renderTarget->height) {
82 sizes.resize(maxLevel);
83 sizes[0] = glm::ivec2(renderTarget->width, renderTarget->height);
84 for (uint32_t i = 1; i < maxLevel; i++) {
85 sizes[i] = glm::ivec2(std::max(1, sizes[i - 1].x / 2), std::max(1, sizes[i - 1].y / 2));
91 deviceContext->setEffect(effect->handle);
92 deviceContext->setDepthStencilState(context->states->noDepthStencilStateHandle);
93 deviceContext->setRasterizerState(context->states->defaultRasterizerStateHandle);
96 setProperties(context, targetSource);
99 if (!targetSourceKey.empty()) {
107 targetSourceHandle = effects->getTextureBinding(effect->handle, targetSourceKey, texUnit);
108 deviceContext->setSamplerState(targetSourceKey +
"Sampler", texUnit, context->states->getSamplerState(ss));
118 deviceContext->setVertexBuffers(
nullptr, 0,
nullptr,
nullptr);
122 size_t currentFirstLevel = std::min(maxLevel - 1u,
static_cast<size_t>(firstLevel));
123 size_t currentLastLevel = std::min(maxLevel - 1u,
static_cast<size_t>(lastLevel));
124 if (currentFirstLevel < currentLastLevel) {
125 for (
size_t l = currentFirstLevel; l < currentLastLevel; l++) {
126 const size_t srcLevel = l;
127 const size_t dstLevel = l + 1;
133 parameters->srcTexelSize = glm::vec2(1.f) / glm::vec2(sizes[srcLevel]);
134 parameters->dstTexelSize = glm::vec2(1.f) / glm::vec2(sizes[dstLevel]);
135 parameters->srcLevel =
static_cast<int>(srcLevel);
136 parameters->dstLevel =
static_cast<int>(dstLevel);
140 deviceContext->setConstantBuffer(parameterBufferBinding, parameterHandle);
144 textureViewDesc.
texture = targetSource->textureHandle;
145 textureViewDesc.
levelIndex =
static_cast<uint32_t
>(srcLevel);
148 size_t code = textureViewDesc.hash();
150 auto found = targetSource->views.find(code);
154 if (found == targetSource->views.end()) {
155 textureView = device->getTextures()->createTextureView(textureViewDesc);
156 targetSource->views.insert({ code, textureView });
158 textureView = found->second;
161 deviceContext->setTexture(targetSourceHandle, textureView);
163 deviceContext->setViewport(0, 0, (
float)sizes[dstLevel].x, (float)sizes[dstLevel].y);
167 }
else if (currentLastLevel < currentFirstLevel) {
168 for (
size_t l = currentFirstLevel; currentLastLevel < l; l--) {
169 const size_t srcLevel = l;
170 const size_t dstLevel = l - 1;
176 parameters->srcTexelSize = glm::vec2(1.f) / glm::vec2(sizes[srcLevel]);
177 parameters->dstTexelSize = glm::vec2(1.f) / glm::vec2(sizes[dstLevel]);
178 parameters->srcLevel =
static_cast<int>(srcLevel);
179 parameters->dstLevel =
static_cast<int>(dstLevel);
183 deviceContext->setConstantBuffer(parameterBufferBinding, parameterHandle);
187 textureViewDesc.
texture = targetSource->textureHandle;
188 textureViewDesc.
levelIndex =
static_cast<uint32_t
>(srcLevel);
191 size_t code = textureViewDesc.hash();
193 auto found = targetSource->views.find(code);
197 if (found == targetSource->views.end()) {
198 textureView = device->getTextures()->createTextureView(textureViewDesc);
199 targetSource->views.insert({ code, textureView });
201 textureView = found->second;
204 deviceContext->setTexture(targetSourceHandle, textureView);
206 deviceContext->setViewport(0, 0, (
float)sizes[dstLevel].x, (float)sizes[dstLevel].y);
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
Contains all Cogs related functionality.
@ Write
The buffer can be mapped and written to by the CPU after creation.
@ ConstantBuffer
The buffer can be bound as input to effects as a constant buffer.
static const Handle_t NoHandle
Represents a handle to nothing.
@ WriteDiscard
Write access. When unmapping the graphics system will discard the old contents of the resource.
Provides RAII style mapping of a buffer resource.
@ TriangleList
List of triangles.
Encapsulates state for texture sampling in a state object.
AddressMode addressModeW
Specifies the addressing mode along the W axis in texture coordinate space.
AddressMode addressModeS
Specifies the addressing mode along the S axis in texture coordinate space.
@ Clamp
Texture coordinates are clamped to the [0, 1] range.
@ MinMagMipLinear
Linear sampling for both minification and magnification.
FilterMode filter
Specifies the filter to use for texture sampling.
AddressMode addressModeT
Specifies the addressing mode along the T axis in texture coordinate space.
Describes how to fetch data from a texture in shaders.
uint32_t numLevels
Number of mipmap levels available.
uint32_t levelIndex
First mipmap level to fetch data from.
TextureHandle texture
Texture.
@ Dynamic
Buffer will be loaded and modified with some frequency.