|
|
|
@ -12,6 +12,7 @@ |
|
|
|
|
#include "soft_body.hpp" |
|
|
|
|
#include "mesh.hpp" |
|
|
|
|
#include "constraints.hpp" |
|
|
|
|
#include "timer.hpp" |
|
|
|
|
|
|
|
|
|
Application::Application() { |
|
|
|
|
createSyncObjects(); |
|
|
|
@ -34,7 +35,7 @@ Application::Application() { |
|
|
|
|
createMeshBuffers(); |
|
|
|
|
|
|
|
|
|
SizeInformation sizeInformation {}; |
|
|
|
|
sizeInformation.vertexCount = vertexBuffer->size / sizeof(Vertex); |
|
|
|
|
sizeInformation.vertexCount = vertexBuffers[0]->size / sizeof(Vertex); |
|
|
|
|
sizeInformation.faceCount = faceBuffer->size / sizeof(Face); |
|
|
|
|
|
|
|
|
|
sizeInformationBuffer = make_unique<Buffer>( |
|
|
|
@ -44,14 +45,14 @@ Application::Application() { |
|
|
|
|
|
|
|
|
|
properties.gravity = {0, -9.81, 0}; |
|
|
|
|
properties.k = 10; |
|
|
|
|
properties.dt = 1.f / 60.f / static_cast<float>(properties.k); |
|
|
|
|
properties.dt = 1.f / 60.f; |
|
|
|
|
|
|
|
|
|
propertiesBuffer = make_unique<Buffer>( |
|
|
|
|
sizeof(Properties), &properties, sizeof(properties), |
|
|
|
|
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, |
|
|
|
|
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0); |
|
|
|
|
|
|
|
|
|
descriptorPool->bindBuffer(*vertexBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0); |
|
|
|
|
descriptorPool->bindBuffer(*vertexBuffers[1 - currentDrawVertexBuffer], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0); |
|
|
|
|
descriptorPool->bindBuffer(*faceBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 1); |
|
|
|
|
descriptorPool->bindBuffer(*edgeBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 2); |
|
|
|
|
descriptorPool->bindBuffer(*triangleBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 3); |
|
|
|
@ -68,12 +69,32 @@ Application::Application() { |
|
|
|
|
vmaFreeStatsString(Instance::GetAllocator(), stats); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#include <future> |
|
|
|
|
#include <chrono> |
|
|
|
|
|
|
|
|
|
using namespace std::chrono; |
|
|
|
|
|
|
|
|
|
void Application::mainLoop() { |
|
|
|
|
std::future compute = std::async(std::launch::async, [this](){ |
|
|
|
|
while (!glfwWindowShouldClose(Instance::instance->window)){ |
|
|
|
|
glfwPollEvents(); |
|
|
|
|
Timer timer; |
|
|
|
|
|
|
|
|
|
auto t1 = system_clock::now(); |
|
|
|
|
update(); |
|
|
|
|
auto t2 = system_clock::now(); |
|
|
|
|
|
|
|
|
|
microseconds updateDuration = duration_cast<microseconds>(t2 - t1); |
|
|
|
|
|
|
|
|
|
microseconds sleepDuration(static_cast<int64_t>(properties.dt * 1000 * 1000)); |
|
|
|
|
std::this_thread::sleep_for(sleepDuration - updateDuration); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
while (!glfwWindowShouldClose(Instance::instance->window)){ |
|
|
|
|
glfwPollEvents(); |
|
|
|
|
drawFrame(); |
|
|
|
|
} |
|
|
|
|
compute.wait(); |
|
|
|
|
vkDeviceWaitIdle(Instance::GetDevice()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -84,9 +105,11 @@ Application::~Application() { |
|
|
|
|
void Application::createSyncObjects() { |
|
|
|
|
imageAvailable = make_unique<Semaphore>(); |
|
|
|
|
renderFinished = make_unique<Semaphore>(); |
|
|
|
|
computeFinished = make_unique<Semaphore>(); |
|
|
|
|
renderInFlight = make_unique<Fence>(true); |
|
|
|
|
computeInFlight = make_unique<Fence>(true); |
|
|
|
|
computeSemaphore = make_unique<Semaphore>(); |
|
|
|
|
transferFinished = make_unique<Semaphore>(); |
|
|
|
|
renderFence = make_unique<Fence>(true); |
|
|
|
|
computeFence = make_unique<Fence>(true); |
|
|
|
|
transferFence = make_unique<Fence>(true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::createMeshBuffers() { |
|
|
|
@ -102,7 +125,7 @@ void Application::createMeshBuffers() { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
body = std::make_unique<SoftBody>(&bunny, 1.f / 3); |
|
|
|
|
for (size_t i = 0; i < 5; i++){ |
|
|
|
|
for (size_t i = 0; i < 10; i++){ |
|
|
|
|
auto copy = std::make_unique<SoftBody>(*body.get()); |
|
|
|
|
copy->applyVertexOffset({i * 2, 0, 2}); |
|
|
|
|
softBodies.push_back(std::move(copy)); |
|
|
|
@ -196,7 +219,10 @@ void Application::createMeshBuffers() { |
|
|
|
|
: Buffer(size, data, size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | additionalUsageFlags, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0) {} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
vertexBuffer = make_unique<SimulationBuffer>(vertices.data(), vertices.size() * sizeof(Vertex), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); |
|
|
|
|
vertexBuffers[0] = make_unique<SimulationBuffer>(vertices.data(), vertices.size() * sizeof(Vertex), |
|
|
|
|
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
|
|
|
|
vertexBuffers[1] = make_unique<SimulationBuffer>(vertices.data(), vertices.size() * sizeof(Vertex), |
|
|
|
|
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); |
|
|
|
|
faceBuffer = make_unique<SimulationBuffer>(faces.data(), faces.size() * sizeof(Face), VK_BUFFER_USAGE_INDEX_BUFFER_BIT); |
|
|
|
|
edgeBuffer = make_unique<SimulationBuffer>(constraintData.edges.data(), constraintData.edges.size() * sizeof(Edge)); |
|
|
|
|
triangleBuffer = make_unique<SimulationBuffer>(constraintData.triangles.data(), constraintData.triangles.size() * sizeof(Triangle)); |
|
|
|
@ -246,24 +272,70 @@ void Application::updateUniformBuffer() { |
|
|
|
|
ubo.projection[1][1] *= -1; |
|
|
|
|
|
|
|
|
|
memcpy(uniformBuffer->allocationInfo.pMappedData, &ubo, sizeof(UniformBufferObject)); |
|
|
|
|
|
|
|
|
|
VkMappedMemoryRange mappedMemoryRange {}; |
|
|
|
|
mappedMemoryRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; |
|
|
|
|
mappedMemoryRange.offset = uniformBuffer->allocationInfo.offset; |
|
|
|
|
mappedMemoryRange.size = uniformBuffer->allocationInfo.size; |
|
|
|
|
mappedMemoryRange.memory = uniformBuffer->allocationInfo.deviceMemory; |
|
|
|
|
|
|
|
|
|
vkFlushMappedMemoryRanges(Instance::GetDevice(), 1, &mappedMemoryRange); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::recordGraphicsCommandBuffer(uint32_t imageIndex) { |
|
|
|
|
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer; |
|
|
|
|
void Application::drawFrame() { |
|
|
|
|
vkWaitForFences(Instance::GetDevice(), 1, &renderFence->handle, VK_TRUE, UINT64_MAX); |
|
|
|
|
|
|
|
|
|
VkCommandBufferBeginInfo beginInfo {}; |
|
|
|
|
uint32_t imageIndex; |
|
|
|
|
VkResult result = vkAcquireNextImageKHR(Instance::GetDevice(), swapchain->handle, UINT64_MAX, imageAvailable->handle, VK_NULL_HANDLE, &imageIndex); |
|
|
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR){ |
|
|
|
|
swapchain->recreateSwapchain(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
vkResetFences(Instance::GetDevice(), 1, &renderFence->handle); |
|
|
|
|
|
|
|
|
|
camera->update(0.017); |
|
|
|
|
updateUniformBuffer(); |
|
|
|
|
|
|
|
|
|
VkCommandBuffer cmdBuffer = Instance::instance->renderingCommandPool->buffers[0]; |
|
|
|
|
{ |
|
|
|
|
vkResetCommandBuffer(cmdBuffer, 0); |
|
|
|
|
|
|
|
|
|
VkCommandBufferBeginInfo beginInfo{}; |
|
|
|
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; |
|
|
|
|
|
|
|
|
|
vkBeginCommandBuffer(cmdBuffer, &beginInfo); |
|
|
|
|
|
|
|
|
|
VkRenderPassBeginInfo renderPassInfo {}; |
|
|
|
|
VkBufferMemoryBarrier vertexBufferBarrier{}; |
|
|
|
|
vertexBufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; |
|
|
|
|
vertexBufferBarrier.size = vertexBuffers[currentDrawVertexBuffer]->size; |
|
|
|
|
vertexBufferBarrier.offset = 0; |
|
|
|
|
vertexBufferBarrier.buffer = vertexBuffers[currentDrawVertexBuffer]->handle; |
|
|
|
|
vertexBufferBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT; |
|
|
|
|
vertexBufferBarrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; |
|
|
|
|
|
|
|
|
|
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 0, |
|
|
|
|
nullptr, 1, &vertexBufferBarrier, 0, nullptr); |
|
|
|
|
|
|
|
|
|
VkBufferMemoryBarrier uniformBufferBarrier {}; |
|
|
|
|
uniformBufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; |
|
|
|
|
uniformBufferBarrier.size = uniformBuffer->size; |
|
|
|
|
uniformBufferBarrier.offset = 0; |
|
|
|
|
uniformBufferBarrier.buffer = uniformBuffer->handle; |
|
|
|
|
uniformBufferBarrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; |
|
|
|
|
uniformBufferBarrier.dstAccessMask = VK_ACCESS_UNIFORM_READ_BIT; |
|
|
|
|
|
|
|
|
|
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, |
|
|
|
|
0, nullptr, 1, &uniformBufferBarrier, 0, nullptr); |
|
|
|
|
|
|
|
|
|
VkRenderPassBeginInfo renderPassInfo{}; |
|
|
|
|
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; |
|
|
|
|
renderPassInfo.renderPass = swapchain->renderPass; |
|
|
|
|
renderPassInfo.framebuffer = swapchain->frameBuffers[imageIndex]; |
|
|
|
|
renderPassInfo.renderArea.offset = {0, 0}; |
|
|
|
|
renderPassInfo.renderArea.extent = swapchain->extent; |
|
|
|
|
|
|
|
|
|
VkClearValue clearValues[2] {}; |
|
|
|
|
VkClearValue clearValues[2]{}; |
|
|
|
|
clearValues[0].color = {{0, 0, 0, 1}}; |
|
|
|
|
clearValues[1].depthStencil = {1.0f, 0}; |
|
|
|
|
|
|
|
|
@ -272,7 +344,7 @@ void Application::recordGraphicsCommandBuffer(uint32_t imageIndex) { |
|
|
|
|
|
|
|
|
|
vkCmdBeginRenderPass(cmdBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); |
|
|
|
|
|
|
|
|
|
VkViewport viewport {}; |
|
|
|
|
VkViewport viewport{}; |
|
|
|
|
viewport.x = 0; |
|
|
|
|
viewport.y = 0; |
|
|
|
|
viewport.width = static_cast<float>(swapchain->extent.width); |
|
|
|
@ -281,51 +353,35 @@ void Application::recordGraphicsCommandBuffer(uint32_t imageIndex) { |
|
|
|
|
viewport.maxDepth = 1; |
|
|
|
|
vkCmdSetViewport(cmdBuffer, 0, 1, &viewport); |
|
|
|
|
|
|
|
|
|
VkRect2D scissor {}; |
|
|
|
|
VkRect2D scissor{}; |
|
|
|
|
scissor.offset = {0, 0}; |
|
|
|
|
scissor.extent = swapchain->extent; |
|
|
|
|
vkCmdSetScissor(cmdBuffer, 0, 1, &scissor); |
|
|
|
|
|
|
|
|
|
recordDrawCommands(); |
|
|
|
|
recordDrawCommands(cmdBuffer); |
|
|
|
|
|
|
|
|
|
vkCmdEndRenderPass(cmdBuffer); |
|
|
|
|
vkEndCommandBuffer(cmdBuffer); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::drawFrame() { |
|
|
|
|
vkWaitForFences(Instance::GetDevice(), 1, &renderInFlight->handle, VK_TRUE, UINT64_MAX); |
|
|
|
|
|
|
|
|
|
uint32_t imageIndex; |
|
|
|
|
VkResult result = vkAcquireNextImageKHR(Instance::GetDevice(), swapchain->handle, UINT64_MAX, imageAvailable->handle, VK_NULL_HANDLE, &imageIndex); |
|
|
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR){ |
|
|
|
|
swapchain->recreateSwapchain(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
vkResetFences(Instance::GetDevice(), 1, &renderInFlight->handle); |
|
|
|
|
|
|
|
|
|
vkResetCommandBuffer(Instance::instance->commandPool->graphicsBuffer, 0); |
|
|
|
|
recordGraphicsCommandBuffer(imageIndex); |
|
|
|
|
|
|
|
|
|
camera->update(0.017); |
|
|
|
|
updateUniformBuffer(); |
|
|
|
|
|
|
|
|
|
VkSubmitInfo submitInfo {}; |
|
|
|
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
|
|
|
|
|
|
|
|
|
VkSemaphore waitSemaphores[] = {imageAvailable->handle, computeFinished->handle}; |
|
|
|
|
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT}; |
|
|
|
|
submitInfo.waitSemaphoreCount = 2; |
|
|
|
|
VkSemaphore waitSemaphores[] = {imageAvailable->handle}; |
|
|
|
|
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; |
|
|
|
|
submitInfo.waitSemaphoreCount = 1; |
|
|
|
|
submitInfo.pWaitSemaphores = waitSemaphores; |
|
|
|
|
submitInfo.pWaitDstStageMask = waitStages; |
|
|
|
|
submitInfo.commandBufferCount = 1; |
|
|
|
|
submitInfo.pCommandBuffers = &Instance::instance->commandPool->graphicsBuffer; |
|
|
|
|
submitInfo.pCommandBuffers = &cmdBuffer; |
|
|
|
|
|
|
|
|
|
VkSemaphore signalSemaphores[] = {renderFinished->handle}; |
|
|
|
|
submitInfo.signalSemaphoreCount = 1; |
|
|
|
|
submitInfo.pSignalSemaphores = signalSemaphores; |
|
|
|
|
|
|
|
|
|
vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, renderInFlight->handle); |
|
|
|
|
submitMutex.lock(); |
|
|
|
|
vkQueueSubmit(Instance::instance->graphicsAndPresentQueue, 1, &submitInfo, renderFence->handle); |
|
|
|
|
submitMutex.unlock(); |
|
|
|
|
|
|
|
|
|
VkPresentInfoKHR presentInfo {}; |
|
|
|
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; |
|
|
|
@ -337,7 +393,10 @@ void Application::drawFrame() { |
|
|
|
|
presentInfo.pSwapchains = swapchains; |
|
|
|
|
presentInfo.pImageIndices = &imageIndex; |
|
|
|
|
|
|
|
|
|
result = vkQueuePresentKHR(Instance::instance->presentQueue, &presentInfo); |
|
|
|
|
submitMutex.lock(); |
|
|
|
|
result = vkQueuePresentKHR(Instance::instance->graphicsAndPresentQueue, &presentInfo); |
|
|
|
|
submitMutex.unlock(); |
|
|
|
|
|
|
|
|
|
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || Instance::instance->windowResized){ |
|
|
|
|
Instance::instance->windowResized = false; |
|
|
|
|
swapchain->recreateSwapchain(); |
|
|
|
@ -345,17 +404,19 @@ void Application::drawFrame() { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::update() { |
|
|
|
|
vkWaitForFences(Instance::GetDevice(), 1, &computeInFlight->handle, VK_TRUE, UINT64_MAX); |
|
|
|
|
vkResetFences(Instance::GetDevice(), 1, &computeInFlight->handle); |
|
|
|
|
vkWaitForFences(Instance::GetDevice(), 1, &transferFence->handle, VK_TRUE, UINT64_MAX); |
|
|
|
|
vkResetFences(Instance::GetDevice(), 1, &transferFence->handle); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->computeBuffer; |
|
|
|
|
vkResetCommandBuffer(cmdBuffer, 0); |
|
|
|
|
currentDrawVertexBuffer = 1 - currentDrawVertexBuffer; |
|
|
|
|
descriptorPool->bindBuffer(*vertexBuffers[1 - currentDrawVertexBuffer], VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::MESH, 0); |
|
|
|
|
|
|
|
|
|
VkCommandBufferBeginInfo beginInfo {}; |
|
|
|
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; |
|
|
|
|
beginInfo.flags = 0; |
|
|
|
|
|
|
|
|
|
VkCommandBuffer cmdBuffer = Instance::instance->computeCommandPool->buffers[0]; |
|
|
|
|
{ |
|
|
|
|
vkResetCommandBuffer(cmdBuffer, 0); |
|
|
|
|
vkBeginCommandBuffer(cmdBuffer, &beginInfo); |
|
|
|
|
recordComputeCommands(cmdBuffer); |
|
|
|
|
vkEndCommandBuffer(cmdBuffer); |
|
|
|
@ -363,19 +424,49 @@ void Application::update() { |
|
|
|
|
VkSubmitInfo submit {}; |
|
|
|
|
submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
|
|
|
|
submit.commandBufferCount = 1; |
|
|
|
|
submit.pCommandBuffers = &Instance::instance->commandPool->computeBuffer; |
|
|
|
|
submit.pCommandBuffers = &cmdBuffer; |
|
|
|
|
submit.signalSemaphoreCount = 1; |
|
|
|
|
submit.pSignalSemaphores = &computeFinished->handle; |
|
|
|
|
submit.pSignalSemaphores = &computeSemaphore->handle; |
|
|
|
|
|
|
|
|
|
vkQueueSubmit(Instance::instance->computeQueue, 1, &submit, computeInFlight->handle); |
|
|
|
|
} |
|
|
|
|
submitMutex.lock(); |
|
|
|
|
vkQueueSubmit(Instance::instance->computeAndTransferQueue, 1, &submit, nullptr); |
|
|
|
|
submitMutex.unlock(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cmdBuffer = Instance::instance->computeCommandPool->buffers[1]; |
|
|
|
|
vkResetCommandBuffer(cmdBuffer, 0); |
|
|
|
|
{ |
|
|
|
|
vkBeginCommandBuffer(cmdBuffer, &beginInfo); |
|
|
|
|
|
|
|
|
|
VkBufferCopy copyRegion {}; |
|
|
|
|
copyRegion.size = vertexBuffers[0]->size; |
|
|
|
|
copyRegion.srcOffset = 0; |
|
|
|
|
copyRegion.dstOffset = 0; |
|
|
|
|
|
|
|
|
|
vkCmdCopyBuffer(cmdBuffer, vertexBuffers[1 - currentDrawVertexBuffer]->handle, vertexBuffers[currentDrawVertexBuffer]->handle, 1, ©Region); |
|
|
|
|
|
|
|
|
|
void Application::recordDrawCommands() { |
|
|
|
|
VkCommandBuffer cmdBuffer = Instance::instance->commandPool->graphicsBuffer; |
|
|
|
|
vkEndCommandBuffer(cmdBuffer); |
|
|
|
|
|
|
|
|
|
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; |
|
|
|
|
|
|
|
|
|
VkSubmitInfo submit {}; |
|
|
|
|
submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
|
|
|
|
submit.commandBufferCount = 1; |
|
|
|
|
submit.pCommandBuffers = &cmdBuffer; |
|
|
|
|
submit.waitSemaphoreCount = 1; |
|
|
|
|
submit.pWaitSemaphores = &computeSemaphore->handle; |
|
|
|
|
submit.pWaitDstStageMask = &waitStage; |
|
|
|
|
|
|
|
|
|
submitMutex.lock(); |
|
|
|
|
vkQueueSubmit(Instance::instance->computeAndTransferQueue, 1, &submit, transferFence->handle); |
|
|
|
|
submitMutex.unlock(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::recordDrawCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
|
vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->handle); |
|
|
|
|
|
|
|
|
|
VkBuffer buffers[] = {vertexBuffer->handle}; |
|
|
|
|
VkBuffer buffers[] = {vertexBuffers[currentDrawVertexBuffer]->handle}; |
|
|
|
|
VkDeviceSize offsets[] = {0}; |
|
|
|
|
vkCmdBindVertexBuffers(cmdBuffer, 0, 1, buffers, offsets); |
|
|
|
|
vkCmdBindIndexBuffer(cmdBuffer, faceBuffer->handle, 0, VK_INDEX_TYPE_UINT32); |
|
|
|
@ -393,7 +484,7 @@ void Application::recordComputeCommands(VkCommandBuffer cmdBuffer) { |
|
|
|
|
return (threads - 1) / blockSize + 1; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
uint32_t vertexGroupCount = getGroupCount(vertexBuffer->size / sizeof(Vertex), BlOCK_SIZE); |
|
|
|
|
uint32_t vertexGroupCount = getGroupCount(vertexBuffers[1 - currentDrawVertexBuffer]->size / sizeof(Vertex), BlOCK_SIZE); |
|
|
|
|
uint32_t faceGroupCount = getGroupCount(faceBuffer->size / sizeof(Face), BlOCK_SIZE); |
|
|
|
|
|
|
|
|
|
VkMemoryBarrier barrier {}; |
|
|
|
|