资源


资源是用于渲染场景的纹理和缓存。应用程序需要创建、载入、复制和使用资源。本节简要介绍资源及应用程序使用资源所需的步骤和方法。更多有关特定资源类型的信息,请参阅纹理顶点缓存索引缓存

所有资源,包括几何体资源IDirect3DIndexBuffer9IDirect3DVertexBuffer9都继承自IDirect3DResource9接口。纹理资源,IDirect3DCubeTexture9IDirect3DTexture9IDirect3DVolumeTexture9都继承自IDirect3DBaseTexture9接口。

信息被分为以下主题:


资源属性


所有资源共享以下属性。

对资源的使用是强制的。若应用程序要将资源用于某一操作,则必须在资源创建时说明该操作。关于为资源定义的用途常数表,请参阅D3DUSAGE

D3DUSAGE_RTPATCHESD3DUSAGE_NPATCHESD3DUSAGE_POINTS常数告诉驱动程序这些缓存将分别被用于triangular patchs,grid patchs,N-patchs,或点精灵。提供这些标志是为了以防万一硬件不使用主机处理就无法执行这些操作,因此驱动程序希望把这些表面分配在系统内存中,让CPU可以访问它们。如果驱动程序可以完全用硬件执行这些操作,那么它可以将这些表面分配在加速图形接口(AGP)内存中,这样既避免了在主机保存一份复本,又提高了性能,一举两得。注意这些标志提供的信息并不是绝对必需的。驱动程序可以检测正在对数据执行这类操作,并在随后几帧把缓存移回系统内存。

有关用途标志及它们与特定资源如何关联的细节,请参阅每个资源创建方法的参考页。

有关资源的表面格式的信息,请参阅D3DFORMAT枚举类型。

存放资源缓存的那种内存被称为池。池的值由D3DPOOL枚举类型定义。对于单个资源包含的不同对象也就是说,mipmap中的mip levels),池不能混合,并且一旦为某资源选择了池,池就不能再被改变了。

资源类型是在运行的时候,当应用程序调用诸如IDirect3DDevice9::CreateCubeTexture之类的资源创建方法时隐式设置的。资源类型由D3DRESOURCETYPE枚举类型定义。应用程序可以在运行的时候查询这些类型,但是,最好大多数场景都无需进行运行时类型检查。


操控资源


为了渲染场景,应用程序需要操控资源。首先,应用程序用以下方法创建纹理资源。

由纹理创建方法返回的纹理对象是表面或立体纹理的容器,这些容器一般被称为缓存。资源拥有的缓存在继承资源的用途、格式和池的同时也有自己的类型。更多信息请参阅资源属性

为了载入图片,应用程序应该调用以下方法,得到对所包含的表面的访问权。更多细节请参阅锁定资源

lock方法接收的参数指出了所包含的表面——例如,纹理的mipmap sub-level或立方体纹理的表面——并返回指向像素的指针。一般的应用程序从不直接使用表面对象。

另外,应用程序用以下方法创建面向几何体的资源。

应用程序通过调用以下方法锁定并填充缓存资源。

如果应用程序允许Microsoft® Direct3D®运行库管理这些资源,那么资源创建过程就到此为止。否则,应用程序还要通过调用IDirect3DDevice9::UpdateTexture方法,负责把系统资源提升为设备可访问的资源,这样硬件加速器就可以使用它们。

要呈现(present)从资源渲染得到的图像,应用程序还需要颜色和深度/模板缓存。对于一般的应用程序,颜色缓存属于设备的交换链,交换链是一个后缓存表面的集合,由设备隐式地创建。深度/模板缓存表面可以被隐式创建,或使用IDirect3DDevice9::CreateDepthStencilSurface方法显式创建。应用程序通过调用IDirect3DDevice9::SetRenderTarget方法将设备与它的深度和颜色缓存关联起来。

更多有关呈现(presenting)最终图像的细节,请参阅呈现场景(Presenting a Scene)


锁定资源


锁定资源意味着允许CPU对它的存储器进行访问,Direct3D为资源定义了以下锁定方法。

有关锁定标志及它们如何与特定资源关联的细节,请参阅每个资源锁定方法的参考页。应用程序开发者应该注意D3DLOCK_DISCARD,D3DLOCK_READONLY和D3DLOCK_NOOVERWRITE标志只是提示。运行库不检查应用程序是否遵循由这些标志指定的功能。可以想象如果应用程序先指定D3DLOCK_READONLY但然后写入资源,那么肯定会导致未定义的结果。一般来说,不正当地使用锁定标志,包括锁定用途标志,将无法保证今后释放操作会成功并可能导致严重的性能下降。

