Sign in to follow this  
maogenc

What are the pros&cons of using HLSL techniques vs native C++ API calls?

Recommended Posts

I'm in the middle of writing a toy rendering engine & have been using native C++ DirectX API calls to handle scene rendering.
For example, I am currently using something that looks like this to manage my shaders:

[source lang="cpp"]
//scene initialization

hr = CompileShaderFromFile(L"ShadowMapping.hlsl", shaderList[i].name, shaderList[i].model, &pShaderBlob);
pShader = CreateShader(pD3DDevice, shaderList[i].model[0], pShaderBlob);
shaderList[i].pShader = pShader;
shaderList[i].pShaderBlob = pShaderBlob;


//scene rendering -- eventually this will be dynamic

pImmediateContext->VSSetShader( (ID3D11VertexShader *)shaderList[1].pShader, NULL, 0 );
pImmediateContext->VSSetConstantBuffers( 0, 1, &pCBNeverChanges );
pImmediateContext->VSSetConstantBuffers( 1, 1, &pCBChangeOnResize );
pImmediateContext->VSSetConstantBuffers( 2, 1, &pCBChangesEveryFrame );

pImmediateContext->PSSetShader( (ID3D11PixelShader *)shaderList[8].pShader, NULL, 0 );
pImmediateContext->PSSetConstantBuffers( 0, 1, &pCBNeverChanges );
pImmediateContext->PSSetConstantBuffers( 2, 1, &pCBChangesEveryFrame );
pImmediateContext->PSSetShaderResources( 0, 1, &pTextureSRV );
pImmediateContext->PSSetShaderResources( 1, 1, &pShadowMapSRView);
pImmediateContext->PSSetSamplers( 0, 1, &pSamplerLinear );
pImmediateContext->PSSetSamplers( 1, 1, &pCmpSampler );

pImmediateContext->GSSetShader( NULL, NULL, 0 );
[/source]


I've also seen people use HLSL techniques like this:
[source lang='cpp']
//HLSL code
technique10 RenderPassStandard
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PS_STANDARD() ) );
SetRasterizerState( backFaceCulling );
}
}

//C++ application code
pRenderTechnique = pEffect->GetTechniqueByName("RenderPassStandard");
pRenderTechnique->GetPassByIndex(0)->Apply( 0 );
[/source]


The obvious difference is that using HLSL techniques is less complicated. What are other considerations in using one over the other?

Share this post


Link to post
Share on other sites
To be clear, those techniques aren't really HLSL. They're effect code, that has to be used in conjunction with the Effects framework.

Anyway the major advantage is that you can keep a lot of state and constant data easily organized in one text file, which makes it simpler to author materials. So for instance if you wanted some transparent material you could author the shader to output alpha, and put a blend state in the same file that enables alpha blending. The major downside is that you have no control over how any of that stuff happens, so you can't apply custom optimizations to suit your engine/game or add new features.

Share this post


Link to post
Share on other sites
The states like, rasterizer state, blendstate, depthstate, Texture Sampler States, etc can be set inside of HLSL files, however, they can also be set through c++ code. The advantage of doing this in c++ is that you can keep track of which state is currently in effect and organize your drawing so that the smallest amount of state changes occur.

c++ basically gives you the ability to manage better, where HLSL typically means it is hard-coded. Try to code as much as possible in c++ to give you the most flexibility.

Share this post


Link to post
Share on other sites
I'm using both methods. I use the Effects framework only to obtain information like which shaders to use and to read annotations. But for rendering, I don't use the Effects framework at all, and instead manually set the shaders, resources, constant buffers, and other state info directly to the D3D API.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this