I just wanted to post some quick related questions before this thread drops.
I am passing a huge cbuffer array to the vertex shader that can contain upto 4096*4 indices which will be used to index into a tbuffer of mvp matrices during instancing.
And I get this warning:
D3D11 WARNING: ID3D11DeviceContext::DrawIndexedInstanced: The size of the Constant Buffer at slot 1 of the Vertex Shader unit is too small (1024 bytes provided, 65536 bytes, at least, expected). This is OK, as out-of-bounds reads are defined to return 0. It is also possible the developer knows the missing data will not be used anyway. This is only a problem if the developer actually intended to bind a sufficiently large Constant Buffer for what the shader expects. [ EXECUTION WARNING #351: DEVICE_DRAW_CONSTANT_BUFFER_TOO_SMALL]
So here is some of the code:
cbuffer InstanceIndices : register(b1)
{
uint4 InstIdxArray[4096];
};
uint ReadInstanceIndex(uint instID)
{
return InstIdxArray[instID >> 2][instID & 3];
}
std::shared_ptr<InstanceResource> CreateInstanceResource(DXDevice &Renderer, std::vector<DWORD> &InstanceIndices)
{
return std::make_shared<InstanceResource>(InstanceIndices.size(), Renderer.CreateInstanceBuffer(InstanceIndices.data(), InstanceIndices.size() * sizeof(DWORD)));
}
CComPtr<ID3D11Buffer> DXDevice::CreateInstanceBuffer(const void* pDataSrc, UINT BufferSize)
{
if (BufferSize % 16 != 0) // Force BufferSize to be a multiple of 16
BufferSize += (16 - (BufferSize % 16));
return CreateBufferResource(pDataSrc, BufferSize, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DEFAULT, 0);
}
CComPtr<ID3D11Buffer> DXDevice::CreateBufferResource(const void* pDataSrc, UINT BufferSize, UINT BindFlags, D3D11_USAGE Usage, UINT CPUAccessFlags)
{
CComPtr<ID3D11Buffer> pBuffer = nullptr;
try
{
if (BufferSize == 0)
throw std::exception("The requested buffer resource is of size 0");
D3D11_SUBRESOURCE_DATA sd;
ZeroMemory(&sd, sizeof(sd));
sd.pSysMem = pDataSrc;
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = Usage;
bd.ByteWidth = BufferSize;
bd.BindFlags = BindFlags;
bd.CPUAccessFlags = CPUAccessFlags;
HR(m_pDevice->CreateBuffer(&bd, &sd, &pBuffer));
}
catch (std::exception &e)
{
WriteFile("error.log", e.what());
return nullptr;
}
return pBuffer;
}
With this code I turn a vector of uints into a cbuffer to be used later for indexing. Is it the uint4 InstIdxArray[4096]; in HLSL that is causing the warning?
Also, I've done some testing at about 250 FPS, I am able to create 260,000 cbuffers (of size 1024 Bytes) per second (yes I am creating 1000 instance buffers and tossing them away every frame):
concurrency::concurrent_vector<std::shared_ptr<InstanceResource>> testvec;
concurrency::parallel_for(0, 1000, [&Renderer, &pCubeMesh, &testvec](int i){
testvec.push_back(CreateInstanceResource(Renderer, pCubeMesh->InstanceIndices));
});
Is this a viable method of feeding the GPU with data? Say I want to instance up 1000 different draw calls. Doing it this way in parallel, creating the buffers means I don't have to map them using the device contex which is single threaded.