Sign in to follow this  
Asesh

ID3D11DeviceContext::UpdateSubresource not updating constant buffers

Recommended Posts

The ID3D11DeviceContext::UpdateSubresource method doesn't update constant buffers that I have declared in the effect file.


// Constant buffer that changes every frame
oD3DBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; // Bind constant buffer
oD3DBufferDesc.ByteWidth = sizeof(SChangesEveryFrameConstantBuffer);
oD3DBufferDesc.Usage = D3D11_USAGE_DEFAULT; // R/W access by the GPU

CHECK_COM(pD3DDevice->CreateBuffer(&oD3DBufferDesc, NULL, &m_pD3DChangesEveryFrameConstBuffer)); // Constant buffer that changes every frame

I created that constant buffer to update this constant buffer in the effect file:


cbuffer CBEveryFrame
{
matrix m_matWorld, m_matView, m_matHomogeneous;
};

now it's time to update the constant buffer
pD3DDeviceContext->UpdateSubresource(m_pD3DChangesEveryFrameConstBuffer, 0, NULL, reinterpret_cast<void *>(g_pChangesEveryFrameConstBuffer), 0, 0);

g_pChangesEveryFrameConstBuffer points to a structure which holds world, view and homogeneous transformation matrices (XNA math)
But it wouldn't update the constant buffer that is declared in the effect file. I have checked their values via PIX and all are set to 0 cause they are not being updated. Am I missing something?

Share this post


Link to post
Share on other sites
[quote name='Asesh' timestamp='1302944487' post='4799072']
The ID3D11DeviceContext::UpdateSubresource method doesn't update constant buffers that I have declared in the effect file.


// Constant buffer that changes every frame
oD3DBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; // Bind constant buffer
oD3DBufferDesc.ByteWidth = sizeof(SChangesEveryFrameConstantBuffer);
oD3DBufferDesc.Usage = D3D11_USAGE_DEFAULT; // R/W access by the GPU

CHECK_COM(pD3DDevice->CreateBuffer(&oD3DBufferDesc, NULL, &m_pD3DChangesEveryFrameConstBuffer)); // Constant buffer that changes every frame

I created that constant buffer to update this constant buffer in the effect file:


cbuffer CBEveryFrame
{
matrix m_matWorld, m_matView, m_matHomogeneous;
};

now it's time to update the constant buffer
pD3DDeviceContext->UpdateSubresource(m_pD3DChangesEveryFrameConstBuffer, 0, NULL, reinterpret_cast<void *>(g_pChangesEveryFrameConstBuffer), 0, 0);

g_pChangesEveryFrameConstBuffer points to a structure which holds world, view and homogeneous transformation matrices (XNA math)
But it wouldn't update the constant buffer that is declared in the effect file. I have checked their values via PIX and all are set to 0 cause they are not being updated. Am I missing something?
[/quote]

As you need CPU write abilities to the buffer you should be creating it with the DYNAMIC flag, not DEFAULT. You should also be specifying CPU_ACCESS_WRITE in the CPUAccessFlags member as well.

Share this post


Link to post
Share on other sites
Turn on DirectX debugging. The Visual Studio in debug output window will tell you what you are doing wrong (basically what Washu said).

http://msdn.microsoft.com/en-us/library/ee416587.aspx
http://blog.rthand.com/post/2010/10/25/Capture-DirectX-1011-debug-output-to-Visual-Studio.aspx

Share this post


Link to post
Share on other sites
It's perfectly possible to use UpdateSubresource() to change the contents of a constant buffer. More detials can be found <a href="http://msdn.microsoft.com/en-us/library/ff476486%28v=vs.85%29.aspx">here</a>


I think that the only thing you don't have set correctly is the src size of the data. I believe you need to set the srcRowPitch to the byte size of the data which also has to be the same size as the constant buffer itself. You can't partially update a constant buffer. The whole things has to be updated.

Share this post


Link to post
Share on other sites
[quote name='Washu' timestamp='1302945250' post='4799074']
[quote name='Asesh' timestamp='1302944487' post='4799072']
The ID3D11DeviceContext::UpdateSubresource method doesn't update constant buffers that I have declared in the effect file.


// Constant buffer that changes every frame
oD3DBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; // Bind constant buffer
oD3DBufferDesc.ByteWidth = sizeof(SChangesEveryFrameConstantBuffer);
oD3DBufferDesc.Usage = D3D11_USAGE_DEFAULT; // R/W access by the GPU

CHECK_COM(pD3DDevice->CreateBuffer(&oD3DBufferDesc, NULL, &m_pD3DChangesEveryFrameConstBuffer)); // Constant buffer that changes every frame

I created that constant buffer to update this constant buffer in the effect file:


cbuffer CBEveryFrame
{
matrix m_matWorld, m_matView, m_matHomogeneous;
};

now it's time to update the constant buffer
pD3DDeviceContext->UpdateSubresource(m_pD3DChangesEveryFrameConstBuffer, 0, NULL, reinterpret_cast<void *>(g_pChangesEveryFrameConstBuffer), 0, 0);

