美文网首页
VK-GL-CTS 初步了解

VK-GL-CTS 初步了解

作者: 集韵增广 | 来源:发表于2022-05-09 09:19 被阅读0次

VK-GL-CTS 初步了解

下载

地址:https://github.com/KhronosGroup/VK-GL-CTS

概要说明

VK-GL-CTS提供针对:Volkan,OpenGL的一致性验证。意思是对这些图形库提供的API严重其在不同的平台的实现是否一致。所以概括起来就是VK-GL-CTS提供对不同平台的图形库的一致性验证框架。


源码获取

git clone https://github.com/KhronosGroup/VK-GL-CTS.git

  1. 目录结构

    .
    ├── Android.mk
    ├── AndroidGen.mk
    ├── CMakeLists.txt
    ├── CODE_OF_CONDUCT.md
    ├── LICENSE
    ├── MODULE_LICENSE_APACHE2
    ├── NOTICE
    ├── OWNERS
    ├── README.md
    ├── android
    ├── data
    ├── doc
    ├── execserver
    ├── executor
    ├── external
    ├── framework
    ├── modules
    ├── scripts
    └── targets
    
  1. 主要内容介绍

    • data:测试数据,提供测试图片和测试shader参数;
    • execserver:测试服务程序,主要为android和ios平台测试框架提供;
    • executor:测试基础程序,测试框架的基础实现,可视作自定义测试框架基础。
    • external:依赖的外部库源码和测试case
    • framework[^移植]:测试框架,包括测试套装和case的实现框架,wrapper。
    • modules:测试目标模块的case
    • scrpits:针对不同平台的编译脚本
    • targets[^移植]:编译脚本目录
  2. 测试框架概览

    • 通用main入口:framework/platform/tcuMain.cpp
    // Implement this in your platform port.
    tcu::Platform* createPlatform (void);
    int main (int argc, char** argv) {
     ……
     try {
         tcu::CommandLine                cmdLine     (argc, argv);
         tcu::DirArchive                 archive     (cmdLine.getArchiveDir());
         tcu::TestLog                    log         (cmdLine.getLogFileName(), cmdLine.getLogFlags());
         de::UniquePtr<tcu::Platform>    platform    (createPlatform());
         de::UniquePtr<tcu::App>         app         (new tcu::App(*platform, archive, log, cmdLine));
    
         // Main loop.
         ……
     }
     catch (const std::exception& e) {
         tcu::die("%s", e.what());
     }
     return exitStatus;
    }
    
    • 测试包注册:externl/openglcts/modules/glcTestPackageRegistry.cpp
    void registerPackages(void)
    {
     tcu::TestPackageRegistry* registry = tcu::TestPackageRegistry::getSingleton();
    
     registry->registerPackage("CTS-Configs", createConfigPackage);
    
    #if DE_OS != DE_OS_ANDROID
     registry->registerPackage("dEQP-EGL", createdEQPEGLPackage);
    #endif
     registry->registerPackage("KHR-GLES2", createES2Package);
    #if DE_OS != DE_OS_ANDROID
     registry->registerPackage("dEQP-GLES2", createdEQPES2Package);
    #endif
    
    #if defined(DEQP_GTF_AVAILABLE)
     registry->registerPackage("GTF-GLES2", createES2GTFPackage);
    #endif
    
     registry->registerPackage("KHR-GLES3", createES30Package);
    #if DE_OS != DE_OS_ANDROID
     registry->registerPackage("dEQP-GLES3", createdEQPES30Package);
    #endif
    
    #if defined(DEQP_GTF_AVAILABLE)
     registry->registerPackage("GTF-GLES3", createES30GTFPackage);
    #endif
    
    #if DE_OS != DE_OS_ANDROID
     registry->registerPackage("dEQP-GLES31", createdEQPES31Package);
    #endif
     registry->registerPackage("dEQP-GL45-GLES31", createdEQPGL45ES31Package);
     registry->registerPackage("dEQP-GL45-GLES3", createdEQPGL45ES3Package);
     registry->registerPackage("KHR-GLES31", createES31Package);
     registry->registerPackage("KHR-GLESEXT", createESEXTPackage);
    
    #if defined(DEQP_GTF_AVAILABLE)
     registry->registerPackage("GTF-GLES31", createES31GTFPackage);
    #endif
    
     registry->registerPackage("KHR-GLES32", createES32Package);
    
     registry->registerPackage("KHR-NoContext", createNoDefaultCustomContextPackage);
     registry->registerPackage("KHR-Single-GL43", createSingleConfigGL43TestPackage);
     registry->registerPackage("KHR-Single-GL44", createSingleConfigGL44TestPackage);
     registry->registerPackage("KHR-Single-GL45", createSingleConfigGL45TestPackage);
     registry->registerPackage("KHR-Single-GL46", createSingleConfigGL46TestPackage);
     registry->registerPackage("KHR-Single-GLES32", createSingleConfigES32TestPackage);
    
     registry->registerPackage("KHR-GL30", createGL30Package);
     registry->registerPackage("KHR-GL31", createGL31Package);
     registry->registerPackage("KHR-GL32", createGL32Package);
     registry->registerPackage("KHR-GL33", createGL33Package);
    
     registry->registerPackage("KHR-GL40", createGL40Package);
     registry->registerPackage("KHR-GL41", createGL41Package);
     registry->registerPackage("KHR-GL42", createGL42Package);
     registry->registerPackage("KHR-COMPAT-GL42", createGL42CompatPackage);
     registry->registerPackage("KHR-GL43", createGL43Package);
     registry->registerPackage("KHR-GL44", createGL44Package);
     registry->registerPackage("KHR-GL45", createGL45Package);
     registry->registerPackage("KHR-GL46", createGL46Package);
    
    #if defined(DEQP_GTF_AVAILABLE)
     registry->registerPackage("GTF-GL30", createGL30GTFPackage);
     registry->registerPackage("GTF-GL31", createGL31GTFPackage);
     registry->registerPackage("GTF-GL32", createGL32GTFPackage);
     registry->registerPackage("GTF-GL33", createGL33GTFPackage);
    
     registry->registerPackage("GTF-GL40", createGL40GTFPackage);
     registry->registerPackage("GTF-GL41", createGL41GTFPackage);
     registry->registerPackage("GTF-GL42", createGL42GTFPackage);
     registry->registerPackage("GTF-GL43", createGL43GTFPackage);
     registry->registerPackage("GTF-GL44", createGL44GTFPackage);
     registry->registerPackage("GTF-GL45", createGL45GTFPackage);
     registry->registerPackage("GTF-GL46", createGL46GTFPackage);
    #endif
    }
    }
    
    • 不同模块的测试用例:external/openglcts/modules里,如下图展示了modules目录的内容
    .
    ├── CMakeLists.txt
    ├── common                                  //测试框架相关源码
    ├── gl                                      //gl的测试case
    ├── glcTestPackageEntry.cpp
    ├── glcTestPackageRegistry.cpp
    ├── glcTestPackageRegistry.hpp
    ├── gles2                                   //gles2的测试case
    ├── gles3                                   //gles3的测试case
    ├── gles31                                  //gles31的测试case 
    ├── gles32                                  //gles32的测试case
    ├── glesext                                 //glesext的测试case
    ├── pch.cpp                                   
    ├── pch.h
    └── runner                                  //glcTestRunner相关文件,不同平台启动的内容也不同,比如glcAndroidTestActivity.cpp也在此文件夹内。
    

