[ATOM-15472] Shader Build Pipeline: Remove Deprecated Files And Funct… (#1079)
* [ATOM-15472] Shader Build Pipeline: Remove Deprecated Files And Functions That Predate The Shader Supervariants These are the essential impactful changes as a result of deprecating the ShaderResourceGroupAsset. * Addressed feedback by @moudgils. Better comments in header files. * More updates related with deprecation of ShaderResourceGroupAsset * Deleted the temporary version 2 classes. * Updated version of the shader asset builders. * Updated version of all the shader related classes impacted by the Supervariant concept and deprecation of ShaderResourceGroupAsset * Changes to *.pass and DGI, Reflections and RayTracing. * changes to material related assets * changes to core lights * Changes to auxgeom/dynamic draw. * changes to decals, lyshine, imguipass * changes to RPI Pass classes * Shader for SceneSrg, ViewSrg and ForwardPass Srgs. * changes to mesh, skinned mesh, Morphtarget. * Fixes to RayTracingPass.cpp & now allow empty srg in shaders. * Updated Atom_RPI.Tests * Simplified InstanceDatabase by removing AddHandler ------------------------------------------------------------------------------------ * Updated DiffuseGI precompiled shaders. Added RayTracingSceneSrg and RayTracingMaterialSrg shader asset. Updated ShaderAssetCreator::Clone to handle the supervariant when processing root variants. Co-authored-by: Doug McDiarmid <dmcdiar@amazon.com> ------------------------------------------------------------------------------------ * Changed semantics for some PassSrg to SRG_PerPass_WithFallback. AuxGeom/FixedShapeProcessor.cpp requires SRG_PerDraw on ObjectSrg. Removed names of SceneSrg and ViewSrg from RPISystemDescriptor.cpp * Moved ShaderLib/Atom/Features/DummyEntryFunctions.azsli To Gems/Atom/RPI/Assets/ShaderLib/Atom/RPI/DummyEntryFunctions.azsli Removed redundant checking for finalization in ShaderResourceGroupLayout.cpp * Fixed race condition bug for Shader::FindOrCreate. InstanceDatabase<>::CreateInstance() needs to be atomic for instance creation and initialization. Added optional InstanceHandler::CreateFunctionWithParams to accomodate to the needs of Instances that need more than an asset reference to be able to be created an initialzed. Removed ShaderResourceGroup::FindOrCreate() only ::Create is available now. * Renamed scene_and_view_srgs.* as SceneAndViewSrgs.* Changed GetAzslFileOfOrigin for GetUniqueId * Fixed unit tests. * Reverted the serialization name of m_uniqueId back to "m_azslFileOfOrigin" so precompiled shaders don't fail in layout comparison. * Fixed AtomCore.Tests Removed non-applicable test. InstanceDatabase.AddHandler() is not available anymore. * The Null rhi is re-enabled for shader compilation. Signed-off-by: garrieta <garrieta@amazon.com>
This commit is contained in:
@@ -34,8 +34,7 @@ namespace UnitTest
|
||||
static const AssetId s_assetId3{ Uuid("{D9CDAB04-D206-431E-BDC0-1DD615D56197}") };
|
||||
|
||||
// test asset type
|
||||
class TestAssetType
|
||||
: public AssetData
|
||||
class TestAssetType : public AssetData
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(TestAssetType, AZ::SystemAllocator, 0);
|
||||
@@ -47,30 +46,30 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class TestInstanceA
|
||||
: public InstanceData
|
||||
class TestInstanceA : public InstanceData
|
||||
{
|
||||
public:
|
||||
AZ_INSTANCE_DATA(TestInstanceA, "{65CBF1C8-F65F-4A84-8A11-B510BC435DB0}");
|
||||
AZ_CLASS_ALLOCATOR(TestInstanceA, AZ::SystemAllocator, 0);
|
||||
|
||||
TestInstanceA(TestAssetType* asset)
|
||||
: m_asset{asset, AZ::Data::AssetLoadBehavior::Default}
|
||||
{}
|
||||
: m_asset{ asset, AZ::Data::AssetLoadBehavior::Default }
|
||||
{
|
||||
}
|
||||
|
||||
Asset<TestAssetType> m_asset;
|
||||
};
|
||||
|
||||
class TestInstanceB
|
||||
: public InstanceData
|
||||
class TestInstanceB : public InstanceData
|
||||
{
|
||||
public:
|
||||
AZ_INSTANCE_DATA(TestInstanceB, "{4ED0A8BF-7800-44B2-AC73-2CB759C61C37}");
|
||||
AZ_CLASS_ALLOCATOR(TestInstanceB, AZ::SystemAllocator, 0);
|
||||
|
||||
TestInstanceB(TestAssetType* asset)
|
||||
: m_asset{asset, AZ::Data::AssetLoadBehavior::Default }
|
||||
{}
|
||||
: m_asset{ asset, AZ::Data::AssetLoadBehavior::Default }
|
||||
{
|
||||
}
|
||||
|
||||
~TestInstanceB()
|
||||
{
|
||||
@@ -86,8 +85,7 @@ namespace UnitTest
|
||||
|
||||
// test asset handler
|
||||
template<typename AssetDataT>
|
||||
class MyAssetHandler
|
||||
: public AssetHandler
|
||||
class MyAssetHandler : public AssetHandler
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(MyAssetHandler, AZ::SystemAllocator, 0);
|
||||
@@ -120,13 +118,12 @@ namespace UnitTest
|
||||
}
|
||||
};
|
||||
|
||||
class InstanceDatabaseTest
|
||||
: public AllocatorsFixture
|
||||
class InstanceDatabaseTest : public AllocatorsFixture
|
||||
{
|
||||
protected:
|
||||
MyAssetHandler<TestAssetType>* m_assetHandler;
|
||||
public:
|
||||
|
||||
public:
|
||||
void SetUp() override
|
||||
{
|
||||
AllocatorsFixture::SetUp();
|
||||
@@ -200,7 +197,7 @@ namespace UnitTest
|
||||
|
||||
AZStd::vector<Uuid> guids;
|
||||
AZStd::vector<Asset<TestAssetType>> assets;
|
||||
|
||||
|
||||
for (size_t i = 0; i < assetIdCount; ++i)
|
||||
{
|
||||
Uuid guid = Uuid::CreateRandom();
|
||||
@@ -211,7 +208,6 @@ namespace UnitTest
|
||||
assets.emplace_back(assetManager.CreateAsset<TestAssetType>(guid, AZ::Data::AssetLoadBehavior::Default));
|
||||
}
|
||||
|
||||
|
||||
AZStd::vector<AZStd::thread> threads;
|
||||
AZStd::mutex mutex;
|
||||
AZStd::atomic<int> threadCount((int)threadCountMax);
|
||||
@@ -232,27 +228,29 @@ namespace UnitTest
|
||||
|
||||
for (size_t i = 0; i < threadCountMax; ++i)
|
||||
{
|
||||
threads.emplace_back([&instanceManager, &threadCount, &cv, &guids, &assets, &durationSeconds]()
|
||||
{
|
||||
AZ::Debug::Timer timer;
|
||||
timer.Stamp();
|
||||
|
||||
while(timer.GetDeltaTimeInSeconds() < durationSeconds)
|
||||
threads.emplace_back(
|
||||
[&instanceManager, &threadCount, &cv, &guids, &assets, &durationSeconds]()
|
||||
{
|
||||
const size_t index = rand() % guids.size();
|
||||
const Uuid uuid = guids[index];
|
||||
const InstanceId instanceId{uuid};
|
||||
const AssetId assetId{uuid};
|
||||
AZ::Debug::Timer timer;
|
||||
timer.Stamp();
|
||||
|
||||
Instance<TestInstanceA> instance = instanceManager.FindOrCreate(instanceId, Asset<TestAssetType>(assetId, azrtti_typeid<TestAssetType>()));
|
||||
EXPECT_NE(instance, nullptr);
|
||||
EXPECT_EQ(instance->GetId(), instanceId);
|
||||
EXPECT_EQ(instance->m_asset, assets[index]);
|
||||
}
|
||||
while (timer.GetDeltaTimeInSeconds() < durationSeconds)
|
||||
{
|
||||
const size_t index = rand() % guids.size();
|
||||
const Uuid uuid = guids[index];
|
||||
const InstanceId instanceId{ uuid };
|
||||
const AssetId assetId{ uuid };
|
||||
|
||||
threadCount--;
|
||||
cv.notify_one();
|
||||
});
|
||||
Instance<TestInstanceA> instance =
|
||||
instanceManager.FindOrCreate(instanceId, Asset<TestAssetType>(assetId, azrtti_typeid<TestAssetType>()));
|
||||
EXPECT_NE(instance, nullptr);
|
||||
EXPECT_EQ(instance->GetId(), instanceId);
|
||||
EXPECT_EQ(instance->m_asset, assets[index]);
|
||||
}
|
||||
|
||||
threadCount--;
|
||||
cv.notify_one();
|
||||
});
|
||||
}
|
||||
|
||||
bool timedOut = false;
|
||||
@@ -261,7 +259,9 @@ namespace UnitTest
|
||||
while (threadCount > 0 && !timedOut)
|
||||
{
|
||||
AZStd::unique_lock<AZStd::mutex> lock(mutex);
|
||||
timedOut = (AZStd::cv_status::timeout == cv.wait_until(lock, AZStd::chrono::system_clock::now() + AZStd::chrono::seconds(durationSeconds * 2)));
|
||||
timedOut =
|
||||
(AZStd::cv_status::timeout ==
|
||||
cv.wait_until(lock, AZStd::chrono::system_clock::now() + AZStd::chrono::seconds(durationSeconds * 2)));
|
||||
}
|
||||
|
||||
EXPECT_TRUE(threadCount == 0) << "One or more threads appear to be deadlocked at " << timer.GetDeltaTimeInSeconds() << " seconds";
|
||||
@@ -280,8 +280,8 @@ namespace UnitTest
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreate)
|
||||
{
|
||||
// This is the original test scenario from when InstanceDatabase was first implemented
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper( 8, 100, 5 );
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(8, 100, 5);
|
||||
|
||||
// This value is checked in as 1 so this test doesn't take too much time, but can be increased locally to soak the test.
|
||||
const size_t attempts = 1;
|
||||
@@ -291,10 +291,10 @@ namespace UnitTest
|
||||
printf("Attempt %zu of %zu... \n", i, attempts);
|
||||
|
||||
// The idea behind this series of tests is that there are two threads sharing one Instance, and both threads try to
|
||||
// create or release that instance at the same time.
|
||||
// create or release that instance at the same time.
|
||||
// At the time, this set of scenarios has something like a 10% failure rate.
|
||||
const size_t duration = 2;
|
||||
// threads, AssetIds, seconds
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(2, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 1, duration);
|
||||
ParallelInstanceCreateHelper(8, 1, duration);
|
||||
@@ -306,7 +306,7 @@ namespace UnitTest
|
||||
|
||||
// Here we try a bunch of different threadCount:assetCount ratios to be thorough
|
||||
const size_t duration = 2;
|
||||
// threads, AssetIds, seconds
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(2, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 2, duration);
|
||||
@@ -328,7 +328,10 @@ namespace UnitTest
|
||||
|
||||
// Tests whether the deleter actually calls delete properly without
|
||||
// a parent database.
|
||||
instance->m_onDeleteCallback = [this, &m_deleted] () { m_deleted = true; };
|
||||
instance->m_onDeleteCallback = [this, &m_deleted]()
|
||||
{
|
||||
m_deleted = true;
|
||||
};
|
||||
}
|
||||
|
||||
EXPECT_TRUE(m_deleted);
|
||||
@@ -386,242 +389,4 @@ namespace UnitTest
|
||||
InstanceDatabase<TestInstanceB>::Destroy();
|
||||
}
|
||||
|
||||
|
||||
class InstanceDatabaseTestWithMultipleSubclasses
|
||||
: public AllocatorsFixture
|
||||
{
|
||||
protected:
|
||||
// We have "BaseAsset" with subclasses "FooAsset" and "BarAsset",
|
||||
// and corresponding "BaseInstance" with subclasses "FooInstance" and "BarInstance".
|
||||
// There is one "InstanceDatabse<BaseInstance>" that can create instances of both subtypes.
|
||||
|
||||
class BaseAsset
|
||||
: public AssetData
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(BaseAsset, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(FooAsset, "{35B443A6-D8ED-4C3C-A3F0-D642251F0AA5}", AssetData);
|
||||
|
||||
BaseAsset()
|
||||
{
|
||||
m_status = AssetStatus::Ready;
|
||||
}
|
||||
};
|
||||
|
||||
class BaseInstance
|
||||
: public InstanceData
|
||||
{
|
||||
public:
|
||||
AZ_INSTANCE_DATA(BaseInstance, "{EFEC3406-2CB7-462E-A676-C22177E143E6}");
|
||||
AZ_CLASS_ALLOCATOR(BaseInstance, AZ::SystemAllocator, 0);
|
||||
|
||||
BaseInstance(BaseAsset* asset)
|
||||
: m_asset{ asset, AZ::Data::AssetLoadBehavior::Default }
|
||||
{}
|
||||
|
||||
Asset<BaseAsset> m_asset;
|
||||
};
|
||||
|
||||
class FooAsset
|
||||
: public BaseAsset
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(FooAsset, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(FooAsset, "{74BAE278-3DCA-4ADD-807E-2A6873F9EA3C}", BaseAsset);
|
||||
};
|
||||
|
||||
class BarAsset
|
||||
: public BaseAsset
|
||||
{
|
||||
public:
|
||||
AZ_CLASS_ALLOCATOR(BarAsset, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(FooAsset, "{2BCD66F5-768B-4569-9FC2-DE92ABC9C0BF}", BaseAsset);
|
||||
};
|
||||
|
||||
class FooInstance
|
||||
: public BaseInstance
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(FooInstance, "{B5487509-5518-4591-AC96-03E623A584B7}", BaseInstance);
|
||||
AZ_CLASS_ALLOCATOR(FooInstance, AZ::SystemAllocator, 0);
|
||||
|
||||
FooInstance(BaseAsset* asset)
|
||||
: BaseInstance(asset)
|
||||
{
|
||||
EXPECT_TRUE(azrtti_typeid<FooAsset>() == asset->GetType());
|
||||
}
|
||||
};
|
||||
|
||||
class BarInstance
|
||||
: public BaseInstance
|
||||
{
|
||||
public:
|
||||
AZ_RTTI(BarInstance, "{CE9C844A-625D-4899-B7DB-8127D4618D25}", BaseInstance);
|
||||
AZ_CLASS_ALLOCATOR(BarInstance, AZ::SystemAllocator, 0);
|
||||
|
||||
BarInstance(BaseAsset* asset)
|
||||
: BaseInstance(asset)
|
||||
{
|
||||
EXPECT_TRUE(azrtti_typeid<BarAsset>() == asset->GetType());
|
||||
}
|
||||
};
|
||||
|
||||
MyAssetHandler<FooAsset> m_fooAssetHandler;
|
||||
MyAssetHandler<BarAsset> m_barAssetHandler;
|
||||
|
||||
public:
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
AllocatorsFixture::SetUp();
|
||||
AllocatorInstance<PoolAllocator>::Create();
|
||||
AllocatorInstance<ThreadPoolAllocator>::Create();
|
||||
|
||||
// create the asset database
|
||||
{
|
||||
AssetManager::Descriptor desc;
|
||||
AssetManager::Create(desc);
|
||||
}
|
||||
|
||||
// create the instance database
|
||||
{
|
||||
InstanceDatabase<BaseInstance>::Create(azrtti_typeid<BaseAsset>());
|
||||
|
||||
InstanceHandler<BaseInstance> fooHandler;
|
||||
fooHandler.m_createFunction = [](AssetData* assetData)
|
||||
{
|
||||
EXPECT_TRUE(azrtti_istypeof<FooAsset>(assetData));
|
||||
return aznew FooInstance(static_cast<FooAsset*>(assetData));
|
||||
};
|
||||
InstanceDatabase<BaseInstance>::Instance().AddHandler(azrtti_typeid<FooAsset>(), fooHandler);
|
||||
|
||||
// Using a different overload of AddHandler()
|
||||
InstanceDatabase<BaseInstance>::Instance().AddHandler(azrtti_typeid<BarAsset>(), [](AssetData* assetData)
|
||||
{
|
||||
EXPECT_TRUE(azrtti_istypeof<BarAsset>(assetData));
|
||||
return aznew BarInstance(static_cast<BarAsset*>(assetData));
|
||||
});
|
||||
}
|
||||
|
||||
AssetManager::Instance().RegisterHandler(&m_fooAssetHandler, AzTypeInfo<FooAsset>::Uuid());
|
||||
AssetManager::Instance().RegisterHandler(&m_barAssetHandler, AzTypeInfo<BarAsset>::Uuid());
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
AssetManager::Instance().UnregisterHandler(&m_fooAssetHandler);
|
||||
AssetManager::Instance().UnregisterHandler(&m_barAssetHandler);
|
||||
AssetManager::Destroy();
|
||||
|
||||
InstanceDatabase<BaseInstance>::Destroy();
|
||||
|
||||
AllocatorInstance<ThreadPoolAllocator>::Destroy();
|
||||
AllocatorInstance<PoolAllocator>::Destroy();
|
||||
AllocatorsFixture::TearDown();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(InstanceDatabaseTestWithMultipleSubclasses, InstanceCreate)
|
||||
{
|
||||
auto& assetManager = AssetManager::Instance();
|
||||
auto& instanceDatabase = InstanceDatabase<BaseInstance>::Instance();
|
||||
|
||||
Asset<FooAsset> fooAsset = assetManager.CreateAsset<FooAsset>(s_assetId0, AZ::Data::AssetLoadBehavior::Default);
|
||||
Asset<BarAsset> barAsset = assetManager.CreateAsset<BarAsset>(s_assetId1, AZ::Data::AssetLoadBehavior::Default);
|
||||
|
||||
// Run the creation tests on 'A' first.
|
||||
|
||||
Instance<BaseInstance> fooInstanceA = instanceDatabase.Find(s_instanceId0);
|
||||
EXPECT_EQ(fooInstanceA, nullptr);
|
||||
|
||||
Instance<BaseInstance> barInstanceA = instanceDatabase.Find(s_instanceId1);
|
||||
EXPECT_EQ(barInstanceA, nullptr);
|
||||
|
||||
fooInstanceA = instanceDatabase.FindOrCreate(s_instanceId0, fooAsset);
|
||||
EXPECT_NE(fooInstanceA, nullptr);
|
||||
EXPECT_EQ(fooInstanceA->m_asset, fooAsset);
|
||||
EXPECT_TRUE(azrtti_typeid<FooInstance>() == fooInstanceA->RTTI_GetType());
|
||||
EXPECT_EQ(fooInstanceA, instanceDatabase.Find(s_instanceId0));
|
||||
|
||||
barInstanceA = instanceDatabase.FindOrCreate(s_instanceId1, barAsset);
|
||||
EXPECT_NE(barInstanceA, nullptr);
|
||||
EXPECT_EQ(barInstanceA->m_asset, barAsset);
|
||||
EXPECT_TRUE(azrtti_typeid<BarInstance>() == barInstanceA->RTTI_GetType());
|
||||
EXPECT_EQ(barInstanceA, instanceDatabase.Find(s_instanceId1));
|
||||
|
||||
// Run the same test on 'B' to make sure it works independently.
|
||||
|
||||
Instance<BaseInstance> fooInstanceB = instanceDatabase.Find(s_instanceId2);
|
||||
EXPECT_EQ(fooInstanceB, nullptr);
|
||||
|
||||
Instance<BaseInstance> barInstanceB = instanceDatabase.Find(s_instanceId3);
|
||||
EXPECT_EQ(barInstanceB, nullptr);
|
||||
|
||||
fooInstanceB = instanceDatabase.FindOrCreate(s_instanceId2, fooAsset);
|
||||
EXPECT_NE(fooInstanceB, nullptr);
|
||||
EXPECT_EQ(fooInstanceB->m_asset, fooAsset);
|
||||
EXPECT_TRUE(azrtti_typeid<FooInstance>() == fooInstanceB->RTTI_GetType());
|
||||
EXPECT_EQ(fooInstanceB, instanceDatabase.Find(s_instanceId2));
|
||||
|
||||
barInstanceB = instanceDatabase.FindOrCreate(s_instanceId3, barAsset);
|
||||
EXPECT_NE(barInstanceB, nullptr);
|
||||
EXPECT_EQ(barInstanceB->m_asset, barAsset);
|
||||
EXPECT_TRUE(azrtti_typeid<BarInstance>() == barInstanceB->RTTI_GetType());
|
||||
EXPECT_EQ(barInstanceB, instanceDatabase.Find(s_instanceId3));
|
||||
|
||||
// Make sure the instances are unique
|
||||
|
||||
EXPECT_NE(fooInstanceA, fooInstanceB);
|
||||
EXPECT_NE(barInstanceA, barInstanceB);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTestWithMultipleSubclasses, TestError_AddHandler_AssetTypeIsNotSubclass)
|
||||
{
|
||||
MyAssetHandler<TestAssetType> testAssetHandler;
|
||||
AssetManager::Instance().RegisterHandler(&testAssetHandler, azrtti_typeid<TestAssetType>());
|
||||
|
||||
// Register an instance handler with an unrelated asset type. This can't actually
|
||||
// check the AssetType yet because all it has are AssetType GUIDs, no actual data.
|
||||
{
|
||||
InstanceHandler<BaseInstance> instanceHandler;
|
||||
instanceHandler.m_createFunction = [](AssetData* assetData)
|
||||
{
|
||||
return aznew BaseInstance(static_cast<BaseAsset*>(assetData));
|
||||
};
|
||||
|
||||
AssetType unrelatedAssetType = azrtti_typeid<TestAssetType>();
|
||||
|
||||
InstanceDatabase<BaseInstance>::Instance().AddHandler(unrelatedAssetType, instanceHandler);
|
||||
}
|
||||
|
||||
// Try to use the unrelated handler. This is where we'll actually get an error.
|
||||
{
|
||||
AZ_TEST_START_ASSERTTEST;
|
||||
|
||||
Asset<TestAssetType> testAsset = AssetManager::Instance().CreateAsset<TestAssetType>(s_assetId0, AZ::Data::AssetLoadBehavior::Default);
|
||||
|
||||
EXPECT_EQ(nullptr, InstanceDatabase<BaseInstance>::Instance().FindOrCreate(s_instanceId0, testAsset));
|
||||
|
||||
AZ_TEST_STOP_ASSERTTEST(1);
|
||||
}
|
||||
|
||||
AssetManager::Instance().UnregisterHandler(&testAssetHandler);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTestWithMultipleSubclasses, TestError_AddHandler_AlreadyExists)
|
||||
{
|
||||
InstanceHandler<BaseInstance> instanceHandler;
|
||||
instanceHandler.m_createFunction = [](AssetData*)
|
||||
{
|
||||
return nullptr; // Doesn't matter
|
||||
};
|
||||
|
||||
AZ_TEST_START_ASSERTTEST;
|
||||
|
||||
// The SetUp() function already registered a handler for FooAsset so this should fail
|
||||
InstanceDatabase<BaseInstance>::Instance().AddHandler(azrtti_typeid<FooAsset>(), instanceHandler);
|
||||
InstanceDatabase<BaseInstance>::Instance().AddHandler(azrtti_typeid<FooAsset>(), [](AssetData*) { return nullptr; });
|
||||
|
||||
AZ_TEST_STOP_ASSERTTEST(2);
|
||||
}
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
Reference in New Issue
Block a user