refactor: extract viewport host surface utilities
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "IViewportHostService.h"
|
||||
#include "SceneViewportPicker.h"
|
||||
#include "SceneViewportCameraController.h"
|
||||
#include "ViewportHostSurfaceUtils.h"
|
||||
#include "UI/ImGuiBackendBridge.h"
|
||||
|
||||
#include <XCEngine/Components/CameraComponent.h>
|
||||
@@ -75,16 +76,6 @@ inline void SetViewportStatusIfEmpty(std::string& statusText, const char* messag
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32_t ClampViewportPixelCoordinate(float value, uint32_t extent) {
|
||||
if (extent == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const float maxCoordinate = static_cast<float>(extent - 1u);
|
||||
const float clamped = (std::max)(0.0f, (std::min)(value, maxCoordinate));
|
||||
return static_cast<uint32_t>(std::floor(clamped));
|
||||
}
|
||||
|
||||
Rendering::Passes::InfiniteGridPassData BuildInfiniteGridPassData(
|
||||
const SceneViewportOverlayData& overlay) {
|
||||
Rendering::Passes::InfiniteGridPassData data = {};
|
||||
@@ -422,28 +413,6 @@ private:
|
||||
m_sceneViewCamera.controller.Focus(center);
|
||||
}
|
||||
|
||||
RHI::TextureDesc BuildViewportTextureDesc(uint32_t width, uint32_t height, RHI::Format format) const {
|
||||
RHI::TextureDesc desc = {};
|
||||
desc.width = width;
|
||||
desc.height = height;
|
||||
desc.depth = 1;
|
||||
desc.mipLevels = 1;
|
||||
desc.arraySize = 1;
|
||||
desc.format = static_cast<uint32_t>(format);
|
||||
desc.textureType = static_cast<uint32_t>(RHI::TextureType::Texture2D);
|
||||
desc.sampleCount = 1;
|
||||
desc.sampleQuality = 0;
|
||||
desc.flags = 0;
|
||||
return desc;
|
||||
}
|
||||
|
||||
RHI::ResourceViewDesc BuildViewportTextureViewDesc(RHI::Format format) const {
|
||||
RHI::ResourceViewDesc desc = {};
|
||||
desc.format = static_cast<uint32_t>(format);
|
||||
desc.dimension = RHI::ResourceViewDimension::Texture2D;
|
||||
return desc;
|
||||
}
|
||||
|
||||
bool CreateViewportColorResources(ViewportEntry& entry) {
|
||||
const RHI::TextureDesc colorDesc =
|
||||
BuildViewportTextureDesc(entry.width, entry.height, RHI::Format::R8G8B8A8_UNorm);
|
||||
@@ -505,22 +474,26 @@ private:
|
||||
}
|
||||
|
||||
bool EnsureViewportResources(ViewportEntry& entry) {
|
||||
if (entry.requestedWidth == 0 || entry.requestedHeight == 0) {
|
||||
return false;
|
||||
ViewportHostResourceReuseQuery reuseQuery = {};
|
||||
reuseQuery.kind = entry.kind;
|
||||
reuseQuery.width = entry.width;
|
||||
reuseQuery.height = entry.height;
|
||||
reuseQuery.requestedWidth = entry.requestedWidth;
|
||||
reuseQuery.requestedHeight = entry.requestedHeight;
|
||||
reuseQuery.resources.hasColorTexture = entry.colorTexture != nullptr;
|
||||
reuseQuery.resources.hasColorView = entry.colorView != nullptr;
|
||||
reuseQuery.resources.hasDepthTexture = entry.depthTexture != nullptr;
|
||||
reuseQuery.resources.hasDepthView = entry.depthView != nullptr;
|
||||
reuseQuery.resources.hasObjectIdTexture = entry.objectIdTexture != nullptr;
|
||||
reuseQuery.resources.hasObjectIdView = entry.objectIdView != nullptr;
|
||||
reuseQuery.resources.hasObjectIdShaderView = entry.objectIdShaderView != nullptr;
|
||||
reuseQuery.resources.hasTextureDescriptor = entry.textureId != ImTextureID{};
|
||||
if (CanReuseViewportResources(reuseQuery)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (entry.width == entry.requestedWidth &&
|
||||
entry.height == entry.requestedHeight &&
|
||||
entry.colorTexture != nullptr &&
|
||||
entry.colorView != nullptr &&
|
||||
entry.depthTexture != nullptr &&
|
||||
entry.depthView != nullptr &&
|
||||
(entry.kind != EditorViewportKind::Scene ||
|
||||
(entry.objectIdTexture != nullptr &&
|
||||
entry.objectIdView != nullptr &&
|
||||
entry.objectIdShaderView != nullptr)) &&
|
||||
entry.textureId != ImTextureID{}) {
|
||||
return true;
|
||||
if (entry.requestedWidth == 0 || entry.requestedHeight == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DestroyViewportResources(entry);
|
||||
@@ -538,7 +511,7 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entry.kind == EditorViewportKind::Scene &&
|
||||
if (ViewportRequiresObjectIdResources(entry.kind) &&
|
||||
!CreateSceneViewportObjectIdResources(entry)) {
|
||||
DestroyViewportResources(entry);
|
||||
return false;
|
||||
@@ -555,21 +528,21 @@ private:
|
||||
}
|
||||
|
||||
Rendering::RenderSurface BuildSurface(const ViewportEntry& entry) const {
|
||||
Rendering::RenderSurface surface(entry.width, entry.height);
|
||||
surface.SetColorAttachment(entry.colorView);
|
||||
surface.SetDepthAttachment(entry.depthView);
|
||||
surface.SetColorStateBefore(entry.colorState);
|
||||
surface.SetColorStateAfter(RHI::ResourceStates::PixelShaderResource);
|
||||
return surface;
|
||||
return BuildViewportRenderSurface(
|
||||
entry.width,
|
||||
entry.height,
|
||||
entry.colorView,
|
||||
entry.depthView,
|
||||
entry.colorState);
|
||||
}
|
||||
|
||||
Rendering::RenderSurface BuildObjectIdSurface(const ViewportEntry& entry) const {
|
||||
Rendering::RenderSurface surface(entry.width, entry.height);
|
||||
surface.SetColorAttachment(entry.objectIdView);
|
||||
surface.SetDepthAttachment(entry.depthView);
|
||||
surface.SetColorStateBefore(entry.objectIdState);
|
||||
surface.SetColorStateAfter(RHI::ResourceStates::PixelShaderResource);
|
||||
return surface;
|
||||
return BuildViewportRenderSurface(
|
||||
entry.width,
|
||||
entry.height,
|
||||
entry.objectIdView,
|
||||
entry.depthView,
|
||||
entry.objectIdState);
|
||||
}
|
||||
|
||||
void AddSceneColorToRenderTargetPass(
|
||||
|
||||
118
editor/src/Viewport/ViewportHostSurfaceUtils.h
Normal file
118
editor/src/Viewport/ViewportHostSurfaceUtils.h
Normal file
@@ -0,0 +1,118 @@
|
||||
#pragma once
|
||||
|
||||
#include "IViewportHostService.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 {
|
||||
namespace Editor {
|
||||
|
||||
struct ViewportHostResourcePresence {
|
||||
bool hasColorTexture = false;
|
||||
bool hasColorView = false;
|
||||
bool hasDepthTexture = false;
|
||||
bool hasDepthView = false;
|
||||
bool hasObjectIdTexture = false;
|
||||
bool hasObjectIdView = false;
|
||||
bool hasObjectIdShaderView = false;
|
||||
bool hasTextureDescriptor = false;
|
||||
};
|
||||
|
||||
struct ViewportHostResourceReuseQuery {
|
||||
EditorViewportKind kind = EditorViewportKind::Scene;
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
uint32_t requestedWidth = 0;
|
||||
uint32_t requestedHeight = 0;
|
||||
ViewportHostResourcePresence resources = {};
|
||||
};
|
||||
|
||||
inline bool ViewportRequiresObjectIdResources(EditorViewportKind kind) {
|
||||
return kind == EditorViewportKind::Scene;
|
||||
}
|
||||
|
||||
inline uint32_t ClampViewportPixelCoordinate(float value, uint32_t extent) {
|
||||
if (extent == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const float maxCoordinate = static_cast<float>(extent - 1u);
|
||||
const float clamped = (std::max)(0.0f, (std::min)(value, maxCoordinate));
|
||||
return static_cast<uint32_t>(std::floor(clamped));
|
||||
}
|
||||
|
||||
inline bool CanReuseViewportResources(const ViewportHostResourceReuseQuery& query) {
|
||||
if (query.requestedWidth == 0 || query.requestedHeight == 0) {
|
||||
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 (!ViewportRequiresObjectIdResources(query.kind)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return query.resources.hasObjectIdTexture &&
|
||||
query.resources.hasObjectIdView &&
|
||||
query.resources.hasObjectIdShaderView;
|
||||
}
|
||||
|
||||
inline RHI::TextureDesc BuildViewportTextureDesc(
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
RHI::Format format) {
|
||||
RHI::TextureDesc desc = {};
|
||||
desc.width = width;
|
||||
desc.height = height;
|
||||
desc.depth = 1;
|
||||
desc.mipLevels = 1;
|
||||
desc.arraySize = 1;
|
||||
desc.format = static_cast<uint32_t>(format);
|
||||
desc.textureType = static_cast<uint32_t>(RHI::TextureType::Texture2D);
|
||||
desc.sampleCount = 1;
|
||||
desc.sampleQuality = 0;
|
||||
desc.flags = 0;
|
||||
return desc;
|
||||
}
|
||||
|
||||
inline RHI::ResourceViewDesc BuildViewportTextureViewDesc(RHI::Format format) {
|
||||
RHI::ResourceViewDesc desc = {};
|
||||
desc.format = static_cast<uint32_t>(format);
|
||||
desc.dimension = RHI::ResourceViewDimension::Texture2D;
|
||||
return desc;
|
||||
}
|
||||
|
||||
inline Rendering::RenderSurface BuildViewportRenderSurface(
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
RHI::RHIResourceView* colorView,
|
||||
RHI::RHIResourceView* depthView,
|
||||
RHI::ResourceStates colorStateBefore,
|
||||
RHI::ResourceStates colorStateAfter = RHI::ResourceStates::PixelShaderResource) {
|
||||
Rendering::RenderSurface surface(width, height);
|
||||
surface.SetColorAttachment(colorView);
|
||||
surface.SetDepthAttachment(depthView);
|
||||
surface.SetColorStateBefore(colorStateBefore);
|
||||
surface.SetColorStateAfter(colorStateAfter);
|
||||
return surface;
|
||||
}
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace XCEngine
|
||||
Reference in New Issue
Block a user