Browse Source

Add grayscale image compute

Compute and graphics pipeline work to gether now. The output image isn't exactly grayscale, but it's something!
master
AliMehrabani 10 months ago
parent
commit
c2f0a45759
  1. 2
      VkTest.pro.user
  2. 167
      VulkanTutorial1.0/ComputeAndGraphics.cpp
  3. 60
      VulkanTutorial1.0/ComputeAndGraphics.h
  4. BIN
      shaders/VulkanTutorial1.0/ComputeAndGraphics/compComp.spv
  5. 24
      shaders/VulkanTutorial1.0/ComputeAndGraphics/shaderCompute.comp
  6. 1
      shaders/VulkanTutorial1.0/ComputeAndGraphics/shaderCompute.vert

2
VkTest.pro.user

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.10.1, 2024-11-10T17:06:43. -->
<!-- Written by QtCreator 4.10.1, 2024-11-12T19:33:00. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

167
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<VkDescriptorSetLayoutBinding> 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<uint32_t>(texWidth), static_cast<uint32_t>(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<uint32_t>(texWidth), static_cast<uint32_t>(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<Particle> 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<size_t>(bufferSize));
vkUnmapMemory(_device, stagingBufferMemory);
}
std::vector<Particle> ComputeAndGraphics::initParticles()
{
std::default_random_engine rndEngine(static_cast<unsigned>(time(nullptr)));
std::uniform_real_distribution<float> rndDist(0.0f, 1.0f);
std::vector<Particle> 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<VkWriteDescriptorSet, 2> 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<uint32_t>(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<VkWriteDescriptorSet, 3> 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<uint32_t>(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<uint32_t>(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<uint32_t>(_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<float, std::chrono::seconds::period>(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<float>(_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();

60
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<VkVertexInputAttributeDescription, 2> getAttributeDescriptions() {
std::array<VkVertexInputAttributeDescription, 2> 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<uint32_t> graphicsFamily;
std::optional<uint32_t> 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<Particle> 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<VkDescriptorSet> _descriptorSets;
VkImage _RawTextureImage;
VkDeviceMemory _RawTextureImageMemory;
VkImageView _RawTextureImageView;
VkImage _textureImage;
VkDeviceMemory _textureImageMemory;
VkImageView _textureImageView;
@ -372,8 +344,14 @@ private:
VkDeviceMemory _depthImageMemory;
VkImageView _depthImageView;
std::vector<VkBuffer> _shaderStorageBuffers;
std::vector<VkDeviceMemory> _shaderStorageBuffersMemory;
std::vector<VkBuffer> _shaderRawStorageBuffers;
std::vector<VkDeviceMemory> _shaderRawStorageBuffersMemory;
std::vector<VkBuffer> _shaderTransformedStorageBuffers;
std::vector<VkDeviceMemory> _shaderTransformedStorageBuffersMemory;
VkDeviceSize _textureImageSize;
uint32_t _textureImageWidth;
uint32_t _textureImageHeight;
VkPipelineLayout _computePipelineLayout;
VkPipeline _computePipeline;
VkDescriptorSetLayout _computeDescriptorSetLayout;

BIN
shaders/VulkanTutorial1.0/ComputeAndGraphics/compComp.spv

Binary file not shown.

24
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);
}

1
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);

Loading…
Cancel
Save