Jump to content

View more

Image of the Day

Inventory ! Va falloir trouver une autre couleur pour le cadre D: #AzTroScreenshot #screenshotsaturday https://t.co/PvxhGL7cOH
IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

Sign up now

Difference between two ways of assigning values to variables in HLSL constant buffer

4: Adsense

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 wngabh11   Members   


Posted 12 February 2013 - 01:47 AM

As far as I know, There are two way passing values to variables in HLSL constant buffer.

cbuffer cbGeometryRender : register( b0 )
    float4x4 WorldMatrix;
    float4x4 ViewMatrix;
    float4x4 ProjMatrix;
    float4x4 WVPMatrix;
    float4x4 VPMatrix;    
    float3 EyePos;
    float3 LightDir; // start at the sun
    float4 SplitPos;



The first way is to use Effect11 Library. For example

ID3DX11Effect *pEffect; // initialize when compiling the fx file
ID3DX11EffectVectorVariable *pEyePos = pEffect->GetVariableByName("EyePos")->AsVector();



The second way is to use the constant buffer created with the desc in the following.

 bd.Usage = D3D11_USAGE_DYNAMIC;
 bd.ByteWidth = sizeof( CONSTANT_BUFFER_STRUCT );
 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
 bd.MiscFlags = 0;
 hr = pd3dDevice->CreateBuffer( &bd, NULL, &g_pCB ); 



On each frame, we map g_pCB to b0, assign the values, and then unmap it. After that, We set constant buffer for each stage.


IS Anyone who know what the differences are between these two methods?

which is better?

can Effect11 Library be used with deferred context?


Can these two ways be used together, i.e., using Effect Library compile the fx file and using the second way to pass the value to GPU?

Edited by wngabh11, 12 February 2013 - 02:01 AM.

#2 MJP   Moderators   


Posted 12 February 2013 - 02:11 AM

The effects framework is just a wrapper on top of core D3D11 functionality. Ultimately it will create, map, and bind buffers just like you've described in your second way. If you step through the calls in your debugger or capture a frame in PIX you'll be able to see what it's doing. The main difference is that it might be more convenient than dealing with the buffer manually, although it may consume more resources and/or do things in a sub-optimal way.

#3 wngabh11   Members   


Posted 12 February 2013 - 03:20 AM

Thanks for help. 

I try to mix two way together. In each frame, I do things in the following order:




ID3DX11EffectTechnoque->GetPassByIndex(0)->Apply( 0, DeviceContext );

Map constant buffer

assign values

Umap constant buffer








But If i render in the order above, I cannot pass the values correctly and thereby cannot render correct things.

Is the order wrong? Or I cannot mix the two ways?

#4 mhagain   Members   


Posted 12 February 2013 - 05:41 PM

The Effects11 source code is available and can be examined; you'll find it at e.g. C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Samples\C++\Effects11


Looking through how it handles cbuffer updates, the way it works is that it builds a chunk of memory representing the cbuffer data, then each Effect->Set call will root through that and copy your data to the appropriate place (setting a dirty flag while doing so), like so:


template<typename IBaseInterface, BOOL IsAnnotation>
HRESULT TIntScalarVariable<IBaseInterface, IsAnnotation>::SetFloat(float Value)
    LPCSTR pFuncName = "ID3DX11EffectScalarVariable::SetFloat";
    if (IsAnnotation) return AnnotationInvalidSetCall(pFuncName);
    return CopyScalarValue<ETVT_Float, ETVT_Int, float, FALSE>(Value, Data.pNumericInt, pFuncName);


Then, before draw calls are issued, it checks if the dirty flag is set and if so it uploads the entire buffer via UpdateSubresource, like so:


// Update constant buffer contents if necessary
D3DX11INLINE void CheckAndUpdateCB_FX(ID3D11DeviceContext *pContext, SConstantBuffer *pCB)
    if (pCB->IsDirty && !pCB->IsNonUpdatable)
        // CB out of date; rebuild it
        pContext->UpdateSubresource(pCB->pD3DObject, 0, NULL, pCB->pBackingStore, pCB->Size, pCB->Size);
        pCB->IsDirty = FALSE;


You can probably do a little better than that yourself (you can also do much worse if you don't manage your cbuffers properly, of course).


It's probably not a good idea to mix the two ways as all it takes is one dirty flag (i.e. one cbuffer variable set via Effects) to cause the entire cbuffer to be marked dirty, which will stomp over anything you set yourself.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.