681 lines
21 KiB
C++
681 lines
21 KiB
C++
#include "Rendering/Internal/RenderPipelineFactory.h"
|
|
|
|
#include <XCEngine/Rendering/RenderPipelineAsset.h>
|
|
#include <XCEngine/Rendering/RenderPipeline.h>
|
|
|
|
#include "Rendering/Execution/DirectionalShadowExecutionState.h"
|
|
#include "Rendering/Pipelines/BuiltinForwardPipeline.h"
|
|
#include "Rendering/Pipelines/ManagedScriptableRenderPipelineAsset.h"
|
|
#include "Rendering/Pipelines/ScriptableRenderPipelineHost.h"
|
|
#include "Rendering/Passes/BuiltinDepthOnlyPass.h"
|
|
#include "Rendering/Passes/BuiltinObjectIdPass.h"
|
|
#include "Rendering/Passes/BuiltinShadowCasterPass.h"
|
|
|
|
#include <mutex>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
|
|
namespace XCEngine {
|
|
namespace Rendering {
|
|
namespace Internal {
|
|
|
|
namespace {
|
|
|
|
std::shared_ptr<const RenderPipelineAsset>
|
|
CreateBuiltinForwardPipelineRendererAsset() {
|
|
static const std::shared_ptr<const RenderPipelineAsset>
|
|
s_builtinForwardPipelineAsset =
|
|
std::make_shared<Pipelines::BuiltinForwardPipelineAsset>();
|
|
return s_builtinForwardPipelineAsset;
|
|
}
|
|
|
|
std::unique_ptr<RenderPass> CreateBuiltinDepthOnlyStandalonePass() {
|
|
return std::make_unique<Passes::BuiltinDepthOnlyPass>();
|
|
}
|
|
|
|
std::unique_ptr<RenderPass> CreateBuiltinObjectIdStandalonePass() {
|
|
return std::make_unique<Passes::BuiltinObjectIdPass>();
|
|
}
|
|
|
|
std::unique_ptr<RenderPass> CreateBuiltinShadowCasterStandalonePass() {
|
|
return std::make_unique<Passes::BuiltinShadowCasterPass>();
|
|
}
|
|
|
|
using PipelineRendererAssetRegistry =
|
|
std::unordered_map<std::string, PipelineRendererAssetFactory>;
|
|
using CameraFrameStandalonePassRegistry =
|
|
std::unordered_map<std::string, CameraFrameStandalonePassFactory>;
|
|
using DirectionalShadowPlanningPolicyRegistry =
|
|
std::unordered_map<std::string, DirectionalShadowPlanningPolicy>;
|
|
using CameraFramePlanPolicyRegistry =
|
|
std::unordered_map<std::string, CameraFramePlanPolicy>;
|
|
using DirectionalShadowExecutionPolicyRegistry =
|
|
std::unordered_map<std::string, DirectionalShadowExecutionPolicy>;
|
|
|
|
PipelineRendererAssetRegistry& GetPipelineRendererAssetRegistry() {
|
|
static PipelineRendererAssetRegistry registry = {};
|
|
return registry;
|
|
}
|
|
|
|
CameraFrameStandalonePassRegistry& GetCameraFrameStandalonePassRegistry() {
|
|
static CameraFrameStandalonePassRegistry registry = {};
|
|
return registry;
|
|
}
|
|
|
|
DirectionalShadowPlanningPolicyRegistry&
|
|
GetDirectionalShadowPlanningPolicyRegistry() {
|
|
static DirectionalShadowPlanningPolicyRegistry registry = {};
|
|
return registry;
|
|
}
|
|
|
|
CameraFramePlanPolicyRegistry& GetCameraFramePlanPolicyRegistry() {
|
|
static CameraFramePlanPolicyRegistry registry = {};
|
|
return registry;
|
|
}
|
|
|
|
DirectionalShadowExecutionPolicyRegistry&
|
|
GetDirectionalShadowExecutionPolicyRegistry() {
|
|
static DirectionalShadowExecutionPolicyRegistry registry = {};
|
|
return registry;
|
|
}
|
|
|
|
std::unordered_set<std::string>& GetBuiltinPipelineRendererAssetKeys() {
|
|
static std::unordered_set<std::string> builtinKeys = {};
|
|
return builtinKeys;
|
|
}
|
|
|
|
std::unordered_set<std::string>& GetBuiltinCameraFrameStandalonePassKeys() {
|
|
static std::unordered_set<std::string> builtinKeys = {};
|
|
return builtinKeys;
|
|
}
|
|
|
|
std::unordered_set<std::string>& GetBuiltinDirectionalShadowPlanningPolicyKeys() {
|
|
static std::unordered_set<std::string> builtinKeys = {};
|
|
return builtinKeys;
|
|
}
|
|
|
|
std::unordered_set<std::string>& GetBuiltinCameraFramePlanPolicyKeys() {
|
|
static std::unordered_set<std::string> builtinKeys = {};
|
|
return builtinKeys;
|
|
}
|
|
|
|
std::unordered_set<std::string>&
|
|
GetBuiltinDirectionalShadowExecutionPolicyKeys() {
|
|
static std::unordered_set<std::string> builtinKeys = {};
|
|
return builtinKeys;
|
|
}
|
|
|
|
std::mutex& GetPipelineRendererAssetRegistryMutex() {
|
|
static std::mutex mutex;
|
|
return mutex;
|
|
}
|
|
|
|
std::mutex& GetCameraFrameStandalonePassRegistryMutex() {
|
|
static std::mutex mutex;
|
|
return mutex;
|
|
}
|
|
|
|
std::mutex& GetDirectionalShadowPlanningPolicyRegistryMutex() {
|
|
static std::mutex mutex;
|
|
return mutex;
|
|
}
|
|
|
|
std::mutex& GetCameraFramePlanPolicyRegistryMutex() {
|
|
static std::mutex mutex;
|
|
return mutex;
|
|
}
|
|
|
|
std::mutex& GetDirectionalShadowExecutionPolicyRegistryMutex() {
|
|
static std::mutex mutex;
|
|
return mutex;
|
|
}
|
|
|
|
void EnsureBuiltinPipelineRendererAssetRegistryInitialized() {
|
|
static const bool initialized = []() {
|
|
PipelineRendererAssetRegistry& registry =
|
|
GetPipelineRendererAssetRegistry();
|
|
registry.emplace(
|
|
"BuiltinForward",
|
|
&CreateBuiltinForwardPipelineRendererAsset);
|
|
GetBuiltinPipelineRendererAssetKeys().insert("BuiltinForward");
|
|
return true;
|
|
}();
|
|
(void)initialized;
|
|
}
|
|
|
|
void EnsureBuiltinCameraFrameStandalonePassRegistryInitialized() {
|
|
static const bool initialized = []() {
|
|
CameraFrameStandalonePassRegistry& registry =
|
|
GetCameraFrameStandalonePassRegistry();
|
|
registry.emplace(
|
|
"BuiltinDepthOnly",
|
|
&CreateBuiltinDepthOnlyStandalonePass);
|
|
registry.emplace(
|
|
"BuiltinObjectId",
|
|
&CreateBuiltinObjectIdStandalonePass);
|
|
registry.emplace(
|
|
"BuiltinShadowCaster",
|
|
&CreateBuiltinShadowCasterStandalonePass);
|
|
std::unordered_set<std::string>& builtinKeys =
|
|
GetBuiltinCameraFrameStandalonePassKeys();
|
|
builtinKeys.insert("BuiltinDepthOnly");
|
|
builtinKeys.insert("BuiltinObjectId");
|
|
builtinKeys.insert("BuiltinShadowCaster");
|
|
return true;
|
|
}();
|
|
(void)initialized;
|
|
}
|
|
|
|
void EnsureBuiltinDirectionalShadowPlanningPolicyRegistryInitialized() {
|
|
static const bool initialized = []() {
|
|
DirectionalShadowPlanningPolicyRegistry& registry =
|
|
GetDirectionalShadowPlanningPolicyRegistry();
|
|
registry.emplace(
|
|
"BuiltinDirectionalShadowPlanning",
|
|
[](CameraRenderRequest& request,
|
|
size_t renderedBaseCameraCount,
|
|
size_t renderedRequestCount,
|
|
const DirectionalShadowPlanningSettings& settings) {
|
|
ApplyDefaultRenderPipelineAssetCameraRenderRequestPolicy(
|
|
request,
|
|
renderedBaseCameraCount,
|
|
renderedRequestCount,
|
|
settings);
|
|
});
|
|
GetBuiltinDirectionalShadowPlanningPolicyKeys().insert(
|
|
"BuiltinDirectionalShadowPlanning");
|
|
return true;
|
|
}();
|
|
(void)initialized;
|
|
}
|
|
|
|
void EnsureBuiltinCameraFramePlanPolicyRegistryInitialized() {
|
|
static const bool initialized = []() {
|
|
CameraFramePlanPolicyRegistry& registry =
|
|
GetCameraFramePlanPolicyRegistry();
|
|
registry.emplace(
|
|
"BuiltinDefaultCameraFramePlan",
|
|
[](CameraFramePlan& plan,
|
|
const FinalColorSettings& defaultFinalColorSettings) {
|
|
ApplyDefaultRenderPipelineAssetCameraFramePlanPolicy(
|
|
plan,
|
|
defaultFinalColorSettings);
|
|
});
|
|
GetBuiltinCameraFramePlanPolicyKeys().insert(
|
|
"BuiltinDefaultCameraFramePlan");
|
|
return true;
|
|
}();
|
|
(void)initialized;
|
|
}
|
|
|
|
void EnsureBuiltinDirectionalShadowExecutionPolicyRegistryInitialized() {
|
|
static const bool initialized = []() {
|
|
DirectionalShadowExecutionPolicyRegistry& registry =
|
|
GetDirectionalShadowExecutionPolicyRegistry();
|
|
registry.emplace(
|
|
"BuiltinDirectionalShadow",
|
|
[](const CameraFramePlan& plan,
|
|
const DirectionalShadowSurfaceAllocation& shadowAllocation,
|
|
DirectionalShadowExecutionState& shadowState) {
|
|
ApplyDefaultRenderPipelineDirectionalShadowExecutionPolicy(
|
|
plan,
|
|
shadowAllocation,
|
|
shadowState);
|
|
return shadowState.shadowCasterRequest.IsValid() &&
|
|
shadowState.shadowData.IsValid();
|
|
});
|
|
GetBuiltinDirectionalShadowExecutionPolicyKeys().insert(
|
|
"BuiltinDirectionalShadow");
|
|
return true;
|
|
}();
|
|
(void)initialized;
|
|
}
|
|
|
|
std::unique_ptr<NativeSceneRenderer> TryCreateNativeSceneRendererFromAsset(
|
|
const std::shared_ptr<const RenderPipelineAsset>& asset) {
|
|
if (asset == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
std::unique_ptr<RenderPipeline> pipeline = asset->CreatePipeline();
|
|
if (pipeline == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
NativeSceneRenderer* const sceneRenderer =
|
|
dynamic_cast<NativeSceneRenderer*>(pipeline.get());
|
|
if (sceneRenderer == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
(void)pipeline.release();
|
|
return std::unique_ptr<NativeSceneRenderer>(sceneRenderer);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
std::shared_ptr<const RenderPipelineAsset> CreateConfiguredRenderPipelineAsset() {
|
|
return Pipelines::CreateConfiguredManagedRenderPipelineAsset();
|
|
}
|
|
|
|
std::shared_ptr<const RenderPipelineAsset> CreateFallbackRenderPipelineAsset() {
|
|
return std::make_shared<Pipelines::ScriptableRenderPipelineHostAsset>();
|
|
}
|
|
|
|
bool RegisterPipelineRendererAssetFactory(
|
|
const std::string& key,
|
|
PipelineRendererAssetFactory factory) {
|
|
if (key.empty() || !factory) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinPipelineRendererAssetRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetPipelineRendererAssetRegistryMutex());
|
|
PipelineRendererAssetRegistry& registry =
|
|
GetPipelineRendererAssetRegistry();
|
|
if (registry.find(key) != registry.end()) {
|
|
return false;
|
|
}
|
|
|
|
registry.emplace(key, std::move(factory));
|
|
return true;
|
|
}
|
|
|
|
bool UnregisterPipelineRendererAssetFactory(const std::string& key) {
|
|
if (key.empty()) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinPipelineRendererAssetRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetPipelineRendererAssetRegistryMutex());
|
|
if (GetBuiltinPipelineRendererAssetKeys().find(key) !=
|
|
GetBuiltinPipelineRendererAssetKeys().end()) {
|
|
return false;
|
|
}
|
|
|
|
PipelineRendererAssetRegistry& registry =
|
|
GetPipelineRendererAssetRegistry();
|
|
return registry.erase(key) != 0u;
|
|
}
|
|
|
|
std::shared_ptr<const RenderPipelineAsset> CreatePipelineRendererAssetByKey(
|
|
const std::string& key) {
|
|
if (key.empty()) {
|
|
return nullptr;
|
|
}
|
|
|
|
EnsureBuiltinPipelineRendererAssetRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetPipelineRendererAssetRegistryMutex());
|
|
const PipelineRendererAssetRegistry& registry =
|
|
GetPipelineRendererAssetRegistry();
|
|
const auto it = registry.find(key);
|
|
if (it == registry.end() || !it->second) {
|
|
return nullptr;
|
|
}
|
|
|
|
return it->second();
|
|
}
|
|
|
|
bool RegisterCameraFrameStandalonePassFactory(
|
|
const std::string& key,
|
|
CameraFrameStandalonePassFactory factory) {
|
|
if (key.empty() || !factory) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinCameraFrameStandalonePassRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetCameraFrameStandalonePassRegistryMutex());
|
|
CameraFrameStandalonePassRegistry& registry =
|
|
GetCameraFrameStandalonePassRegistry();
|
|
if (registry.find(key) != registry.end()) {
|
|
return false;
|
|
}
|
|
|
|
registry.emplace(key, std::move(factory));
|
|
return true;
|
|
}
|
|
|
|
bool UnregisterCameraFrameStandalonePassFactory(
|
|
const std::string& key) {
|
|
if (key.empty()) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinCameraFrameStandalonePassRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetCameraFrameStandalonePassRegistryMutex());
|
|
if (GetBuiltinCameraFrameStandalonePassKeys().find(key) !=
|
|
GetBuiltinCameraFrameStandalonePassKeys().end()) {
|
|
return false;
|
|
}
|
|
|
|
CameraFrameStandalonePassRegistry& registry =
|
|
GetCameraFrameStandalonePassRegistry();
|
|
return registry.erase(key) != 0u;
|
|
}
|
|
|
|
std::unique_ptr<RenderPass> CreateCameraFrameStandalonePassByKey(
|
|
const std::string& key) {
|
|
if (key.empty()) {
|
|
return nullptr;
|
|
}
|
|
|
|
EnsureBuiltinCameraFrameStandalonePassRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetCameraFrameStandalonePassRegistryMutex());
|
|
const CameraFrameStandalonePassRegistry& registry =
|
|
GetCameraFrameStandalonePassRegistry();
|
|
const auto it = registry.find(key);
|
|
if (it == registry.end() || !it->second) {
|
|
return nullptr;
|
|
}
|
|
|
|
return it->second();
|
|
}
|
|
|
|
bool RegisterDirectionalShadowPlanningPolicy(
|
|
const std::string& key,
|
|
DirectionalShadowPlanningPolicy policy) {
|
|
if (key.empty() || !policy) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinDirectionalShadowPlanningPolicyRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetDirectionalShadowPlanningPolicyRegistryMutex());
|
|
DirectionalShadowPlanningPolicyRegistry& registry =
|
|
GetDirectionalShadowPlanningPolicyRegistry();
|
|
if (registry.find(key) != registry.end()) {
|
|
return false;
|
|
}
|
|
|
|
registry.emplace(key, std::move(policy));
|
|
return true;
|
|
}
|
|
|
|
bool UnregisterDirectionalShadowPlanningPolicy(
|
|
const std::string& key) {
|
|
if (key.empty()) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinDirectionalShadowPlanningPolicyRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetDirectionalShadowPlanningPolicyRegistryMutex());
|
|
if (GetBuiltinDirectionalShadowPlanningPolicyKeys().find(key) !=
|
|
GetBuiltinDirectionalShadowPlanningPolicyKeys().end()) {
|
|
return false;
|
|
}
|
|
|
|
DirectionalShadowPlanningPolicyRegistry& registry =
|
|
GetDirectionalShadowPlanningPolicyRegistry();
|
|
return registry.erase(key) != 0u;
|
|
}
|
|
|
|
bool ApplyDirectionalShadowPlanningPolicyByKey(
|
|
const std::string& key,
|
|
CameraRenderRequest& request,
|
|
size_t renderedBaseCameraCount,
|
|
size_t renderedRequestCount,
|
|
const DirectionalShadowPlanningSettings& settings) {
|
|
if (key.empty()) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinDirectionalShadowPlanningPolicyRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetDirectionalShadowPlanningPolicyRegistryMutex());
|
|
const DirectionalShadowPlanningPolicyRegistry& registry =
|
|
GetDirectionalShadowPlanningPolicyRegistry();
|
|
const auto it = registry.find(key);
|
|
if (it == registry.end() || !it->second) {
|
|
return false;
|
|
}
|
|
|
|
it->second(
|
|
request,
|
|
renderedBaseCameraCount,
|
|
renderedRequestCount,
|
|
settings);
|
|
return true;
|
|
}
|
|
|
|
bool RegisterCameraFramePlanPolicy(
|
|
const std::string& key,
|
|
CameraFramePlanPolicy policy) {
|
|
if (key.empty() || !policy) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinCameraFramePlanPolicyRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetCameraFramePlanPolicyRegistryMutex());
|
|
CameraFramePlanPolicyRegistry& registry =
|
|
GetCameraFramePlanPolicyRegistry();
|
|
if (registry.find(key) != registry.end()) {
|
|
return false;
|
|
}
|
|
|
|
registry.emplace(key, std::move(policy));
|
|
return true;
|
|
}
|
|
|
|
bool UnregisterCameraFramePlanPolicy(
|
|
const std::string& key) {
|
|
if (key.empty()) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinCameraFramePlanPolicyRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetCameraFramePlanPolicyRegistryMutex());
|
|
if (GetBuiltinCameraFramePlanPolicyKeys().find(key) !=
|
|
GetBuiltinCameraFramePlanPolicyKeys().end()) {
|
|
return false;
|
|
}
|
|
|
|
CameraFramePlanPolicyRegistry& registry =
|
|
GetCameraFramePlanPolicyRegistry();
|
|
return registry.erase(key) != 0u;
|
|
}
|
|
|
|
bool ApplyCameraFramePlanPolicyByKey(
|
|
const std::string& key,
|
|
CameraFramePlan& plan,
|
|
const FinalColorSettings& defaultFinalColorSettings) {
|
|
if (key.empty()) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinCameraFramePlanPolicyRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetCameraFramePlanPolicyRegistryMutex());
|
|
const CameraFramePlanPolicyRegistry& registry =
|
|
GetCameraFramePlanPolicyRegistry();
|
|
const auto it = registry.find(key);
|
|
if (it == registry.end() || !it->second) {
|
|
return false;
|
|
}
|
|
|
|
it->second(
|
|
plan,
|
|
defaultFinalColorSettings);
|
|
return true;
|
|
}
|
|
|
|
bool RegisterDirectionalShadowExecutionPolicy(
|
|
const std::string& key,
|
|
DirectionalShadowExecutionPolicy policy) {
|
|
if (key.empty() || !policy) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinDirectionalShadowExecutionPolicyRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetDirectionalShadowExecutionPolicyRegistryMutex());
|
|
DirectionalShadowExecutionPolicyRegistry& registry =
|
|
GetDirectionalShadowExecutionPolicyRegistry();
|
|
if (registry.find(key) != registry.end()) {
|
|
return false;
|
|
}
|
|
|
|
registry.emplace(key, std::move(policy));
|
|
return true;
|
|
}
|
|
|
|
bool UnregisterDirectionalShadowExecutionPolicy(
|
|
const std::string& key) {
|
|
if (key.empty()) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinDirectionalShadowExecutionPolicyRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetDirectionalShadowExecutionPolicyRegistryMutex());
|
|
if (GetBuiltinDirectionalShadowExecutionPolicyKeys().find(key) !=
|
|
GetBuiltinDirectionalShadowExecutionPolicyKeys().end()) {
|
|
return false;
|
|
}
|
|
|
|
DirectionalShadowExecutionPolicyRegistry& registry =
|
|
GetDirectionalShadowExecutionPolicyRegistry();
|
|
return registry.erase(key) != 0u;
|
|
}
|
|
|
|
bool ConfigureDirectionalShadowExecutionStateByKey(
|
|
const std::string& key,
|
|
const CameraFramePlan& plan,
|
|
const DirectionalShadowSurfaceAllocation& shadowAllocation,
|
|
DirectionalShadowExecutionState& shadowState) {
|
|
if (key.empty()) {
|
|
return false;
|
|
}
|
|
|
|
EnsureBuiltinDirectionalShadowExecutionPolicyRegistryInitialized();
|
|
|
|
std::lock_guard<std::mutex> lock(
|
|
GetDirectionalShadowExecutionPolicyRegistryMutex());
|
|
const DirectionalShadowExecutionPolicyRegistry& registry =
|
|
GetDirectionalShadowExecutionPolicyRegistry();
|
|
const auto it = registry.find(key);
|
|
if (it == registry.end() || !it->second) {
|
|
return false;
|
|
}
|
|
|
|
return it->second(
|
|
plan,
|
|
shadowAllocation,
|
|
shadowState);
|
|
}
|
|
|
|
std::shared_ptr<const RenderPipelineAsset> ResolveRenderPipelineAssetOrDefault(
|
|
std::shared_ptr<const RenderPipelineAsset> preferredAsset) {
|
|
if (preferredAsset != nullptr) {
|
|
return std::move(preferredAsset);
|
|
}
|
|
|
|
if (std::shared_ptr<const RenderPipelineAsset> configuredAsset =
|
|
CreateConfiguredRenderPipelineAsset();
|
|
configuredAsset != nullptr) {
|
|
return configuredAsset;
|
|
}
|
|
|
|
return CreateFallbackRenderPipelineAsset();
|
|
}
|
|
|
|
std::unique_ptr<RenderPipeline> CreateRenderPipelineOrDefault(
|
|
const std::shared_ptr<const RenderPipelineAsset>& preferredAsset,
|
|
std::shared_ptr<const RenderPipelineAsset>* outResolvedAsset) {
|
|
const std::shared_ptr<const RenderPipelineAsset> resolvedAsset =
|
|
ResolveRenderPipelineAssetOrDefault(preferredAsset);
|
|
if (resolvedAsset != nullptr) {
|
|
if (std::unique_ptr<RenderPipeline> pipeline =
|
|
resolvedAsset->CreatePipeline()) {
|
|
if (outResolvedAsset != nullptr) {
|
|
*outResolvedAsset = resolvedAsset;
|
|
}
|
|
return pipeline;
|
|
}
|
|
}
|
|
|
|
const std::shared_ptr<const RenderPipelineAsset> defaultAsset =
|
|
ResolveRenderPipelineAssetOrDefault(nullptr);
|
|
if (defaultAsset != nullptr &&
|
|
defaultAsset != resolvedAsset) {
|
|
if (std::unique_ptr<RenderPipeline> pipeline =
|
|
defaultAsset->CreatePipeline()) {
|
|
if (outResolvedAsset != nullptr) {
|
|
*outResolvedAsset = defaultAsset;
|
|
}
|
|
return pipeline;
|
|
}
|
|
}
|
|
|
|
const std::shared_ptr<const RenderPipelineAsset> fallbackAsset =
|
|
CreateFallbackRenderPipelineAsset();
|
|
if (fallbackAsset != nullptr &&
|
|
fallbackAsset != resolvedAsset &&
|
|
fallbackAsset != defaultAsset) {
|
|
if (std::unique_ptr<RenderPipeline> pipeline =
|
|
fallbackAsset->CreatePipeline()) {
|
|
if (outResolvedAsset != nullptr) {
|
|
*outResolvedAsset = fallbackAsset;
|
|
}
|
|
return pipeline;
|
|
}
|
|
}
|
|
|
|
if (outResolvedAsset != nullptr) {
|
|
*outResolvedAsset =
|
|
fallbackAsset != nullptr
|
|
? fallbackAsset
|
|
: (defaultAsset != nullptr
|
|
? defaultAsset
|
|
: resolvedAsset);
|
|
}
|
|
return std::make_unique<Pipelines::ScriptableRenderPipelineHost>();
|
|
}
|
|
|
|
std::unique_ptr<NativeSceneRenderer> CreateNativeSceneRendererFromAsset(
|
|
const std::shared_ptr<const RenderPipelineAsset>& preferredAsset,
|
|
std::shared_ptr<const RenderPipelineAsset>* outResolvedAsset) {
|
|
if (std::unique_ptr<NativeSceneRenderer> sceneRenderer =
|
|
TryCreateNativeSceneRendererFromAsset(preferredAsset)) {
|
|
if (outResolvedAsset != nullptr) {
|
|
*outResolvedAsset = preferredAsset;
|
|
}
|
|
return sceneRenderer;
|
|
}
|
|
|
|
if (outResolvedAsset != nullptr) {
|
|
outResolvedAsset->reset();
|
|
}
|
|
return CreateDefaultNativeSceneRenderer();
|
|
}
|
|
|
|
std::unique_ptr<NativeSceneRenderer> CreateDefaultNativeSceneRenderer() {
|
|
return std::make_unique<Pipelines::BuiltinForwardPipeline>();
|
|
}
|
|
|
|
} // namespace Internal
|
|
} // namespace Rendering
|
|
} // namespace XCEngine
|