ID3D11Resource和ID3D11View

Resource:ID3D11Resource和ID3D11View
博客分类: DirectX11_API

概述:无论是什么系统,数据永远是其最核心的部分,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代码 收藏代码
DXGI_RESOURCE_PRIORITY_MINIMUM // 最小优先级
DXGI_RESOURCE_PRIORITY_LOW
DXGI_RESOURCE_PRIORITY_NORMAL
DXGI_RESOURCE_PRIORITY_HIGH
DXGI_RESOURCE_PRIORITY_MAXIMUM // 最大优先级
这两个方法用于处理,当存储空间不够的时候优先释放那些内存的,主要用于对性能的优化。这里不清楚的是,不知道是先驱逐优先级高的,还是优先级低的。
getType :获取的资源的类型,一看应该很明白哦。
Cpp代码 收藏代码
typedef enum D3D11_RESOURCE_DIMENSION {
D3D11_RESOURCE_DIMENSION_UNKNOWN = 0,
D3D11_RESOURCE_DIMENSION_BUFFER = 1,
D3D11_RESOURCE_DIMENSION_TEXTURE1D = 2,
D3D11_RESOURCE_DIMENSION_TEXTURE2D = 3,
D3D11_RESOURCE_DIMENSION_TEXTURE3D = 4
} D3D11_RESOURCE_DIMENSION;

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

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

1.定义顶点格式:用一个结构体描述顶点的信息,渲染的时候用到
Java代码
struct VertexInput // 结构体的名字任意取,成员的类型也不是必须得用D3DX的类型,关键得hlsl里面有这样的类型即可。
{
Vector3 position; // 位置
Vector3 normal; // 法向量
Vector3 tangent; // 切线
Vector3 bitangent; // 双向切线
Vector2 texture; // 纹理坐标
Color4 color; // 顶点颜色
};
这个是我自己定义的格式,根据不同需要灵活定义。

2.CreateBuffer :
Cpp代码
HRESULT CreateBuffer(
[in] const D3D11_BUFFER_DESC *pDesc,
[in, optional] const D3D11_SUBRESOURCE_DATA *pInitialData,
[out, optional] ID3D11Buffer **ppBuffer
);
最终会得到一个ID3D11Buffer对象,但是要想创建必须传入上述两个结构体对象。

3.D3D11_SUBRESOURCE_DATA :(这个结构在创建纹理的时候也会用到)
Cpp代码
typedef struct D3D11_SUBRESOURCE_DATA {
const void *pSysMem; // 指向数据源的指针
UINT SysMemPitch; // 步长,当缓存的是纹理的时候有用
UINT SysMemSlicePitch; // 同上
} D3D11_SUBRESOURCE_DATA;
这个结构比上面的简单,pSysMem此时指向数据存储在内存的源,最终它在创建buffer的时候被拷贝到一个新的位置。
4.D3D11_BUFFER_DESC :
Cpp代码 收藏代码
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 :
Cpp代码 收藏代码
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代码 收藏代码
void GetResource(
[out] ID3D11Resource **ppResource
);
这是它的唯一方法,可以获取与之对应的资源对象。
ID3D11DepthStencilView :访问数据在纹理深度模版。
ID3D11RenderTargetView :访问数据的渲染目标。
ID3D11ShaderResourceView :在着色器资源的访问数据。
ID3D11UnorderedAccessView :在一个无序的资源访问数据。

CreateShaderResourceView :其它与之类似

Cpp代码 收藏代码
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

你可能感兴趣的:(ID3D11Resource和ID3D11View)