#include #include #include #include #include using namespace XCEngine::Rendering; namespace Resources = XCEngine::Resources; namespace { class DummyManagedRenderPipelineBridge final : public Pipelines::ManagedRenderPipelineBridge { }; class GraphicsSettingsStateScope final { public: GraphicsSettingsStateScope() : m_savedDescriptor( GetGraphicsSettingsState() .GetConfiguredRenderPipelineAssetDescriptor()) , m_savedAssetRef( GetGraphicsSettingsState() .GetConfiguredRenderPipelineAssetRef()) , m_savedBridge( GetGraphicsSettingsState().GetManagedRenderPipelineBridge()) { } ~GraphicsSettingsStateScope() { GraphicsSettingsState& state = GetGraphicsSettingsState(); if (m_savedBridge != nullptr) { state.SetManagedRenderPipelineBridge(m_savedBridge); } else { state.ClearManagedRenderPipelineBridge(); } if (m_savedAssetRef.IsValid()) { state.SetConfiguredRenderPipelineAssetSelection( m_savedAssetRef, m_savedDescriptor); } else if (m_savedDescriptor.IsValid() || m_savedDescriptor.managedAssetHandle != 0u) { state.SetConfiguredRenderPipelineAssetDescriptor( m_savedDescriptor); } else { state.ClearConfiguredRenderPipelineAssetDescriptor(); } } private: Pipelines::ManagedRenderPipelineAssetDescriptor m_savedDescriptor = {}; Resources::AssetRef m_savedAssetRef = {}; std::shared_ptr m_savedBridge = nullptr; }; Resources::AssetRef MakeRenderPipelineAssetRefForTest( uint64_t guidLow = 2u) { Resources::AssetRef assetRef = {}; assetRef.assetGuid = Resources::AssetGUID(1u, guidLow); assetRef.localID = Resources::kMainAssetLocalID; assetRef.resourceType = Resources::ResourceType::RenderPipelineAsset; return assetRef; } } // namespace TEST(GraphicsSettingsState_Test, StoresRenderPipelineAssetDescriptorAndBumpsEnvironmentGeneration) { GraphicsSettingsStateScope scope; GraphicsSettingsState& state = GetGraphicsSettingsState(); state.ClearConfiguredRenderPipelineAssetDescriptor(); const size_t generationBefore = state.GetEnvironmentGeneration(); const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = { "XCEngine.GameScripts", "Gameplay", "ManagedUniversalRenderPipelineProbeAsset", 42u }; state.SetConfiguredRenderPipelineAssetDescriptor(descriptor); const Pipelines::ManagedRenderPipelineAssetDescriptor resolved = state.GetConfiguredRenderPipelineAssetDescriptor(); EXPECT_EQ(resolved.assemblyName, descriptor.assemblyName); EXPECT_EQ(resolved.namespaceName, descriptor.namespaceName); EXPECT_EQ(resolved.className, descriptor.className); EXPECT_EQ(resolved.managedAssetHandle, descriptor.managedAssetHandle); EXPECT_FALSE(state.GetConfiguredRenderPipelineAssetRef().IsValid()); EXPECT_GT(state.GetEnvironmentGeneration(), generationBefore); } TEST( GraphicsSettingsState_Test, StoresRenderPipelineAssetRefAsSelectionRootAndDescriptorAsRuntimeCache) { GraphicsSettingsStateScope scope; GraphicsSettingsState& state = GetGraphicsSettingsState(); state.ClearConfiguredRenderPipelineAssetDescriptor(); const Resources::AssetRef assetRef = MakeRenderPipelineAssetRefForTest(); const Pipelines::ManagedRenderPipelineAssetDescriptor descriptor = { "XCEngine.RenderPipelines.Universal", "XCEngine.Rendering.Universal", "UniversalRenderPipelineAsset", 0u }; const size_t generationBefore = state.GetEnvironmentGeneration(); state.SetConfiguredRenderPipelineAssetSelection( assetRef, descriptor); const Resources::AssetRef resolvedAssetRef = state.GetConfiguredRenderPipelineAssetRef(); EXPECT_EQ(resolvedAssetRef.assetGuid, assetRef.assetGuid); EXPECT_EQ(resolvedAssetRef.localID, assetRef.localID); EXPECT_EQ(resolvedAssetRef.resourceType, assetRef.resourceType); const Pipelines::ManagedRenderPipelineAssetDescriptor resolvedDescriptor = state.GetConfiguredRenderPipelineAssetDescriptor(); EXPECT_EQ(resolvedDescriptor.assemblyName, descriptor.assemblyName); EXPECT_EQ(resolvedDescriptor.namespaceName, descriptor.namespaceName); EXPECT_EQ(resolvedDescriptor.className, descriptor.className); EXPECT_TRUE(resolvedDescriptor.assetRef.IsValid()); EXPECT_EQ(resolvedDescriptor.assetRef.assetGuid, assetRef.assetGuid); EXPECT_GT(state.GetEnvironmentGeneration(), generationBefore); } TEST( GraphicsSettingsState_Test, RuntimeDescriptorUpdatePreservesConfiguredRenderPipelineAssetRef) { GraphicsSettingsStateScope scope; GraphicsSettingsState& state = GetGraphicsSettingsState(); state.ClearConfiguredRenderPipelineAssetDescriptor(); const Resources::AssetRef assetRef = MakeRenderPipelineAssetRefForTest(3u); state.SetConfiguredRenderPipelineAssetRef(assetRef); Pipelines::ManagedRenderPipelineAssetDescriptor runtimeDescriptor = { "GameScripts", "Gameplay", "ProjectConfiguredRenderPipelineAsset", 77u }; state.UpdateConfiguredRenderPipelineAssetRuntimeDescriptor( runtimeDescriptor); const Resources::AssetRef resolvedAssetRef = state.GetConfiguredRenderPipelineAssetRef(); EXPECT_EQ(resolvedAssetRef.assetGuid, assetRef.assetGuid); EXPECT_EQ(resolvedAssetRef.localID, assetRef.localID); EXPECT_EQ(resolvedAssetRef.resourceType, assetRef.resourceType); const Pipelines::ManagedRenderPipelineAssetDescriptor resolvedDescriptor = state.GetConfiguredRenderPipelineAssetDescriptor(); EXPECT_EQ(resolvedDescriptor.managedAssetHandle, 77u); EXPECT_TRUE(resolvedDescriptor.assetRef.IsValid()); EXPECT_EQ(resolvedDescriptor.assetRef.assetGuid, assetRef.assetGuid); } TEST(GraphicsSettingsState_Test, StoresManagedBridgeAndBumpsBridgeAndEnvironmentGenerations) { GraphicsSettingsStateScope scope; GraphicsSettingsState& state = GetGraphicsSettingsState(); state.ClearManagedRenderPipelineBridge(); const size_t environmentGenerationBefore = state.GetEnvironmentGeneration(); const size_t bridgeGenerationBefore = state.GetManagedRenderPipelineBridgeGeneration(); const auto bridge = std::make_shared(); state.SetManagedRenderPipelineBridge(bridge); EXPECT_EQ(state.GetManagedRenderPipelineBridge(), bridge); EXPECT_GT(state.GetManagedRenderPipelineBridgeGeneration(), bridgeGenerationBefore); EXPECT_GT(state.GetEnvironmentGeneration(), environmentGenerationBefore); }