| /* |
| * Copyright (C) 2016 Intel Corporation. All Rights Reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the |
| * "Software"), to deal in the Software without restriction, including |
| * without limitation the rights to use, copy, modify, merge, publish, |
| * distribute, sub license, and/or sell copies of the Software, and to |
| * permit persons to whom the Software is furnished to do so, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the |
| * next paragraph) shall be included in all copies or substantial portions |
| * of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
| * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR |
| * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| #include "test_va_api_fixture.h" |
| |
| #include <algorithm> |
| #include <functional> |
| |
| #include <fcntl.h> // for O_RDWR |
| #include <unistd.h> // for close() |
| #include <va/va_drm.h> |
| |
| namespace VAAPI { |
| |
| VAAPIFixture::VAAPIFixture() |
| : ::testing::Test::Test() |
| , m_vaDisplay(NULL) |
| , m_drmHandle(-1) |
| , drmDevicePaths({ "/dev/dri/renderD128", "/dev/dri/card0" }) |
| , m_maxEntrypoints(0) |
| , m_maxProfiles(0) |
| , m_numProfiles(0) |
| , m_maxConfigAttributes(0) |
| , m_configID(VA_INVALID_ID) |
| , m_contextID(VA_INVALID_ID) |
| , m_bufferID(VA_INVALID_ID) |
| |
| { |
| m_profileList.clear(); |
| m_entrypointList.clear(); |
| m_configAttribList.clear(); |
| m_configAttribToCreateConfig.clear(); |
| m_querySurfaceAttribList.clear(); |
| m_surfaceID.clear(); |
| } |
| |
| VAAPIFixture::~VAAPIFixture() |
| { |
| m_vaDisplay = NULL; |
| if (m_drmHandle >= 0) |
| close(m_drmHandle); |
| m_drmHandle = -1; |
| } |
| |
| VADisplay VAAPIFixture::getDisplay() |
| { |
| |
| uint32_t i; |
| |
| for (i = 0; i < sizeof(drmDevicePaths) / sizeof(*drmDevicePaths); i++) { |
| m_drmHandle = open(drmDevicePaths[i].c_str(), O_RDWR); |
| if (m_drmHandle < 0) |
| continue; |
| m_vaDisplay = vaGetDisplayDRM(m_drmHandle); |
| |
| if (m_vaDisplay) |
| return m_vaDisplay; |
| } |
| |
| return m_vaDisplay; |
| } |
| |
| VADisplay VAAPIFixture::doInitialize() |
| { |
| VADisplay vaDisplay; |
| int majorVersion, minorVersion; |
| |
| vaDisplay = getDisplay(); |
| EXPECT_TRUE(vaDisplay); |
| |
| if (vaDisplay) { |
| EXPECT_STATUS(vaInitialize(vaDisplay, &majorVersion, &minorVersion)); |
| } |
| |
| return vaDisplay; |
| } |
| |
| void VAAPIFixture::doGetMaxProfiles() |
| { |
| m_maxProfiles = vaMaxNumProfiles(m_vaDisplay); |
| EXPECT_TRUE(m_maxProfiles > 0) << m_maxProfiles |
| << " profiles are reported, check setup"; |
| } |
| |
| void VAAPIFixture::doGetMaxEntrypoints() |
| { |
| m_maxEntrypoints = vaMaxNumEntrypoints(m_vaDisplay); |
| EXPECT_TRUE(m_maxEntrypoints > 0) |
| << m_maxEntrypoints << " entrypoints are reported, check setup"; |
| } |
| |
| void VAAPIFixture::doGetMaxNumConfigAttribs() |
| { |
| m_maxConfigAttributes = vaMaxNumConfigAttributes(m_vaDisplay); |
| |
| EXPECT_EQ(m_maxConfigAttributes, 32); |
| } |
| |
| void VAAPIFixture::doGetMaxValues() |
| { |
| |
| doGetMaxProfiles(); |
| doGetMaxEntrypoints(); |
| doGetMaxNumConfigAttribs(); |
| } |
| |
| void VAAPIFixture::doQueryConfigProfiles() |
| { |
| m_profileList.resize(m_maxProfiles); |
| |
| ASSERT_STATUS( |
| vaQueryConfigProfiles(m_vaDisplay, &m_profileList[0], &m_numProfiles)); |
| |
| // at least one profile should be supported for tests to be executed |
| ASSERT_TRUE(m_numProfiles > 0); |
| |
| m_profileList.resize(m_numProfiles); |
| } |
| |
| std::vector<VAProfile> VAAPIFixture::getSupportedProfileList() |
| { |
| return m_profileList; |
| } |
| |
| std::vector<VAEntrypoint> VAAPIFixture::getSupportedEntrypointList() |
| { |
| return m_entrypointList; |
| } |
| |
| bool VAAPIFixture::doFindProfileInList(VAProfile profile) |
| { |
| return std::find(m_profileList.begin(), m_profileList.end(), profile) |
| != m_profileList.end(); |
| } |
| |
| void VAAPIFixture::doQueryConfigEntrypoints(VAProfile profile) |
| { |
| int numEntrypoints = 0; |
| |
| m_entrypointList.resize(m_maxEntrypoints); |
| ASSERT_STATUS(vaQueryConfigEntrypoints( |
| m_vaDisplay, profile, &m_entrypointList[0], &numEntrypoints)); |
| |
| EXPECT_TRUE(numEntrypoints > 0); |
| |
| m_entrypointList.resize(numEntrypoints); |
| } |
| |
| bool VAAPIFixture::doFindEntrypointInList(VAEntrypoint entrypoint) |
| { |
| return std::find(m_entrypointList.begin(), m_entrypointList.end(), |
| entrypoint) |
| != m_entrypointList.end(); |
| } |
| |
| void VAAPIFixture::doFillConfigAttribList() |
| { |
| m_configAttribList.clear(); |
| // fill it with all the VAConfigAttribs known |
| for (auto& it : m_vaConfigAttribs) { |
| VAConfigAttrib configAttrib; |
| |
| configAttrib.type = it; |
| |
| m_configAttribList.push_back(configAttrib); |
| } |
| |
| EXPECT_EQ(m_configAttribList.size(), m_vaConfigAttribs.size()); |
| } |
| |
| void VAAPIFixture::doGetConfigAttributes(VAProfile profile, |
| VAEntrypoint entrypoint) |
| { |
| int numAttributes = m_configAttribList.size(); |
| ASSERT_STATUS(vaGetConfigAttributes(m_vaDisplay, profile, entrypoint, |
| &m_configAttribList[0], numAttributes)); |
| } |
| |
| void VAAPIFixture::doGetConfigAttributes( |
| VAProfile profile, VAEntrypoint entrypoint, |
| std::vector<VAConfigAttrib>& configAttrib) |
| { |
| int numAttributes = configAttrib.size(); |
| ASSERT_STATUS(vaGetConfigAttributes(m_vaDisplay, profile, entrypoint, |
| &configAttrib[0], numAttributes)); |
| } |
| |
| const std::vector<VAConfigAttrib>& VAAPIFixture::getConfigAttribList() const |
| { |
| return m_configAttribList; |
| } |
| |
| const std::vector<VAConfigAttrib>& |
| VAAPIFixture::getQueryConfigAttribList() const |
| { |
| return m_queryConfigAttribList; |
| } |
| |
| void VAAPIFixture::doCheckAttribsMatch(std::vector<VAConfigAttrib> configAttrib) |
| { |
| auto itOne = m_queryConfigAttribList.begin(); |
| auto itTwo = configAttrib.begin(); |
| auto diff = 0; |
| |
| EXPECT_EQ(configAttrib.size(), m_queryConfigAttribList.size()); |
| |
| while (itOne != m_queryConfigAttribList.end() |
| && itTwo != configAttrib.end()) { |
| if (itOne->value != itTwo->value || itOne->type != itTwo->type) { |
| diff++; |
| } |
| itOne++; |
| itTwo++; |
| } |
| |
| EXPECT_TRUE(diff == 0); |
| } |
| |
| void VAAPIFixture::doCreateConfigWithAttrib(VAProfile profile, |
| VAEntrypoint entrypoint) |
| { |
| |
| m_configAttribToCreateConfig.clear(); |
| for (auto& it : m_configAttribList) { |
| |
| if (it.value != VA_ATTRIB_NOT_SUPPORTED) |
| m_configAttribToCreateConfig.push_back(it); |
| } |
| |
| ASSERT_STATUS(vaCreateConfig( |
| m_vaDisplay, profile, entrypoint, &m_configAttribToCreateConfig[0], |
| m_configAttribToCreateConfig.size(), &m_configID)); |
| |
| EXPECT_TRUE(m_configID > 0); |
| |
| doQueryConfigAttributes(profile, entrypoint); |
| } |
| |
| void VAAPIFixture::doDestroyConfig() |
| { |
| ASSERT_STATUS(vaDestroyConfig(m_vaDisplay, m_configID)); |
| } |
| |
| void VAAPIFixture::doQuerySurfacesWithConfigAttribs(VAProfile profile, |
| VAEntrypoint entrypoint) |
| { |
| std::vector<VASurfaceAttrib> m_querySurfaceAttribList; |
| uint32_t queryNumSurfaceAttribs; |
| |
| doCreateConfigWithAttrib(profile, entrypoint); |
| |
| ASSERT_STATUS(vaQuerySurfaceAttributes(m_vaDisplay, m_configID, |
| NULL, |
| &queryNumSurfaceAttribs)); |
| EXPECT_TRUE(queryNumSurfaceAttribs > 0); |
| m_querySurfaceAttribList.resize(queryNumSurfaceAttribs); |
| |
| ASSERT_STATUS(vaQuerySurfaceAttributes(m_vaDisplay, m_configID, |
| &m_querySurfaceAttribList[0], |
| &queryNumSurfaceAttribs)); |
| |
| EXPECT_TRUE(queryNumSurfaceAttribs > 0); |
| EXPECT_TRUE(queryNumSurfaceAttribs <= m_querySurfaceAttribList.size()); |
| m_querySurfaceAttribList.resize(queryNumSurfaceAttribs); |
| |
| for (auto& it : m_querySurfaceAttribList) { |
| |
| unsigned int flags |
| = 0 | VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE; |
| |
| EXPECT_NE(it.flags & flags, |
| (unsigned int)VA_SURFACE_ATTRIB_NOT_SUPPORTED); |
| EXPECT_TRUE((it.value.type >= VAGenericValueTypeInteger) |
| && it.value.type <= VAGenericValueTypeFunc); |
| } |
| } |
| |
| inline bool isSurfaceAttribInList(VASurfaceAttrib surfaceAttrib, |
| VASurfaceAttribType surfaceAttribType) |
| { |
| return surfaceAttrib.type == surfaceAttribType; |
| } |
| |
| void VAAPIFixture::doGetMaxSurfaceResolution( |
| VAProfile profile, VAEntrypoint entrypoint, |
| std::pair<uint32_t, uint32_t>& maxResolution) |
| { |
| std::vector<VASurfaceAttrib>::iterator it; |
| doQuerySurfacesNoConfigAttribs(profile, entrypoint); |
| it = std::find_if(m_querySurfaceAttribList.begin(), |
| m_querySurfaceAttribList.end(), |
| std::bind(isSurfaceAttribInList, std::placeholders::_1, |
| VASurfaceAttribMaxWidth)); |
| |
| EXPECT_TRUE(it != m_querySurfaceAttribList.end()); |
| |
| EXPECT_EQ(it->value.type, VAGenericValueTypeInteger); |
| |
| maxResolution.first = it->value.value.i; |
| |
| it = std::find_if(m_querySurfaceAttribList.begin(), |
| m_querySurfaceAttribList.end(), |
| std::bind(isSurfaceAttribInList, std::placeholders::_1, |
| VASurfaceAttribMaxHeight)); |
| |
| EXPECT_TRUE(it != m_querySurfaceAttribList.end()); |
| |
| EXPECT_EQ(it->value.type, VAGenericValueTypeInteger); |
| |
| maxResolution.second = it->value.value.i; |
| } |
| |
| void VAAPIFixture::doCreateConfigNoAttrib(VAProfile profile, |
| VAEntrypoint entrypoint) |
| { |
| |
| ASSERT_STATUS( |
| vaCreateConfig(m_vaDisplay, profile, entrypoint, NULL, 0, &m_configID)); |
| |
| EXPECT_TRUE(m_configID > 0); |
| |
| doQueryConfigAttributes(profile, entrypoint); |
| } |
| |
| void VAAPIFixture::doQueryConfigAttributes(VAProfile profile, |
| VAEntrypoint entrypoint, |
| VAStatus expectation) |
| { |
| VAProfile queryProfile; |
| VAEntrypoint queryEntrypoint; |
| int queryNumConfigAttribs; |
| |
| m_queryConfigAttribList.resize(m_maxConfigAttributes); // va-api requirement |
| |
| ASSERT_EQ(vaQueryConfigAttributes( |
| m_vaDisplay, m_configID, &queryProfile, &queryEntrypoint, |
| &m_queryConfigAttribList[0], &queryNumConfigAttribs), |
| expectation); |
| |
| if (expectation == VA_STATUS_SUCCESS) { |
| m_queryConfigAttribList.resize(queryNumConfigAttribs); |
| EXPECT_EQ(queryProfile, profile); |
| EXPECT_EQ(queryEntrypoint, entrypoint); |
| EXPECT_TRUE(queryNumConfigAttribs > 0); |
| |
| m_queryConfigAttribList.resize(queryNumConfigAttribs); |
| |
| // reported Config Attributes should be supported |
| for (auto& it : m_queryConfigAttribList) { |
| EXPECT_NE(it.value, VA_ATTRIB_NOT_SUPPORTED); |
| } |
| } |
| } |
| |
| void VAAPIFixture::doQuerySurfacesNoConfigAttribs(VAProfile profile, |
| VAEntrypoint entrypoint) |
| { |
| uint32_t queryNumSurfaceAttribs; |
| |
| doCreateConfigNoAttrib(profile, entrypoint); |
| |
| ASSERT_STATUS(vaQuerySurfaceAttributes(m_vaDisplay, m_configID, |
| NULL, |
| &queryNumSurfaceAttribs)); |
| EXPECT_TRUE(queryNumSurfaceAttribs > 0); |
| m_querySurfaceAttribList.resize(queryNumSurfaceAttribs); |
| |
| ASSERT_STATUS(vaQuerySurfaceAttributes(m_vaDisplay, m_configID, |
| &m_querySurfaceAttribList[0], |
| &queryNumSurfaceAttribs)); |
| |
| EXPECT_TRUE(queryNumSurfaceAttribs > 0); |
| EXPECT_TRUE(queryNumSurfaceAttribs <= m_querySurfaceAttribList.size()); |
| m_querySurfaceAttribList.resize(queryNumSurfaceAttribs); |
| |
| for (auto& it : m_querySurfaceAttribList) { |
| |
| unsigned int flags |
| = 0 | VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE; |
| |
| EXPECT_NE(it.flags & flags, |
| (unsigned int)VA_SURFACE_ATTRIB_NOT_SUPPORTED); |
| EXPECT_TRUE((it.value.type >= VAGenericValueTypeInteger) |
| && it.value.type <= VAGenericValueTypeFunc); |
| } |
| } |
| |
| inline bool isConfigAttribInList(VAConfigAttrib configAttrib, |
| VAConfigAttribType type) |
| { |
| return configAttrib.type == type; |
| } |
| |
| void VAAPIFixture::doCreateSurfaces(VAProfile profile, VAEntrypoint entrypoint, |
| std::pair<uint32_t, uint32_t> resolution) |
| { |
| VASurfaceAttrib* attribList = NULL; |
| uint32_t numAttribs = 0; |
| // when ConfigAttribs were not queried just do YUV420 as it is considered |
| // the universal supported format by the driver. RT formats depend on |
| // profile and entrypoint. |
| unsigned int formats = VA_RT_FORMAT_YUV420; |
| |
| m_surfaceID.resize(10); |
| |
| if (!m_querySurfaceAttribList.empty()) { |
| numAttribs = m_querySurfaceAttribList.size(); |
| attribList = &m_querySurfaceAttribList[0]; |
| } |
| |
| if (!m_queryConfigAttribList.empty()) { |
| std::vector<VAConfigAttrib>::iterator it = std::find_if( |
| m_queryConfigAttribList.begin(), m_queryConfigAttribList.end(), |
| std::bind(isConfigAttribInList, std::placeholders::_1, |
| VAConfigAttribRTFormat)); |
| formats = it->value; |
| } |
| |
| for (auto& itFormat : m_vaRTFormats) { |
| unsigned int currentFormat = formats & itFormat; |
| |
| if (currentFormat) { |
| |
| ASSERT_STATUS(vaCreateSurfaces( |
| m_vaDisplay, currentFormat, resolution.first, resolution.second, |
| &m_surfaceID[0], 10, attribList, numAttribs)); |
| formats &= ~itFormat; |
| } |
| } |
| } |
| |
| void VAAPIFixture::doCreateContext(std::pair<uint32_t, uint32_t> resolution, |
| VAStatus expectation) |
| { |
| m_contextID = 0; |
| ASSERT_EQ(vaCreateContext(m_vaDisplay, m_configID, resolution.first, |
| resolution.second, VA_PROGRESSIVE, |
| &m_surfaceID[0], m_surfaceID.size(), |
| &m_contextID), |
| expectation); |
| } |
| |
| void VAAPIFixture::doDestroyContext(VAStatus expectation) |
| { |
| ASSERT_EQ(vaDestroyContext(m_vaDisplay, m_contextID), expectation); |
| } |
| |
| void VAAPIFixture::doCreateBuffer(VABufferType bufferType) |
| { |
| ASSERT_STATUS(vaCreateBuffer(m_vaDisplay, m_contextID, bufferType, |
| sizeof(bufferType), 1, NULL, &m_bufferID)); |
| } |
| |
| void VAAPIFixture::doDestroyBuffer() |
| { |
| ASSERT_STATUS(vaDestroyBuffer(m_vaDisplay, m_bufferID)); |
| } |
| |
| void VAAPIFixture::doCreateConfig(VAProfile profile, VAEntrypoint entrypoint) |
| { |
| m_configID = 0; |
| ASSERT_STATUS( |
| vaCreateConfig(m_vaDisplay, profile, entrypoint, NULL, 0, &m_configID)); |
| EXPECT_NE(m_configID, 0u); |
| } |
| |
| void VAAPIFixture::doCreateConfigToFail(VAProfile profile, |
| VAEntrypoint entrypoint, int error) |
| { |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| |
| m_configID = 0; |
| |
| vaStatus = vaCreateConfig(m_vaDisplay, profile, entrypoint, NULL, 0, |
| &m_configID); |
| ASSERT_EQ(vaStatus, error); |
| |
| EXPECT_EQ(m_configID, 0u); |
| |
| m_queryConfigAttribList.resize(m_maxConfigAttributes); // va-api requirement |
| |
| doQueryConfigAttributes(profile, entrypoint, |
| VA_STATUS_ERROR_INVALID_CONFIG); |
| |
| ASSERT_EQ(vaDestroyConfig(m_vaDisplay, m_configID), |
| VA_STATUS_ERROR_INVALID_CONFIG); |
| } |
| |
| void VAAPIFixture::doTerminate() { EXPECT_STATUS(vaTerminate(m_vaDisplay)); } |
| |
| TEST_F(VAAPIFixture, getDisplay) |
| { |
| VADisplay vaDisplay; |
| |
| vaDisplay = getDisplay(); |
| ASSERT_TRUE(vaDisplay); |
| } |
| |
| void VAAPIFixture::doLogSkipTest(VAProfile profile, VAEntrypoint entrypoint) |
| { |
| RecordProperty("skipped", true); |
| std::cout << "[ SKIPPED ]" |
| << " " << profile << " / " << entrypoint |
| << " not supported on this hardware" << std::endl; |
| } |
| } // namespace VAAPI |