xref: /aosp_15_r20/external/angle/src/libANGLE/TransformFeedback_unittest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "gmock/gmock.h"
8*8975f5c5SAndroid Build Coastguard Worker #include "gtest/gtest.h"
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Buffer.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Caps.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/TransformFeedback.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/BufferImpl_mock.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/TransformFeedbackImpl_mock.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "tests/angle_unittests_utils.h"
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker using ::testing::_;
18*8975f5c5SAndroid Build Coastguard Worker using ::testing::get;
19*8975f5c5SAndroid Build Coastguard Worker using ::testing::Return;
20*8975f5c5SAndroid Build Coastguard Worker using ::testing::SetArgumentPointee;
21*8975f5c5SAndroid Build Coastguard Worker 
22*8975f5c5SAndroid Build Coastguard Worker namespace
23*8975f5c5SAndroid Build Coastguard Worker {
24*8975f5c5SAndroid Build Coastguard Worker 
ACTION(CreateMockTransformFeedbackImpl)25*8975f5c5SAndroid Build Coastguard Worker ACTION(CreateMockTransformFeedbackImpl)
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker     return new rx::MockTransformFeedbackImpl(arg0);
28*8975f5c5SAndroid Build Coastguard Worker }
29*8975f5c5SAndroid Build Coastguard Worker 
30*8975f5c5SAndroid Build Coastguard Worker class TransformFeedbackTest : public testing::Test
31*8975f5c5SAndroid Build Coastguard Worker {
32*8975f5c5SAndroid Build Coastguard Worker   protected:
TransformFeedbackTest()33*8975f5c5SAndroid Build Coastguard Worker     TransformFeedbackTest() : mImpl(nullptr), mFeedback(nullptr) {}
34*8975f5c5SAndroid Build Coastguard Worker 
SetUp()35*8975f5c5SAndroid Build Coastguard Worker     void SetUp() override
36*8975f5c5SAndroid Build Coastguard Worker     {
37*8975f5c5SAndroid Build Coastguard Worker         EXPECT_CALL(mMockFactory, createTransformFeedback(_))
38*8975f5c5SAndroid Build Coastguard Worker             .WillOnce(CreateMockTransformFeedbackImpl())
39*8975f5c5SAndroid Build Coastguard Worker             .RetiresOnSaturation();
40*8975f5c5SAndroid Build Coastguard Worker 
41*8975f5c5SAndroid Build Coastguard Worker         // Set a reasonable number of tf attributes
42*8975f5c5SAndroid Build Coastguard Worker         mCaps.maxTransformFeedbackSeparateAttributes = 8;
43*8975f5c5SAndroid Build Coastguard Worker 
44*8975f5c5SAndroid Build Coastguard Worker         mFeedback = new gl::TransformFeedback(&mMockFactory, gl::TransformFeedbackID{1}, mCaps);
45*8975f5c5SAndroid Build Coastguard Worker         mFeedback->addRef();
46*8975f5c5SAndroid Build Coastguard Worker 
47*8975f5c5SAndroid Build Coastguard Worker         mImpl = rx::GetImplAs<rx::MockTransformFeedbackImpl>(mFeedback);
48*8975f5c5SAndroid Build Coastguard Worker         EXPECT_CALL(*mImpl, destructor());
49*8975f5c5SAndroid Build Coastguard Worker     }
50*8975f5c5SAndroid Build Coastguard Worker 
TearDown()51*8975f5c5SAndroid Build Coastguard Worker     void TearDown() override
52*8975f5c5SAndroid Build Coastguard Worker     {
53*8975f5c5SAndroid Build Coastguard Worker         if (mFeedback)
54*8975f5c5SAndroid Build Coastguard Worker         {
55*8975f5c5SAndroid Build Coastguard Worker             mFeedback->release(nullptr);
56*8975f5c5SAndroid Build Coastguard Worker         }
57*8975f5c5SAndroid Build Coastguard Worker 
58*8975f5c5SAndroid Build Coastguard Worker         // Only needed because the mock is leaked if bugs are present,
59*8975f5c5SAndroid Build Coastguard Worker         // which logs an error, but does not cause the test to fail.
60*8975f5c5SAndroid Build Coastguard Worker         // Ordinarily mocks are verified when destroyed.
61*8975f5c5SAndroid Build Coastguard Worker         testing::Mock::VerifyAndClear(mImpl);
62*8975f5c5SAndroid Build Coastguard Worker     }
63*8975f5c5SAndroid Build Coastguard Worker 
64*8975f5c5SAndroid Build Coastguard Worker     rx::MockGLFactory mMockFactory;
65*8975f5c5SAndroid Build Coastguard Worker     rx::MockTransformFeedbackImpl *mImpl;
66*8975f5c5SAndroid Build Coastguard Worker     gl::TransformFeedback *mFeedback;
67*8975f5c5SAndroid Build Coastguard Worker     gl::Caps mCaps;
68*8975f5c5SAndroid Build Coastguard Worker };
69*8975f5c5SAndroid Build Coastguard Worker 
TEST_F(TransformFeedbackTest,SideEffectsOfStartAndStop)70*8975f5c5SAndroid Build Coastguard Worker TEST_F(TransformFeedbackTest, SideEffectsOfStartAndStop)
71*8975f5c5SAndroid Build Coastguard Worker {
72*8975f5c5SAndroid Build Coastguard Worker     testing::InSequence seq;
73*8975f5c5SAndroid Build Coastguard Worker 
74*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(mFeedback->isActive());
75*8975f5c5SAndroid Build Coastguard Worker     EXPECT_CALL(*mImpl, begin(nullptr, gl::PrimitiveMode::Triangles));
76*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(angle::Result::Continue,
77*8975f5c5SAndroid Build Coastguard Worker               mFeedback->begin(nullptr, gl::PrimitiveMode::Triangles, nullptr));
78*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(mFeedback->isActive());
79*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(gl::PrimitiveMode::Triangles, mFeedback->getPrimitiveMode());
80*8975f5c5SAndroid Build Coastguard Worker     EXPECT_CALL(*mImpl, end(nullptr));
81*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(angle::Result::Continue, mFeedback->end(nullptr));
82*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(mFeedback->isActive());
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker 
TEST_F(TransformFeedbackTest,SideEffectsOfPauseAndResume)85*8975f5c5SAndroid Build Coastguard Worker TEST_F(TransformFeedbackTest, SideEffectsOfPauseAndResume)
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker     testing::InSequence seq;
88*8975f5c5SAndroid Build Coastguard Worker 
89*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(mFeedback->isActive());
90*8975f5c5SAndroid Build Coastguard Worker     EXPECT_CALL(*mImpl, begin(nullptr, gl::PrimitiveMode::Triangles));
91*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(angle::Result::Continue,
92*8975f5c5SAndroid Build Coastguard Worker               mFeedback->begin(nullptr, gl::PrimitiveMode::Triangles, nullptr));
93*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(mFeedback->isPaused());
94*8975f5c5SAndroid Build Coastguard Worker     EXPECT_CALL(*mImpl, pause(nullptr));
95*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(angle::Result::Continue, mFeedback->pause(nullptr));
96*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(mFeedback->isPaused());
97*8975f5c5SAndroid Build Coastguard Worker     EXPECT_CALL(*mImpl, resume(nullptr));
98*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(angle::Result::Continue, mFeedback->resume(nullptr));
99*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(mFeedback->isPaused());
100*8975f5c5SAndroid Build Coastguard Worker     EXPECT_CALL(*mImpl, end(nullptr));
101*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(angle::Result::Continue, mFeedback->end(nullptr));
102*8975f5c5SAndroid Build Coastguard Worker }
103*8975f5c5SAndroid Build Coastguard Worker 
TEST_F(TransformFeedbackTest,BufferBinding)104*8975f5c5SAndroid Build Coastguard Worker TEST_F(TransformFeedbackTest, BufferBinding)
105*8975f5c5SAndroid Build Coastguard Worker {
106*8975f5c5SAndroid Build Coastguard Worker     rx::MockBufferImpl *bufferImpl = new rx::MockBufferImpl;
107*8975f5c5SAndroid Build Coastguard Worker     EXPECT_CALL(*bufferImpl, destructor()).Times(1).RetiresOnSaturation();
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker     rx::MockGLFactory mockGLFactory;
110*8975f5c5SAndroid Build Coastguard Worker     EXPECT_CALL(mockGLFactory, createBuffer(_))
111*8975f5c5SAndroid Build Coastguard Worker         .Times(1)
112*8975f5c5SAndroid Build Coastguard Worker         .WillOnce(Return(bufferImpl))
113*8975f5c5SAndroid Build Coastguard Worker         .RetiresOnSaturation();
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker     gl::Buffer *buffer = new gl::Buffer(&mockGLFactory, {1});
116*8975f5c5SAndroid Build Coastguard Worker 
117*8975f5c5SAndroid Build Coastguard Worker     static const size_t bindIndex = 0;
118*8975f5c5SAndroid Build Coastguard Worker 
119*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(mFeedback->getIndexedBufferCount(),
120*8975f5c5SAndroid Build Coastguard Worker               static_cast<GLuint>(mCaps.maxTransformFeedbackSeparateAttributes));
121*8975f5c5SAndroid Build Coastguard Worker 
122*8975f5c5SAndroid Build Coastguard Worker     EXPECT_CALL(*mImpl, bindIndexedBuffer(_, _, _));
123*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(angle::Result::Continue,
124*8975f5c5SAndroid Build Coastguard Worker               mFeedback->bindIndexedBuffer(nullptr, bindIndex, buffer, 0, 1));
125*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < mFeedback->getIndexedBufferCount(); i++)
126*8975f5c5SAndroid Build Coastguard Worker     {
127*8975f5c5SAndroid Build Coastguard Worker         if (i == bindIndex)
128*8975f5c5SAndroid Build Coastguard Worker         {
129*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(mFeedback->getIndexedBuffer(i).get(), buffer);
130*8975f5c5SAndroid Build Coastguard Worker         }
131*8975f5c5SAndroid Build Coastguard Worker         else
132*8975f5c5SAndroid Build Coastguard Worker         {
133*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(mFeedback->getIndexedBuffer(i).get(), nullptr);
134*8975f5c5SAndroid Build Coastguard Worker         }
135*8975f5c5SAndroid Build Coastguard Worker     }
136*8975f5c5SAndroid Build Coastguard Worker 
137*8975f5c5SAndroid Build Coastguard Worker     // force-release the feedback object to ensure the buffer is released.
138*8975f5c5SAndroid Build Coastguard Worker     const size_t releaseCount = mFeedback->getRefCount();
139*8975f5c5SAndroid Build Coastguard Worker     for (size_t count = 0; count < releaseCount; ++count)
140*8975f5c5SAndroid Build Coastguard Worker     {
141*8975f5c5SAndroid Build Coastguard Worker         mFeedback->release(nullptr);
142*8975f5c5SAndroid Build Coastguard Worker     }
143*8975f5c5SAndroid Build Coastguard Worker 
144*8975f5c5SAndroid Build Coastguard Worker     mFeedback = nullptr;
145*8975f5c5SAndroid Build Coastguard Worker 
146*8975f5c5SAndroid Build Coastguard Worker     testing::Mock::VerifyAndClear(bufferImpl);
147*8975f5c5SAndroid Build Coastguard Worker }
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
150