Stencil Test(模板测试)不得不说的那些事- 中文社区博客

文章推薦指數: 80 %
投票人數:10人

Stencil test是per-fragment operations的一种,这就意味着它处于fragment shader (片段着色器)之后,stencil test的主要作用就是根据stencil buffer ... Groups ArmResearch DesignStart EducationHub Innovation OpenSourceSoftwareandPlatforms Forums AIandMLforum ArchitecturesandProcessorsforum ArmDevelopmentPlatformsforum ArmDevelopmentStudioforum ArmVirtualHardwareforum Automotiveforum CompilersandLibrariesforum Graphics,Gaming,andVRforum HighPerformanceComputing(HPC)forum InfrastructureSolutionsforum InternetofThings(IoT)forum Keilforum MorelloForum OperatingSystemsforum SoCDesignandSimulationforum 中文社区论区 Blogs AIandMLblog Announcements ArchitecturesandProcessorsblog Automotiveblog Graphics,Gaming,andVRblog HighPerformanceComputing(HPC)blog InfrastructureSolutionsblog Innovationblog InternetofThings(IoT)blog Mobileblog OperatingSystemsblog ResearchArticles SoCDesignandSimulationblog SmartHomes Tools,SoftwareandIDEsblog WorksonArmblog 中文社区博客 Support Openasupportcase Documentation Downloads Training ArmApprovedprogram ArmDesignReviews CommunityHelp More Cancel 中文社区 中文社区博客 StencilTest(模板测试)不得不说的那些事 Blogs Forum 视频和文件 Members Mentions Sub-Groups Tags Jump... Cancel New 中文社区requiresmembershipforparticipation-clicktojoin Moreblogsin中文社区 ARM中国大学计划博客 Arm新闻 中文mbed博客 中文社区博客 恩智浦汽车电子MCU讨论区博客   Tags chinese performance graphics 中文 stencil_test opengl_es Actions RSS More Cancel Relatedblogposts Relatedforumthreads StencilTest(模板测试)不得不说的那些事 FrankLi March19,2015 StencilTest是什么Stencil的中文翻译是模板或者蒙板,并不是非常容易理解的一个词。

在了解stenciltest之前,先来了解一下stencilbuffer。

在OpenGLES中,有三个可以绘制的buffer(缓存),colorbuffer(颜色缓存),depthbuffer(深度缓存)和stencilbuffer(模板缓存)。

对于colorbuffer和depthbuffer来说,buffer里面存储的一般都是浮点数,然而对于stencilbuffer,buffer存储的是无符号整数,确切的说,0或者1。

在OpenGLES中,stencilbuffer一般最大有8位,这就意味着stencilbuffer的最大值就是0xFF。

首先要建立起来的观念就是stencilbuffer的操作并不是加减乘除等算术运算,而是位操作运算。

这对理解stenciltest有很大的帮助。

下面这张图是stenciltest在graphicspipeline里面的位置,Stenciltest是per-fragmentoperations的一种,这就意味着它处于fragmentshader(片段着色器)之后,stenciltest的主要作用就是根据stencilbuffer的内容,来丢弃不需要的fragments。

Stenciltest需要的三个基本元素就是每个fragment的stencil的缓存值参考值,作为一个基准进行比较比较的函数OpenGLES提供了三个stenciltest相关的函数,voidglStencilMask(GLuintmask);voidglStencilOp(GLenumsfail,GLenumdpfail,GLenumdppass);voidglStencilFunc(GLenumfunc,GLintref,GLuintmask);简单讲一下这三个函数,glStencilMask控制着写stencilbuffer之前要做的一个与操作glStencilOp设置了在完成stenciltest后对当前fragment的stencil值的操作stenciltest的结果有三种情况stenciltest失败stenciltest成功,depthtest失败stenciltest成功,depthtest成功对于stencil值有7个操作GL_KEEPGL_ZEROGL_REPLACEGL_INCRGL_INCR_WRAPGL_DECRGL_DECR_WRAPGL_INVERTglStencilFunc提供了三个参数比较函数func,这个和depthtest是完全一样的比较基准值ref比较时需要用到的mask可以看到stenciltest提供了相当多的功能用于比较,下面的章节会详细描述下比较的算法。

StencilTest的算法在描述算法之前让我们先设定好一些变量,stencilmask.mask表示glStencilMask里面的masksfailop表示stenciltest失败的操作,dpfailop表示stenciltest成功,depthtest失败的操作,dppassop表示stenciltest成功,depthtest成功的操作,stencilop表示stenciltest后的操作stencilfunc.func表示glStencilFunc里面的func,stencilfunc.ref表示glStencilFunc.ref,stencilfunc.mask表示glStencilFunc.maskstencilbuf[]来表示stencilbuffer,[x,y]代表fragment的坐标用伪代码来表示算法, //stenciltest比较的时候需要mask status=stencilfunc.func((stencilbuf[x,y]&stencilfunc.mask),(stencilfunc.ref&stencilfunc.mask)); status|=depth_test_result; if(status==stencil_test_fail)stencilop=sfailop; elseif(status==stencil_test_pass&depth_test_fail)stencilop=dpfailop; elseif(status==stencil_test_pass&depth_test_pass)stencilop=dppassop; //stenciltest结束后的操作不需要mask stencil_new_value=stencilop(stencilbuf[x,y]); //写入stencilbuffer的时候需要另一个mask stencilbuf[x,y]=(stencil_new_value&stencilmask.mask)|(stencilbuf[x,y]&(~stencilmask.mask)); 以上就是stenciltest的全过程,其实只要能搞清楚不同的mask在stenciltest中所起的作用应该就能完全理解这个略显复杂的算法了。

StencilTest在应用程序端的性能优化对于应用程序来讲,由于各家厂商的硬件行为可能都不一致,很难写出适配所有硬件的优化好的应用程序。

但是对于stenciltest来讲,这里有一个小小的技巧可以借鉴。

大家可以留意下stenciltest的七个操作,其中有一个操作是GL_KEEP。

大家可以想象下硬件里的流水线,如果stenciltest失败了,那么就丢弃当前的fragment,并且更新stencilbuffer如果stenciltest成功了,那么就更新当前的fragment,并且更新stencilbuffer更新stencilbuffer就意味着用新的stencilvalue来替换旧的stencilvalue通常替换就意味着一个“写”的操作,从优化的角度来讲,如果新值和旧值是一样的,就可以直接跳过不写了。

所以这里就带来了一个可以在应用程序端优化的方向不管stenciltest的结果如何,只要开发者认为stencilbuffer是不需要更新的,尽量多用GL_KEEP,避免GL_REPLACE。

尤其当你觉得GL_REPLACE的功能包括了GL_KEEP的时候。

多用GL_KEEP就意味着你要仔细考虑下stenciltest的比较函数,举个例子,假如应用程序只希望写stencilbuffer,下面两种情况是等价的 glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE); glStencilFunc(GL_ALWAYS,ref,mask); glStencilOp(GL_KEEP,GL_REPLACE,GL_REPLACE); glStencilFunc(GL_NOTEQUAL,ref,mask); 希望这可以给大家带来一些启发,从而写出更好的OpenGLES程序。

中文社区博客 Armv9-A构架引入可伸缩矩阵扩展(SME) ZenonXiu(修志龙) 原文:https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/scalable-matrix-extension-armv9-a-architecture 作者:MartinWeidmannJuly14,2021 翻译:修志龙(ZenonXiu) Arm构架为从超级计算机到广泛的设备带来可伸缩的向量处理… February9,2022 Arm机密计算架构技术白皮书 ZenonXiu(修志龙) 作者:Arm首席应用工程师DavidBrooke 原文:https://developer.arm.com/documentation/den0125/0100 1.     概述 在本篇文章中,我们将介绍机密计算(ConfidentialComputing)在现代计算平台中扮演的角色,并解释机密计算的原理。

然后我们将说明Arm机密计算架构(ArmCCA)如何在Arm计算平台中实现机密计算… July16,2021 Armv8.1-MPointerAuthentication和BranchTargetIdentification扩展 ZenonXiu(修志龙) 原文作者:AlanMujumdar  April7,2021 原文链接:https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension 翻译… April19,2021



請為這篇文章評分?