1 /*
2 * Copyright (c) 2018, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 #include "ddi_test_encode.h"
23 
24 using namespace std;
25 
TEST_F(MediaEncodeDdiTest,EncodeHEVC_DualPipe)26 TEST_F(MediaEncodeDdiTest, EncodeHEVC_DualPipe)
27 {
28     m_GpuCmdFactory = g_gpuCmdFactoryEncodeHevcDualPipe;
29     EncTestData *pEncData = m_encTestFactory.GetEncTestData("HEVC-DualPipe");
30     ExectueEncodeTest(pEncData);
31     delete pEncData;
32 }
33 
TEST_F(MediaEncodeDdiTest,EncodeAVC_DualPipe)34 TEST_F(MediaEncodeDdiTest, EncodeAVC_DualPipe)
35 {
36     m_GpuCmdFactory = g_gpuCmdFactoryEncodeAvcDualPipe;
37     EncTestData *pEncData = m_encTestFactory.GetEncTestData("AVC-DualPipe");
38     ExectueEncodeTest(pEncData);
39     delete pEncData;
40 }
41 
ExectueEncodeTest(EncTestData * pEncData)42 void MediaEncodeDdiTest::ExectueEncodeTest(EncTestData *pEncData)
43 {
44     vector<Platform_t> platforms = m_driverLoader.GetPlatforms();
45     for (int i = 0; i < m_driverLoader.GetPlatformNum(); i++)
46     {
47         if (m_encTestCfg.IsEncTestEnabled(DeviceConfigTable[platforms[i]],
48             pEncData->GetFeatureID()))
49         {
50             CmdValidator::GpuCmdsValidationInit(m_GpuCmdFactory, platforms[i]);
51             EncodeExecute(pEncData, platforms[i]);
52         }
53     }
54 }
55 
EncodeExecute(EncTestData * pEncData,Platform_t platform)56 void MediaEncodeDdiTest::EncodeExecute(EncTestData *pEncData, Platform_t platform)
57 {
58     VAConfigID      config_id;
59     VAContextID     context_id;
60     VASurfaceStatus surface_status;
61 
62     // So far we still use DeviceConfigTable to find the platform, as the libdrm mock use this.
63     // If we want to use vector Platforms, we would use vector in libdrm too.
64     int ret = m_driverLoader.InitDriver(platform);
65     EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
66         << ", Failed function = m_driverLoader.InitDriver" << endl;
67 
68     // The attribute only use RCType and FEI function type in createconfig.
69     ret = m_driverLoader.m_ctx.vtable->vaCreateConfig(&m_driverLoader.m_ctx,
70         pEncData->GetFeatureID().profile, pEncData->GetFeatureID().entrypoint,
71         (VAConfigAttrib *)&(pEncData->GetConfAttrib()[0]), pEncData->GetConfAttrib().size(), &config_id);
72     EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
73         << ", Failed function = m_driverLoader.m_ctx.vtable->vaCreateConfig" << endl;
74 
75     vector<VASurfaceID> &resources = pEncData->GetResources();
76     ret = m_driverLoader.m_ctx.vtable->vaCreateSurfaces2(&m_driverLoader.m_ctx, VA_RT_FORMAT_YUV420,
77         pEncData->GetWidth(), pEncData->GetHeight(), &resources[0], resources.size(),
78         (VASurfaceAttrib *)&(pEncData->GetSurfAttrib()[0]), pEncData->GetSurfAttrib().size());
79     EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
80         << ", Failed function = m_driverLoader.m_ctx.vtable->vaCreateSurfaces2" << endl;
81 
82     ret = m_driverLoader.m_ctx.vtable->vaCreateContext(&m_driverLoader.m_ctx, config_id, pEncData->GetWidth(),
83         pEncData->GetHeight(), VA_PROGRESSIVE, &resources[0], resources.size(), &context_id);
84     EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
85         << ", Failed function = m_driverLoader.m_ctx.vtable->vaCreateContext" << endl;
86 
87     for (int i = 0; i < pEncData->m_num_frames; i++)
88     {
89         ret = m_driverLoader.m_ctx.vtable->vaBeginPicture(&m_driverLoader.m_ctx, context_id,resources[0]);
90 
91         vector<vector<CompBufConif>> &compBufs = pEncData->GetCompBuffers();
92         ret = m_driverLoader.m_ctx.vtable->vaCreateBuffer(&m_driverLoader.m_ctx, context_id, compBufs[i][0].bufType,
93             compBufs[i][0].bufSize, 1, compBufs[i][0].pData, &compBufs[i][0].bufID);
94         EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
95             << ", Failed function = m_driverLoader.m_ctx.vtable->vaCreateBuffer" << endl;
96 
97         pEncData->UpdateCompBuffers(i);
98         for (int j = 1; j < compBufs[i].size(); j++)
99         {
100             ret = m_driverLoader.m_ctx.vtable->vaCreateBuffer(&m_driverLoader.m_ctx, context_id,
101                 compBufs[i][j].bufType, compBufs[i][j].bufSize, 1, compBufs[i][j].pData, &compBufs[i][j].bufID);
102             EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
103                 << ", Failed function = m_driverLoader.m_ctx.vtable->vaCreateBuffer" << endl;
104 
105             // In RenderPicture, it suppose all needed buffer has been created already.
106             // Suppose the compBufs[0] is always EncCodedBuffer, so we won't render it.
107             // If we render it, the ret is still Success, but would with log"not supported
108             // buffer type in vpgEncodeRenderPicture."
109             ret = m_driverLoader.m_ctx.vtable->vaRenderPicture(&m_driverLoader.m_ctx,
110                 context_id, &compBufs[i][j].bufID, 1);
111             EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
112                 << ", Failed function = m_driverLoader.m_ctx.vtable->vaRenderPicture" << endl;
113         }
114 
115         ret = m_driverLoader.m_ctx.vtable->vaEndPicture(&m_driverLoader.m_ctx, context_id);
116         EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
117             << ", Failed function = m_driverLoader.m_ctx.vtable->vaEndPicture" << endl;
118 
119         ret = m_driverLoader.m_ctx.vtable->vaSyncSurface(&m_driverLoader.m_ctx, resources[0]);
120         EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
121             << ", Failed function = m_driverLoader.m_ctx.vtable->vaSyncSurface" << endl;
122 
123         do
124         {
125             ret = m_driverLoader.m_ctx.vtable->vaQuerySurfaceStatus(&m_driverLoader.m_ctx,
126                 resources[0], &surface_status);
127         } while (surface_status != VASurfaceReady);
128 
129         for (int j = 0; j < compBufs[i].size(); j++)
130         {
131             ret = m_driverLoader.m_ctx.vtable->vaDestroyBuffer(&m_driverLoader.m_ctx, compBufs[i][j].bufID);
132             EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
133                 << ", Failed function = m_driverLoader.m_ctx.vtable->vaDestroyBuffer" << endl;
134         }
135       }
136 
137     ret = m_driverLoader.m_ctx.vtable->vaDestroySurfaces(&m_driverLoader.m_ctx,
138         &resources[0], resources.size());
139     EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
140         << ", Failed function = m_driverLoader.m_ctx.vtable->vaDestroySurfaces" << endl;
141 
142     ret = m_driverLoader.m_ctx.vtable->vaDestroyContext(&m_driverLoader.m_ctx, context_id);
143     EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
144         << ", Failed function = m_driverLoader.m_ctx.vtable->vaDestroyContext" << endl;
145 
146     ret = m_driverLoader.m_ctx.vtable->vaDestroyConfig(&m_driverLoader.m_ctx, config_id);
147     EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
148         << ", Failed function = m_driverLoader.m_ctx.vtable->vaDestroyConfig" << endl;
149 
150     ret = m_driverLoader.CloseDriver();
151     EXPECT_EQ(VA_STATUS_SUCCESS, ret) << "Platform = " << g_platformName[platform]
152         << ", Failed function = m_driverLoader.CloseDriver" << endl;
153 }
154 
EncodeTestConfig()155 EncodeTestConfig::EncodeTestConfig()
156 {
157     m_mapPlatformFeatureID[DeviceConfigTable[igfxSKLAKE]]     = {
158         TEST_Intel_Encode_HEVC,
159         TEST_Intel_Encode_AVC ,
160     };
161     m_mapPlatformFeatureID[DeviceConfigTable[igfxBROXTON]]    = {
162         TEST_Intel_Encode_HEVC,
163         TEST_Intel_Encode_AVC ,
164     };
165     m_mapPlatformFeatureID[DeviceConfigTable[igfxBROADWELL]]  = {
166         TEST_Intel_Encode_AVC ,
167     };
168 }
169 
IsEncTestEnabled(DeviceConfig platform,FeatureID featureId)170 bool EncodeTestConfig::IsEncTestEnabled(DeviceConfig platform, FeatureID featureId)
171 {
172     const auto &featureIdArray = m_mapPlatformFeatureID[platform];
173     for (int i = 0; i < featureIdArray.size(); i++)
174     {
175         // In fact, we may need to call QueryEntroyPoint to make sure it does have this config.
176         // But we suppose this test is done in Caps test.
177         // Otherwise, here is need to call QueryEntroyPoint to check if it's supported.
178         if (featureId == featureIdArray[i])
179         {
180             return true;
181         }
182     }
183 
184     return false;
185 }
186