Resource:ID3D11Resource和ID3D11View

概述:无论是什么系统,数据永远是其最核心的部分,DX系列火了这么多年直到今天才把其数据结构整的比较简洁。以ID3D11Resource 为基类和以ID3D11View为基类的所有类型使DX的数据分层了model-view两层结构,使得原本的数据变的更加清晰。ID3D11Resource 可以确定数据的成分是buffer还是texture,ID3D11View确定数据的应用场景是渲染目标还是深度模板。

 

资源的属性:(在创建资源的时候需要描述的内容)

Usage :资源的使用方式,例如纹理资源,是作为texture还是render target

format :数据的格式。主要是存储的格式,例如像素的存储格式之类。

pool :存放资源的存储器类型,以及管理方式。

type :资源类型。

内存划分:

1.System Memory :系统内存

2.Local Video Memory :显存,GPU会有比较高的读写能力,但是CPU读写的话效率比较低。

3.Nonlocal Video Memory (AGP/PCIE):这个是主板上的一块内存,这块内存GPU和CPU读和写的效率都比较高。

策略:如果只是CPU用的就放到系统内存,如果是GPU用的就放到LVM,如果是两者交互比较多的,就放到NVM中。此外,在使用的优先级上,GPU先使用显存,CPU先使用AGP/PCIE(效率比系统内存高)。

 

资源的介绍:

资源分为缓冲资源和纹理资源

ID3D11Resource -----> ID3D11Buffer (缓冲资源)

ID3D11Resource -----> ID3D11Texture1D,ID3D11Texture2D,ID3D11Texture3D (纹理资源)

虽然buffer和texture都是resource,但是在使用上还是有些区别。buffer在创建的时候就指定了它的view而且可以指定多种类型的view,所以在使用的时候buffer具备model和view两种身份它可以直接被hlsl使用。

 

ID3D11Resource :它不能被直接使用,一般使用它的子。

GetEvictionPriority :的资源获取驱逐优先。

SetEvictionPriority :将驱逐优先的资源。

Java代码   收藏代码

  1. DXGI_RESOURCE_PRIORITY_MINIMUM  // 最小优先级  
  2. DXGI_RESOURCE_PRIORITY_LOW  
  3. DXGI_RESOURCE_PRIORITY_NORMAL  
  4. DXGI_RESOURCE_PRIORITY_HIGH  
  5. DXGI_RESOURCE_PRIORITY_MAXIMUM // 最大优先级  

 这两个方法用于处理,当存储空间不够的时候优先释放那些内存的,主要用于对性能的优化。这里不清楚的是,不知道是先驱逐优先级高的,还是优先级低的。

getType :获取的资源的类型,一看应该很明白哦。

Cpp代码    收藏代码
  1. typedef enum D3D11_RESOURCE_DIMENSION {   
  2.   D3D11_RESOURCE_DIMENSION_UNKNOWN    = 0,  
  3.   D3D11_RESOURCE_DIMENSION_BUFFER     = 1,  
  4.   D3D11_RESOURCE_DIMENSION_TEXTURE1D  = 2,  
  5.   D3D11_RESOURCE_DIMENSION_TEXTURE2D  = 3,  
  6.   D3D11_RESOURCE_DIMENSION_TEXTURE3D  = 4  
  7. } D3D11_RESOURCE_DIMENSION;  

 

ID3D11Buffer :缓冲区接口访问缓冲区的资源,即非结构化的内存(这里提到非结构化内存是因为还有结构化内存)。缓冲区通常存储顶点或索引数据。

 

VertexBuffer 和 IndexBuffer:(分别描述顶点和顶点的索引)

 

1.定义顶点格式:用一个结构体描述顶点的信息,渲染的时候用到

Java代码 
  1. struct VertexInput  // 结构体的名字任意取,成员的类型也不是必须得用D3DX的类型,关键得hlsl里面有这样的类型即可。  
  2. {  
  3.     Vector3 position; // 位置  
  4.     Vector3 normal;   // 法向量  
  5.     Vector3 tangent;  // 切线  
  6.     Vector3 bitangent; // 双向切线  
  7.     Vector2 texture; // 纹理坐标  
  8.     Color4 color; // 顶点颜色  
  9. };  

 这个是我自己定义的格式,根据不同需要灵活定义。

 

2.CreateBuffer :

