D3D11 Placing data directly into Map Resource?

Started by
4 comments, last by Samith 10 years, 4 months ago

I was wondering, is it possible to place index data directly into a Map Resouce without using memcpy?

I'm working on a sprite batcher and right now I use memcpy to place the vertex data from my Quad struct into the vertex Map Resouce. But I don't really think I need use memcopy for my index data, since I can just base the index I need off the current vertex buffer position. In D3D9 I was able to do this by doing


//Load the indices in the index buffer
indices[currentIndexBufferPosition] = currentVertexBufferPosition;
indices[currentIndexBufferPosition + 1] = currentVertexBufferPosition + 1;
indices[currentIndexBufferPosition + 2] = currentVertexBufferPosition + 2;
indices[currentIndexBufferPosition + 3] = currentVertexBufferPosition + 3;
indices[currentIndexBufferPosition + 4] = currentVertexBufferPosition;
indices[currentIndexBufferPosition + 5] = currentVertexBufferPosition + 2;
	

Is this possible with Map Resources and D3D11? Or will I need to make a tiny index array just so I can use memcpy?

Advertisement

You can do it the same way.. what exactly do you have a problem with?

Show your memcpy code and we can help you change it.

I would say deviceContext->Map() and then on the mapped sub-resource struct you have a void-pointer to the mapped data, that you can cast to uint32_t if you use 32-bit indices and fill it.

I think we might have a misunderstanding, I do not want to map my indexes using memcpy like this


batchContext->Map(indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapIndexResource);
memcpy((UINT*)mapIndexResource.pData, indices, sizeof(indices));
batchContext->Unmap(indexBuffer, 0);

I was hoping I could do something like, so I can just base the index value off of my vertex buffer position


batchContext->Map(indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapIndexResource);

//This code does not work not sure if I can do something like this
(UINT*)mapIndexResource.pData[0] = vertxPos;
(UINT*)mapIndexResource.pData[1] = vertxPos + 1;
(UINT*)mapIndexResource.pData[2] = vertxPos + 2;
(UINT*)mapIndexResource.pData[3] = vertxPos + 3;

/* So on and etc */

batchContext->Unmap(indexBuffer, 0);

I think we might have a misunderstanding, I do not want to map my indexes using memcpy like this


batchContext->Map(indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapIndexResource);
memcpy((UINT*)mapIndexResource.pData, indices, sizeof(indices));
batchContext->Unmap(indexBuffer, 0);

I was hoping I could do something like, so I can just base the index value off of my vertex buffer position


batchContext->Map(indexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapIndexResource);

//This code does not work not sure if I can do something like this
(UINT*)mapIndexResource.pData[0] = vertxPos;
(UINT*)mapIndexResource.pData[1] = vertxPos + 1;
(UINT*)mapIndexResource.pData[2] = vertxPos + 2;
(UINT*)mapIndexResource.pData[3] = vertxPos + 3;

/* So on and etc */

batchContext->Unmap(indexBuffer, 0);

You're not casting pData correctly. It should look more like this:


((UINT*)mapIndexResource.pData)[0] = vertxPos;  // must cast pData from void* to UINT* before indexing as an array

Also, since you're casting pData to UINT* (which is 32 bits wide) your indices will have a stride of 4 bytes. If you're using 16 bit indices you'll want to cast pData to an unsigned short or something so that your indices have a stride of 2 bytes.

In summary: memcpy isn't magic. You can fill out the mapped resource data however you please.

Quote

I am assuming I'm using 32 bits for my index buffer because of


deviceContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);

And I assume if I wanted to use 16 bits I do, right?


batchContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0);

//===

int maxIndices = 6; //Just for example

//Buffer Description
D3D11_BUFFER_DESC indexBufferDesc;
ZeroMemory(&indexBufferDesc, sizeof(D3D11_BUFFER_DESC));
indexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
indexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.ByteWidth = maxIndices * sizeof(USHORT);
indexBufferDesc.StructureByteStride = 0;
indexBufferDesc.MiscFlags = 0;

Other than bandwidth usage is there any reason to use 16 bits over 32 bits?

I am assuming I'm using 32 bits for my index buffer because of


deviceContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);

And I assume if I wanted to use 16 bits I do, right?


batchContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R16_UINT, 0);

That's correct, looks like you've got it under control.


Other than bandwidth usage is there any reason to use 16 bits over 32 bits?

I'm not aware of any other reason for using 16 bit indices other than bandwidth.

This topic is closed to new replies.

Advertisement