g_pChangesEveryFrameConstBuffer points to a structure which holds world, view and homogeneous transformation matrices (XNA math)
But it wouldn't update the constant buffer that is declared in the effect file. I have checked their values via PIX and all are set to 0 cause they are not being updated. Am I missing something?
[/quote]

As you need CPU write abilities to the buffer you should be creating it with the DYNAMIC flag, not DEFAULT. You should also be specifying CPU_ACCESS_WRITE in the CPUAccessFlags member as well.
[/quote]

D3D11: ERROR: ID3D11DeviceContext::UpdateSubresource: Can only invoke UpdateSubresource when the destination Resource was created with D3D11_USAGE_DEFAULT and is not a multisampled Resource. The destination Resource has (1) samples. [ RESOURCE_MANIPULATION ERROR #289: UPDATESUBRESOURCE_INVALIDDESTINATIONSTATE ]

So there's something wrong...Anyways thanks

Share this post


Link to post
Share on other sites
[quote name='DieterVW' timestamp='1302969959' post='4799159']
It's perfectly possible to use UpdateSubresource() to change the contents of a constant buffer. More detials can be found <a href="http://msdn.microsoft.com/en-us/library/ff476486%28v=vs.85%29.aspx">here</a>


I think that the only thing you don't have set correctly is the src size of the data. I believe you need to set the srcRowPitch to the byte size of the data which also has to be the same size as the constant buffer itself. You can't partially update a constant buffer. The whole things has to be updated.
[/quote]

I looked at the tutorials and it basically does the same thing that I have done:

From Dx SDK tutorial:

// Create the constant buffer
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(ConstantBuffer);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = g_pd3dDevice->CreateBuffer( &bd, NULL, &g_pConstantBuffer );

ConstantBuffer cb1;
cb1.mWorld = XMMatrixTranspose( g_World1 );
cb1.mView = XMMatrixTranspose( g_View );
cb1.mProjection = XMMatrixTranspose( g_Projection );
g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb1, 0, 0 );


Here's mine:


// Constant buffer that changes every frame
struct SChangesEveryFrameConstantBuffer
{
//---------------------------------------------------------------------------
// Name: SChangesEveryFrameConstantBuffer
// Desc: Default constructor
//---------------------------------------------------------------------------
SChangesEveryFrameConstantBuffer()
{
m_oXMWorldMatrix = ::XMMatrixIdentity();
m_oXMViewMatrix = ::XMMatrixIdentity();
m_oXMHomogeneousMatrix = ::XMMatrixIdentity();
}

//---------------------------------------------------------------------------
// Name: buildHomogeneousMatrix
// Desc: Combine all the transformation matrices to form homogeneous matrix
//---------------------------------------------------------------------------
void buildHomogeneousMatrix()
{
m_oXMViewMatrix = g_pCamera->getViewMatrix(); // View transformation matrix
m_oXMHomogeneousMatrix = m_oXMWorldMatrix * m_oXMViewMatrix * g_pCamera->getProjectionMatrix(); // Calculate homogeneous transformation matrix
}

XMMATRIX m_oXMWorldMatrix; // World matrix
XMMATRIX m_oXMViewMatrix; // View matrix
XMMATRIX m_oXMHomogeneousMatrix; // Homogeneous matrix
};

from cpp file:

D3D11_BUFFER_DESC oD3DBufferDesc = {0};


// Constant buffer that changes every frame
oD3DBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; // Bind constant buffer
oD3DBufferDesc.ByteWidth = sizeof(SChangesEveryFrameConstantBuffer);
oD3DBufferDesc.Usage = D3D11_USAGE_DEFAULT; // R/W access by the GPU

// Create a constant buffer that changes every frame
CHECK_COM(pD3DDevice->CreateBuffer(&oD3DBufferDesc, NULL, &m_pD3DChangesEveryFrameConstBuffer));

And methods to retrieve the handles to constant buffers will succeed, for eg:


// Retrieve the handles to the constant buffers
m_pD3DXEffectEveryFrameConstBuffer = m_pD3DXEffect->GetConstantBufferByName("CBEveryFrame"); // Constant buffer that changes every frame
if(!m_pD3DXEffectEveryFrameConstBuffer->IsValid())
return E_FAIL;
m_pD3DXEffectNeverChangesConstBuffer = m_pD3DXEffect->GetConstantBufferByName("CBNeverChanges"); // Constant buffer that never changes
if(!m_pD3DXEffectNeverChangesConstBuffer->IsValid())
return E_FAIL;

at last:

HRESULT CEffect::updateEveryFrameConstantBuffers(ID3D11DeviceContext *pD3DDeviceContext)
{
g_pChangesEveryFrameConstBuffer->buildHomogeneousMatrix(); // Combine the transformation matrcies to form homogeneous matrix

pD3DDeviceContext->UpdateSubresource(m_pD3DChangesEveryFrameConstBuffer, 0, NULL, reinterpret_cast<void *>(g_pChangesEveryFrameConstBuffer), 0, 0);

return S_OK;
}

Dx won't display any message onto the output window and it's return type is void so how do I find what's wrong?

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