Implement render graph compiler and transient fullscreen execution
This commit is contained in:
@@ -285,6 +285,98 @@ private:
|
||||
XCEngine::RHI::RHIDeviceInfo m_deviceInfo = {};
|
||||
};
|
||||
|
||||
class MockNoopCommandList final : public XCEngine::RHI::RHICommandList {
|
||||
public:
|
||||
void Shutdown() override {}
|
||||
void Reset() override {}
|
||||
void Close() override {}
|
||||
|
||||
void TransitionBarrier(
|
||||
XCEngine::RHI::RHIResourceView*,
|
||||
XCEngine::RHI::ResourceStates,
|
||||
XCEngine::RHI::ResourceStates) override {
|
||||
}
|
||||
|
||||
void BeginRenderPass(
|
||||
XCEngine::RHI::RHIRenderPass*,
|
||||
XCEngine::RHI::RHIFramebuffer*,
|
||||
const XCEngine::RHI::Rect&,
|
||||
uint32_t,
|
||||
const XCEngine::RHI::ClearValue*) override {
|
||||
}
|
||||
|
||||
void EndRenderPass() override {}
|
||||
void SetShader(XCEngine::RHI::RHIShader*) override {}
|
||||
void SetPipelineState(XCEngine::RHI::RHIPipelineState*) override {}
|
||||
void SetGraphicsDescriptorSets(
|
||||
uint32_t,
|
||||
uint32_t,
|
||||
XCEngine::RHI::RHIDescriptorSet**,
|
||||
XCEngine::RHI::RHIPipelineLayout*) override {
|
||||
}
|
||||
void SetComputeDescriptorSets(
|
||||
uint32_t,
|
||||
uint32_t,
|
||||
XCEngine::RHI::RHIDescriptorSet**,
|
||||
XCEngine::RHI::RHIPipelineLayout*) override {
|
||||
}
|
||||
void SetPrimitiveTopology(XCEngine::RHI::PrimitiveTopology) override {}
|
||||
void SetViewport(const XCEngine::RHI::Viewport&) override {}
|
||||
void SetViewports(uint32_t, const XCEngine::RHI::Viewport*) override {}
|
||||
void SetScissorRect(const XCEngine::RHI::Rect&) override {}
|
||||
void SetScissorRects(uint32_t, const XCEngine::RHI::Rect*) override {}
|
||||
void SetRenderTargets(
|
||||
uint32_t,
|
||||
XCEngine::RHI::RHIResourceView**,
|
||||
XCEngine::RHI::RHIResourceView*) override {
|
||||
}
|
||||
void SetStencilRef(uint8_t) override {}
|
||||
void SetBlendFactor(const float[4]) override {}
|
||||
void SetVertexBuffers(
|
||||
uint32_t,
|
||||
uint32_t,
|
||||
XCEngine::RHI::RHIResourceView**,
|
||||
const uint64_t*,
|
||||
const uint32_t*) override {
|
||||
}
|
||||
void SetIndexBuffer(XCEngine::RHI::RHIResourceView*, uint64_t) override {}
|
||||
void Draw(uint32_t, uint32_t, uint32_t, uint32_t) override {}
|
||||
void DrawIndexed(uint32_t, uint32_t, uint32_t, int32_t, uint32_t) override {}
|
||||
void Clear(float, float, float, float, uint32_t) override {}
|
||||
void ClearRenderTarget(
|
||||
XCEngine::RHI::RHIResourceView*,
|
||||
const float[4],
|
||||
uint32_t,
|
||||
const XCEngine::RHI::Rect*) override {
|
||||
}
|
||||
void ClearDepthStencil(
|
||||
XCEngine::RHI::RHIResourceView*,
|
||||
float,
|
||||
uint8_t,
|
||||
uint32_t,
|
||||
const XCEngine::RHI::Rect*) override {
|
||||
}
|
||||
void CopyResource(XCEngine::RHI::RHIResourceView*, XCEngine::RHI::RHIResourceView*) override {}
|
||||
void Dispatch(uint32_t, uint32_t, uint32_t) override {}
|
||||
};
|
||||
|
||||
class MockNoopCommandQueue final : public XCEngine::RHI::RHICommandQueue {
|
||||
public:
|
||||
void Shutdown() override {}
|
||||
void ExecuteCommandLists(uint32_t, void**) override {}
|
||||
void Signal(XCEngine::RHI::RHIFence*, uint64_t) override {}
|
||||
void Wait(XCEngine::RHI::RHIFence*, uint64_t) override {}
|
||||
uint64_t GetCompletedValue() override { return 0u; }
|
||||
void WaitForIdle() override {}
|
||||
XCEngine::RHI::CommandQueueType GetType() const override {
|
||||
return XCEngine::RHI::CommandQueueType::Direct;
|
||||
}
|
||||
uint64_t GetTimestampFrequency() const override { return 0u; }
|
||||
void* GetNativeHandle() override { return nullptr; }
|
||||
void WaitForPreviousFrame() override {}
|
||||
uint64_t GetCurrentFrame() const override { return 0u; }
|
||||
};
|
||||
|
||||
struct MockPipelineAssetState {
|
||||
int createCalls = 0;
|
||||
std::shared_ptr<MockPipelineState> lastCreatedPipelineState;
|
||||
@@ -516,10 +608,13 @@ public:
|
||||
};
|
||||
|
||||
RenderContext CreateValidContext() {
|
||||
static MockNoopCommandList s_commandList;
|
||||
static MockNoopCommandQueue s_commandQueue;
|
||||
|
||||
RenderContext context;
|
||||
context.device = reinterpret_cast<XCEngine::RHI::RHIDevice*>(1);
|
||||
context.commandList = reinterpret_cast<XCEngine::RHI::RHICommandList*>(1);
|
||||
context.commandQueue = reinterpret_cast<XCEngine::RHI::RHICommandQueue*>(1);
|
||||
context.commandList = &s_commandList;
|
||||
context.commandQueue = &s_commandQueue;
|
||||
return context;
|
||||
}
|
||||
|
||||
@@ -688,7 +783,7 @@ TEST(CameraRenderer_Test, UsesOverrideCameraAndSurfaceSizeWhenSubmittingScene) {
|
||||
request.cameraDepth = overrideCamera->GetDepth();
|
||||
request.clearFlags = RenderClearFlags::None;
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(state->renderCalls, 1);
|
||||
EXPECT_EQ(state->lastSurfaceWidth, 640u);
|
||||
EXPECT_EQ(state->lastSurfaceHeight, 480u);
|
||||
@@ -728,7 +823,7 @@ TEST(CameraRenderer_Test, AppliesRequestClearColorOverrideToSceneData) {
|
||||
request.hasClearColorOverride = true;
|
||||
request.clearColorOverride = XCEngine::Math::Color(0.27f, 0.27f, 0.27f, 1.0f);
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_FLOAT_EQ(state->lastClearColor.r, 0.27f);
|
||||
EXPECT_FLOAT_EQ(state->lastClearColor.g, 0.27f);
|
||||
EXPECT_FLOAT_EQ(state->lastClearColor.b, 0.27f);
|
||||
@@ -756,7 +851,7 @@ TEST(CameraRenderer_Test, PromotesSkyboxMaterialIntoEnvironmentFrameData) {
|
||||
request.surface = RenderSurface(320, 200);
|
||||
request.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1));
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_TRUE(state->lastHasSkybox);
|
||||
EXPECT_EQ(state->lastEnvironmentMode, RenderEnvironmentMode::MaterialSkybox);
|
||||
EXPECT_EQ(state->lastSkyboxMaterial, &skyboxMaterial);
|
||||
@@ -788,7 +883,7 @@ TEST(CameraRenderer_Test, ExecutesInjectedPreAndPostPassSequencesAroundPipelineR
|
||||
request.preScenePasses = &prePasses;
|
||||
request.postScenePasses = &postPasses;
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{
|
||||
@@ -830,7 +925,7 @@ TEST(CameraRenderer_Test, ExecutesObjectIdPassBetweenPipelineAndPostPassesWhenRe
|
||||
request.objectId.surface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1));
|
||||
request.objectId.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(2));
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{
|
||||
@@ -883,7 +978,7 @@ TEST(CameraRenderer_Test, RoutesSceneColorThroughPostProcessAndFinalOutputStages
|
||||
request.finalOutput.destinationSurface = request.surface;
|
||||
request.finalOutput.passes = &finalOutputPasses;
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(state->lastSurfaceWidth, 256u);
|
||||
EXPECT_EQ(state->lastSurfaceHeight, 128u);
|
||||
EXPECT_EQ(state->lastCameraViewportWidth, 256u);
|
||||
@@ -970,7 +1065,7 @@ TEST(CameraRenderer_Test, ChainsMultiPassPostProcessThroughIntermediateSurface)
|
||||
request.postProcess.destinationSurface.SetColorAttachment(destinationColorAttachment);
|
||||
request.postProcess.passes = &postProcessPasses;
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
|
||||
ASSERT_NE(firstPassRaw, nullptr);
|
||||
EXPECT_TRUE(firstPassRaw->lastHasSourceSurface);
|
||||
@@ -1082,7 +1177,7 @@ TEST(CameraRenderer_Test, KeepsPostProcessAndFinalOutputScratchSurfacesIndepende
|
||||
request.finalOutput.destinationSurface.SetColorAttachment(finalOutputDestination);
|
||||
request.finalOutput.passes = &finalOutputPasses;
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
|
||||
ASSERT_NE(postSecondPassRaw, nullptr);
|
||||
EXPECT_EQ(postSecondPassRaw->lastSourceSurfaceWidth, 512u);
|
||||
@@ -1100,9 +1195,12 @@ TEST(CameraRenderer_Test, KeepsPostProcessAndFinalOutputScratchSurfacesIndepende
|
||||
EXPECT_EQ(allocationState->createTextureCalls, 2);
|
||||
EXPECT_EQ(allocationState->createRenderTargetViewCalls, 2);
|
||||
EXPECT_EQ(allocationState->createShaderViewCalls, 2);
|
||||
EXPECT_EQ(allocationState->shutdownTextureCalls, 0);
|
||||
EXPECT_EQ(allocationState->shutdownRenderTargetViewCalls, 0);
|
||||
EXPECT_EQ(allocationState->shutdownShaderViewCalls, 0);
|
||||
EXPECT_EQ(allocationState->shutdownTextureCalls, 2);
|
||||
EXPECT_EQ(allocationState->shutdownRenderTargetViewCalls, 2);
|
||||
EXPECT_EQ(allocationState->shutdownShaderViewCalls, 2);
|
||||
EXPECT_EQ(allocationState->destroyTextureCalls, 2);
|
||||
EXPECT_EQ(allocationState->destroyRenderTargetViewCalls, 2);
|
||||
EXPECT_EQ(allocationState->destroyShaderViewCalls, 2);
|
||||
EXPECT_EQ(
|
||||
pipelineState->eventLog,
|
||||
(std::vector<std::string>{
|
||||
@@ -1185,7 +1283,7 @@ TEST(CameraRenderer_Test, ExecutesFormalFrameStagesInDocumentedOrder) {
|
||||
request.objectId.surface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(6));
|
||||
request.objectId.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(7));
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{
|
||||
@@ -1245,7 +1343,7 @@ TEST(CameraRenderer_Test, ExecutesShadowCasterAndDepthOnlyRequestsBeforeMainPipe
|
||||
request.depthOnly.hasClearColorOverride = true;
|
||||
request.depthOnly.clearColorOverride = XCEngine::Math::Color(0.3f, 0.2f, 0.1f, 1.0f);
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{
|
||||
@@ -1309,7 +1407,7 @@ TEST(CameraRenderer_Test, AutoAllocatesDirectionalShadowSurfaceFromShadowPlan) {
|
||||
request.directionalShadow.cameraData.viewProjection =
|
||||
XCEngine::Math::Matrix4x4::Translation(XCEngine::Math::Vector3(11.0f, 12.0f, 13.0f));
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(
|
||||
pipelineState->eventLog,
|
||||
(std::vector<std::string>{
|
||||
@@ -1391,7 +1489,7 @@ TEST(CameraRenderer_Test, ReusesDirectionalShadowSurfaceWhenPlanMatches) {
|
||||
request.directionalShadow.cameraData.viewportHeight = 128;
|
||||
request.directionalShadow.cameraData.clearFlags = RenderClearFlags::Depth;
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
XCEngine::RHI::RHIResourceView* firstShadowMap = pipelineState->lastShadowMap;
|
||||
ASSERT_NE(firstShadowMap, nullptr);
|
||||
EXPECT_EQ(allocationState->createTextureCalls, 1);
|
||||
@@ -1400,7 +1498,7 @@ TEST(CameraRenderer_Test, ReusesDirectionalShadowSurfaceWhenPlanMatches) {
|
||||
EXPECT_EQ(allocationState->shutdownDepthViewCalls, 0);
|
||||
EXPECT_EQ(allocationState->destroyTextureCalls, 0);
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(allocationState->createTextureCalls, 1);
|
||||
EXPECT_EQ(allocationState->createDepthViewCalls, 1);
|
||||
EXPECT_EQ(allocationState->createShaderViewCalls, 1);
|
||||
@@ -1449,7 +1547,7 @@ TEST(CameraRenderer_Test, RecreatesDirectionalShadowSurfaceWhenPlanSizeChanges)
|
||||
request.directionalShadow.cameraData.viewportHeight = 128;
|
||||
request.directionalShadow.cameraData.clearFlags = RenderClearFlags::Depth;
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
XCEngine::RHI::RHIResourceView* firstShadowMap = pipelineState->lastShadowMap;
|
||||
ASSERT_NE(firstShadowMap, nullptr);
|
||||
|
||||
@@ -1458,7 +1556,7 @@ TEST(CameraRenderer_Test, RecreatesDirectionalShadowSurfaceWhenPlanSizeChanges)
|
||||
request.directionalShadow.cameraData.viewportWidth = 512;
|
||||
request.directionalShadow.cameraData.viewportHeight = 256;
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(allocationState->createTextureCalls, 2);
|
||||
EXPECT_EQ(allocationState->createDepthViewCalls, 2);
|
||||
EXPECT_EQ(allocationState->createShaderViewCalls, 2);
|
||||
@@ -1512,7 +1610,7 @@ TEST(CameraRenderer_Test, EnablesDirectionalShadowSurfaceAfterInitialFrameWithou
|
||||
request.surface = RenderSurface(320, 180);
|
||||
request.cameraDepth = camera->GetDepth();
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(pipelineState->eventLog, (std::vector<std::string>{ "pipeline" }));
|
||||
EXPECT_FALSE(pipelineState->lastHasMainDirectionalShadow);
|
||||
EXPECT_EQ(pipelineState->lastShadowMap, nullptr);
|
||||
@@ -1529,7 +1627,7 @@ TEST(CameraRenderer_Test, EnablesDirectionalShadowSurfaceAfterInitialFrameWithou
|
||||
request.directionalShadow.cameraData.viewportHeight = 128;
|
||||
request.directionalShadow.cameraData.clearFlags = RenderClearFlags::Depth;
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(
|
||||
pipelineState->eventLog,
|
||||
(std::vector<std::string>{
|
||||
@@ -1572,7 +1670,7 @@ TEST(CameraRenderer_Test, StopsRenderingWhenShadowCasterRequestIsInvalid) {
|
||||
request.shadowCaster.surface = RenderSurface(64, 64);
|
||||
request.shadowCaster.surface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1));
|
||||
|
||||
EXPECT_FALSE(renderer.Render(request));
|
||||
EXPECT_FALSE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_TRUE(state->eventLog.empty());
|
||||
}
|
||||
|
||||
@@ -1599,7 +1697,7 @@ TEST(CameraRenderer_Test, StopsRenderingWhenPostProcessRequestIsInvalid) {
|
||||
request.postProcess.destinationSurface = RenderSurface(320, 180);
|
||||
request.postProcess.destinationSurface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1));
|
||||
|
||||
EXPECT_FALSE(renderer.Render(request));
|
||||
EXPECT_FALSE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_TRUE(state->eventLog.empty());
|
||||
}
|
||||
|
||||
@@ -1626,7 +1724,7 @@ TEST(CameraRenderer_Test, ShutsDownInitializedPassesWhenPipelineRenderFails) {
|
||||
request.cameraDepth = camera->GetDepth();
|
||||
request.preScenePasses = &prePasses;
|
||||
|
||||
EXPECT_FALSE(renderer.Render(request));
|
||||
EXPECT_FALSE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{ "init:pre", "pre", "pipeline" }));
|
||||
@@ -1663,7 +1761,7 @@ TEST(CameraRenderer_Test, StopsRenderingWhenObjectIdPassFails) {
|
||||
request.objectId.surface.SetColorAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(1));
|
||||
request.objectId.surface.SetDepthAttachment(reinterpret_cast<XCEngine::RHI::RHIResourceView*>(2));
|
||||
|
||||
EXPECT_FALSE(renderer.Render(request));
|
||||
EXPECT_FALSE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{ "init:pre", "pre", "pipeline", "objectId" }));
|
||||
@@ -1695,7 +1793,7 @@ TEST(CameraRenderer_Test, ShutsDownSequencesWhenPostPassInitializationFails) {
|
||||
request.preScenePasses = &prePasses;
|
||||
request.postScenePasses = &postPasses;
|
||||
|
||||
EXPECT_FALSE(renderer.Render(request));
|
||||
EXPECT_FALSE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(
|
||||
state->eventLog,
|
||||
(std::vector<std::string>{
|
||||
@@ -2460,7 +2558,7 @@ TEST(CameraRenderer_Test, UsesResolvedRenderAreaForCameraViewportDimensions) {
|
||||
request.surface = RenderSurface(640, 480);
|
||||
request.surface.SetRenderArea(XCEngine::Math::RectInt(80, 120, 320, 240));
|
||||
|
||||
ASSERT_TRUE(renderer.Render(request));
|
||||
ASSERT_TRUE(renderer.Render(CameraFramePlan::FromRequest(request)));
|
||||
EXPECT_EQ(state->lastRenderAreaX, 80);
|
||||
EXPECT_EQ(state->lastRenderAreaY, 120);
|
||||
EXPECT_EQ(state->lastRenderAreaWidth, 320);
|
||||
@@ -2574,8 +2672,11 @@ TEST(SceneRenderer_Test, SortsManualCameraRequestsByDepthBeforeRendering) {
|
||||
nearRequest.cameraStackOrder = 0;
|
||||
nearRequest.clearFlags = RenderClearFlags::Depth;
|
||||
|
||||
const std::vector<CameraRenderRequest> requests = { farRequest, nearRequest };
|
||||
ASSERT_TRUE(renderer.Render(requests));
|
||||
const std::vector<CameraFramePlan> plans = {
|
||||
CameraFramePlan::FromRequest(farRequest),
|
||||
CameraFramePlan::FromRequest(nearRequest)
|
||||
};
|
||||
ASSERT_TRUE(renderer.Render(plans));
|
||||
ASSERT_EQ(state->renderedCameras.size(), 2u);
|
||||
ASSERT_EQ(state->renderedClearFlags.size(), 2u);
|
||||
EXPECT_EQ(state->renderedCameras[0], nearCamera);
|
||||
@@ -2612,8 +2713,11 @@ TEST(SceneRenderer_Test, PreservesManualSubmissionOrderForEqualPriorityRequests)
|
||||
CameraRenderRequest secondRequest = firstRequest;
|
||||
secondRequest.camera = secondCamera;
|
||||
|
||||
const std::vector<CameraRenderRequest> requests = { secondRequest, firstRequest };
|
||||
ASSERT_TRUE(renderer.Render(requests));
|
||||
const std::vector<CameraFramePlan> plans = {
|
||||
CameraFramePlan::FromRequest(secondRequest),
|
||||
CameraFramePlan::FromRequest(firstRequest)
|
||||
};
|
||||
ASSERT_TRUE(renderer.Render(plans));
|
||||
ASSERT_EQ(state->renderedCameras.size(), 2u);
|
||||
EXPECT_EQ(state->renderedCameras[0], secondCamera);
|
||||
EXPECT_EQ(state->renderedCameras[1], firstCamera);
|
||||
|
||||
Reference in New Issue
Block a user