diff --git a/VkTest.pro.user b/VkTest.pro.user index 86d2911..3d3a480 100644 --- a/VkTest.pro.user +++ b/VkTest.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/VulkanTutorial1.0/ComputeAndGraphics.cpp b/VulkanTutorial1.0/ComputeAndGraphics.cpp index 9c52a66..9e0c3f5 100644 --- a/VulkanTutorial1.0/ComputeAndGraphics.cpp +++ b/VulkanTutorial1.0/ComputeAndGraphics.cpp @@ -85,9 +85,9 @@ void ComputeAndGraphics::initVulkan() createImageViews(); createRenderPass(); createDescriptorSetLayout(); -// createComputeDescriptorSetLayout(); + createComputeDescriptorSetLayout(); createGraphicsPipeline(); -// createComputePipeline(); + createComputePipeline(); createCommandPool(); createDepthResources(); createFramebuffers(); @@ -96,14 +96,14 @@ void ComputeAndGraphics::initVulkan() createTextureSampler(); createVertexBuffer(); createIndexBuffer(); -// createShaderStorageBuffers(); + createShaderStorageBuffers(); createUniformBuffers(); createDescriptorPool(); -// createComputeDescriptorPool(); + createComputeDescriptorPool(); createDescriptorSets(); -// createComputeDescriptorSets(); + createComputeDescriptorSets(); createCommandBuffer(); -// createComputeCommandBuffers(); + createComputeCommandBuffers(); createSyncObjects(); } @@ -651,9 +651,9 @@ void ComputeAndGraphics::createDescriptorSetLayout() { void ComputeAndGraphics::createComputeDescriptorSetLayout() { VkDescriptorSetLayoutBinding uboLayoutBinding = createLayoutBindingInfo(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); - VkDescriptorSetLayoutBinding computeLayoutBinding1 = createLayoutBindingInfo(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); + VkDescriptorSetLayoutBinding computeLayoutBinding1 = createLayoutBindingInfo(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); - VkDescriptorSetLayoutBinding computeLayoutBinding2 = createLayoutBindingInfo(3, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); + VkDescriptorSetLayoutBinding computeLayoutBinding2 = createLayoutBindingInfo(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT); std::vector bindings = {uboLayoutBinding, computeLayoutBinding1, computeLayoutBinding2}; VkDescriptorSetLayoutCreateInfo layoutInfo{}; @@ -1022,6 +1022,9 @@ void ComputeAndGraphics::createTextureImage() { int texWidth, texHeight, texChannels; stbi_uc* pixels = stbi_load("/home/ali-mehrabani/Qt_projects/VkTest/textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha); VkDeviceSize imageSize = texWidth * texHeight * 4; +// qDebug() << imageSize; +// qDebug() << texWidth; +// qDebug() << texHeight; if (!pixels) { throw std::runtime_error("failed to load texture image!"); @@ -1034,13 +1037,13 @@ void ComputeAndGraphics::createTextureImage() { stbi_image_free(pixels); - createImage(texWidth, texHeight, 1, VK_SAMPLE_COUNT_1_BIT, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL + createImage(texWidth, texHeight, 1, VK_SAMPLE_COUNT_1_BIT, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_LINEAR , VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _textureImage, _textureImageMemory); - transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1); - copyBufferToImage(stagingBuffer, _textureImage, static_cast(texWidth), static_cast(texHeight)); - transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1); +// transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1); +// copyBufferToImage(stagingBuffer, _textureImage, static_cast(texWidth), static_cast(texHeight)); +// transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1); vkDestroyBuffer(_device, stagingBuffer, nullptr); vkFreeMemory(_device, stagingBufferMemory, nullptr); @@ -1428,61 +1431,42 @@ uint32_t ComputeAndGraphics::findMemoryType(uint32_t typeFilter, VkMemoryPropert } void ComputeAndGraphics::createShaderStorageBuffers() { + int texWidth, texHeight, texChannels; + stbi_uc* pixels = stbi_load("/home/ali-mehrabani/Qt_projects/VkTest/textures/texture.jpg", &texWidth, &texHeight, &texChannels, STBI_rgb_alpha); + _textureImageSize = texWidth * texHeight * 4; + _textureImageWidth = texWidth; + _textureImageHeight = texHeight; + + if (!pixels) { + throw std::runtime_error("failed to load texture image!"); + } VkBuffer stagingBuffer; VkDeviceMemory stagingBufferMemory; - copyParticlesToStagingBuffer(stagingBuffer, stagingBufferMemory); + copyImageToStagingBuffer(stagingBuffer, stagingBufferMemory, pixels, _textureImageSize); - initShaderStorageBuffers(stagingBuffer); + initShaderStorageBuffers(stagingBuffer, _textureImageSize); vkDestroyBuffer(_device, stagingBuffer, nullptr); vkFreeMemory(_device, stagingBufferMemory, nullptr); } -void ComputeAndGraphics::initShaderStorageBuffers(VkBuffer& stagingBuffer) +void ComputeAndGraphics::initShaderStorageBuffers(VkBuffer& stagingBuffer, VkDeviceSize bufferSize) { - VkDeviceSize bufferSize = sizeof(Particle) * PARTICLE_COUNT; - _shaderStorageBuffers.resize(MAX_FRAMES_IN_FLIGHT); - _shaderStorageBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT); + _shaderRawStorageBuffers.resize(MAX_FRAMES_IN_FLIGHT); + _shaderRawStorageBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT); + _shaderTransformedStorageBuffers.resize(MAX_FRAMES_IN_FLIGHT); + _shaderTransformedStorageBuffersMemory.resize(MAX_FRAMES_IN_FLIGHT); for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { - createBuffer(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT - , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _shaderStorageBuffers[i], _shaderStorageBuffersMemory[i]); - copyBuffer(stagingBuffer, _shaderStorageBuffers[i], bufferSize); - } -} + createBuffer(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT + , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _shaderRawStorageBuffers[i], _shaderRawStorageBuffersMemory[i]); + copyBuffer(stagingBuffer, _shaderRawStorageBuffers[i], bufferSize); -void ComputeAndGraphics::copyParticlesToStagingBuffer(VkBuffer& stagingBuffer, VkDeviceMemory& stagingBufferMemory) -{ - std::vector particles = initParticles(); - - VkDeviceSize bufferSize = sizeof(Particle) * PARTICLE_COUNT; - createBuffer(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT - , stagingBuffer, stagingBufferMemory); - - void* data; - vkMapMemory(_device, stagingBufferMemory, 0, bufferSize, 0, &data); - memcpy(data, particles.data(), reinterpret_cast(bufferSize)); - vkUnmapMemory(_device, stagingBufferMemory); -} - -std::vector ComputeAndGraphics::initParticles() -{ - std::default_random_engine rndEngine(static_cast(time(nullptr))); - std::uniform_real_distribution rndDist(0.0f, 1.0f); - - std::vector particles(PARTICLE_COUNT); - for (auto& particle : particles) { - float r = 0.25f * sqrt(rndDist(rndEngine)); - float theta = rndDist(rndEngine) * 2.0f * 3.14159265358979323846f; - float x = r * cos(theta) * HEIGHT / WIDTH; - float y = r * sin(theta); - particle.position = glm::vec2(x, y); - particle.velocity = glm::normalize(glm::vec2(x,y)) * 0.00025f; - particle.color = glm::vec4(rndDist(rndEngine), rndDist(rndEngine), rndDist(rndEngine), 1.0f); + createBuffer(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT + , VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, _shaderTransformedStorageBuffers[i], _shaderTransformedStorageBuffersMemory[i]); + copyBuffer(stagingBuffer, _shaderTransformedStorageBuffers[i], bufferSize); } - - return particles; } void ComputeAndGraphics::createUniformBuffers() { @@ -1547,19 +1531,19 @@ void ComputeAndGraphics::createDescriptorSets() std::array descriptorWrites{}; - addUniformBufferWriteDescriptor(descriptorWrites[0], &bufferInfo, i, 0); + addUniformBufferWriteDescriptor(descriptorWrites[0], &bufferInfo, _descriptorSets[i], 0); - addImageWriteDescriptor(descriptorWrites[1], &imageInfo, i, 1); + addImageWriteDescriptor(descriptorWrites[1], &imageInfo, _descriptorSets[i], 1); vkUpdateDescriptorSets(_device, static_cast(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr); } } -void ComputeAndGraphics::addUniformBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, size_t index +void ComputeAndGraphics::addUniformBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, VkDescriptorSet dstSet , uint32_t dstBinding) { descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.dstSet = _descriptorSets[index]; + descriptorWrite.dstSet = dstSet; descriptorWrite.dstBinding = dstBinding; descriptorWrite.dstArrayElement = 0; descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; @@ -1567,11 +1551,11 @@ void ComputeAndGraphics::addUniformBufferWriteDescriptor(VkWriteDescriptorSet& d descriptorWrite.pBufferInfo = bufferInfo; } -void ComputeAndGraphics::addImageWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorImageInfo* imageInfo, size_t index +void ComputeAndGraphics::addImageWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorImageInfo* imageInfo, VkDescriptorSet dstSet , uint32_t dstBinding) { descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.dstSet = _descriptorSets[index]; + descriptorWrite.dstSet = dstSet; descriptorWrite.dstBinding = dstBinding; descriptorWrite.dstArrayElement = 0; descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; @@ -1623,24 +1607,23 @@ void ComputeAndGraphics::createComputeDescriptorSets() std::array descriptorWrites{}; - addUniformBufferWriteDescriptor(descriptorWrites[0], &bufferInfo, i, 0); + addUniformBufferWriteDescriptor(descriptorWrites[0], &bufferInfo, _computeDescriptorSets[i], 0); - VkDescriptorBufferInfo storageBufferInfoLastFrame = createDescriptorBufferInfo(_shaderStorageBuffers[(i - 1) % MAX_FRAMES_IN_FLIGHT] - , sizeof(Particle) * PARTICLE_COUNT); - addStorageBufferWriteDescriptor(descriptorWrites[1], &storageBufferInfoLastFrame, i, 1); + VkDescriptorBufferInfo storageBufferInfoLastFrame = createDescriptorBufferInfo(_shaderRawStorageBuffers[i], _textureImageSize); + addStorageBufferWriteDescriptor(descriptorWrites[1], &storageBufferInfoLastFrame, _computeDescriptorSets[i], 1); - VkDescriptorBufferInfo storageBufferInfoCurrentFrame = createDescriptorBufferInfo(_shaderStorageBuffers[i], sizeof(Particle) * PARTICLE_COUNT); - addStorageBufferWriteDescriptor(descriptorWrites[2], &storageBufferInfoCurrentFrame, i, 2); + VkDescriptorBufferInfo storageBufferInfoCurrentFrame = createDescriptorBufferInfo(_shaderTransformedStorageBuffers[i], _textureImageSize); + addStorageBufferWriteDescriptor(descriptorWrites[2], &storageBufferInfoCurrentFrame, _computeDescriptorSets[i], 2); vkUpdateDescriptorSets(_device, static_cast(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr); } } -void ComputeAndGraphics::addStorageBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, size_t index +void ComputeAndGraphics::addStorageBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, VkDescriptorSet dstSet , uint32_t dstBinding) { descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descriptorWrite.dstSet = _descriptorSets[index]; + descriptorWrite.dstSet = dstSet; descriptorWrite.dstBinding = dstBinding; descriptorWrite.dstArrayElement = 0; descriptorWrite.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; @@ -1657,7 +1640,7 @@ void ComputeAndGraphics::allocateComputeDescriptorSets() allocInfo.descriptorSetCount = static_cast(MAX_FRAMES_IN_FLIGHT); allocInfo.pSetLayouts = layouts.data(); - _descriptorSets.resize(MAX_FRAMES_IN_FLIGHT); + _computeDescriptorSets.resize(MAX_FRAMES_IN_FLIGHT); if (vkAllocateDescriptorSets(_device, &allocInfo, _computeDescriptorSets.data()) != VK_SUCCESS) { throw std::runtime_error("failed to allocate descriptor sets!"); } @@ -1733,7 +1716,9 @@ void ComputeAndGraphics::mainLoop() } void ComputeAndGraphics::drawFrame(){ -// computeSubmission(); + computeSubmission(); + + copyTransformedBufferToTextureImage(); VkResult result = graphicsSubmission(); if (result == VK_ERROR_OUT_OF_DATE_KHR) @@ -1744,12 +1729,17 @@ void ComputeAndGraphics::drawFrame(){ currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; } +void ComputeAndGraphics::copyTransformedBufferToTextureImage() +{ + transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1); + copyBufferToImage(_shaderTransformedStorageBuffers[currentFrame], _textureImage, _textureImageWidth, _textureImageHeight); + transitionImageLayout(_textureImage, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 1); +} + void ComputeAndGraphics::computeSubmission() { vkWaitForFences(_device, 1, &_computeInFlightFences[currentFrame], VK_TRUE, UINT64_MAX); - updateUniformBuffer(currentFrame); - vkResetFences(_device, 1, &_computeInFlightFences[currentFrame]); vkResetCommandBuffer(_computeCommandBuffers[currentFrame], /*VkCommandBufferResetFlagBits*/ 0); @@ -1790,10 +1780,10 @@ VkResult ComputeAndGraphics::graphicsSubmission() throw std::runtime_error("failed to acquire swap chain image!"); } -// VkSemaphore waitSemaphores[] = {_computeFinishedSemaphores[currentFrame], _imageAvailableSemaphores[currentFrame]}; -// VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; - VkSemaphore waitSemaphores[] = {_imageAvailableSemaphores[currentFrame]}; - VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; + VkSemaphore waitSemaphores[] = {_computeFinishedSemaphores[currentFrame], _imageAvailableSemaphores[currentFrame]}; + VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; +// VkSemaphore waitSemaphores[] = {_imageAvailableSemaphores[currentFrame]}; +// VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; VkSemaphore signalSemaphores[] = {_renderFinishedSemaphores[currentFrame]}; drawSubmission(imageIndex, waitSemaphores, waitStages, signalSemaphores); @@ -1825,7 +1815,7 @@ VkSubmitInfo ComputeAndGraphics::createDrawSubmitInfo(VkSemaphore* waitSemaphore VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.waitSemaphoreCount = 1; + submitInfo.waitSemaphoreCount = 2; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; @@ -1958,7 +1948,7 @@ void ComputeAndGraphics::recordComputeCommandBuffer(VkCommandBuffer commandBuffe vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, _computePipelineLayout, 0, 1, &_computeDescriptorSets[currentFrame], 0, nullptr); - vkCmdDispatch(commandBuffer, PARTICLE_COUNT / 256, 1, 1); + vkCmdDispatch(commandBuffer, static_cast(_textureImageSize / 8), 1, 1); if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) { throw std::runtime_error("failed to record compute command buffer!"); @@ -1973,8 +1963,8 @@ void ComputeAndGraphics::updateUniformBuffer(uint32_t currentImage) { float time = std::chrono::duration(currentTime - startTime).count(); UniformBufferObject ubo{}; - ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(22.5f), glm::vec3(0.0f, 0.0f, 1.0f)); - ubo.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); + ubo.model = glm::rotate(glm::mat4(1.0f), glm::radians(0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); + ubo.view = glm::lookAt(glm::vec3(0.001f, 0.001f, 1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); ubo.proj = glm::perspective(glm::radians(45.0f), _swapChainExtent.width / static_cast(_swapChainExtent.height), 0.1f, 10.0f); ubo.proj[1][1] *= -1; @@ -2030,8 +2020,10 @@ void ComputeAndGraphics::cleanPipeline() void ComputeAndGraphics::cleanBuffers() { for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { - vkDestroyBuffer(_device, _shaderStorageBuffers[i], nullptr); - vkFreeMemory(_device, _shaderStorageBuffersMemory[i], nullptr); + vkDestroyBuffer(_device, _shaderRawStorageBuffers[i], nullptr); + vkFreeMemory(_device, _shaderRawStorageBuffersMemory[i], nullptr); + vkDestroyBuffer(_device, _shaderTransformedStorageBuffers[i], nullptr); + vkFreeMemory(_device, _shaderTransformedStorageBuffersMemory[i], nullptr); } for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { @@ -2075,6 +2067,15 @@ void ComputeAndGraphics::cleanBase() glfwTerminate(); } +void ComputeAndGraphics::cleanDescriptors() +{ + vkDestroyDescriptorPool(_device, _descriptorPool, nullptr); + vkDestroyDescriptorSetLayout(_device, _descriptorSetLayout, nullptr); + + vkDestroyDescriptorPool(_device, _computeDescriptorPool, nullptr); + vkDestroyDescriptorSetLayout(_device, _computeDescriptorSetLayout, nullptr); +} + void ComputeAndGraphics::cleanup() { cleanupSwapChain(); @@ -2085,9 +2086,7 @@ void ComputeAndGraphics::cleanup() vkDestroyImage(_device, _textureImage, nullptr); vkFreeMemory(_device, _textureImageMemory, nullptr); - vkDestroyDescriptorPool(_device, _descriptorPool, nullptr); - - vkDestroyDescriptorSetLayout(_device, _descriptorSetLayout, nullptr); + cleanDescriptors(); cleanBuffers(); diff --git a/VulkanTutorial1.0/ComputeAndGraphics.h b/VulkanTutorial1.0/ComputeAndGraphics.h index 338ef3c..434877e 100644 --- a/VulkanTutorial1.0/ComputeAndGraphics.h +++ b/VulkanTutorial1.0/ComputeAndGraphics.h @@ -29,39 +29,6 @@ const int MAX_FRAMES_IN_FLIGHT = 2; -const uint32_t PARTICLE_COUNT = 8192; - -struct Particle { - alignas(16) glm::vec2 position; - alignas(16) glm::vec2 velocity; - alignas(16) glm::vec4 color; - - static VkVertexInputBindingDescription getBindingDescription() { - VkVertexInputBindingDescription bindingDescription{}; - bindingDescription.binding = 0; - bindingDescription.stride = sizeof(Particle); - bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; - - return bindingDescription; - } - - static std::array getAttributeDescriptions() { - std::array attributeDescriptions{}; - - attributeDescriptions[0].binding = 0; - attributeDescriptions[0].location = 0; - attributeDescriptions[0].format = VK_FORMAT_R32G32_SFLOAT; - attributeDescriptions[0].offset = offsetof(Particle, position); - - attributeDescriptions[1].binding = 0; - attributeDescriptions[1].location = 1; - attributeDescriptions[1].format = VK_FORMAT_R32G32B32A32_SFLOAT; - attributeDescriptions[1].offset = offsetof(Particle, color); - - return attributeDescriptions; - } -}; - struct QueueFamilyIndices { std::optional graphicsFamily; std::optional presentFamily; @@ -269,19 +236,17 @@ private: void copyIndicesToStagingBuffer(VkBuffer& stagingBuffer, VkDeviceMemory& stagingBufferMemory); void allocateAndBindBufferMemory(VkBuffer& buffer, VkDeviceMemory& bufferMemory, VkMemoryPropertyFlags properties); - void copyParticlesToStagingBuffer(VkBuffer& stagingBuffer, VkDeviceMemory& stagingBufferMemory); - std::vector initParticles(); - void initShaderStorageBuffers(VkBuffer& stagingBuffer); + void initShaderStorageBuffers(VkBuffer& stagingBuffer, VkDeviceSize bufferSize); void allocateDescriptorSets(); VkDescriptorBufferInfo createDescriptorBufferInfo(VkBuffer buffer, VkDeviceSize range); VkDescriptorImageInfo createDescriptorImageInfo(); - void addUniformBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, size_t index, uint32_t dstBinding); - void addImageWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorImageInfo* imageInfo, size_t index, uint32_t dstBinding); + void addUniformBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, VkDescriptorSet dstSet, uint32_t dstBinding); + void addImageWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorImageInfo* imageInfo, VkDescriptorSet dstSet, uint32_t dstBinding); void allocateComputeDescriptorSets(); - void addStorageBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, size_t index, uint32_t dstBinding); + void addStorageBufferWriteDescriptor(VkWriteDescriptorSet& descriptorWrite, VkDescriptorBufferInfo* bufferInfo, VkDescriptorSet dstSet, uint32_t dstBinding); void computeSubmission(); VkSubmitInfo createComputeSubmitInfo(); @@ -299,6 +264,9 @@ private: void cleanBuffers(); void cleanSyncObjects(); void cleanBase(); + void cleanDescriptors(); + + void copyTransformedBufferToTextureImage(); const int32_t WIDTH = 800; const int32_t HEIGHT = 600; @@ -363,6 +331,10 @@ private: VkDescriptorPool _descriptorPool; std::vector _descriptorSets; + VkImage _RawTextureImage; + VkDeviceMemory _RawTextureImageMemory; + VkImageView _RawTextureImageView; + VkImage _textureImage; VkDeviceMemory _textureImageMemory; VkImageView _textureImageView; @@ -372,8 +344,14 @@ private: VkDeviceMemory _depthImageMemory; VkImageView _depthImageView; - std::vector _shaderStorageBuffers; - std::vector _shaderStorageBuffersMemory; + std::vector _shaderRawStorageBuffers; + std::vector _shaderRawStorageBuffersMemory; + std::vector _shaderTransformedStorageBuffers; + std::vector _shaderTransformedStorageBuffersMemory; + VkDeviceSize _textureImageSize; + uint32_t _textureImageWidth; + uint32_t _textureImageHeight; + VkPipelineLayout _computePipelineLayout; VkPipeline _computePipeline; VkDescriptorSetLayout _computeDescriptorSetLayout; diff --git a/shaders/VulkanTutorial1.0/ComputeAndGraphics/compComp.spv b/shaders/VulkanTutorial1.0/ComputeAndGraphics/compComp.spv index 7416b6f..848ba5b 100644 Binary files a/shaders/VulkanTutorial1.0/ComputeAndGraphics/compComp.spv and b/shaders/VulkanTutorial1.0/ComputeAndGraphics/compComp.spv differ diff --git a/shaders/VulkanTutorial1.0/ComputeAndGraphics/shaderCompute.comp b/shaders/VulkanTutorial1.0/ComputeAndGraphics/shaderCompute.comp index 156d0eb..1af5f3d 100644 --- a/shaders/VulkanTutorial1.0/ComputeAndGraphics/shaderCompute.comp +++ b/shaders/VulkanTutorial1.0/ComputeAndGraphics/shaderCompute.comp @@ -1,32 +1,26 @@ #version 450 -struct Particle { - vec2 position; - vec2 velocity; - vec4 color; -}; - layout (binding = 0) uniform ParameterUBO { float deltaTime; } ubo; -layout(std140, binding = 2) readonly buffer ParticleSSBOIn { - Particle particlesIn[ ]; +layout(std140, binding = 1) readonly buffer TexelSSBOIn { + vec4 texelsIn[]; }; -layout(std140, binding = 3) buffer ParticleSSBOOut { - Particle particlesOut[ ]; +layout(std140, binding = 2) buffer TexelSSBOOut { + vec4 texelsOut[]; }; -layout (local_size_x = 256, local_size_y = 1, local_size_z = 1) in; +layout (local_size_x = 8, local_size_y = 1, local_size_z = 1) in; void main() { - uint index = gl_GlobalInvocationID.x; + uint idx = gl_GlobalInvocationID.x; - Particle particleIn = particlesIn[index]; + vec4 texelIn = texelsIn[idx]; - particlesOut[index].position = particleIn.position + particleIn.velocity.xy * ubo.deltaTime; - particlesOut[index].velocity = particleIn.velocity; + float gray = dot(texelIn.rgb, vec3(0.2627, 0.6780, 0.0593)); + texelsOut[idx] = vec4(vec3(gray), 1.0); } diff --git a/shaders/VulkanTutorial1.0/ComputeAndGraphics/shaderCompute.vert b/shaders/VulkanTutorial1.0/ComputeAndGraphics/shaderCompute.vert index 8e31111..24f0cb2 100644 --- a/shaders/VulkanTutorial1.0/ComputeAndGraphics/shaderCompute.vert +++ b/shaders/VulkanTutorial1.0/ComputeAndGraphics/shaderCompute.vert @@ -16,6 +16,7 @@ layout(location = 1) out vec2 fragTexCoord; void main() { gl_Position = vec4(inPosition, 1.0); gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 1.0); +// gl_Position = vec4(inPosition, 1.0); // gl_PointSize = 5.0; // gl_Position = vec4(inPosition.xy, 1.0, 1.0);