下载第三方软件

进入VK-GL-CTS目录,执行python external/fetch_sources.py.

注意,此部分可能下载困难,需要科学上网

编译[^cmake] 和 测试

  1. 由于是cmake,所以和下载的文件平行的位置创建build目录:

    mkdir x11gl (或者 mkdir gles32,根据不同编译对象建立不同目录)
    
  2. VK-GLS-CTS cmake 有两个选项:

    • -DDEQP_TARGET:依赖目标,如android,default,iOS,null,osx,raspi,curfaceless,vulkan_headless,wayland,x11_egl,x11_egl_glx,x11_glx
    • -DCLSTS_GTF_TARGET:测试对象,如gles2,gles3,gles31,gles32和gl
  3. 编译

    cmake <path to VK-GL-CTS> -DDEQP_TARGET=x11_glx -DGLCTS_GTF_TARGET=gl (或是:cmake <path to VK-GL-CTS> -DDEQP_TARGET=null -DGLCTS_GTF_TARGET=gl/gles32)
    cmake --build external/openglcts
    
  4. Debug

    cmake <path to VK-GL-CTS> -DDEQP_TARGET=default -DGLCTS_GTF_TARGET=gl -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_FLAGS=-m64 -DCMAKE_CXX_FLAGS=-m64
    cmake --build . -j12
    
  5. 测试

    ./cts-runner --type=gl45 (套装级测试)
    ./glcts --deqp-case=dEQP-GLES2.info.* (用例级测试)
    
  6. 测试结果

    在测试位置的本地目录会有个TestResults.qpa文件(默认不改log输出时可见)

编译框架详解

根CMakeLists

