Fix scene selection outline mask path

This commit is contained in:
2026-04-09 05:16:04 +08:00
parent c48311eaaf
commit 2084412010
29 changed files with 1250 additions and 56 deletions

View File

@@ -180,6 +180,19 @@ TEST(MaterialLoader, ResourceManagerRegistersMaterialAndShaderLoaders) {
manager.Shutdown();
}
TEST(MaterialLoader, BuiltinDefaultPrimitiveMaterialLeavesRenderStateOverrideDisabled) {
ResourceManager& manager = ResourceManager::Get();
manager.Initialize();
const auto materialHandle = manager.Load<Material>(GetBuiltinDefaultPrimitiveMaterialPath());
ASSERT_TRUE(materialHandle.IsValid());
ASSERT_NE(materialHandle->GetShader(), nullptr);
EXPECT_EQ(materialHandle->GetShader()->GetPath(), GetBuiltinForwardLitShaderPath());
EXPECT_FALSE(materialHandle->HasRenderStateOverride());
manager.Shutdown();
}
TEST(MaterialLoader, LoadValidMaterialParsesRenderMetadata) {
ResourceManager& manager = ResourceManager::Get();
manager.Initialize();

View File

@@ -69,6 +69,8 @@ TEST(ShaderLoader, CanLoad) {
EXPECT_TRUE(loader.CanLoad(GetBuiltinUnlitShaderPath()));
EXPECT_TRUE(loader.CanLoad(GetBuiltinObjectIdShaderPath()));
EXPECT_TRUE(loader.CanLoad(GetBuiltinObjectIdOutlineShaderPath()));
EXPECT_TRUE(loader.CanLoad(GetBuiltinSelectionMaskShaderPath()));
EXPECT_TRUE(loader.CanLoad(GetBuiltinSelectionOutlineShaderPath()));
EXPECT_FALSE(loader.CanLoad("test.vert"));
EXPECT_FALSE(loader.CanLoad("test.frag"));
EXPECT_FALSE(loader.CanLoad("test.glsl"));
@@ -2516,6 +2518,27 @@ TEST(ShaderLoader, LoadBuiltinObjectIdShaderBuildsAuthoringVariants) {
delete shader;
}
TEST(ShaderLoader, LoadBuiltinSelectionMaskShaderBuildsAuthoringVariants) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinSelectionMaskShaderPath());
ASSERT_TRUE(result);
ASSERT_NE(result.resource, nullptr);
Shader* shader = static_cast<Shader*>(result.resource);
ASSERT_NE(shader, nullptr);
ASSERT_TRUE(shader->IsValid());
const ShaderPass* alphaTestPass = shader->FindPass("SelectionMask");
ASSERT_NE(alphaTestPass, nullptr);
EXPECT_EQ(alphaTestPass->resources.Size(), 4u);
ASSERT_EQ(alphaTestPass->keywordDeclarations.Size(), 1u);
EXPECT_EQ(alphaTestPass->keywordDeclarations[0].type, ShaderKeywordDeclarationType::ShaderFeatureLocal);
ASSERT_EQ(alphaTestPass->keywordDeclarations[0].options.Size(), 2u);
EXPECT_EQ(alphaTestPass->keywordDeclarations[0].options[1], "XC_ALPHA_TEST");
delete shader;
}
TEST(ShaderLoader, LoadBuiltinDepthOnlyShaderBuildsAuthoringVariants) {
ShaderLoader loader;
LoadResult result = loader.Load(GetBuiltinDepthOnlyShaderPath());

View File

@@ -78,10 +78,16 @@ SceneViewportOverlayFrameData CreateOverlayFrameDataWithLine(const SceneViewport
}
TEST(SceneViewportRenderPassBundleTest, BuildRenderPlanCreatesGridOutlineAndOverlayPasses) {
DummyResourceView objectIdShaderView(ResourceViewType::ShaderResource);
DummyResourceView depthView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
DummyResourceView depthShaderView(ResourceViewType::ShaderResource, Format::D24_UNorm_S8_UInt);
DummyResourceView selectionMaskView(ResourceViewType::RenderTarget);
DummyResourceView selectionMaskShaderView(ResourceViewType::ShaderResource);
ViewportRenderTargets targets = {};
targets.objectIdShaderView = &objectIdShaderView;
targets.depthView = &depthView;
targets.depthShaderView = &depthShaderView;
targets.selectionMaskView = &selectionMaskView;
targets.selectionMaskShaderView = &selectionMaskShaderView;
const SceneViewportOverlayData overlay = CreateValidOverlay();
const SceneViewportOverlayFrameData editorOverlayFrameData =
@@ -100,12 +106,13 @@ TEST(SceneViewportRenderPassBundleTest, BuildRenderPlanCreatesGridOutlineAndOver
EXPECT_EQ(result.warningStatusText, nullptr);
}
TEST(SceneViewportRenderPassBundleTest, BuildRenderPlanReportsMissingObjectIdShaderView) {
TEST(SceneViewportRenderPassBundleTest, BuildRenderPlanReportsMissingSelectionOutlineResources) {
const SceneViewportOverlayData overlay = CreateValidOverlay();
ViewportRenderTargets targets = {};
SceneViewportRenderPassBundle bundle;
const auto result = bundle.BuildRenderPlan(
{},
targets,
overlay,
{ 42u },
{},
@@ -113,7 +120,7 @@ TEST(SceneViewportRenderPassBundleTest, BuildRenderPlanReportsMissingObjectIdSha
EXPECT_EQ(result.plan.postScenePasses.GetPassCount(), 1u);
EXPECT_EQ(result.plan.overlayPasses.GetPassCount(), 0u);
EXPECT_STREQ(result.warningStatusText, "Scene object id shader view is unavailable");
EXPECT_STREQ(result.warningStatusText, "Scene selection outline resources are unavailable");
}
} // namespace

View File

@@ -18,11 +18,15 @@ using XCEngine::Editor::GetSceneViewportInfiniteGridShaderPath;
using XCEngine::Editor::GetSceneViewportPointLightGizmoIconPath;
using XCEngine::Editor::GetSceneViewportSpotLightGizmoIconPath;
using XCEngine::Resources::GetBuiltinObjectIdOutlineShaderPath;
using XCEngine::Resources::GetBuiltinSelectionMaskShaderPath;
using XCEngine::Resources::GetBuiltinSelectionOutlineShaderPath;
using XCEngine::Resources::LoadResult;
using XCEngine::Resources::ResourceHandle;
using XCEngine::Resources::ResourceManager;
using XCEngine::Resources::Shader;
using XCEngine::Resources::ShaderBackend;
using XCEngine::Resources::ShaderKeywordDeclarationType;
using XCEngine::Resources::ShaderKeywordSet;
using XCEngine::Resources::ShaderLoader;
using XCEngine::Resources::ShaderPass;
using XCEngine::Resources::ShaderStageVariant;
@@ -110,4 +114,61 @@ TEST(SceneViewportShaderPathsTest, ResourceManagerLoadsSceneViewportOutlineShade
manager.Shutdown();
}
TEST(SceneViewportShaderPathsTest, ResourceManagerLoadsSelectionOutlineShadersByResolvedPath) {
ResourceManager& manager = ResourceManager::Get();
manager.Shutdown();
const ResourceHandle<Shader> maskShaderHandle = manager.Load<Shader>(GetBuiltinSelectionMaskShaderPath());
ASSERT_TRUE(maskShaderHandle.IsValid());
const ShaderPass* maskPass = maskShaderHandle->FindPass("SelectionMask");
ASSERT_NE(maskPass, nullptr);
ASSERT_EQ(maskPass->variants.Size(), 4u);
ASSERT_EQ(maskPass->keywordDeclarations.Size(), 1u);
EXPECT_EQ(maskPass->keywordDeclarations[0].type, ShaderKeywordDeclarationType::ShaderFeatureLocal);
ASSERT_EQ(maskPass->keywordDeclarations[0].options.Size(), 2u);
EXPECT_EQ(maskPass->keywordDeclarations[0].options[0], "_");
EXPECT_EQ(maskPass->keywordDeclarations[0].options[1], "XC_ALPHA_TEST");
EXPECT_TRUE(maskShaderHandle->PassDeclaresKeyword("SelectionMask", "XC_ALPHA_TEST"));
const ShaderStageVariant* maskFragment = maskShaderHandle->FindVariant(
"SelectionMask",
ShaderType::Fragment,
ShaderBackend::D3D12);
ASSERT_NE(maskFragment, nullptr);
EXPECT_NE(
std::string(maskFragment->sourceCode.CStr()).find("XC_BUILTIN_SELECTION_MASK_D3D12_PS"),
std::string::npos);
ShaderKeywordSet alphaKeywords = {};
alphaKeywords.enabledKeywords.PushBack("XC_ALPHA_TEST");
const ShaderStageVariant* alphaMaskFragment = maskShaderHandle->FindVariant(
"SelectionMask",
ShaderType::Fragment,
ShaderBackend::D3D12,
alphaKeywords);
ASSERT_NE(alphaMaskFragment, nullptr);
EXPECT_NE(
std::string(alphaMaskFragment->sourceCode.CStr()).find("#define XC_ALPHA_TEST 1"),
std::string::npos);
const ResourceHandle<Shader> outlineShaderHandle = manager.Load<Shader>(GetBuiltinSelectionOutlineShaderPath());
ASSERT_TRUE(outlineShaderHandle.IsValid());
const ShaderPass* outlinePass = outlineShaderHandle->FindPass("SelectionOutline");
ASSERT_NE(outlinePass, nullptr);
ASSERT_EQ(outlinePass->variants.Size(), 2u);
const ShaderStageVariant* outlineFragment = outlineShaderHandle->FindVariant(
"SelectionOutline",
ShaderType::Fragment,
ShaderBackend::D3D12);
ASSERT_NE(outlineFragment, nullptr);
EXPECT_NE(
std::string(outlineFragment->sourceCode.CStr()).find("XC_BUILTIN_SELECTION_OUTLINE_D3D12_PS"),
std::string::npos);
manager.Shutdown();
}
} // namespace

View File

@@ -73,9 +73,15 @@ TEST(ViewportHostSurfaceUtilsTest, ViewportReuseRequiresObjectIdOnlyForSceneView
EXPECT_TRUE(ViewportRequiresObjectIdResources(EditorViewportKind::Scene));
EXPECT_FALSE(CanReuseViewportResources(sceneQuery));
sceneQuery.resources.hasDepthShaderView = true;
sceneQuery.resources.hasObjectIdTexture = true;
sceneQuery.resources.hasObjectIdDepthTexture = true;
sceneQuery.resources.hasObjectIdDepthView = true;
sceneQuery.resources.hasObjectIdView = true;
sceneQuery.resources.hasObjectIdShaderView = true;
sceneQuery.resources.hasSelectionMaskTexture = true;
sceneQuery.resources.hasSelectionMaskView = true;
sceneQuery.resources.hasSelectionMaskShaderView = true;
EXPECT_TRUE(CanReuseViewportResources(sceneQuery));
}
@@ -90,9 +96,15 @@ TEST(ViewportHostSurfaceUtilsTest, ViewportReuseRejectsMismatchedOrMissingResour
query.resources.hasColorView = true;
query.resources.hasDepthTexture = true;
query.resources.hasDepthView = true;
query.resources.hasDepthShaderView = true;
query.resources.hasObjectIdTexture = true;
query.resources.hasObjectIdDepthTexture = true;
query.resources.hasObjectIdDepthView = true;
query.resources.hasObjectIdView = true;
query.resources.hasObjectIdShaderView = true;
query.resources.hasSelectionMaskTexture = true;
query.resources.hasSelectionMaskView = true;
query.resources.hasSelectionMaskShaderView = true;
query.resources.hasTextureDescriptor = true;
EXPECT_TRUE(CanReuseViewportResources(query));

View File

@@ -190,6 +190,7 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportSelectionOutlineStyleApplies
TEST(ViewportRenderFlowUtilsTest, ApplySceneRenderRequestSetupAttachesOptionalPassesAndObjectIdSurface) {
DummyResourceView depthView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
DummyResourceView objectIdDepthView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
DummyResourceView objectIdView(ResourceViewType::RenderTarget);
DummyResourceView objectIdShaderView(ResourceViewType::ShaderResource);
@@ -197,6 +198,7 @@ TEST(ViewportRenderFlowUtilsTest, ApplySceneRenderRequestSetupAttachesOptionalPa
targets.width = 800;
targets.height = 600;
targets.depthView = &depthView;
targets.objectIdDepthView = &objectIdDepthView;
targets.objectIdView = &objectIdView;
targets.objectIdShaderView = &objectIdShaderView;
targets.objectIdState = ResourceStates::Common;
@@ -217,7 +219,7 @@ TEST(ViewportRenderFlowUtilsTest, ApplySceneRenderRequestSetupAttachesOptionalPa
EXPECT_TRUE(request.objectId.IsRequested());
ASSERT_EQ(request.objectId.surface.GetColorAttachments().size(), 1u);
EXPECT_EQ(request.objectId.surface.GetColorAttachments()[0], &objectIdView);
EXPECT_EQ(request.objectId.surface.GetDepthAttachment(), &depthView);
EXPECT_EQ(request.objectId.surface.GetDepthAttachment(), &objectIdDepthView);
const auto requestArea = request.surface.GetRenderArea();
const auto objectIdArea = request.objectId.surface.GetRenderArea();
@@ -247,9 +249,18 @@ TEST(ViewportRenderFlowUtilsTest, ApplySceneRenderRequestSetupSkipsUnavailableOp
}
TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanCollectsPostSceneAndOverlayPasses) {
DummyResourceView depthView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
DummyResourceView depthShaderView(ResourceViewType::ShaderResource, Format::D24_UNorm_S8_UInt);
DummyResourceView selectionMaskView(ResourceViewType::RenderTarget);
DummyResourceView selectionMaskShaderView(ResourceViewType::ShaderResource);
DummyResourceView objectIdShaderView(ResourceViewType::ShaderResource);
ViewportRenderTargets targets = {};
targets.depthView = &depthView;
targets.depthShaderView = &depthShaderView;
targets.selectionMaskView = &selectionMaskView;
targets.selectionMaskShaderView = &selectionMaskShaderView;
targets.objectIdShaderView = &objectIdShaderView;
const SceneViewportOverlayData overlay = CreateValidOverlay();
@@ -274,11 +285,16 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanCollectsPostSceneA
return std::make_unique<NoopRenderPass>();
},
[&selectionOutlinePassFactoryCallCount](
RHIResourceView* objectIdTextureView,
ViewportRenderTargets* outlineTargets,
const std::vector<uint64_t>& selectedObjectIds,
const SceneViewportSelectionOutlineStyle& style) {
++selectionOutlinePassFactoryCallCount;
EXPECT_NE(objectIdTextureView, nullptr);
EXPECT_NE(outlineTargets, nullptr);
if (outlineTargets == nullptr) {
return std::unique_ptr<NoopRenderPass>();
}
EXPECT_NE(outlineTargets->selectionMaskShaderView, nullptr);
EXPECT_NE(outlineTargets->depthShaderView, nullptr);
EXPECT_EQ(selectedObjectIds.size(), 2u);
EXPECT_FLOAT_EQ(style.outlineWidthPixels, 2.0f);
return std::make_unique<NoopRenderPass>();
@@ -301,6 +317,7 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanCollectsPostSceneA
TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanSkipsRhiOverlayPassWhenFrameContainsOnlySceneIcons) {
const SceneViewportOverlayData overlay = CreateValidOverlay();
ViewportRenderTargets targets = {};
SceneViewportOverlayFrameData editorOverlayFrameData = {};
editorOverlayFrameData.overlay = overlay;
@@ -310,7 +327,7 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanSkipsRhiOverlayPas
size_t overlayFactoryCallCount = 0u;
const auto result = BuildSceneViewportRenderPlan(
{},
targets,
overlay,
{},
editorOverlayFrameData,
@@ -318,7 +335,7 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanSkipsRhiOverlayPas
return std::make_unique<NoopRenderPass>();
},
[](
RHIResourceView*,
ViewportRenderTargets*,
const std::vector<uint64_t>&,
const SceneViewportSelectionOutlineStyle&) {
return std::make_unique<NoopRenderPass>();
@@ -337,8 +354,9 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanSkipsRhiOverlayPas
TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanWarnsWhenSelectionOutlineCannotAccessObjectIdTexture) {
const SceneViewportOverlayData overlay = CreateValidOverlay();
ViewportRenderTargets targets = {};
const auto result = BuildSceneViewportRenderPlan(
{},
targets,
overlay,
{ 42u },
{},
@@ -346,7 +364,7 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanWarnsWhenSelection
return std::make_unique<NoopRenderPass>();
},
[](
RHIResourceView*,
ViewportRenderTargets*,
const std::vector<uint64_t>&,
const SceneViewportSelectionOutlineStyle&) {
return std::make_unique<NoopRenderPass>();
@@ -357,11 +375,12 @@ TEST(ViewportRenderFlowUtilsTest, BuildSceneViewportRenderPlanWarnsWhenSelection
false);
EXPECT_EQ(result.plan.postScenePasses.GetPassCount(), 1u);
EXPECT_STREQ(result.warningStatusText, "Scene object id shader view is unavailable");
EXPECT_STREQ(result.warningStatusText, "Scene selection outline resources are unavailable");
}
TEST(ViewportRenderFlowUtilsTest, ApplySceneViewportRenderPlanAttachesPlannedPassesAndClearState) {
DummyResourceView depthView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
DummyResourceView objectIdDepthView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
DummyResourceView objectIdView(ResourceViewType::RenderTarget);
DummyResourceView objectIdShaderView(ResourceViewType::ShaderResource);
@@ -369,6 +388,7 @@ TEST(ViewportRenderFlowUtilsTest, ApplySceneViewportRenderPlanAttachesPlannedPas
targets.width = 800;
targets.height = 600;
targets.depthView = &depthView;
targets.objectIdDepthView = &objectIdDepthView;
targets.objectIdView = &objectIdView;
targets.objectIdShaderView = &objectIdShaderView;
@@ -395,14 +415,19 @@ TEST(ViewportRenderFlowUtilsTest, ApplySceneViewportRenderPlanAttachesPlannedPas
TEST(ViewportRenderFlowUtilsTest, MarkSceneRenderSuccessMovesTargetsToShaderResourceState) {
DummyResourceView depthView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
DummyResourceView objectIdView(ResourceViewType::RenderTarget);
DummyResourceView objectIdDepthView(ResourceViewType::DepthStencil, Format::D24_UNorm_S8_UInt);
DummyResourceView selectionMaskView(ResourceViewType::RenderTarget);
ViewportRenderTargets targets = {};
targets.width = 640;
targets.height = 360;
targets.depthView = &depthView;
targets.objectIdDepthView = &objectIdDepthView;
targets.objectIdView = &objectIdView;
targets.selectionMaskView = &selectionMaskView;
targets.colorState = ResourceStates::Common;
targets.objectIdState = ResourceStates::Common;
targets.selectionMaskState = ResourceStates::Common;
XCEngine::Rendering::CameraRenderRequest request = {};
request.surface = RenderSurface(640, 360);
@@ -411,16 +436,19 @@ TEST(ViewportRenderFlowUtilsTest, MarkSceneRenderSuccessMovesTargetsToShaderReso
MarkSceneViewportRenderSuccess(targets, request);
EXPECT_EQ(targets.colorState, ResourceStates::PixelShaderResource);
EXPECT_EQ(targets.objectIdState, ResourceStates::PixelShaderResource);
EXPECT_EQ(targets.selectionMaskState, ResourceStates::PixelShaderResource);
EXPECT_TRUE(targets.hasValidObjectIdFrame);
ViewportRenderTargets noObjectIdTargets = {};
noObjectIdTargets.colorState = ResourceStates::Common;
noObjectIdTargets.objectIdState = ResourceStates::Common;
noObjectIdTargets.selectionMaskState = ResourceStates::Common;
XCEngine::Rendering::CameraRenderRequest noObjectIdRequest = {};
MarkSceneViewportRenderSuccess(noObjectIdTargets, noObjectIdRequest);
EXPECT_EQ(noObjectIdTargets.colorState, ResourceStates::PixelShaderResource);
EXPECT_EQ(noObjectIdTargets.objectIdState, ResourceStates::PixelShaderResource);
EXPECT_EQ(noObjectIdTargets.selectionMaskState, ResourceStates::PixelShaderResource);
EXPECT_FALSE(noObjectIdTargets.hasValidObjectIdFrame);
}

View File

@@ -8,6 +8,7 @@ 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;
@@ -78,10 +79,16 @@ TEST(ViewportRenderTargetsTest, BuildReuseQueryReflectsCurrentResourcePresence)
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.objectIdTexture = reinterpret_cast<RHITexture*>(static_cast<uintptr_t>(0x5));
targets.objectIdView = reinterpret_cast<RHIResourceView*>(static_cast<uintptr_t>(0x6));
targets.objectIdShaderView = reinterpret_cast<RHIResourceView*>(static_cast<uintptr_t>(0x7));
targets.textureHandle.nativeHandle = 0x8;
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;
@@ -94,25 +101,36 @@ TEST(ViewportRenderTargetsTest, BuildReuseQueryReflectsCurrentResourcePresence)
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);
@@ -123,8 +141,14 @@ TEST(ViewportRenderTargetsTest, BuildSurfaceUsesTargetAttachmentsAndStates) {
const auto objectIdSurface = BuildViewportObjectIdSurface(targets);
ASSERT_EQ(objectIdSurface.GetColorAttachments().size(), 1u);
EXPECT_EQ(objectIdSurface.GetColorAttachments()[0], &objectIdView);
EXPECT_EQ(objectIdSurface.GetDepthAttachment(), &depthView);
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) {
@@ -132,9 +156,15 @@ TEST(ViewportRenderTargetsTest, DestroyViewportRenderTargetsShutsDownAndClearsSt
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;
@@ -143,9 +173,15 @@ TEST(ViewportRenderTargetsTest, DestroyViewportRenderTargetsShutsDownAndClearsSt
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;
@@ -153,6 +189,7 @@ TEST(ViewportRenderTargetsTest, DestroyViewportRenderTargetsShutsDownAndClearsSt
targets.textureHandle.height = 360;
targets.colorState = ResourceStates::RenderTarget;
targets.objectIdState = ResourceStates::PixelShaderResource;
targets.selectionMaskState = ResourceStates::PixelShaderResource;
targets.hasValidObjectIdFrame = true;
DestroyViewportRenderTargets(nullptr, targets);
@@ -161,18 +198,30 @@ TEST(ViewportRenderTargetsTest, DestroyViewportRenderTargetsShutsDownAndClearsSt
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);
@@ -180,6 +229,7 @@ TEST(ViewportRenderTargetsTest, DestroyViewportRenderTargetsShutsDownAndClearsSt
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);
}