Jump to content
  • Advertisement
Sign in to follow this  
karnalta

DX11 [SlimDX, DX11] How to use DataBox ?

This topic is 3072 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

Hi,

I need a bit of help about the usage of DataBox to update resource under SlimDX / DX11. I need to update the content of my ConstantBuffer but I can't ...

Here is how I initialize my ConstantBuffer :



m_Buffer = new D3D11.Buffer(m_D3D11Device, dataStream, new D3D11.BufferDescription()
{
BindFlags = m_BindFlag,
OptionFlags = SlimDX.Direct3D11.ResourceOptionFlags.None,
CpuAccessFlags = m_CPUAccessFlag,
SizeInBytes = size,
StructureByteStride = stride,
Usage = m_ResourceUsage
});



Where dataStream is a DataStream containing my Matrices. Now my problem is how to update my buffer at each frame with UpdateSubResources, I try this way but nothing update :



DataBox db = new DataBox((int)dataStream.Length, (int)dataStream.Length, dataStream);
m_D3D11Device.ImmediateContext.UpdateSubresource(db, m_Buffer, 0);




Can somone help me with DataBox usage please ?

Thank a lot.

Share this post


Link to post
Share on other sites
Advertisement
As the documentation of the constant buffer states, you cannot update only a portion of a constant buffer. A constant buffer is all or nothing. Perhaps a tbuffer would work better for you.

Share this post


Link to post
Share on other sites
I don't want to update a part of a buffer, I want to update it all.

In all C++ sample from DirectX SDK, it use the function UpdateSubResource() to update the constant buffer on each frame rendering. But under SlimDX, this function requiere a DataBox as parameter to be used and I don't understand how they work...

What I am looking for is a simple sample on how to update a constant buffer under slimdx.

Share this post


Link to post
Share on other sites
Ah, sorry, miss understood your question. Well, I don't have a sample, but it does say in the DX documentation

Quote:
For a shader-constant buffer; set pDstBox to NULL. It is not possible to use this method to partially update a shader-constant buffer.


I don't know how that would work in the SlimDX wrapper. However since SlimDX is open source, you could take a look at source and see what ussage is necessary to make sure it passes in NULL.

Share this post


Link to post
Share on other sites
I will take a look in the code cause it's not possible in SlimDX to pass null to the databox as the ony parameter taken by UpdateSubResource are (DataBox, Resource, Resource slot). So it seem it's needed to pass the data by the DataBox.

Share this post


Link to post
Share on other sites
I have opened an issue.

But I don't understand what is the problem.

In native C++ it's used like this :


g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb1, 0, 0 );


(where cb1 is a struct)


In SlimDX the function is :


void DeviceContext::UpdateSubresource( DataBox^ source, Resource^ resource, int subresource )
{
InternalPointer->UpdateSubresource( resource->InternalPointer, static_cast<UINT>( subresource), 0, source->Data->PositionPointer, source->RowPitch,source->SlicePitch);
}



So if I use it like this it should work I think but it's not :

DataStream cbStream = new DataStream(240, true, true);
cbStream.Write<ConstantBuffer>(cb);
cbStream.Position = 0;

DataBox db = new DataBox(0, 0, cbStream);
g_pd3dDevice.ImmediateContext.UpdateSubresource(db, g_pConstantBuffer, 0);


Share this post


Link to post
Share on other sites
A simple struct :


[StructLayout(LayoutKind.Explicit, Size=240)]
public struct ConstantBuffer
{
[FieldOffset(0)]
public Matrix mWorld;
[FieldOffset(64)]
public Matrix mView;
[FieldOffset(128)]
public Matrix mProjection;
[FieldOffset(192)]
public Vector4 mLightDir;
[FieldOffset(208)]
public Vector4 mLightColor;
[FieldOffset(224)]
public Vector4 Color;
};



And at each frame I try to set the constant buffer value.

If I recreate totaly the buffer like this, it work fine :


// Update Constant buffer
ConstantBuffer cb = new ConstantBuffer();
cb.mWorld = Matrix.Transpose(g_World);
cb.mProjection = Matrix.Transpose(g_Projection);
cb.mView = Matrix.Transpose(g_View);
cb.mLightDir = new Vector4(0.0f, 0.0f, -1.0f, 1.0f);
cb.mLightColor = new Vector4(1.2f, 0.1f, 1.0f, 1.0f);
cb.Color = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);

DataStream cbStream = new DataStream(240, true, true);
cbStream.Write<ConstantBuffer>(cb);
cbStream.Position = 0;

g_pConstantBuffer.Dispose();
g_pConstantBuffer = new D3D11.Buffer(g_pd3dDevice, cbStream, new D3D11.BufferDescription()
{
BindFlags = SlimDX.Direct3D11.BindFlags.ConstantBuffer,
CpuAccessFlags = SlimDX.Direct3D11.CpuAccessFlags.Write,
OptionFlags = SlimDX.Direct3D11.ResourceOptionFlags.None,
Usage = SlimDX.Direct3D11.ResourceUsage.Dynamic,
SizeInBytes = 240,
StructureByteStride = 0
});



But if I try to update it with about the same method but trying to use UpdateSubresource instead of recreating totally the buffer, it doesn't work :


// Update Constant buffer
ConstantBuffer cb = new ConstantBuffer();
cb.mWorld = Matrix.Transpose(g_World);
cb.mProjection = Matrix.Transpose(g_Projection);
cb.mView = Matrix.Transpose(g_View);
cb.mLightDir = new Vector4(0.0f, 0.0f, -1.0f, 1.0f);
cb.mLightColor = new Vector4(1.2f, 0.1f, 1.0f, 1.0f);
cb.Color = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);

DataStream cbStream = new DataStream(240, true, true);
cbStream.Write<ConstantBuffer>(cb);
cbStream.Position = 0;

DataBox db = new DataBox(0, 0, cbStream);
g_pd3dDevice.ImmediateContext.UpdateSubresource(db, g_pConstantBuffer, 0);

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!