Question

I have a vertex buffer created as follows:

ID3D10Buffer * VertexBuffer;
Vertex_PosCol * Vertices;
D3D10_SUBRESOURCE_DATA VertexData;


    Vertices = new Vertex_PosCol[VerticeCount];

    Vertices[0].Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
    Vertices[0].Color = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);

    Vertices[1].Position = D3DXVECTOR3(-1.0f, 2.0f, 0.0f);
    Vertices[1].Color = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f);

    Vertices[2].Position = D3DXVECTOR3(1.0f, 2.0f, 0.0f);
    Vertices[2].Color = D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f);

    Vertices[3].Position = D3DXVECTOR3(2.0f, 1.0f, 0.0f);
    Vertices[3].Color = D3DXVECTOR4(0.0f, 0.0f, 1.0f, 1.0f);

    Vertices[4].Position = D3DXVECTOR3(2.0f, -1.0f, 0.0f);
    Vertices[4].Color = D3DXVECTOR4(1.0f, 1.0f, 0.0f, 1.0f);

    Vertices[5].Position = D3DXVECTOR3(1.0f, -2.0f, 0.0f);
    Vertices[5].Color = D3DXVECTOR4(0.0f, 1.0f, 1.0f, 1.0f);

    Vertices[6].Position = D3DXVECTOR3(-1.0f, -2.0f, 0.0f);
    Vertices[6].Color = D3DXVECTOR4(1.0f, 0.0f, 1.0f, 1.0f);

    Vertices[7].Position = D3DXVECTOR3(-2.0f, -1.0f, 0.0f);
    Vertices[7].Color = D3DXVECTOR4(1.0f, 0.0f, 0.0f, 1.0f);

    Vertices[8].Position = D3DXVECTOR3(-2.0f, 1.0f, 0.0f);
    Vertices[8].Color = D3DXVECTOR4(0.0f, 1.0f, 0.0f, 1.0f);

    D3D10_BUFFER_DESC vbd;
    vbd.Usage = D3D10_USAGE_DYNAMIC;
    vbd.ByteWidth = sizeof(Vertex_PosCol) * VerticeCount;
    vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
    vbd.MiscFlags = 0;


    VertexData.pSysMem = Vertices;

    HRESULT result = this->GDM.Device->CreateBuffer(&vbd, &VertexData, &VertexBuffer);

I am currently using ID3D10Buffer::Map() to update my vertices which works fine right now. This issue is that my application may require large amounts of vertex updates in the future but not every vertex in every mesh/buffer(one day, a buffer will hold multiple meshes). As far as I have looked everywhere says to use ID3D10Device::CopySubresourceRegion(). That is exactly what i want to do! Except I can't get it to work. I simply don't understand how it works. I read Microsoft's page on it and it's not directed towards vertex buffers. I was hoping that someone can explain to me how to implement it in regards to vertex buffers and/or link me to some helpful resources that do the same.

Was it helpful?

Solution

It's not quite clear what you're asking, because you cannot update buffer with ID3D10Device::CopySubresourceRegion(). I'm trying to clarify resource copying and resource updating in my answer.

Updating resource

By "updating" resource we usually mean transferring data from system memory to GPU memory1, with overwriting. For updating resource you use either ID3D10Buffer::Map()/ID3D10Buffer::Unmap() pair or ID3D10Device::UpdateSubresource() method. Which is better to use depends on resource properties and update frequency (read Nvidia's "canonical" paper).

Usage is really straightforward. Here is a case for simple 1D buffer, such as vertex buffer.

// Source array/vector (srcData): [xxxxDATADATADATADATADATAxxxxxxxxxxx]
//                                     ^                   ^
//                                 srcBegin        (srcBegin+bytesToCopy)
//
// Destination buffer (pBuffer):  [xxDATADATADATADATADATAxxxxxxxxxxxxx]  
//                                   ^                   ^
//                              destinationBegin  (destinationBegin+bytesToCopy)
D3D11_BOX box{};
box.left = destinationBegin;
box.right = destinationBegin + bytesToCopy;
box.top = 0;
box.bottom = 1;
box.front = 0;
box.back = 1;
Device->UpdateSubresource(pBuffer, 0, &box, (uint8_t*)srcData+srcBegin, 0, 0);

Copying resource

As name states, ID3D10Device::CopySubresourceRegion() method is suited for copying data between two resources (such as buffers or textures). Simplifying, you can think of it as of copying chunks of data inside videocard's memory (but that's not always true). You cannot "update" GPU memory with that method, as data being copied already there.

Here is a simple example:

D3D11_BOX srcBox{};
srcBox.left = srcBegin;
srcBox.right = srcBegin + size;
srcBox.top = 0;
srcBox.bottom = 1;
srcBox.front = 0;
srcBox.back = 1;
Device->CopySubresourceRegion(pDst, 0, dstBegin, 0, 0, pSrc, 0, &srcBox);

Hope it helps.

BTW, there is no any reason to learn DirectX 10 in 2013. You can start with DirectX 11, its API is almost the same, but more features.


1 This explanation is overly simplified. We can never be sure where given resource resides (GPU, system memory, whatever storage), as it is up to driver implementer to decide where when and which kinds of resources to store.

OTHER TIPS

tip: size is the amount of verts times their bytesize each

    D3D11_BOX srcBox{};
    srcBox.left = srcBegin;
    srcBox.right = srcBegin + size;   <-here
    srcBox.top = 0;
    srcBox.bottom = 1;
    srcBox.front = 0;
    srcBox.back = 1;
    Device->CopySubresourceRegion(pDst, 0, dstBegin, 0, 0, pSrc, 0, &srcBox);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top