[ZZ] cbuffer和tbuffer

[ZZ] cbuffer和tbuffer

http://blog.chinaunix.net/uid-20235103-id-2578297.html

 

 Shader Model 4支持的新东西,通过打包数据可以获得更好的性能。原文转发:
Shader Constants (DirectX HLSL)

In shader model 4, shader constants are stored in one or more buffer resources in memory. They can be organized into two types of buffers: constant buffers (cbuffers) and texture buffers (tbuffers). Constant buffers are optimized for constant-variable usage, which is characterized by lower-latency access and more frequent update from the CPU. For this reason, additional size, layout, and access restrictions apply to these resources. Texture buffers are accessed like textures and perform better for arbitrarily indexed data. Regardless of which type of resource you use, there is no limit to the number of constant buffers or texture buffers an application can create.

Declaring a constant buffer or a texture buffer looks very much like a structure declaration in C, with the addition of the register and packoffset keywords for manually assigning registers or packing data.

BufferType [Name] [: register(b#)] {     VariableDeclaration [: packoffset(c#.xyzw)];      … };

 

Parameters BufferType

[in] The buffer type.

BufferType Description
cbuffer constant buffer
tbuffer texture buffer

 

Name

[in] Optional, ASCII string containing a unique buffer name.

register(b#)

[in] Optional keyword, used to manually pack constant data. Constants can be packed in a register only in a constant buffer, where the starting register is given by the register number (#).

VariableDeclaration

[in] Variable declaration, similar to a structure member declaration. This can be any HLSL type or effect object (except a texture or a sampler object).

packoffset(c#.xyzw)

[in] Optional keyword, used to manually pack constant data. Constants can be packed in any constant buffer, where the register number is given by (#). Sub-component packing (using xyzw swizzling) is available for constants whose size fit within a single register (do not cross a register boundary). For instance, a float4 could not be packed in a single register starting with the y component as it would not fit in a four-component register.

Remarks

Constant buffers reduce the bandwidth required to update shader constants by allowing shader constants to be grouped together and committed at the same time rather than making individual calls to commit each constant separately.

A constant buffer is a specialized buffer resource that is accessed like a buffer. Each constant buffer can hold up to 4096 vectors; each vector contains up to four 32-bit values. You can bind up to 14 constant buffers per pipeline stage (2 additional slots are reserved for internal use).

A texture buffer is a specialized buffer resource that is accessed like a texture. Texture access (as compared with buffer access) can have better performance for arbitrarily indexed data. You can bind up to 128 texture buffers per pipeline stage.

A buffer resource is designed to minimize the overhead of setting shader constants. The effect framework (see ID3D10Effect Interface) will manage updating constant and texture buffers, or you can use the Direct3D API to update buffers (see Copying and Accessing Resource Data (Direct3D 10) for information). An application can also copy data from another buffer (such as a render target or a stream-output target) into a constant buffer.

For additional information on using constant buffers in a D3D10 application see Resource Types (Direct3D 10) and Creating Buffer Resources (Direct3D 10).

For additional information on using constant buffers in a D3D11 application see Introduction to Buffers in Direct3D 11 and How to: Create a Constant Buffer.

A constant buffer does not require a view to be bound to the pipeline. A texture buffer, however, requires a view and must be bound to a texture slot (or must be bound withSetTextureBuffer when using an effect).

There are two ways to pack constants data: using the register (DirectX HLSL) and packoffset (DirectX HLSL) keywords.

Differences between Direct3D 9 and Direct3D 10 and 11:

Unlike the auto-allocation of constants in Direct3D 9, which did not perform packing and instead assigned each variable to a set of float4 registers, HLSL constant variables follow packing rules in Direct3D 10 and 11.

 

Organizing constant buffers

Constant buffers reduce the bandwidth required to update shader constants by allowing shader constants to be grouped together and committed at the same time rather than making individual calls to commit each constant separately.

The best way to efficiently use constant buffers is to organize shader variables into constant buffers based on their frequency of update. This allows an application to minimize the bandwidth required for updating shader constants. For example, a shader might declare two constant buffers and organize the data in each based on their frequency of update: data that needs to be updated on a per-object basis (like a world matrix) is grouped into a constant buffer which could be updated for each object. This is separate from data that characterizes a scene and is therefore likely to be updated much less often (when the scene changes).

cbuffer myObject



float4x4 matWorld;

float3 vObjectPosition;

int arrayIndex;

}

cbuffer myScene

{

float3 vSunPosition;

float4x4 matView;

}

Default constant buffers

There are two default constant buffers available, $Global and $Param. Variables which are placed in the global scope are added implicitly to the $Global cbuffer, using the same packing method as is used for cbuffers. Uniform parameters in the parameter list of a function appear in the $Param constant buffer when a shader is compiled outside of the effects framework. When compiled inside the effects framework, all uniforms must resolve to variables defined in the global scope.

Examples

Here is an example from Skinning10 Sample that is a texture buffer made up of an array of matrices.

tbuffer tbAnimMatrices

{

matrix g_mTexBoneWorld[MAX_BONE_MATRICES];

};

This example declaration manually assigns a constant buffer to start at a particular register, and also packs particular elements by subcomponents.

cbuffer MyBuffer : register(b3)

{

float4 Element1 : packoffset(c0);

float1 Element2 : packoffset(c1);

float1 Element3 : packoffset(c1.y);

}

Related Topics Shader Model 4

 

 另:

在DirectX10 SDK的范例中,主要是使用Effect框架来组织Shader。但是有些情况下,引擎需要自己来生成或管理shader,sampler,textrue等,这样Effect框架的灵活性就显的不够了。

SDK的“HLSLWithoutFX10 Sample”中 演示了如何不使用Effect框架的方法,但是有些问题没有说到。主要是关于Shader与应用程序间的数据传递。要传递的数据主要有 constant buffer,samplerstate,textrue(resource)。查阅了一些资料加上摸索加上Exjoy的帮助,整理了 一下不使用Effect框架来管理数据传递的方法。主要有两种:

1 最简单也是直接的就是用寄存器名来绑定数据了。

首先是constant的传递。

这 里要先提一下DirectX10中新引入的constant buffer。在DX10中,constant存放于常量缓冲区中,每个常量缓冲区由 4096个常量寄存器组成,共有16个常量缓冲区。这样就可以根据constant更新的频率来组织,可以提升性能。Constant buffer会为 两种:cbuffer,tbuffer。注意tbuffer是并不是用来存储纹理的,而是指可以像纹理那样来访问其中的数据,对于索引类数据有更好的性 能。

来看实例:

在shader中有如下定义

cbuffer MyBuffer : register(b3)

{

float4 Element1 : packoffset(c0);

float1 Element2 : packoffset(c1);

float1 Element3 : packoffset(c1.y);

}

 

register(bN):b表示constant buffer,N为input slot (0-15) 。

即表示Mybuffer存放于b3中。

在应用程序中使用如下。

 

g_pd3dDevice->VSSetConstantBuffers( 3, 1, pBuffers );

 

 

第一个参数即为要传递的buffer放置的slot起点。类似的函数PSSetConstantBuffers,GSSetConstantBuffers。

Textrue类似,语法为register(tN), t 表示纹理,N 为input slot (0-127) 。

例,PS中:

Texture2D txDiffuse : register(t3);

应用程序中:g_pd3dDevice->PSSetShaderResources( 3, 1, texViewArray );

 

 

Samplers语法为register(sN), s 表示取样器,s 为input slot (0-127) 。

例,PS中:

SamplerState samLinear2 : register(s4)

{

Filter = MIN_MAG_MIP_LINEAR;

AddressU = Wrap;

AddressV = Wrap;

};

 

应用程序中使用的函数为ID3D10Device::PSGetSamplers()。

 

 

2 使用shader reflect系统

这种方法可以按变量名来传递数据。

举个例子来说吧,PS中有如下定义:

 

Texture2D txDiffuse;

SamplerState samLinear

{

Filter = MIN_MAG_MIP_LINEAR;

AddressU = Wrap;

AddressV = Wrap;

};

cbuffer pscb0

{

float4 color;

};

 

 

(1)创建一个ID3D10ShaderReflection对象,通过这个对象可以从已编译好的shader中取得相应的信息。

hr = D3D10ReflectShader( (void*) pPSBuf->GetBufferPointer(), pPSBuf->GetBufferSize(),&pIShaderReflection );

 

(2)调用GetDesc,得到的D3D10_SHADER_DESC中的BoundResources为当前的shader绑定的resource数量。这里的resouce包括了constant buffer,texture,sampler,此处返回的BoundResources为3。

D3D10_SHADER_DESC desc;

if( pIShaderReflection )

{

pIShaderReflection->GetDesc( &desc );

}

 

 

(3)使用GetResourceBindingDesc得到具体的每个resource的绑定信息。

D3D10_SHADER_INPUT_BIND_DESC resourceBindingDesc0;

D3D10_SHADER_INPUT_BIND_DESC resourceBindingDesc1;

D3D10_SHADER_INPUT_BIND_DESC resourceBindingDesc2;

if( pIShaderReflection )

{

pIShaderReflection->GetResourceBindingDesc(0, &resourceBindingDesc0);

pIShaderReflection->GetResourceBindingDesc(1, &resourceBindingDesc1);

pIShaderReflection->GetResourceBindingDesc(2, &resourceBindingDesc2 );

}

 

     D3D10_SHADER_INPUT_BIND_DESC结构中的主要的属性有:

     LPCSTR Name  绑定的resource的名字

     D3D10_SHADER_INPUT_TYPE Typ

       D3D10_SHADER_INPUT_TYPE为枚举        量:D3D10_SIT_CBUFFER,D3D10_SIT_TBUFFER,

    D3D10_SIT_TEXTURE,D3D10_SIT_SAMPLER

   注意,此处的D3D10_SIT_CBUFFER,D3D10_SIT_TBUFFER都是指constant buffer。     UINT BindPoint:资源绑定的slot。即我们要使用的。

 

此处结果为:

resourceBindingDesc0  samLinear

resourceBindingDesc1  txDiffuse

resourceBindingDesc2  pscb0

 

(4)根据(3)得到的信息进行具体的绑定,我们要绑定纹理,所以使用resourceBindingDesc1:

 

 

const char* texname1 = “txDiffuse”;

if( strcmp( texname1, resourceBindingDesc1.Name) == NULL )

{

    //给PS设置纹理

g_pd3dDevice->PSSetShaderResources( resourceBindingDesc1.BindPoint, 1, texViewArray );

}

 

 

Constant buffer和sampler类似。

转载于:https://www.cnblogs.com/kylegui/p/3854182.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/100834.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • voliate关键字[通俗易懂]

    voliate关键字[通俗易懂]1.voliate简介在上一篇文章中我们深入理解了java关键字synchronized,我们知道在java中还有一大神器就是关键volatile,可以说是和synchronized各领风骚,其中奥妙,我们来共同探讨下.通过上一篇的文章我们了解到synchronized是阻塞同步的,在线程竞争激烈的情况下会升级为重量级锁。而voliate就可以说是java虚拟机提供的最轻量级的同步锁。但它同时…

    2022年4月29日
    81
  • 从汇编语言到Windows内核编程_windows内核编程pdf

    从汇编语言到Windows内核编程_windows内核编程pdf天书夜读-从汇编语言到Windows内核编程链接:https://pan.baidu.com/s/1sk6alCWRQvDziEYLUrxArw提取码:podo

    2022年10月8日
    0
  • 模糊隶属函数确定例题_高斯隶属度函数

    模糊隶属函数确定例题_高斯隶属度函数1、模糊隶属度函数的确定方法直觉法:人们用自己对模糊概念的认识和理解,或者人们对模糊概念的普遍认同来建立隶属函数。这种方法通常用于描述人们熟知、有共识的客观模糊现象,或者用于难于采集数据的情形。二元对比排序法:二元对比排序方法就是通过对多个对象进行两两对比来确定某种特征下的顺序,由此来决定这些对象对该特征的隶属程度。这种方法更适用于根据事物的抽象性质由专家来确定隶属函数的情形,可以通过多名专家或者一个委员会,甚至–次民意测验来实施。模糊统计实验法:类似于统计学中的大样本实验法,根据概

    2022年10月29日
    0
  • cover letter 和response letter的写法

    cover letter 和response letter的写法http://emuch.net/bbs/viewthread.php?tid=988184&fpage=1投稿感受和体会bydingdang15fromemuch投稿感受和体会bydingdang15fromemuch几个月前认识了小木虫网站,从此就喜欢上了这里.每天有空都上这里,看一下虫友发表论文的经验,体会,怎么投稿,怎么回复审稿人的意见等,还有热心虫友提供的英文

    2022年5月1日
    36
  • 【数据库】count(*),count(1)和count(列)

    【数据库】count(*),count(1)和count(列)【数据库】count(*),count(1)和count(列)

    2022年4月25日
    41
  • Python文本情感分析_Python数据分析实战

    Python文本情感分析_Python数据分析实战本文由来为了赚足学分丰富假期生活,初衷是分析老师对学生作业的评价和学生对老师的评价的。本来这个任务是在N多天前就应该完成了,无奈本人懒癌晚期+拖延症不想治疗,不是因为火烧眉毛就绝对没有今天的文章。本文旨在记录自己的学习过程,就这样,开干啦!序幕既然题目是“基于情感词典的文本情感分析”,那么情感词典就是必不可少的了。对于情感词典的要求:要包含积极的词语和消极的词语、每一种类的数量要足够多、包含足够广…

    2022年8月23日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号