Cpp代码 
  1. HRESULT CreateBuffer(  
  2.   [in]             const D3D11_BUFFER_DESC *pDesc,  
  3.   [in, optional]   const D3D11_SUBRESOURCE_DATA *pInitialData,  
  4.   [out, optional]  ID3D11Buffer **ppBuffer  
  5. );   

 最终会得到一个ID3D11Buffer对象,但是要想创建必须传入上述两个结构体对象。 

 

3.D3D11_SUBRESOURCE_DATA :(这个结构在创建纹理的时候也会用到)

Cpp代码 
  1. typedef struct D3D11_SUBRESOURCE_DATA {  
  2.   const void *pSysMem; // 指向数据源的指针  
  3.   UINT       SysMemPitch; // 步长,当缓存的是纹理的时候有用  
  4.   UINT       SysMemSlicePitch; // 同上  
  5. } D3D11_SUBRESOURCE_DATA;  

这个结构比上面的简单,pSysMem此时指向数据存储在内存的源,最终它在创建buffer的时候被拷贝到一个新的位置。

4.D3D11_BUFFER_DESC :

typedef struct D3D11_BUFFER_DESC {  // 这个结构体对buffer的结果进行描述,站多大内容空间之类的,这样好开辟内存空间。  
  UINT        ByteWidth;  // 缓冲区大小,单位为字节  
  D3D11_USAGE Usage; // 一个枚举,描述的是GPU和CPU对此buffer的读写能力,其实这涉及到这个buffer将会存储在那个地方  
  UINT        BindFlags; // 这个描述的是buffer的类型  
  UINT        CPUAccessFlags; // 设置CPU访问权限,不访问设置为0  
  UINT        MiscFlags; // 如果不使用设置为0,可以多选,暂时不知用法  
  UINT        StructureByteStride; // ??? 不理解  
} D3D11_BUFFER_DESC;  
  
typedef enum D3D11_USAGE { // 2(描述的是访问权限) 
  D3D11_USAGE_DEFAULT    = 0,  // 默认值,GPU具备读写能力  
  D3D11_USAGE_IMMUTABLE  = 1, // GPU可读,CPU不可访问,如果选择这种方式必须得初始化buffer,你懂的  
  D3D11_USAGE_DYNAMIC    = 2, // GPU只读,CPU只写  
  D3D11_USAGE_STAGING    = 3 // 这种是CPU可以完全控制,GPU只能复制数据,与0完全相反。  
} D3D11_USAGE;  
  
typedef enum D3D11_BIND_FLAG { // 对应第3个参数,此标志是多选  
  D3D11_BIND_VERTEX_BUFFER     = 0x1L, // 顶点缓存  
  D3D11_BIND_INDEX_BUFFER      = 0x2L, // 索引缓存  
  D3D11_BIND_CONSTANT_BUFFER   = 0x4L, // 常数缓存,不可与其他标志共用  
  D3D11_BIND_SHADER_RESOURCE   = 0x8L, // view :作为渲染器的使用缓冲
  D3D11_BIND_STREAM_OUTPUT     = 0x10L, // view :作为流出去的目标缓冲
  D3D11_BIND_RENDER_TARGET     = 0x20L, // view :作为渲染目标  
  D3D11_BIND_DEPTH_STENCIL     = 0x40L, // view :作为深度模板  
  D3D11_BIND_UNORDERED_ACCESS  = 0x80L, // view :作为无序的什么东东
  D3D11_BIND_DECODER           = 0x200L, // ??? 
  D3D11_BIND_VIDEO_ENCODER     = 0x400L // ???  
} D3D11_BIND_FLAG;   
  
typedef enum D3D11_CPU_ACCESS_FLAG {  // 对应第4个参数,多选,与第二个参数要结合使用.  
  D3D11_CPU_ACCESS_WRITE  = 0x10000L,   
  D3D11_CPU_ACCESS_READ   = 0x20000L  
} D3D11_CPU_ACCESS_FLAG;  

 buffer只有3类:顶点,索引和常量。然后他们会以各种view的形势被使用D3D11_BIND_FLAG就是描述这些的。

 

 ID3D11Texture1D,ID3D11Texture2D,ID3D11Texture3D : 纹理接口访问 纹理数据,这是结构化的内存。

 

CreateTexture2D :

