[Zz] cbuffer and tbuffer

Source: Internet
Author: User

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

 

The new things supported by Shader Model 4 can achieve better performance by packaging data. Original article forwarding:
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 (could t 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 (#). 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 cocould not be packed in a single register starting with the Y component as it wocould 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 CALS 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 (seeId3d10effect 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 boundSettexturebufferWhen 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 CALS 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 cocould 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 ).

Copycbuffer 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.

Copytbuffer tbanimmatrices
{
Matrix g_mtexboneworld [max_bone_matrices];
};

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

Copycbuffer mybuffer: Register (B3)
{
Float4 element1: packoffset (C0 );
Float1 element2: packoffset (C1 );
Float1 element3: packoffset (c1.y );
}

Related Topics Shader Model 4

 

In addition:

In the directx10 SDK example, the shader is organized using the effect framework. However, in some cases, the engine needs to generate or manage the shader, sampler, and textrue by itself, so that the flexibility of the effect framework is insufficient.

The "hlslwithoutfx10 sample" in the SDK demonstrates how to avoid using the effect framework, but some problems are not mentioned. It is mainly about data transmission between the shader and the application. The data to be transmitted mainly includes constant buffer, samplerstate, and textrue (resource ). I checked some materials and found out how to manage data transmission without using the effect framework with the help of exjoy. There are two main types:

1. The simplest and most direct method is to bind data with the register name.

First, constant transmission.

In this case, we should first mention the constant buffer introduced in directx10. In dx10, constant is stored in the constant buffer. Each constant buffer is composed of 4096 constant registers and has 16 constant buffers. This can be organized based on the frequency of constant updates to improve performance. Constant buffer can be cbuffer or tbuffer. Note that tbuffer is not used to store textures, but to access the data like textures, which is better for index data.

Let's look at the instance:

The shader has the following definitions:

Cbuffer mybuffer: Register (B3)
{
Float4 element1: packoffset (C0 );
Float1 element2: packoffset (C1 );
Float1 element3: packoffset (c1.y );
}

 

Register (BN): B indicates the constant buffer, and N is the input slot (0-15 ).

That is, mybuffer is stored in B3.

Use the following in an application.

 

G_pd3ddevice-> vssetconstantbuffers (3, 1, pbuffers );

 

 

The first parameter is the slot start point of the buffer to be transferred. Similar functions: pssetconstantbuffers and gssetconstantbuffers.

Similar to textrue, the syntax is register (TN), t indicates texture, and N is input slot (0-127 ).

For example, in PS:

Texture2d txdiffuse: Register (T3 );

In the Application: g_pd3ddevice-> pssetshaderresources (3, 1, texviewarray );

 

 

Samplers syntax is register (SN), s indicates the sampler, and s indicates the input slot (0-127 ).

For example, in PS:

Samplerstate samlinear2: Register (S4)
{
Filter = min_mag_mip_linear;
Addressu = wrap;
Addressv = wrap;
};

 

The function used in the application is id3d10device: psgetsamplers ().

 

 

2. Use the shader reflect System

This method can pass data by variable name.

For example, PS is defined as follows:

 

Texture2d txdiffuse;

Samplerstate samlinear
{
Filter = min_mag_mip_linear;
Addressu = wrap;
Addressv = wrap;
};

Cbuffer pscb0
{
Float4 color;
};

 

 

(1) Create an id3d10shaderreflection object, through which the corresponding information can be obtained from the compiled shader.

HR = d3d10reflectshader (void *) ppsbuf-> getbufferpointer (), ppsbuf-> getbuffersize (), & pishaderreflection );

 

(2) Call getdesc. The boundresources in d3d10_shader_desc is the number of resources bound to the current shader. Here, the resouce includes the constant buffer, texture, and sampler. Here, the returned boundresources is 3.

D3d10_shader_desc DESC;
If (pishaderreflection)
{
Pishaderreflection-> getdesc (& DESC );
}

 

 

(3) Use getresourcebindingdesc to obtain the binding information of each 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 );
}

 

The main attributes in the d3d10_shader_input_bind_desc structure are:

Lpcstr nameName of the bound Resource

D3d10_shader_input_type typ

D3d10_shader_input_type is the enumerated quantity: d3d10_sit_cbuffer, d3d10_sit_tbuffer,

D3d10_sit_texture, d3d10_sit_sampler


Note that both d3d10_sit_cbuffer and d3d10_sit_tbuffer indicate constant buffer.Uint bindpoint: The slot bound to the resource. That is, what we want to use.

 

The result is as follows:

Resourcebindingdesc0 samlinear

Resourcebindingdesc1 txdiffuse

Resourcebindingdesc2 pscb0

 

(4) bind the texture according to the information obtained in step 3. Use resourcebindingdesc1:

 

 

Const char * texname1 = "txdiffuse ";

If (strcmp (texname1, resourcebindingdesc1.name) = NULL)
{
// Set texture for PS
G_pd3ddevice-> pssetshaderresources (resourcebindingdesc1.bindpoint, 1, texviewarray );
}

 

 

Constant buffer is similar to sampler.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.