1 /*
2 * Copyright (C) 2016 Intel Corporation. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sub license, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #include "test_va_api_fixture.h"
26
27 #include <functional>
28 #include <sstream>
29
30 namespace VAAPI
31 {
32
33 // The following tests will operate on supported profile/entrypoint
34 // combinations that the driver does support.
35
36 class VAAPISurfaceFixture
37 : public VAAPIFixtureSharedDisplay
38 {
39 public:
VAAPISurfaceFixture(const VAProfile & p,const VAEntrypoint & e)40 VAAPISurfaceFixture(const VAProfile& p, const VAEntrypoint& e)
41 : VAAPIFixtureSharedDisplay()
42 , profile(p)
43 , entrypoint(e)
44 { }
45
46 protected:
47 const VAProfile& profile;
48 const VAEntrypoint& entrypoint;
49
testWithSupportedConfigAttributes(const std::function<void (const ConfigAttributes &)> & test)50 void testWithSupportedConfigAttributes(
51 const std::function<void (const ConfigAttributes&)>& test)
52 {
53 ConfigAttributes supported;
54 getConfigAttributes(profile, entrypoint, supported);
55
56 // create config with each individual supported attribute
57 for (const auto& attrib : supported) {
58 const auto match = g_vaConfigAttribBitMasks.find(attrib.type);
59 if (match != g_vaConfigAttribBitMasks.end()) {
60 // it's a bitfield attribute
61 const BitMasks& masks = match->second;
62 for (const auto mask : masks) { // for all bitmasks
63 if ((attrib.value & mask) == mask) { // supported value
64 const ConfigAttributes attribs(
65 1, {/*type :*/ attrib.type, /*value :*/ mask });
66 SCOPED_TRACE(attribs.front());
67 createConfig(profile, entrypoint, attribs);
68 test(attribs);
69 destroyConfig();
70 }
71 }
72 } else {
73 // it's a standard attribute
74 const ConfigAttributes attribs(1, attrib);
75 SCOPED_TRACE(attribs.front());
76 createConfig(profile, entrypoint, attribs);
77 test(attribs);
78 destroyConfig();
79 }
80 }
81 }
82
testWithSupportedSurfaceAttributes(const std::function<void (const SurfaceAttributes &)> & test)83 void testWithSupportedSurfaceAttributes(
84 const std::function<void (const SurfaceAttributes&)>& test)
85 {
86 SurfaceAttributes supported;
87 querySurfaceAttributes(supported);
88
89 const uint32_t drmMemMask = VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM
90 | VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME
91 #if VA_CHECK_VERSION(1, 21, 0)
92 | VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_3
93 #endif
94 | VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2;
95
96 // create surfaces for each supported attribute
97 for (const auto& attrib : supported) {
98 const auto match = g_vaSurfaceAttribBitMasks.find(attrib.type);
99 if (match != g_vaSurfaceAttribBitMasks.end()) {
100 // it's a bitfield attribute
101 ASSERT_EQ(attrib.value.type, VAGenericValueTypeInteger);
102 uint32_t bitfield(0);
103 const BitMasks& masks = match->second;
104 for (const auto mask : masks) { // for all bitmasks
105 if ((attrib.value.value.i & mask) == mask) {
106 // supported value
107 bitfield |= mask;
108
109 if ((attrib.type == VASurfaceAttribMemoryType)
110 && (drmMemMask & mask) == mask) {
111 // skip drm memory types for now as it requires much
112 // more setup
113 continue;
114 } else {
115 VASurfaceAttrib maskAttrib = attrib;
116 maskAttrib.value.value.i = mask;
117 const SurfaceAttributes attribs = {maskAttrib,};
118 SCOPED_TRACE(attribs.front());
119 test(attribs);
120 }
121 }
122 }
123 // ensure we processed all supported values
124 EXPECT_EQ(bitfield, (uint32_t)attrib.value.value.i);
125 } else {
126 // it's a standard attribute
127 const SurfaceAttributes attribs = {attrib,};
128 SCOPED_TRACE(attribs.front());
129 test(attribs);
130 }
131 }
132 }
133 };
134
135 typedef ::testing::WithParamInterface <
136 std::tuple<VAProfile, VAEntrypoint> > QuerySurfacesParamInterface;
137
138 class VAAPIQuerySurfaces
139 : public QuerySurfacesParamInterface
140 , public VAAPISurfaceFixture
141 {
142 public:
VAAPIQuerySurfaces()143 VAAPIQuerySurfaces()
144 : QuerySurfacesParamInterface()
145 , VAAPISurfaceFixture(
146 ::testing::get<0>(GetParam()),
147 ::testing::get<1>(GetParam()))
148 { }
149 };
150
TEST_P(VAAPIQuerySurfaces,QuerySurfacesWithConfigAttribs)151 TEST_P(VAAPIQuerySurfaces, QuerySurfacesWithConfigAttribs)
152 {
153 if (!isSupported(profile, entrypoint)) {
154 skipTest(profile, entrypoint);
155 return;
156 }
157
158 const auto test = [&](const ConfigAttributes & ca) {
159 SurfaceAttributes attribs;
160 querySurfaceAttributes(attribs);
161 };
162
163 testWithSupportedConfigAttributes(test);
164 }
165
TEST_P(VAAPIQuerySurfaces,QuerySurfacesNoConfigAttribs)166 TEST_P(VAAPIQuerySurfaces, QuerySurfacesNoConfigAttribs)
167 {
168 if (!isSupported(profile, entrypoint)) {
169 skipTest(profile, entrypoint);
170 return;
171 }
172
173 createConfig(profile, entrypoint);
174 SurfaceAttributes attribs;
175 querySurfaceAttributes(attribs);
176 destroyConfig();
177 }
178
179 INSTANTIATE_TEST_SUITE_P(
180 QuerySurfaces, VAAPIQuerySurfaces,
181 ::testing::Combine(::testing::ValuesIn(g_vaProfiles),
182 ::testing::ValuesIn(g_vaEntrypoints)));
183
184 typedef typename ::testing::WithParamInterface<std::tuple<
185 VAProfile, VAEntrypoint, Resolution>> CreateSurfacesParamInterface;
186
187 class VAAPICreateSurfaces
188 : public CreateSurfacesParamInterface
189 , public VAAPISurfaceFixture
190 {
191 public:
VAAPICreateSurfaces()192 VAAPICreateSurfaces()
193 : CreateSurfacesParamInterface()
194 , VAAPISurfaceFixture(
195 ::testing::get<0>(GetParam()),
196 ::testing::get<1>(GetParam()))
197 , resolution(::testing::get<2>(GetParam()))
198 { }
199
200 protected:
201 const Resolution& resolution;
202 };
203
TEST_P(VAAPICreateSurfaces,CreateSurfacesWithConfigAttribs)204 TEST_P(VAAPICreateSurfaces, CreateSurfacesWithConfigAttribs)
205 {
206 if (!isSupported(profile, entrypoint)) {
207 skipTest(profile, entrypoint);
208 return;
209 }
210
211 // VA_RT_FORMAT_YUV420 is considered the universal supported format by
212 // drivers
213 unsigned format = VA_RT_FORMAT_YUV420;
214
215 const auto testSurfaces = [&](const SurfaceAttributes & attribs) {
216 Surfaces surfaces(10, VA_INVALID_SURFACE);
217 createSurfaces(surfaces, format, resolution, attribs);
218 destroySurfaces(surfaces);
219 };
220
221 const auto test = [&](const ConfigAttributes & attribs) {
222 const auto match = std::find_if(attribs.begin(), attribs.end(),
223 [](const VAConfigAttrib & a) {
224 return a.type == VAConfigAttribRTFormat;
225 });
226 if (match != attribs.end()) {
227 format = match->value;
228 }
229 testWithSupportedSurfaceAttributes(testSurfaces);
230
231 // reset format to default
232 format = VA_RT_FORMAT_YUV420;
233 };
234
235 testWithSupportedConfigAttributes(test);
236 }
237
TEST_P(VAAPICreateSurfaces,CreateSurfacesNoConfigAttrib)238 TEST_P(VAAPICreateSurfaces, CreateSurfacesNoConfigAttrib)
239 {
240 if (!isSupported(profile, entrypoint)) {
241 skipTest(profile, entrypoint);
242 return;
243 }
244
245 const auto test = [&](const SurfaceAttributes & attribs) {
246 Surfaces surfaces(10, VA_INVALID_SURFACE);
247 createSurfaces(surfaces, VA_RT_FORMAT_YUV420, resolution, attribs);
248 destroySurfaces(surfaces);
249 };
250
251 createConfig(profile, entrypoint);
252 testWithSupportedSurfaceAttributes(test);
253 destroyConfig();
254 }
255
TEST_P(VAAPICreateSurfaces,CreateSurfacesNoAttrib)256 TEST_P(VAAPICreateSurfaces, CreateSurfacesNoAttrib)
257 {
258 if (!isSupported(profile, entrypoint)) {
259 skipTest(profile, entrypoint);
260 return;
261 }
262
263 createConfig(profile, entrypoint);
264 Surfaces surfaces(10, VA_INVALID_SURFACE);
265 createSurfaces(surfaces, VA_RT_FORMAT_YUV420, resolution);
266 destroySurfaces(surfaces);
267 destroyConfig();
268 }
269
270 INSTANTIATE_TEST_SUITE_P(
271 CreateSurfaces, VAAPICreateSurfaces,
272 ::testing::Combine(::testing::ValuesIn(g_vaProfiles),
273 ::testing::ValuesIn(g_vaEntrypoints),
274 ::testing::ValuesIn(g_vaResolutions)));
275
276 } // namespace VAAPI
277