根CMakeLists主要定义:

  • 版本(cmake>3.10.2,python>3)
  • 编译目标(targets目录里的具体对象,默认default及default.cmake)和 项目 (dEQP-Core-default)
  • 定义变量,见set(DEQP_XXX);定义构建参数,见add_definitions;定义头文件,见include_directories;定义子cmake,见include;定义宏/宏函数,见macro,
  • 定义需要编译的subdirectory,见add_subdirectory,注意,这就是具体的编译步骤 。具体步骤为:
    1. 编译external里的第三方库,如glslang,spirv-tools,amber等;
    2. 编译framework里的delibs,如debase,depool等,相当于自己实现的基础库函数以避免对不同平台的依赖;
    3. 编译execserver和executor,测试框架的基础库
    4. 编译全部framework,modules,framework主要是针对不同的平台开发的平台适配内容,即为实现接口测试而需要的基础适配代码;modules是针对不同版本gl库开发的接口测试用例;
    5. 最后编译external/openglcts,生成测试对应的可执行文件 cts-runnerglcts

script脚本

用python写的工具,README介绍的主要两类,一个就是android生成apk的脚本,一个就是log分析和格式转换相关的。但是这里面其实有些基础的测试相关工具,如build_caselists.py,类似于直接运行的cmake命令。

platform的选择

根据DE_OS_IS_UNIX 和 DEQP_USE_X11确定是使用platform/lnx内的platform实现,如:tcu::Platform* tcu::lnx::LinuxPlatform;并且,由于在cmake编译时使用 -DDEQP_TARGET=default ,所以targets/default 目录里的default.cmake会被调用,然后在此文件里会找 find_package(X11) ,如果找到则会设置:set(DEQP_USE_X11 ON)set(DEQP_SUPPORT_GLX ON)

测试框架详解

cts-runner详解

  1. 编译:在源码目录CMakeList里定义了add_executable生成cts-runner,主要涉及两个文件:glcTestRunnerMain.cpp和glcTestPackageEntry.cpp
add_executable(cts-runner runner/glcTestRunnerMain.cpp glcTestPackageEntry.cpp)
  1. 主要调用关系
graph LR
glcTestRunnerMain[cts-runner] -->main(main)
    main --> platform(Platform)
    main --> glcTestRunner.cpp(TestRunner)
    glcTestRunner.cpp(TestRunner) --> init --> |--type| getDefaultConfigList
    init --> |--type| getTestRunParam
    glcTestRunner.cpp(TestRunner) --> initSession --> createSession --> tcuApp(createApp) --> tcuTestPackage.cpp(TestPackageRegistry)
    glcTestRunner.cpp(TestRunner) --> iterateSession --> glcTestRunner(RunSession.iterate) --> tcuApp.cpp(App.iterate)
    

总结:cts-runner根据参数里的--type初始化对应的配置文件和运行参数,然后生成 tcuAPP,根据注册的TestPackage进行具体测试

所以进一步需要了解的为:

  • Platform:主要对应的是具体的平台框架的实现,如Display和Context实现,对应的实现逻辑可以参考framework/platform内的实现。

    ├── android   
    ├── CMakeLists.txt
    ├── ios
    ├── lnx  //linux
    ├── null
    ├── nullws
    ├── osx
    ├── raspi
    ├── surfaceless
    ├── tcuMain.cpp
    ├── vanilla
    └── win32
    
  • ConfigList:根据传入--type,初始化基本配置,包括EGL,WGL,主要初始化display,render等需要的参数,如尺寸,RGB,YUV等的参数值,其中对应具体运行的case配置也是在ConfigList里,如 --deqp-case

  • RunParam:初始化基本参数,包括ES,GL等,主要初始化api,screen,surface,randonseed等

  • TestPackage:参考之前的测试包注册 ,实现对应的测试用例。

glcts详解

  1. 编译:和 cts-runner 不同,glcts独立的可执行程序是在 *external/openglcts/modules/CMakeLists里定义模块

    add_deqp_module(glcts "${GLCTS_SRCS}" "${GLCTS_LIBS}" glcTestPackageEntry.cpp)
    

    然后再在总CMakeLists里根据module名称套用tcuMain生成的可执行程序

    add_executable(${MODULE_NAME} ${PROJECT_SOURCE_DIR}/framework/platform/tcuMain.cpp ${ENTRY})
    
  2. 主要调用关系

    参加之前的 测试框架概览 ,tcuMain主要调用的就是tcuApp,所以glcts其实就是cts-runner最终调用的部分。cts-runner是在由 --type 对应的TestRunner里配置对应的参数。

    graph LR
    tcuMain[glcts] -->tcuApp(App) --> TestPackageRegistry(TestPackageRoot) --> tcuTestSessionExecutor(caseListFilter) --> TestSessionExecutor(iterate) 
    STATE_EXECUTE_TEST_CASE --> RenderCase(executeForConfig)
    tcu::App::iterate --> tcu::TestSessionExecutor --> tcu::TestHierarchyIterator --> deqp::egl::TestPackage --> deqp::egl::EglTestContext
    

    总结:cts-runner根据参数里的--type初始化对应的配置文件和运行参数,然后生成 tcuAPP,根据注册的TestPackage进行具体测试

