Multiple objects per thread
This commit is contained in:
parent
ad49cb7997
commit
3caeb6ee84
1 changed files with 57 additions and 37 deletions
|
|
@ -79,20 +79,27 @@ public:
|
||||||
glm::vec3 color;
|
glm::vec3 color;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MeshData {
|
struct MeshBuffer {
|
||||||
glm::vec3 pos;
|
|
||||||
glm::vec3 rotation;
|
|
||||||
float deltaT;
|
|
||||||
vkMeshLoader::MeshBufferInfo vertices;
|
vkMeshLoader::MeshBufferInfo vertices;
|
||||||
vkMeshLoader::MeshBufferInfo indices;
|
vkMeshLoader::MeshBufferInfo indices;
|
||||||
uint32_t indexCount;
|
uint32_t indexCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ObjectData {
|
||||||
|
glm::vec3 pos;
|
||||||
|
glm::vec3 rotation;
|
||||||
|
float deltaT;
|
||||||
|
};
|
||||||
|
|
||||||
struct ThreadData {
|
struct ThreadData {
|
||||||
MeshData meshData;
|
MeshBuffer mesh;
|
||||||
VkCommandPool commandPool;
|
VkCommandPool commandPool;
|
||||||
|
// One command buffer per render object
|
||||||
std::vector<VkCommandBuffer> commandBuffer;
|
std::vector<VkCommandBuffer> commandBuffer;
|
||||||
ThreadPushConstantBlock pushConstBlock;
|
// One push constant block per render object
|
||||||
|
std::vector<ThreadPushConstantBlock> pushConstBlock;
|
||||||
|
// Per object information (position, rotation, etc.)
|
||||||
|
std::vector<ObjectData> objectData;
|
||||||
};
|
};
|
||||||
std::vector<ThreadData> threadData;
|
std::vector<ThreadData> threadData;
|
||||||
|
|
||||||
|
|
@ -163,7 +170,6 @@ public:
|
||||||
{
|
{
|
||||||
ThreadData *thread = &threadData[i];
|
ThreadData *thread = &threadData[i];
|
||||||
|
|
||||||
|
|
||||||
// Create one command pool for each thread
|
// Create one command pool for each thread
|
||||||
VkCommandPoolCreateInfo cmdPoolInfo = vkTools::initializers::commandPoolCreateInfo();
|
VkCommandPoolCreateInfo cmdPoolInfo = vkTools::initializers::commandPoolCreateInfo();
|
||||||
cmdPoolInfo.queueFamilyIndex = swapChain.queueNodeIndex;
|
cmdPoolInfo.queueFamilyIndex = swapChain.queueNodeIndex;
|
||||||
|
|
@ -186,14 +192,14 @@ public:
|
||||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||||
meshes.ufo.vertices.size,
|
meshes.ufo.vertices.size,
|
||||||
nullptr,
|
nullptr,
|
||||||
&thread->meshData.vertices.buf,
|
&thread->mesh.vertices.buf,
|
||||||
&thread->meshData.vertices.mem);
|
&thread->mesh.vertices.mem);
|
||||||
createBuffer(
|
createBuffer(
|
||||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||||
meshes.ufo.indices.size,
|
meshes.ufo.indices.size,
|
||||||
nullptr,
|
nullptr,
|
||||||
&thread->meshData.indices.buf,
|
&thread->mesh.indices.buf,
|
||||||
&thread->meshData.indices.mem);
|
&thread->mesh.indices.mem);
|
||||||
|
|
||||||
// Copy from mesh buffer
|
// Copy from mesh buffer
|
||||||
VkBufferCopy copyRegion = {};
|
VkBufferCopy copyRegion = {};
|
||||||
|
|
@ -203,7 +209,7 @@ public:
|
||||||
vkCmdCopyBuffer(
|
vkCmdCopyBuffer(
|
||||||
setupCmdBuffer,
|
setupCmdBuffer,
|
||||||
meshes.ufo.vertices.buf,
|
meshes.ufo.vertices.buf,
|
||||||
thread->meshData.vertices.buf,
|
thread->mesh.vertices.buf,
|
||||||
1,
|
1,
|
||||||
©Region);
|
©Region);
|
||||||
// Index buffer
|
// Index buffer
|
||||||
|
|
@ -211,18 +217,24 @@ public:
|
||||||
vkCmdCopyBuffer(
|
vkCmdCopyBuffer(
|
||||||
setupCmdBuffer,
|
setupCmdBuffer,
|
||||||
meshes.ufo.indices.buf,
|
meshes.ufo.indices.buf,
|
||||||
thread->meshData.indices.buf,
|
thread->mesh.indices.buf,
|
||||||
1,
|
1,
|
||||||
©Region);
|
©Region);
|
||||||
|
|
||||||
thread->meshData.indexCount = meshes.ufo.indexCount;
|
thread->mesh.indexCount = meshes.ufo.indexCount;
|
||||||
|
|
||||||
float step = 360.0f / (float)numThreads;
|
thread->pushConstBlock.resize(numObjectsPerThread);
|
||||||
|
thread->objectData.resize(numObjectsPerThread);
|
||||||
|
|
||||||
|
float step = 360.0f / (float)(numThreads * numObjectsPerThread);
|
||||||
float radius = 20.0f;
|
float radius = 20.0f;
|
||||||
thread->meshData.pos.x = sin(glm::radians(step * i)) * radius;
|
for (uint32_t j = 0; j < numObjectsPerThread; j++)
|
||||||
thread->meshData.pos.z = cos(glm::radians(step * i)) * radius;
|
{
|
||||||
thread->meshData.rotation = glm::vec3(0.0f, (float)(rand() % 360), 0.0f);
|
thread->objectData[j].pos.x = sin(glm::radians(step * (i * numObjectsPerThread + j))) * radius;
|
||||||
thread->meshData.deltaT = (float)(rand() % 255) / 255.0f;
|
thread->objectData[j].pos.z = cos(glm::radians(step * (i * numObjectsPerThread + j))) * radius;
|
||||||
|
thread->objectData[j].rotation = glm::vec3(0.0f, (float)(rand() % 360), 0.0f);
|
||||||
|
thread->objectData[j].deltaT = (float)i / (float)numThreads;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Submit buffer copies to the queue
|
// Submit buffer copies to the queue
|
||||||
|
|
@ -252,20 +264,21 @@ public:
|
||||||
|
|
||||||
// Update
|
// Update
|
||||||
// todo : timebased
|
// todo : timebased
|
||||||
thread->meshData.rotation.y += 0.15f;
|
ObjectData *objectData = &thread->objectData[cmdBufferIndex];
|
||||||
if (thread->meshData.rotation.y > 360.0f)
|
objectData->rotation.y += 0.15f;
|
||||||
thread->meshData.rotation.y -= 360.0f;
|
if (objectData->rotation.y > 360.0f)
|
||||||
thread->meshData.deltaT += 0.0005f;
|
objectData->rotation.y -= 360.0f;
|
||||||
if (thread->meshData.deltaT > 1.0f)
|
objectData->deltaT += 0.0005f;
|
||||||
thread->meshData.deltaT -= 1.0f;
|
if (objectData->deltaT > 1.0f)
|
||||||
thread->meshData.pos.y = sin(glm::radians(thread->meshData.deltaT * 360.0f)) * 1.5f;
|
objectData->deltaT -= 1.0f;
|
||||||
|
objectData->pos.y = sin(glm::radians(objectData->deltaT * 360.0f)) * 1.5f;
|
||||||
|
|
||||||
glm::mat4 model = glm::translate(glm::mat4(), thread->meshData.pos);
|
glm::mat4 model = glm::translate(glm::mat4(), objectData->pos);
|
||||||
model = glm::rotate(model, -sinf(glm::radians(thread->meshData.deltaT * 360.0f)) * 0.25f, glm::vec3(1.0f, 0.0f, 0.0f));
|
model = glm::rotate(model, -sinf(glm::radians(objectData->deltaT * 360.0f)) * 0.25f, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
model = glm::rotate(model, glm::radians(thread->meshData.rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
|
model = glm::rotate(model, glm::radians(objectData->rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
model = glm::rotate(model, glm::radians(thread->meshData.deltaT * 360.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
model = glm::rotate(model, glm::radians(objectData->deltaT * 360.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
|
||||||
thread->pushConstBlock.mvp = matrices.projection * matrices.view * model;
|
thread->pushConstBlock[cmdBufferIndex].mvp = matrices.projection * matrices.view * model;
|
||||||
|
|
||||||
// Update shader push constant block
|
// Update shader push constant block
|
||||||
// Contains model view matrix
|
// Contains model view matrix
|
||||||
|
|
@ -275,16 +288,19 @@ public:
|
||||||
VK_SHADER_STAGE_VERTEX_BIT,
|
VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
0,
|
0,
|
||||||
sizeof(ThreadPushConstantBlock),
|
sizeof(ThreadPushConstantBlock),
|
||||||
&thread->pushConstBlock);
|
&thread->pushConstBlock[cmdBufferIndex]);
|
||||||
|
|
||||||
VkDeviceSize offsets[1] = { 0 };
|
VkDeviceSize offsets[1] = { 0 };
|
||||||
vkCmdBindVertexBuffers(cmdBuffer, 0, 1, &thread->meshData.vertices.buf, offsets);
|
vkCmdBindVertexBuffers(cmdBuffer, 0, 1, &thread->mesh.vertices.buf, offsets);
|
||||||
vkCmdBindIndexBuffer(cmdBuffer, thread->meshData.indices.buf, 0, VK_INDEX_TYPE_UINT32);
|
vkCmdBindIndexBuffer(cmdBuffer, thread->mesh.indices.buf, 0, VK_INDEX_TYPE_UINT32);
|
||||||
vkCmdDrawIndexed(cmdBuffer, thread->meshData.indexCount, 1, 0, 0, 0);
|
vkCmdDrawIndexed(cmdBuffer, thread->mesh.indexCount, 1, 0, 0, 0);
|
||||||
|
|
||||||
vkTools::checkResult(vkEndCommandBuffer(cmdBuffer));
|
vkTools::checkResult(vkEndCommandBuffer(cmdBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Updates the secondary command buffers using a thread pool
|
||||||
|
// and puts them into the primary command buffer that's
|
||||||
|
// lat submitted to the queue for rendering
|
||||||
void updateCommandBuffers(VkFramebuffer frameBuffer)
|
void updateCommandBuffers(VkFramebuffer frameBuffer)
|
||||||
{
|
{
|
||||||
VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo();
|
VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo();
|
||||||
|
|
@ -322,8 +338,12 @@ public:
|
||||||
|
|
||||||
for (uint32_t t = 0; t < numThreads; t++)
|
for (uint32_t t = 0; t < numThreads; t++)
|
||||||
{
|
{
|
||||||
threadPool.threads[t]->addJob([=] { threadRenderCode(t, 0, inheritanceInfo); });
|
// Add a job to the thread's queue for each object to be rendered
|
||||||
commandBuffers.push_back(threadData[t].commandBuffer[0]);
|
for (uint32_t i = 0; i < numObjectsPerThread; i++)
|
||||||
|
{
|
||||||
|
threadPool.threads[t]->addJob([=] { threadRenderCode(t, i, inheritanceInfo); });
|
||||||
|
commandBuffers.push_back(threadData[t].commandBuffer[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
threadPool.wait();
|
threadPool.wait();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue