从外观上来看,每个glSet都必须在其中包含glBind(something)
不完全是。正如下面几段所述,这是另一种方式。
即使是事实,请记住,与常规函数调用相比,从客户端应用程序到GL服务器(又称为驱动程序)的GL命令具有大量的调度开销。即使我们假设DSA函数只是现有函数的包装器,它们还是位于GL服务器内部的包装器,因此可以(少)减少开销。
如果OpenGL仍然是状态机,则无法利用流式处理应用于单个对象的更改。
GPU不是状态机。GL状态机接口是一种模拟,它包装了类似DSA的驱动程序内部组件,而不是相反。
清除一层包装(即需要大量调用GL服务器的一层)显然是一个胜利,即使只有很小的一层。
在处理多个线程时,状态机方法也没有多大意义。在这种用例中,GL仍然很糟糕,但是驱动程序经常在后台使用线程,并且状态机需要大量线程同步或真正花哨的并行算法/构造才能使事情可靠地工作。
DSA扩展继续以状态更改来表达其操作,因为毕竟它是对现有基于状态的文档的扩展,而不是全新的API,因此必须准备好插入现有GL规范文档的语言和术语。即使该现有语言非常适合作为现代图形硬件API的工作。
请说明新DSA的原因和优势。
最大的理由是,旧方法很痛苦。很难将可能会各自修改或依赖GL状态的库组合在一起。由于其深深的过程状态管理根源,难以以面向对象或功能形式有效包装GL API,这使得以各种非C语言包装API变得困难,也使得提供高效的图形设备包装程序变得困难从Direct3D抽象OpenGL。
第二是程序状态机API开销,如前所述。
第三,DSA函数从旧的API适当地更改了语义,从而提高了效率。例如,以前可变的东西变成不可变的,这从GL服务器中删除了很多记帐代码。当GL服务器不必处理可变对象时,可以将应用程序的调用分派到硬件或更快(或以更多并行方式)进行验证。
-
EXT_direct_state_access扩展规范中提供了其他理由和解释。
-
与API设计相关的硬件更改相当多。
记住OpenGL可以追溯到1991年。目标硬件不是消费级图形卡(不存在),而是大型CAD工作站等。那个时代的硬件与今天的性能有很大不同。多线程的情况比较少见,内存总线和CPU的速度差距较小,GPU的功能仅比固定功能三角形渲染多。
增加了越来越多的固定功能。各种照明模型,纹理模式等都已添加,每种都需要自己的状态。当您具有少数状态时,基于状态的简单方法就可以工作。随着越来越多的状态被添加,API开始在接缝处爆发。该API变得更加笨拙,但与硬件模式的区别并不大,因为它们确实基于许多状态开关。
然后,可编程硬件随之出现。硬件已经变得越来越可编程,到现在为止,硬件支持一点状态,一些用户提供的程序以及很多缓冲区。必须模仿以前时代的所有状态,就像那个时代的所有固定功能功能都被驾驶员模仿一样。
硬件也变得越来越并行。这需要其他硬件重新设计,这使得图形状态更改非常昂贵。硬件在不可变状态的大块中工作。由于这些更改,驱动程序不能简单地应用用户立即设置的状态的每一个点,而是必须自动批量处理更改并在需要时隐式应用它们。
现代硬件的运行距离经典OpenGL模型还要远。DSA是大约10年前需要的一个小更改(最初承诺是OpenGL 3.0的一部分),类似于D3D10所做的。要保持OpenGL的相关性,上述许多硬件更改所需的不仅仅是DSA,这就是为什么还可以使用更多可大大改变OpenGL模型的大型扩展的原因。然后是全新的GLnext API以及D3D12,Mantle,Metal等。其中没有一个可以保留过时的状态机抽象。