target详解

target里存的都是cmake文件,在编译时-DDEQP_TARGET=?选择的对象即为target文件下的子文件夹。

targets
├── android
├── default
├── ios
├── null
├── nullws
├── osx
├── raspi
├── surfaceless
├── vulkan_headless
├── wayland
├── x11_egl
├── x11_egl_glx
└── x11_glx

platform详解

platform里存的是不同框架内的图形库的入口实现,以Debug对应的函数为例,LinuxPlatform实现 m_vkPlatformm_glPlatformm_eglPlatform 三个platform;

Display详解

graph LR
main --> createPlatform --> tcu::lnx::(LinuxPlatform) --> tcu::lnx::egl::Platform(egl::Platform) --> tcu::lnx::x11::egl::createDisplayFactory(createDisplayFactory) --> tcu::lnx::x11::egl::DisplayFactory(DisplayFactory) --> tcu::lnx::x11::egl::WindowFactory[WindowFactory]
eglw::DefaultLibrary[library]--> eglu::NativeDislay(Display) --> eglu::NativeWindow(Window) --> eglu::NativeWindowFactory(WindowFactory)

移植分析

移植涉及的API文件

framework/common/tcuPlatform.hpp
framework/opengl/gluPlatform.hpp
framework/egl/egluPlatform.hpp
framework/platform/tcuMain.cpp

如何增加测试对象和测试模块

  1. 测试对象为targets目录内的内容

    .
    ├── android
    ├── default
    ├── ios
    ├── null
    ├── nullws
    ├── osx
    ├── raspi
    ├── surfaceless
    ├── vulkan_headless
    ├── wayland
    ├── x11_egl
    ├── x11_egl_glx
    └── x11_glx
    

    以上为写文章时最新的目录内容。子目录为编译生成具体对象测试程序的cmake脚本,举个例子

    message("*** Using null context target")
    
    set(DEQP_TARGET_NAME "Null")
    
    set(TCUTIL_PLATFORM_SRCS
     null/tcuNullPlatform.cpp
     null/tcuNullPlatform.hpp
     null/tcuNullRenderContext.cpp
     null/tcuNullRenderContext.hpp
     null/tcuNullContextFactory.cpp
     null/tcuNullContextFactory.hpp
     )
    
    

    以上是null对象的生成脚步,内部文件对应位置则为framework/platform目录内。对应不同软件平台实现了不同GL接口和初始化实现

  2. 测试框架

    framework/common内是VK-GL-CTS的测试框架,对应生成的cts-runner和glcts是external/openglcts/modules里的文件。cts-runner对应的main就是runner/glcTestRunnerMain.cpp,glcts对应的则是glcTestPackageEntry.cpp(内部依赖glcTestPackageRegistry.cpp)然后根据cmake的编译规则add_module,add_executable,使用tcuapp.cpp作为glcts程序的main入口对模块级别的测试用例进行测试。


相关文章

  • VK-GL-CTS 初步了解

    VK-GL-CTS 初步了解 下载 地址:https://github.com/KhronosGroup/VK-G...

  • 初步了解

    什么是css语法?CSS (Cascading Style Sheets) 层叠样式表,用来编辑 HTML中元素...

  • LLVM 初步了解

    什么是LLVM 官网:https://llvm.org/ LLVM项目是模块化、可重用的编译器以及工具链技术的集合...

  • 初步了解阿德勒

    这周在读的书都可以算作心理类的。其中《幸福的勇气》《自卑与超越》和前段时间看的《被讨厌的勇气》都是阿德勒心理学理论...

  • css初步了解

    层叠样式表 (Cascading Style Sheets) css可以用来为网页创建样式表,通过样式表可以对网页...

  • Hbase初步了解

    特点:单表可以有百亿行,百万列,数据矩阵横向和纵向两个维度所支持的数据量级都非常有弹性面向列的存储和权限控制(可以...

  • 初步了解ObjectMapper

    参考GitHub - Hearst-DD/ObjectMapper: Simple JSON Object map...

  • 初步了解RTP

    实时传输协议RTP(Real-time Transport Protocol)是一个网络传输协议,RTP协议...

  • 初步了解RTMP

    1 RTMP 实时消息传输协议,是现在比较常用的协议 它有三种变种: 1)工作在TCP之上的明文协议,使用端口19...

  • OkHttp 初步了解

    http://blog.csdn.net/lmj623565791/article/details/4791108...

网友评论

      本文标题:VK-GL-CTS 初步了解

      本文链接:https://www.haomeiwen.com/subject/yythurtx.html