Files
XCEngine/tests/editor/test_viewport_render_targets.cpp

237 lines
11 KiB
C++

#include <gtest/gtest.h>
#include "Viewport/ViewportHostRenderTargets.h"
#include <string>
namespace {
using XCEngine::Editor::BuildViewportColorSurface;
using XCEngine::Editor::BuildViewportObjectIdSurface;
using XCEngine::Editor::BuildViewportSelectionMaskSurface;
using XCEngine::Editor::BuildViewportRenderTargetsReuseQuery;
using XCEngine::Editor::DestroyViewportRenderTargets;
using XCEngine::Editor::EditorViewportKind;
using XCEngine::Editor::ViewportRenderTargets;
using XCEngine::RHI::Format;
using XCEngine::RHI::RHIResourceView;
using XCEngine::RHI::RHITexture;
using XCEngine::RHI::ResourceStates;
using XCEngine::RHI::ResourceViewDimension;
using XCEngine::RHI::ResourceViewType;
using XCEngine::RHI::TextureType;
class DummyTexture final : public RHITexture {
public:
explicit DummyTexture(Format format = Format::R8G8B8A8_UNorm)
: m_format(format) {
}
uint32_t GetWidth() const override { return 1; }
uint32_t GetHeight() const override { return 1; }
uint32_t GetDepth() const override { return 1; }
uint32_t GetMipLevels() const override { return 1; }
Format GetFormat() const override { return m_format; }
TextureType GetTextureType() const override { return TextureType::Texture2D; }
ResourceStates GetState() const override { return m_state; }
void SetState(ResourceStates state) override { m_state = state; }
void* GetNativeHandle() override { return nullptr; }
const std::string& GetName() const override { return m_name; }
void SetName(const std::string& name) override { m_name = name; }
void Shutdown() override { shutdownCalled = true; }
bool shutdownCalled = false;
private:
Format m_format = Format::R8G8B8A8_UNorm;
ResourceStates m_state = ResourceStates::Common;
std::string m_name;
};
class DummyResourceView final : public RHIResourceView {
public:
explicit DummyResourceView(
ResourceViewType viewType = ResourceViewType::RenderTarget,
Format format = Format::R8G8B8A8_UNorm)
: m_viewType(viewType)
, m_format(format) {
}
void Shutdown() override { shutdownCalled = true; }
void* GetNativeHandle() override { return nullptr; }
bool IsValid() const override { return true; }
ResourceViewType GetViewType() const override { return m_viewType; }
ResourceViewDimension GetDimension() const override { return ResourceViewDimension::Texture2D; }
Format GetFormat() const override { return m_format; }
bool shutdownCalled = false;
private:
ResourceViewType m_viewType = ResourceViewType::RenderTarget;
Format m_format = Format::R8G8B8A8_UNorm;
};
TEST(ViewportRenderTargetsTest, BuildReuseQueryReflectsCurrentResourcePresence) {
ViewportRenderTargets targets = {};
targets.width = 1280;
targets.height = 720;
targets.colorTexture = reinterpret_cast<RHITexture*>(static_cast<uintptr_t>(0x1));
targets.colorView = reinterpret_cast<RHIResourceView*>(static_cast<uintptr_t>(0x2));
targets.depthTexture = reinterpret_cast<RHITexture*>(static_cast<uintptr_t>(0x3));
targets.depthView = reinterpret_cast<RHIResourceView*>(static_cast<uintptr_t>(0x4));
targets.depthShaderView = reinterpret_cast<RHIResourceView*>(static_cast<uintptr_t>(0x5));
targets.objectIdTexture = reinterpret_cast<RHITexture*>(static_cast<uintptr_t>(0x6));
targets.objectIdDepthTexture = reinterpret_cast<RHITexture*>(static_cast<uintptr_t>(0x7));
targets.objectIdDepthView = reinterpret_cast<RHIResourceView*>(static_cast<uintptr_t>(0x8));
targets.objectIdView = reinterpret_cast<RHIResourceView*>(static_cast<uintptr_t>(0x9));
targets.objectIdShaderView = reinterpret_cast<RHIResourceView*>(static_cast<uintptr_t>(0xA));
targets.selectionMaskTexture = reinterpret_cast<RHITexture*>(static_cast<uintptr_t>(0xB));
targets.selectionMaskView = reinterpret_cast<RHIResourceView*>(static_cast<uintptr_t>(0xC));
targets.selectionMaskShaderView = reinterpret_cast<RHIResourceView*>(static_cast<uintptr_t>(0xD));
targets.textureHandle.nativeHandle = 0xE;
targets.textureHandle.width = 1280;
targets.textureHandle.height = 720;
const auto query =
BuildViewportRenderTargetsReuseQuery(EditorViewportKind::Scene, targets, 1280, 720);
EXPECT_EQ(query.width, 1280u);
EXPECT_EQ(query.height, 720u);
EXPECT_TRUE(query.resources.hasColorTexture);
EXPECT_TRUE(query.resources.hasColorView);
EXPECT_TRUE(query.resources.hasDepthTexture);
EXPECT_TRUE(query.resources.hasDepthView);
EXPECT_TRUE(query.resources.hasDepthShaderView);
EXPECT_TRUE(query.resources.hasObjectIdTexture);
EXPECT_TRUE(query.resources.hasObjectIdDepthTexture);
EXPECT_TRUE(query.resources.hasObjectIdDepthView);
EXPECT_TRUE(query.resources.hasObjectIdView);
EXPECT_TRUE(query.resources.hasObjectIdShaderView);
EXPECT_TRUE(query.resources.hasSelectionMaskTexture);
EXPECT_TRUE(query.resources.hasSelectionMaskView);
EXPECT_TRUE(query.resources.hasSelectionMaskShaderView);
EXPECT_TRUE(query.resources.hasTextureDescriptor);
}
TEST(ViewportRenderTargetsTest, BuildSurfaceUsesTargetAttachmentsAndStates) {
DummyResourceView colorView(ResourceViewType::RenderTarget);
DummyResourceView depthView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
DummyResourceView objectIdDepthView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
DummyResourceView objectIdView(ResourceViewType::RenderTarget);
DummyResourceView selectionMaskView(ResourceViewType::RenderTarget);
ViewportRenderTargets targets = {};
targets.width = 800;
targets.height = 600;
targets.colorView = &colorView;
targets.depthView = &depthView;
targets.objectIdDepthView = &objectIdDepthView;
targets.objectIdView = &objectIdView;
targets.selectionMaskView = &selectionMaskView;
targets.colorState = ResourceStates::Common;
targets.objectIdState = ResourceStates::PixelShaderResource;
targets.selectionMaskState = ResourceStates::PixelShaderResource;
const auto colorSurface = BuildViewportColorSurface(targets);
ASSERT_EQ(colorSurface.GetColorAttachments().size(), 1u);
EXPECT_EQ(colorSurface.GetColorAttachments()[0], &colorView);
EXPECT_EQ(colorSurface.GetDepthAttachment(), &depthView);
EXPECT_EQ(colorSurface.GetColorStateBefore(), ResourceStates::Common);
const auto objectIdSurface = BuildViewportObjectIdSurface(targets);
ASSERT_EQ(objectIdSurface.GetColorAttachments().size(), 1u);
EXPECT_EQ(objectIdSurface.GetColorAttachments()[0], &objectIdView);
EXPECT_EQ(objectIdSurface.GetDepthAttachment(), &objectIdDepthView);
EXPECT_EQ(objectIdSurface.GetColorStateBefore(), ResourceStates::PixelShaderResource);
const auto selectionMaskSurface = BuildViewportSelectionMaskSurface(targets);
ASSERT_EQ(selectionMaskSurface.GetColorAttachments().size(), 1u);
EXPECT_EQ(selectionMaskSurface.GetColorAttachments()[0], &selectionMaskView);
EXPECT_EQ(selectionMaskSurface.GetDepthAttachment(), &depthView);
EXPECT_EQ(selectionMaskSurface.GetColorStateBefore(), ResourceStates::PixelShaderResource);
}
TEST(ViewportRenderTargetsTest, DestroyViewportRenderTargetsShutsDownAndClearsState) {
auto* colorTexture = new DummyTexture();
auto* colorView = new DummyResourceView(ResourceViewType::RenderTarget);
auto* depthTexture = new DummyTexture(Format::D24_UNorm_S8_UInt);
auto* depthView = new DummyResourceView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
auto* depthShaderView = new DummyResourceView(ResourceViewType::ShaderResource, Format::D24_UNorm_S8_UInt);
auto* objectIdTexture = new DummyTexture();
auto* objectIdDepthTexture = new DummyTexture(Format::D24_UNorm_S8_UInt);
auto* objectIdDepthView = new DummyResourceView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
auto* objectIdView = new DummyResourceView(ResourceViewType::RenderTarget);
auto* objectIdShaderView = new DummyResourceView(ResourceViewType::ShaderResource);
auto* selectionMaskTexture = new DummyTexture();
auto* selectionMaskView = new DummyResourceView(ResourceViewType::RenderTarget);
auto* selectionMaskShaderView = new DummyResourceView(ResourceViewType::ShaderResource);
ViewportRenderTargets targets = {};
targets.width = 640;
targets.height = 360;
targets.colorTexture = colorTexture;
targets.colorView = colorView;
targets.depthTexture = depthTexture;
targets.depthView = depthView;
targets.depthShaderView = depthShaderView;
targets.objectIdTexture = objectIdTexture;
targets.objectIdDepthTexture = objectIdDepthTexture;
targets.objectIdDepthView = objectIdDepthView;
targets.objectIdView = objectIdView;
targets.objectIdShaderView = objectIdShaderView;
targets.selectionMaskTexture = selectionMaskTexture;
targets.selectionMaskView = selectionMaskView;
targets.selectionMaskShaderView = selectionMaskShaderView;
targets.imguiCpuHandle.ptr = 123;
targets.imguiGpuHandle.ptr = 456;
targets.textureHandle.nativeHandle = 789;
targets.textureHandle.width = 640;
targets.textureHandle.height = 360;
targets.colorState = ResourceStates::RenderTarget;
targets.objectIdState = ResourceStates::PixelShaderResource;
targets.selectionMaskState = ResourceStates::PixelShaderResource;
targets.hasValidObjectIdFrame = true;
DestroyViewportRenderTargets(nullptr, targets);
EXPECT_TRUE(colorTexture->shutdownCalled);
EXPECT_TRUE(colorView->shutdownCalled);
EXPECT_TRUE(depthTexture->shutdownCalled);
EXPECT_TRUE(depthView->shutdownCalled);
EXPECT_TRUE(depthShaderView->shutdownCalled);
EXPECT_TRUE(objectIdTexture->shutdownCalled);
EXPECT_TRUE(objectIdDepthTexture->shutdownCalled);
EXPECT_TRUE(objectIdDepthView->shutdownCalled);
EXPECT_TRUE(objectIdView->shutdownCalled);
EXPECT_TRUE(objectIdShaderView->shutdownCalled);
EXPECT_TRUE(selectionMaskTexture->shutdownCalled);
EXPECT_TRUE(selectionMaskView->shutdownCalled);
EXPECT_TRUE(selectionMaskShaderView->shutdownCalled);
EXPECT_EQ(targets.width, 0u);
EXPECT_EQ(targets.height, 0u);
EXPECT_EQ(targets.colorTexture, nullptr);
EXPECT_EQ(targets.colorView, nullptr);
EXPECT_EQ(targets.depthTexture, nullptr);
EXPECT_EQ(targets.depthView, nullptr);
EXPECT_EQ(targets.depthShaderView, nullptr);
EXPECT_EQ(targets.objectIdTexture, nullptr);
EXPECT_EQ(targets.objectIdDepthTexture, nullptr);
EXPECT_EQ(targets.objectIdDepthView, nullptr);
EXPECT_EQ(targets.objectIdView, nullptr);
EXPECT_EQ(targets.objectIdShaderView, nullptr);
EXPECT_EQ(targets.selectionMaskTexture, nullptr);
EXPECT_EQ(targets.selectionMaskView, nullptr);
EXPECT_EQ(targets.selectionMaskShaderView, nullptr);
EXPECT_EQ(targets.imguiCpuHandle.ptr, 0u);
EXPECT_EQ(targets.imguiGpuHandle.ptr, 0u);
EXPECT_EQ(targets.textureHandle.nativeHandle, 0u);
EXPECT_EQ(targets.textureHandle.width, 0u);
EXPECT_EQ(targets.textureHandle.height, 0u);
EXPECT_EQ(targets.colorState, ResourceStates::Common);
EXPECT_EQ(targets.objectIdState, ResourceStates::Common);
EXPECT_EQ(targets.selectionMaskState, ResourceStates::Common);
EXPECT_FALSE(targets.hasValidObjectIdFrame);
}
} // namespace