@@ -93,6 +93,101 @@ TEST(TestingSwapChainBaseTest, ToleratesConfiguredImageDifferences)
9393
9494#if !PLATFORM_WEB
9595
96+ class ComparisonFailureImageGuard
97+ {
98+ public:
99+ ComparisonFailureImageGuard ()
100+ {
101+ const testing::TestInfo* const TestInfo = testing::UnitTest::GetInstance ()->current_test_info ();
102+ VERIFY_EXPR (TestInfo != nullptr );
103+ if (TestInfo != nullptr )
104+ m_FileName = std::string{TestInfo->test_suite_name ()} + " ." + TestInfo->name () + " _FAIL_.png" ;
105+ }
106+
107+ ~ComparisonFailureImageGuard ()
108+ {
109+ if (!m_FileName.empty ())
110+ FileSystem::DeleteFile (m_FileName.c_str ());
111+ }
112+
113+ // clang-format off
114+ ComparisonFailureImageGuard (const ComparisonFailureImageGuard&) = delete ;
115+ ComparisonFailureImageGuard& operator =(const ComparisonFailureImageGuard&) = delete ;
116+ // clang-format on
117+
118+ private:
119+ std::string m_FileName;
120+ };
121+
122+ void TestSnapshotComparisonFailure (Uint32 Channel)
123+ {
124+ ASSERT_LT (Channel, 4u );
125+
126+ GPUTestingEnvironment::ScopedReset AutoReset;
127+
128+ GPUTestingEnvironment* const pEnvironment = GPUTestingEnvironment::GetInstance ();
129+ IDeviceContext* const pContext = pEnvironment->GetDeviceContext ();
130+ ISwapChain* const pSwapChain = pEnvironment->GetSwapChain ();
131+ ASSERT_NE (pContext, nullptr );
132+ ASSERT_NE (pSwapChain, nullptr );
133+
134+ RefCntAutoPtr<ITestingSwapChain> pTestingSwapChain{pSwapChain, IID_TestingSwapChain};
135+ ASSERT_NE (pTestingSwapChain, nullptr );
136+
137+ const SwapChainDesc& SwapChainDesc = pSwapChain->GetDesc ();
138+ std::vector<Uint8> ReferencePixels (static_cast <size_t >(SwapChainDesc.Width ) * SwapChainDesc.Height * 4 , 255 );
139+ pTestingSwapChain->SetReferenceData (ReferencePixels.data ());
140+
141+ float ClearColor[] = {1 , 1 , 1 , 1 };
142+ ClearColor[Channel] = 0 ;
143+ ITextureView* pRTV = pSwapChain->GetCurrentBackBufferRTV ();
144+ pContext->SetRenderTargets (1 , &pRTV, nullptr , RESOURCE_STATE_TRANSITION_MODE_TRANSITION );
145+ pContext->ClearRenderTarget (pRTV, ClearColor, RESOURCE_STATE_TRANSITION_MODE_TRANSITION );
146+
147+ ComparisonFailureImageGuard FailureImageGuard;
148+ EXPECT_NONFATAL_FAILURE (
149+ pTestingSwapChain->CompareWithSnapshot (nullptr ),
150+ " Image rendered by the test differs from the reference image" );
151+ }
152+
153+ void TestImageComparisonFailure (Uint32 Channel)
154+ {
155+ ASSERT_LT (Channel, 3u );
156+
157+ GPUTestingEnvironment::ScopedReset AutoReset;
158+
159+ GPUTestingEnvironment* const pEnvironment = GPUTestingEnvironment::GetInstance ();
160+ IDeviceContext* const pContext = pEnvironment->GetDeviceContext ();
161+ ISwapChain* const pSwapChain = pEnvironment->GetSwapChain ();
162+ ASSERT_NE (pContext, nullptr );
163+ ASSERT_NE (pSwapChain, nullptr );
164+
165+ RefCntAutoPtr<ITestingSwapChain> pTestingSwapChain{pSwapChain, IID_TestingSwapChain};
166+ ASSERT_NE (pTestingSwapChain, nullptr );
167+
168+ const SwapChainDesc& SwapChainDesc = pSwapChain->GetDesc ();
169+ std::vector<Uint8> ReferencePixels (static_cast <size_t >(SwapChainDesc.Width ) * SwapChainDesc.Height * 4 , 255 );
170+
171+ TempDirectory TempDir{" TestingSwapChainBaseTest" };
172+ const std::string ImageName = TempDir.Get () + " /Reference" ;
173+ const std::string ImagePath = ImageName + " .png" ;
174+ DumpTestImage (ReferencePixels.data (), Uint64{SwapChainDesc.Width } * 4 ,
175+ SwapChainDesc.Width , SwapChainDesc.Height ,
176+ TEX_FORMAT_RGBA8_UNORM , ImageName.c_str (), false );
177+ ASSERT_TRUE (pTestingSwapChain->LoadReferenceImage (ImagePath.c_str ()));
178+
179+ float ClearColor[] = {1 , 1 , 1 , 1 };
180+ ClearColor[Channel] = 0 ;
181+ ITextureView* pRTV = pSwapChain->GetCurrentBackBufferRTV ();
182+ pContext->SetRenderTargets (1 , &pRTV, nullptr , RESOURCE_STATE_TRANSITION_MODE_TRANSITION );
183+ pContext->ClearRenderTarget (pRTV, ClearColor, RESOURCE_STATE_TRANSITION_MODE_TRANSITION );
184+
185+ ComparisonFailureImageGuard FailureImageGuard;
186+ EXPECT_NONFATAL_FAILURE (
187+ pTestingSwapChain->CompareWithSnapshot (nullptr ),
188+ " Image rendered by the test differs from the reference image" );
189+ }
190+
96191TEST (TestingSwapChainBaseTest, LoadsPNGAsRGBA8)
97192{
98193 constexpr Uint32 Width = 2 ;
@@ -105,11 +200,11 @@ TEST(TestingSwapChainBaseTest, LoadsPNGAsRGBA8)
105200 0 ,
106201 255 ,
107202 0 ,
108- 64 ,
203+ 85 ,
109204 0 ,
110205 0 ,
111206 255 ,
112- 128 ,
207+ 170 ,
113208 255 ,
114209 255 ,
115210 255 ,
@@ -122,6 +217,51 @@ TEST(TestingSwapChainBaseTest, LoadsPNGAsRGBA8)
122217 DumpTestImage (SourcePixels.data (), Width * 4 , Width, Height,
123218 TEX_FORMAT_RGBA8_UNORM , ImageName.c_str (), false );
124219
220+ std::vector<Uint8> LoadedPixels;
221+ Uint32 LoadedWidth = 0 ;
222+ Uint32 LoadedHeight = 0 ;
223+ ASSERT_TRUE (LoadTestImage (ImagePath.c_str (), LoadedPixels, LoadedWidth, LoadedHeight));
224+ EXPECT_EQ (LoadedWidth, Width);
225+ EXPECT_EQ (LoadedHeight, Height);
226+ EXPECT_EQ (LoadedPixels.size (), SourcePixels.size ());
227+ for (size_t Pixel = 0 ; Pixel < SourcePixels.size (); Pixel += 4 )
228+ {
229+ EXPECT_TRUE (std::equal (LoadedPixels.begin () + Pixel,
230+ LoadedPixels.begin () + Pixel + 3 ,
231+ SourcePixels.begin () + Pixel));
232+ EXPECT_EQ (LoadedPixels[Pixel + 3 ], 255 );
233+ }
234+ }
235+
236+ TEST (TestingSwapChainBaseTest, PreservesImageAlphaWhenRequested)
237+ {
238+ constexpr Uint32 Width = 2 ;
239+ constexpr Uint32 Height = 2 ;
240+ constexpr std::array<Uint8, Width * Height * 4 > SourcePixels{
241+ 255 ,
242+ 0 ,
243+ 0 ,
244+ 0 ,
245+ 0 ,
246+ 255 ,
247+ 0 ,
248+ 85 ,
249+ 0 ,
250+ 0 ,
251+ 255 ,
252+ 170 ,
253+ 255 ,
254+ 255 ,
255+ 255 ,
256+ 255 ,
257+ };
258+
259+ TempDirectory TempDir{" TestingSwapChainBaseTest" };
260+ const std::string ImageName = TempDir.Get () + " /ReferenceWithAlpha" ;
261+ const std::string ImagePath = ImageName + " .png" ;
262+ DumpTestImage (SourcePixels.data (), Width * 4 , Width, Height,
263+ TEX_FORMAT_RGBA8_UNORM , ImageName.c_str (), false , true );
264+
125265 std::vector<Uint8> LoadedPixels;
126266 Uint32 LoadedWidth = 0 ;
127267 Uint32 LoadedHeight = 0 ;
@@ -132,7 +272,7 @@ TEST(TestingSwapChainBaseTest, LoadsPNGAsRGBA8)
132272 EXPECT_TRUE (std::equal (LoadedPixels.begin (), LoadedPixels.end (), SourcePixels.begin ()));
133273}
134274
135- TEST (TestingSwapChainBaseTest, LoadsReferenceImageIntoSwapChain )
275+ TEST (TestingSwapChainBaseTest, ImageComparisonIgnoresAlphaDifference )
136276{
137277 GPUTestingEnvironment::ScopedReset AutoReset;
138278
@@ -146,14 +286,7 @@ TEST(TestingSwapChainBaseTest, LoadsReferenceImageIntoSwapChain)
146286 ASSERT_NE (pTestingSwapChain, nullptr );
147287
148288 const SwapChainDesc& SwapChainDesc = pSwapChain->GetDesc ();
149- std::vector<Uint8> ReferencePixels (static_cast <size_t >(SwapChainDesc.Width ) * SwapChainDesc.Height * 4 );
150- for (size_t Pixel = 0 ; Pixel < ReferencePixels.size (); Pixel += 4 )
151- {
152- ReferencePixels[Pixel + 0 ] = 255 ;
153- ReferencePixels[Pixel + 1 ] = 0 ;
154- ReferencePixels[Pixel + 2 ] = 0 ;
155- ReferencePixels[Pixel + 3 ] = 255 ;
156- }
289+ std::vector<Uint8> ReferencePixels (static_cast <size_t >(SwapChainDesc.Width ) * SwapChainDesc.Height * 4 , 255 );
157290
158291 TempDirectory TempDir{" TestingSwapChainBaseTest" };
159292 const std::string ImageName = TempDir.Get () + " /Reference" ;
@@ -163,50 +296,49 @@ TEST(TestingSwapChainBaseTest, LoadsReferenceImageIntoSwapChain)
163296 TEX_FORMAT_RGBA8_UNORM , ImageName.c_str (), false );
164297 ASSERT_TRUE (pTestingSwapChain->LoadReferenceImage (ImagePath.c_str ()));
165298
166- constexpr float ClearColor[] = {1 , 0 , 0 , 1 };
299+ // File references describe visible RGB output; render-target alpha is not
300+ // part of the comparison.
301+ constexpr float ClearColor[] = {1 , 1 , 1 , 0 };
167302 ITextureView* pRTV = pSwapChain->GetCurrentBackBufferRTV ();
168303 pContext->SetRenderTargets (1 , &pRTV, nullptr , RESOURCE_STATE_TRANSITION_MODE_TRANSITION );
169304 pContext->ClearRenderTarget (pRTV, ClearColor,
170305 RESOURCE_STATE_TRANSITION_MODE_TRANSITION );
171306 pTestingSwapChain->CompareWithSnapshot (nullptr );
172307}
173308
174- TEST (TestingSwapChainBaseTest, ReportsComparisonFailure )
309+ TEST (TestingSwapChainBaseTest, ReportsSnapshotRedComparisonFailure )
175310{
176- GPUTestingEnvironment::ScopedReset AutoReset;
177-
178- GPUTestingEnvironment* const pEnvironment = GPUTestingEnvironment::GetInstance ();
179- IDeviceContext* const pContext = pEnvironment->GetDeviceContext ();
180- ISwapChain* const pSwapChain = pEnvironment->GetSwapChain ();
181- ASSERT_NE (pContext, nullptr );
182- ASSERT_NE (pSwapChain, nullptr );
311+ TestSnapshotComparisonFailure (0 );
312+ }
183313
184- RefCntAutoPtr<ITestingSwapChain> pTestingSwapChain{pSwapChain, IID_TestingSwapChain};
185- ASSERT_NE (pTestingSwapChain, nullptr );
314+ TEST (TestingSwapChainBaseTest, ReportsSnapshotGreenComparisonFailure)
315+ {
316+ TestSnapshotComparisonFailure (1 );
317+ }
186318
187- const SwapChainDesc& SwapChainDesc = pSwapChain-> GetDesc ();
188- std::vector<Uint8> ReferencePixels ( static_cast < size_t >(SwapChainDesc. Width ) * SwapChainDesc. Height * 4 , 0 );
189- for ( size_t Pixel = 3 ; Pixel < ReferencePixels. size (); Pixel += 4 )
190- ReferencePixels[Pixel] = 255 ;
319+ TEST (TestingSwapChainBaseTest, ReportsSnapshotBlueComparisonFailure)
320+ {
321+ TestSnapshotComparisonFailure ( 2 );
322+ }
191323
192- TempDirectory TempDir{" TestingSwapChainBaseTest" };
193- const std::string ImageName = TempDir.Get () + " /Reference" ;
194- const std::string ImagePath = ImageName + " .png" ;
195- DumpTestImage (ReferencePixels.data (), Uint64{SwapChainDesc.Width } * 4 ,
196- SwapChainDesc.Width , SwapChainDesc.Height ,
197- TEX_FORMAT_RGBA8_UNORM , ImageName.c_str (), false );
198- ASSERT_TRUE (pTestingSwapChain->LoadReferenceImage (ImagePath.c_str ()));
324+ TEST (TestingSwapChainBaseTest, ReportsSnapshotAlphaComparisonFailure)
325+ {
326+ TestSnapshotComparisonFailure (3 );
327+ }
199328
200- constexpr float ClearColor[] = { 1 , 1 , 1 , 1 };
201- ITextureView* pRTV = pSwapChain-> GetCurrentBackBufferRTV ();
202- pContext-> SetRenderTargets ( 1 , &pRTV, nullptr , RESOURCE_STATE_TRANSITION_MODE_TRANSITION );
203- pContext-> ClearRenderTarget (pRTV, ClearColor, RESOURCE_STATE_TRANSITION_MODE_TRANSITION );
329+ TEST (TestingSwapChainBaseTest, ReportsImageRedComparisonFailure)
330+ {
331+ TestImageComparisonFailure ( 0 );
332+ }
204333
205- EXPECT_NONFATAL_FAILURE (
206- pTestingSwapChain->CompareWithSnapshot (nullptr ),
207- " Image rendered by the test differs from the reference image" );
334+ TEST (TestingSwapChainBaseTest, ReportsImageGreenComparisonFailure)
335+ {
336+ TestImageComparisonFailure (1 );
337+ }
208338
209- FileSystem::DeleteFile (" TestingSwapChainBaseTest.ReportsComparisonFailure_FAIL_.png" );
339+ TEST (TestingSwapChainBaseTest, ReportsImageBlueComparisonFailure)
340+ {
341+ TestImageComparisonFailure (2 );
210342}
211343
212344#endif
0 commit comments