HRESULT CreateTexture2D( // 
  [in]   const D3D11_TEXTURE2D_DESC *pDesc,
  [in]   const D3D11_SUBRESOURCE_DATA *pInitialData,
  [out]  ID3D11Texture2D **ppTexture2D
);

typedef struct D3D11_TEXTURE2D_DESC {
  UINT             Width; // 宽度
  UINT             Height; // 高度
  UINT             MipLevels; // mip的级别
  UINT             ArraySize; // 这个值在创建纹理数组时有用
  DXGI_FORMAT      Format; // 格式,像素点存储的格式
  DXGI_SAMPLE_DESC SampleDesc; // 多重采样?
  D3D11_USAGE      Usage; // GPU和CPU对纹理的访问权限
  UINT             BindFlags; // 绑定到流水线标志 (多选)
  UINT             CPUAccessFlags; // 定制CPU访问权限
  UINT             MiscFlags; // ???
} D3D11_TEXTURE2D_DESC;

typedef struct D3D11_SUBRESOURCE_DATA {
  const void *pSysMem; // 这个指针指向数据的真实位置
  UINT       SysMemPitch; // 这两个参数描述的是纹理的跨度
  UINT       SysMemSlicePitch; //
} D3D11_SUBRESOURCE_DATA;

 

 

上述这些接口都只有一个方法:GetDesc 用来获取描述信息,这说明它们自身的内容并不是有自己提供接口给外部使用,而是借组第三方接口来进行使用。从某种意义上来讲,在我们使用的时候,我们只需把它们当中一个普通的变量即可,真正需要关注的是使用它们的类。

 

ID3D11View :一个ID3D11View的子类可以把渲染过程中,需要用到的一部分资源绑定到渲染管道。

Java代码    收藏代码
  1. void GetResource(  
  2.   [out]  ID3D11Resource **ppResource  
  3. );  

 这是它的唯一方法,可以获取与之对应的资源对象。

ID3D11DepthStencilView :访问数据在纹理深度模版。

ID3D11RenderTargetView :访问数据的渲染目标。

ID3D11ShaderResourceView :在着色器资源的访问数据。

ID3D11UnorderedAccessView :在一个无序的资源访问数据。

 

CreateShaderResourceView :其它与之类似

 

HRESULT CreateShaderResourceView(
  [in]   ID3D11Resource *pResource, // 这个就是纹理对象
  [in]   const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, // 
  [out]  ID3D11ShaderResourceView **ppSRView
);

typedef struct D3D11_SHADER_RESOURCE_VIEW_DESC {
  DXGI_FORMAT         Format; // 纹理创建的时候已经描述过这个属性,不清楚这里是否可以空着
  D3D11_SRV_DIMENSION ViewDimension; // 描述资源的类型,与union 对应
  union {
    D3D11_BUFFER_SRV        Buffer; 
    D3D11_TEX1D_SRV         Texture1D;
    D3D11_TEX1D_ARRAY_SRV   Texture1DArray;
    D3D11_TEX2D_SRV         Texture2D;
    D3D11_TEX2D_ARRAY_SRV   Texture2DArray;
    D3D11_TEX2DMS_SRV       Texture2DMS;
    D3D11_TEX2DMS_ARRAY_SRV Texture2DMSArray;
    D3D11_TEX3D_SRV         Texture3D;
    D3D11_TEXCUBE_SRV       TextureCube;
    D3D11_TEXCUBE_ARRAY_SRV TextureCubeArray;
    D3D11_BUFFEREX_SRV      BufferEx;
  };
} D3D11_SHADER_RESOURCE_VIEW_DESC;

 

 创建ResourceView本身比较简单,因为方法已经对ResourceView的性质做了决定,还有就是在创建纹理和buffer的时候也有一个标志位描述view。

 

在渲染管道的使用:

渲染管道几乎每个阶段都配备有setbuffer和setview(Resources)的方法。这即表示每个渲染阶段都能够获取到自己想要的数据,另一方面又说明buffer的传递与texture的传递并不是采用相同的API。但是,我们看到ResourceView的定义里面很明显有支持buffer的痕迹,但是在使用上又为其开小灶。不清楚微软的意图是什么?不知道如果我们不buffer定义到ResourceView里面渲染管道会怎么处理它。

 

 保存纹理到本地:

D3DX11SaveTextureToFile

 

你可能感兴趣的:(DirectX11_API)