|
|
|
@ -10,10 +10,10 @@ |
|
|
|
|
Application::Application() { |
|
|
|
|
new Instance; |
|
|
|
|
swapchain = new Swapchain(); |
|
|
|
|
pipeline = new Pipeline(swapchain->renderPass); |
|
|
|
|
graphicsPipeline = new Pipeline(swapchain->renderPass); |
|
|
|
|
auto stagedVertexBuffer = Buffer::createStagedVertexBuffer(); |
|
|
|
|
vertexBuffer = new Buffer(stagedVertexBuffer->size, |
|
|
|
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, |
|
|
|
|
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, |
|
|
|
|
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); |
|
|
|
|
|
|
|
|
|
auto stagedIndexBuffer = Buffer::createStagedIndexBuffer(); |
|
|
|
@ -28,7 +28,8 @@ Application::Application() { |
|
|
|
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); |
|
|
|
|
vkMapMemory(Instance::instance->device, uniformBuffer->memory, 0, bufferSize, 0, &uniformBufferMapped); |
|
|
|
|
|
|
|
|
|
pipeline->createDescriptorSet(uniformBuffer); |
|
|
|
|
graphicsPipeline->createDescriptorSet(uniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); |
|
|
|
|
computePipeline = new ComputePipeline(vertexBuffer); |
|
|
|
|
commandPool = new CommandPool(); |
|
|
|
|
|
|
|
|
|
stagedVertexBuffer->copyTo(vertexBuffer, commandPool); |
|
|
|
@ -38,6 +39,8 @@ Application::Application() { |
|
|
|
|
delete stagedIndexBuffer; |
|
|
|
|
|
|
|
|
|
createSyncObjects(); |
|
|
|
|
|
|
|
|
|
recordComputeCommandBuffer(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::updateUniformBuffer() { |
|
|
|
@ -77,7 +80,7 @@ void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t im |
|
|
|
|
renderPassInfo.pClearValues = clearValues; |
|
|
|
|
|
|
|
|
|
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE); |
|
|
|
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->handle); |
|
|
|
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->handle); |
|
|
|
|
|
|
|
|
|
VkViewport viewport {}; |
|
|
|
|
viewport.x = 0; |
|
|
|
@ -97,7 +100,7 @@ void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t im |
|
|
|
|
VkDeviceSize offsets[] = {0}; |
|
|
|
|
vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets); |
|
|
|
|
vkCmdBindIndexBuffer(commandBuffer, indexBuffer->handle, 0, VK_INDEX_TYPE_UINT32); |
|
|
|
|
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->layout, 0, 1, &pipeline->descriptorSet, 0, nullptr); |
|
|
|
|
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &graphicsPipeline->descriptorSet, 0, nullptr); |
|
|
|
|
|
|
|
|
|
vkCmdDrawIndexed(commandBuffer, indices.size(), 1, 0, 0, 0); |
|
|
|
|
|
|
|
|
@ -105,8 +108,32 @@ void Application::recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t im |
|
|
|
|
vkEndCommandBuffer(commandBuffer); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::createSyncObjects() { |
|
|
|
|
VkSemaphoreCreateInfo semaphoreInfo {}; |
|
|
|
|
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; |
|
|
|
|
|
|
|
|
|
VkFenceCreateInfo fenceInfo {}; |
|
|
|
|
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; |
|
|
|
|
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; |
|
|
|
|
|
|
|
|
|
vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &imageAvailableSemaphore); |
|
|
|
|
vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &renderFinishedSemaphore); |
|
|
|
|
vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &computeFinishedSemaphore); |
|
|
|
|
vkCreateFence(Instance::instance->device, &fenceInfo, nullptr, &renderInFlightFence); |
|
|
|
|
vkCreateFence(Instance::instance->device, &fenceInfo, nullptr, &computeInFlightFence); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::mainLoop() { |
|
|
|
|
while (!glfwWindowShouldClose(Instance::instance->window)){ |
|
|
|
|
glfwPollEvents(); |
|
|
|
|
update(); |
|
|
|
|
drawFrame(); |
|
|
|
|
} |
|
|
|
|
vkDeviceWaitIdle(Instance::instance->device); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::drawFrame() { |
|
|
|
|
vkWaitForFences(Instance::instance->device, 1, &inFlightFence, VK_TRUE, UINT64_MAX); |
|
|
|
|
vkWaitForFences(Instance::instance->device, 1, &renderInFlightFence, VK_TRUE, UINT64_MAX); |
|
|
|
|
|
|
|
|
|
uint32_t imageIndex; |
|
|
|
|
VkResult result = vkAcquireNextImageKHR(Instance::instance->device, swapchain->handle, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex); |
|
|
|
@ -115,10 +142,10 @@ void Application::drawFrame() { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
vkResetFences(Instance::instance->device, 1, &inFlightFence); |
|
|
|
|
vkResetFences(Instance::instance->device, 1, &renderInFlightFence); |
|
|
|
|
|
|
|
|
|
vkResetCommandBuffer(commandPool->buffer, 0); |
|
|
|
|
recordCommandBuffer(commandPool->buffer, imageIndex); |
|
|
|
|
vkResetCommandBuffer(commandPool->graphicsBuffer, 0); |
|
|
|
|
recordCommandBuffer(commandPool->graphicsBuffer, imageIndex); |
|
|
|
|
|
|
|
|
|
updateUniformBuffer(); |
|
|
|
|
|
|
|
|
@ -131,13 +158,15 @@ void Application::drawFrame() { |
|
|
|
|
submitInfo.pWaitSemaphores = waitSemaphores; |
|
|
|
|
submitInfo.pWaitDstStageMask = waitStages; |
|
|
|
|
submitInfo.commandBufferCount = 1; |
|
|
|
|
submitInfo.pCommandBuffers = &commandPool->buffer; |
|
|
|
|
submitInfo.pCommandBuffers = &commandPool->graphicsBuffer; |
|
|
|
|
|
|
|
|
|
VkSemaphore signalSemaphores[] = {renderFinishedSemaphore}; |
|
|
|
|
submitInfo.signalSemaphoreCount = 1; |
|
|
|
|
submitInfo.pSignalSemaphores = signalSemaphores; |
|
|
|
|
submitInfo.waitSemaphoreCount = 1; |
|
|
|
|
submitInfo.pWaitSemaphores = &computeFinishedSemaphore; |
|
|
|
|
|
|
|
|
|
vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, inFlightFence); |
|
|
|
|
vkQueueSubmit(Instance::instance->graphicsQueue, 1, &submitInfo, renderInFlightFence); |
|
|
|
|
|
|
|
|
|
VkPresentInfoKHR presentInfo {}; |
|
|
|
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; |
|
|
|
@ -156,37 +185,48 @@ void Application::drawFrame() { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::createSyncObjects() { |
|
|
|
|
VkSemaphoreCreateInfo semaphoreInfo {}; |
|
|
|
|
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; |
|
|
|
|
void Application::update() { |
|
|
|
|
vkWaitForFences(Instance::instance->device, 1, &computeInFlightFence, VK_TRUE, UINT64_MAX); |
|
|
|
|
vkResetFences(Instance::instance->device, 1, &computeInFlightFence); |
|
|
|
|
|
|
|
|
|
VkFenceCreateInfo fenceInfo {}; |
|
|
|
|
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; |
|
|
|
|
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; |
|
|
|
|
VkSubmitInfo submit {}; |
|
|
|
|
submit.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
|
|
|
|
submit.commandBufferCount = 1; |
|
|
|
|
submit.pCommandBuffers = &commandPool->computeBuffer; |
|
|
|
|
submit.signalSemaphoreCount = 1; |
|
|
|
|
submit.pSignalSemaphores = &computeFinishedSemaphore; |
|
|
|
|
|
|
|
|
|
vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &imageAvailableSemaphore); |
|
|
|
|
vkCreateSemaphore(Instance::instance->device, &semaphoreInfo, nullptr, &renderFinishedSemaphore); |
|
|
|
|
vkCreateFence(Instance::instance->device, &fenceInfo, nullptr, &inFlightFence); |
|
|
|
|
vkQueueSubmit(Instance::instance->computeQueue, 1, &submit, computeInFlightFence); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Application::mainLoop() { |
|
|
|
|
while (!glfwWindowShouldClose(Instance::instance->window)){ |
|
|
|
|
glfwPollEvents(); |
|
|
|
|
drawFrame(); |
|
|
|
|
} |
|
|
|
|
vkDeviceWaitIdle(Instance::instance->device); |
|
|
|
|
void Application::recordComputeCommandBuffer() { |
|
|
|
|
VkCommandBuffer buffer = commandPool->computeBuffer; |
|
|
|
|
|
|
|
|
|
VkCommandBufferBeginInfo beginInfo {}; |
|
|
|
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; |
|
|
|
|
|
|
|
|
|
vkBeginCommandBuffer(buffer, &beginInfo); |
|
|
|
|
|
|
|
|
|
vkCmdBindPipeline(buffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->handle); |
|
|
|
|
vkCmdBindDescriptorSets(buffer, VK_PIPELINE_BIND_POINT_COMPUTE, computePipeline->layout,0, 1, &computePipeline->descriptorSet, 0, nullptr); |
|
|
|
|
vkCmdDispatch(buffer, 1, 1, 1); |
|
|
|
|
|
|
|
|
|
vkEndCommandBuffer(buffer); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Application::~Application() { |
|
|
|
|
delete swapchain; |
|
|
|
|
vkDestroySemaphore(Instance::instance->device, imageAvailableSemaphore, nullptr); |
|
|
|
|
vkDestroySemaphore(Instance::instance->device, renderFinishedSemaphore, nullptr); |
|
|
|
|
vkDestroyFence(Instance::instance->device, inFlightFence, nullptr); |
|
|
|
|
vkDestroySemaphore(Instance::instance->device, computeFinishedSemaphore, nullptr); |
|
|
|
|
vkDestroyFence(Instance::instance->device, renderInFlightFence, nullptr); |
|
|
|
|
vkDestroyFence(Instance::instance->device, computeInFlightFence, nullptr); |
|
|
|
|
delete commandPool; |
|
|
|
|
delete vertexBuffer; |
|
|
|
|
delete indexBuffer; |
|
|
|
|
delete uniformBuffer; |
|
|
|
|
delete pipeline; |
|
|
|
|
delete graphicsPipeline; |
|
|
|
|
delete computePipeline; |
|
|
|
|
delete Instance::instance; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|