Jump to content
  • Advertisement
Sign in to follow this  
stu_pidd_cow

DX11 [D3D11] Constant buffers and textures...

This topic is 2780 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to get my head around textures, but I think I'm coming to the realisation that I don't understand constant buffers entirely, either. My biggest trouble is finding how to link access a texture from a shader.

I have created a ID3D11ShaderResourceView via D3DX11CreateShaderResourceViewFromFile and everything has worked fine up to here. I've heard that constant buffers and textures are completely different, and that I have to link it to a shader using CSSetShaderResources. Is this right? How am I then supposed to access this particular texture from the shader?

On a similar note, how do constant buffers work in terms of accessing it from the shader? The way I understand it is the constant buffer is treated as an array (or memory block), and you access a particular part of it by using register( c# ) where # is the start of the memory you want to use. Is this correct?

Thanks.

Share this post


Link to post
Share on other sites
Advertisement
A constant buffer is bound to the pipeline directly instead of needing a resource view like the texture. Using both of these resource types from within HLSL requires the declaration of an appropriate resource object in the HLSL code. For example, here is a sample shader that has a constant buffer declared in it:


cbuffer Transforms
{
matrix WorldViewProjMatrix;
matrix WorldViewMatrix;
};


struct VS_INPUT
{
float3 position : POSITION;
float2 tex : TEXCOORDS0;
float3 normal : NORMAL;
};

struct VS_OUTPUT
{
float4 position : SV_Position;
float2 tex : TEXCOORDS0;
float3 normal : NORMAL;
};


VS_OUTPUT VSMAIN( in VS_INPUT input )
{
VS_OUTPUT output;

output.position = mul( float4( input.position, 1.0f ), WorldViewProjMatrix );
output.tex = input.tex;

float3 ViewSpaceNormals = mul( float4( input.normal, 0.0f ), WorldViewMatrix ).xyz;
output.normal = ViewSpaceNormals * 0.5f + 0.5f;

return output;
}

And here is the matching pixel shader with a texture declared in it:

Texture2D       ColorTexture : register( t0 );           
SamplerState LinearSampler : register( s0 );


struct VS_OUTPUT
{
float4 position : SV_Position;
float2 tex : TEXCOORD0;
float3 normal : NORMAL;
};

float4 PSMAIN( in VS_OUTPUT input ) : SV_Target
{
float4 vValues = ColorTexture.Sample( LinearSampler, input.tex );

return( vValues );
}

You have the option of either sampling a texture or directly loading its memory, both of which are performed with the methods of the resource object that is declared (as shown above).

The constant buffer contents are globally visible within the scope of the file taht they are declared in. So from the first snippet above, the named parameters WorldViewProjMatrix and WorldViewMatrix are both visible as if they weren't declared inside the cbuffer. This means that the names within all of your cbuffers need to unique as well, so watch out for that.

Share this post


Link to post
Share on other sites
You bind a texture by setting its shader resource view onto the pipeline for whichever stage you want to access it. So PSSetShaderResources for the pixel shader, VSSetShaderResources for the vertex shader, etc. Constant buffers on the other hand are bound with PSSetConstantBuffers or the equivalent for the stage you want to use them in.

Constant buffers in shaders provide a very simple way to access a small number of individual constants in your shader. You access individual constants as if they were global variables. It looks like this:

cbuffer VSConstants : register(cb0)
{
float4x4 World;
float4x4 WorldViewProjection;
}

// Vertex shader
VSOutput VSMain(in VSInput input)
{
float3 worldPos = mul(input.Position, World).xyz;
...
}


Textures are accessed using a Texture object. There's a few types of texture objects (Texture2D, Texture3D, TextureCube, Texture2DMS) depending on the type and MSAA settings for the texture. See the documentation for the methods you can call on a texture object. "Sample" is the most standard, where you provide texture coordinates and a sampler state. This allows you to do your standard texture fetch with linear/aniso filtering + mipmapping. The other methods are useful for more specialized cases.

I would suggest that you have a look through the samples that come with the SDK. Almost all of them use textures and constant buffers.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!