Files
XCEngine/new_editor/app/Viewport/ViewportSurfaceUtils.h

131 lines
4.2 KiB
C++

#pragma once
#include "ProductViewportTypes.h"
#include <XCEngine/RHI/RHIEnums.h>
#include <XCEngine/RHI/RHIResourceView.h>
#include <XCEngine/RHI/RHITypes.h>
#include <XCEngine/Rendering/RenderSurface.h>
#include <algorithm>
#include <cmath>
#include <cstdint>
namespace XCEngine::UI::Editor::App {
struct ProductViewportResourcePresence {
bool hasColorTexture = false;
bool hasColorView = false;
bool hasDepthTexture = false;
bool hasDepthView = false;
bool hasDepthShaderView = false;
bool hasObjectIdTexture = false;
bool hasObjectIdDepthTexture = false;
bool hasObjectIdDepthView = false;
bool hasObjectIdView = false;
bool hasObjectIdShaderView = false;
bool hasSelectionMaskTexture = false;
bool hasSelectionMaskView = false;
bool hasSelectionMaskShaderView = false;
bool hasTextureDescriptor = false;
};
struct ProductViewportResourceReuseQuery {
ProductViewportKind kind = ProductViewportKind::Scene;
std::uint32_t width = 0;
std::uint32_t height = 0;
std::uint32_t requestedWidth = 0;
std::uint32_t requestedHeight = 0;
ProductViewportResourcePresence resources = {};
};
inline bool ProductViewportRequiresObjectIdResources(ProductViewportKind kind) {
return kind == ProductViewportKind::Scene;
}
inline std::uint32_t ClampViewportPixelCoordinate(float value, std::uint32_t extent) {
if (extent == 0u) {
return 0u;
}
const float maxCoordinate = static_cast<float>(extent - 1u);
const float clamped = (std::max)(0.0f, (std::min)(value, maxCoordinate));
return static_cast<std::uint32_t>(std::floor(clamped));
}
inline bool CanReuseProductViewportResources(const ProductViewportResourceReuseQuery& query) {
if (query.requestedWidth == 0u || query.requestedHeight == 0u) {
return false;
}
if (query.width != query.requestedWidth || query.height != query.requestedHeight) {
return false;
}
if (!query.resources.hasColorTexture ||
!query.resources.hasColorView ||
!query.resources.hasDepthTexture ||
!query.resources.hasDepthView ||
!query.resources.hasTextureDescriptor) {
return false;
}
if (!ProductViewportRequiresObjectIdResources(query.kind)) {
return true;
}
return query.resources.hasObjectIdTexture &&
query.resources.hasObjectIdDepthTexture &&
query.resources.hasObjectIdDepthView &&
query.resources.hasObjectIdView &&
query.resources.hasObjectIdShaderView &&
query.resources.hasDepthShaderView &&
query.resources.hasSelectionMaskTexture &&
query.resources.hasSelectionMaskView &&
query.resources.hasSelectionMaskShaderView;
}
inline ::XCEngine::RHI::TextureDesc BuildProductViewportTextureDesc(
std::uint32_t width,
std::uint32_t height,
::XCEngine::RHI::Format format) {
::XCEngine::RHI::TextureDesc desc = {};
desc.width = width;
desc.height = height;
desc.depth = 1;
desc.mipLevels = 1;
desc.arraySize = 1;
desc.format = static_cast<std::uint32_t>(format);
desc.textureType = static_cast<std::uint32_t>(::XCEngine::RHI::TextureType::Texture2D);
desc.sampleCount = 1;
desc.sampleQuality = 0;
desc.flags = 0;
return desc;
}
inline ::XCEngine::RHI::ResourceViewDesc BuildProductViewportTextureViewDesc(
::XCEngine::RHI::Format format) {
::XCEngine::RHI::ResourceViewDesc desc = {};
desc.format = static_cast<std::uint32_t>(format);
desc.dimension = ::XCEngine::RHI::ResourceViewDimension::Texture2D;
return desc;
}
inline ::XCEngine::Rendering::RenderSurface BuildProductViewportRenderSurface(
std::uint32_t width,
std::uint32_t height,
::XCEngine::RHI::RHIResourceView* colorView,
::XCEngine::RHI::RHIResourceView* depthView,
::XCEngine::RHI::ResourceStates colorStateBefore,
::XCEngine::RHI::ResourceStates colorStateAfter =
::XCEngine::RHI::ResourceStates::PixelShaderResource) {
::XCEngine::Rendering::RenderSurface surface(width, height);
surface.SetColorAttachment(colorView);
surface.SetDepthAttachment(depthView);
surface.SetColorStateBefore(colorStateBefore);
surface.SetColorStateAfter(colorStateAfter);
return surface;
}
} // namespace XCEngine::UI::Editor::App