1 // copyright (c) 2022 the android open source project
2 //
3 // licensed under the apache license, version 2.0 (the "license");
4 // you may not use this file except in compliance with the license.
5 // you may obtain a copy of the license at
6 //
7 // http://www.apache.org/licenses/license-2.0
8 //
9 // unless required by applicable law or agreed to in writing, software
10 // distributed under the license is distributed on an "as is" basis,
11 // without warranties or conditions of any kind, either express or implied.
12 // see the license for the specific language governing permissions and
13 // limitations under the license.
14
15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
17
18 #include "VkDecoderGlobalState.cpp"
19
20 #include "aemu/base/testing/TestUtils.h"
21
22 namespace gfxstream {
23 namespace vk {
24 namespace {
25 using ::testing::_;
26 using ::testing::InSequence;
27 using ::testing::MockFunction;
28 using ::testing::Return;
29 using ::testing::Test;
30 using ::testing::UnorderedElementsAre;
31
32 class VkDecoderGlobalStateExternalFenceTest : public Test {
33 protected:
34 class MockDispatch {
35 public:
36 MOCK_METHOD(VkResult, vkGetFenceStatus, (VkDevice device, VkFence fence), ());
37 MOCK_METHOD(VkResult,
38 vkResetFences,
39 (VkDevice device, uint32_t numFences, const VkFence* fence),
40 ());
41 };
42
VkDecoderGlobalStateExternalFenceTest()43 VkDecoderGlobalStateExternalFenceTest()
44 : mDevice(reinterpret_cast<VkDevice>(0x2222'0000)), mPool(&mMockDispatch, mDevice) {}
45
~VkDecoderGlobalStateExternalFenceTest()46 ~VkDecoderGlobalStateExternalFenceTest() {
47 mPool.popAll();
48 }
49
50 MockDispatch mMockDispatch;
51 VkDevice mDevice;
52 ExternalFencePool<MockDispatch> mPool;
53 };
54
55 using VkDecoderGlobalStateExternalFenceDeathTest = VkDecoderGlobalStateExternalFenceTest;
56
TEST_F(VkDecoderGlobalStateExternalFenceTest,poolNoDeviceFences)57 TEST_F(VkDecoderGlobalStateExternalFenceTest, poolNoDeviceFences) {
58 VkFenceCreateInfo createInfo{
59 .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
60 .pNext = 0,
61 .flags = 0,
62 };
63 ASSERT_EQ(VK_NULL_HANDLE, mPool.pop(&createInfo));
64 }
65
TEST_F(VkDecoderGlobalStateExternalFenceTest,poolReuseSignalledFence)66 TEST_F(VkDecoderGlobalStateExternalFenceTest, poolReuseSignalledFence) {
67 {
68 InSequence s;
69 EXPECT_CALL(mMockDispatch, vkGetFenceStatus(_, _)).WillOnce(Return(VK_SUCCESS));
70 EXPECT_CALL(mMockDispatch, vkResetFences(_, _, _)).WillOnce(Return(VK_SUCCESS));
71 }
72
73 VkFence fence = reinterpret_cast<VkFence>(0x1234'0000);
74 VkFenceCreateInfo createInfo{
75 .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
76 .pNext = 0,
77 .flags = 0,
78 };
79 mPool.add(fence);
80 VkFence reusedFence = mPool.pop(&createInfo);
81
82 ASSERT_EQ(fence, reusedFence);
83 }
84
TEST_F(VkDecoderGlobalStateExternalFenceTest,poolReuseSignalledFenceAsSignaled)85 TEST_F(VkDecoderGlobalStateExternalFenceTest, poolReuseSignalledFenceAsSignaled) {
86 {
87 InSequence s;
88 EXPECT_CALL(mMockDispatch, vkGetFenceStatus(_, _)).WillOnce(Return(VK_SUCCESS));
89 EXPECT_CALL(mMockDispatch, vkResetFences(_, _, _)).Times(0);
90 }
91
92 VkFence fence = reinterpret_cast<VkFence>(0x1234'0000);
93 VkFenceCreateInfo createInfo{
94 .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
95 .pNext = 0,
96 .flags = VK_FENCE_CREATE_SIGNALED_BIT,
97 };
98 mPool.add(fence);
99 VkFence reusedFence = mPool.pop(&createInfo);
100
101 ASSERT_EQ(fence, reusedFence);
102 }
103
TEST_F(VkDecoderGlobalStateExternalFenceTest,poolUnsignalledFence)104 TEST_F(VkDecoderGlobalStateExternalFenceTest, poolUnsignalledFence) {
105 {
106 InSequence s;
107 EXPECT_CALL(mMockDispatch, vkGetFenceStatus(_, _)).WillOnce(Return(VK_NOT_READY));
108 EXPECT_CALL(mMockDispatch, vkResetFences(_, _, _)).Times(0);
109 }
110
111 VkFence fence = reinterpret_cast<VkFence>(0x1234'0000);
112 VkFenceCreateInfo createInfo{
113 .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
114 .pNext = 0,
115 .flags = 0,
116 };
117 mPool.add(fence);
118
119 ASSERT_EQ(VK_NULL_HANDLE, mPool.pop(&createInfo));
120 }
121
TEST_F(VkDecoderGlobalStateExternalFenceTest,poolPopAll)122 TEST_F(VkDecoderGlobalStateExternalFenceTest, poolPopAll) {
123 VkFence fence1 = reinterpret_cast<VkFence>(0x1234'0000);
124 VkFence fence2 = reinterpret_cast<VkFence>(0x2234'0000);
125 VkFence fence3 = reinterpret_cast<VkFence>(0x3234'0000);
126 mPool.add(fence1);
127 mPool.add(fence2);
128 mPool.add(fence3);
129
130 std::vector<VkFence> result = mPool.popAll();
131 ASSERT_THAT(result, UnorderedElementsAre(fence1, fence2, fence3));
132 }
133
TEST_F(VkDecoderGlobalStateExternalFenceDeathTest,undestroyedFences)134 TEST_F(VkDecoderGlobalStateExternalFenceDeathTest, undestroyedFences) {
135 ASSERT_DEATH(
136 {
137 ExternalFencePool<MockDispatch> pool(&mMockDispatch, mDevice);
138 VkFence fence = reinterpret_cast<VkFence>(0x1234'0000);
139 pool.add(fence);
140 },
141 MatchesStdRegex(
142 "External fence pool for device 0000000022220000|0x22220000 destroyed but 1 "
143 "fences still not destroyed."));
144 }
145
146 } // namespace
147 } // namespace vk
148 } // namespace gfxstream
149