一个锁定操作后应该跟随一个解锁操作。例如,在锁定一个纹理后,应用程序随后通过给锁定的纹理解锁以结束对它的访问。除了允许处理器的访问外,在锁定期间,任何涉及到该资源的其它操作被序列化(译注:可能是在锁定期间,把涉及到该表面的其它操作都记录下来,但并不真正执行,等到解锁后再执行被记录下来但并未执行的操作)。对资源的锁定只允许有一次,即使是不重叠的区域,只要一个表面的锁定操作仍未完成,硬件加速器就不能对该表面进行操作。

每种资源接口都有锁定该资源所包含的缓存的方法。每种纹理资源还可以锁定它的一部分。二维资源(表面)允许锁定子矩形(sub-rectangle),立体纹理资源允许锁定子卷或子盒(sub volume or boxes)。每种锁定方法返回一个结构,它包含了指向存放资源的存储器的指针和表示行或位面数据之间的距离值(译注:亦即pitch),该距离值取决于资源的类型。更多细节,请参阅资源接口的方法列表。返回的指针总是指向被锁定子区域的左上角。

当使用索引或顶点缓存时,可以进行多次锁定调用,但是,必须确保锁定调用的数量与解锁调用的数量相同。

因为Microsoft DirectX®的压缩纹理格式将像素编码为4×4的块进行存储,所以只能在4×4的边界进行锁定操作。


资源间的关系


下图描绘了在句法上可能对特定资源及其所含内容进行的操作。更多有关如何使用资源的信息,请参阅管理资源

从左到右的箭头表示目标类型由箭头指向的方法创建,而从右到左的箭头表示这些类型的资源可以作为参数传入由箭头指向的方法。


管理资源


资源管理是将资源从系统内存提升到设备可访问存储器及从设备可访问存储器中抛弃的过程。Microsoft® Direct3D®运行库有自己的基于最近最少使用(least-recently-used)优先级技术的管理算法。当Direct3D检测到在一帧中——在IDirect3DDevice9::BeginSceneIDirect3DDevice9::EndScene调用之间——设备可访问内存无法同时存储所有资源时,它就切换到最近最多使用(most-recently-used)优先级技术。

在创建时使用D3DPOOL_MANAGED标志指定一个由系统管理的资源。由系统管理的资源在设备的丢失状态和操作状态间的转换中持续存在。通过调用IDirect3DDevice9::Reset设备可以被重置,并且这类资源可以继续正常运作而无需重新载入图片。但是,如果设备必须被销毁和重建,那么所有用D3DPOOL_MANAGED创建的资源也必须被重建。

在创建时使用D3DPOOL_DEFAULT标志指定把资源放在默认的池中。在默认的池中的资源在设备从丢失状态到操作状态的转换过程中不持续存在,这些资源必须在调用Reset之前释放,然后重建。

更多有关设备的丢失状态的信息,请参阅丢失的设备

注意不是所有的类型和用途都支持资源管理。例如,用D3DUSAGE_RENDERTARGET标志创建的对象不支持资源管理。另外,不建议对需要频繁改变其内容的对象使用资源管理。例如,在某些硬件上对一个每帧都需改变的顶点缓存进行自动管理会严重降低性能。但是,对纹理资源来说这不是一个问题。


由应用程序管理的资源及分配策略


由系统管理的顶点缓存或索引缓存在创建时不能通过指定D3DUSAGE_DYNAMIC标志被声明为动态的,这就使得对顶点缓存内容的每一次修改都需要一次额外的复制操作。动态顶点缓存用于渲染动态几何体,数据从BSP树(binary space partition tree)或其它用于可见判别的数据结构引入。为了完成这个任务,可以预先为想要使用的格式分配缓存。这些资源然后通过应用程序中的资源管理器分配出去以满足应用程序的需要。因为应用程序同时使用为数不多的不同的顶点跨度(vertex stride),并且只有不同的跨度才需要不同的顶点缓存,所以动态顶点缓存的总数很小。当用这种方式管理动态资源时,需要保证对资源的频繁需求不会严重降低应用程序的性能。

当使用同时由Direct3D和由应用程序管理的资源时,应该在创建任何由Direct3D管理的资源之前,把由应用程序管理的资源分配在D3DPOOL_DEFAULT内存中。这使Direct3D的内存管理器可以保持对可用内存的精确计数。