diff --git a/.gitignore b/.gitignore index 378eac2..4508cfb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,6 @@ -build +build/ +bin/ + +# vim +*swo +*swp diff --git a/src/BufferUtils.cpp b/src/BufferUtils.cpp index acf617e..d0a7e6f 100644 --- a/src/BufferUtils.cpp +++ b/src/BufferUtils.cpp @@ -1,3 +1,4 @@ +#include #include "BufferUtils.h" #include "Instance.h" @@ -75,7 +76,7 @@ void BufferUtils::CreateBufferFromData(Device* device, VkCommandPool commandPool // Fill the staging buffer void *data; vkMapMemory(device->GetVkDevice(), stagingBufferMemory, 0, bufferSize, 0, &data); - memcpy(data, bufferData, static_cast(bufferSize)); + std::memcpy(data, bufferData, static_cast(bufferSize)); vkUnmapMemory(device->GetVkDevice(), stagingBufferMemory); // Create the buffer diff --git a/src/Device.h b/src/Device.h index 18b8632..06d8d81 100644 --- a/src/Device.h +++ b/src/Device.h @@ -4,7 +4,10 @@ #include #include "QueueFlags.h" #include "SwapChain.h" +#include "Instance.h" +//Forward declaration to resolve circular dependency +class Instance; class SwapChain; class Device { friend class Instance; diff --git a/src/Instance.h b/src/Instance.h index afc54c5..6a7de2d 100644 --- a/src/Instance.h +++ b/src/Instance.h @@ -6,6 +6,9 @@ #include "QueueFlags.h" #include "Device.h" +// Forward declaration to resolve circular dependency +class Device; + extern const bool ENABLE_VALIDATION; class Instance { diff --git a/src/Renderer.cpp b/src/Renderer.cpp index b445d04..8af5511 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -24,6 +24,8 @@ Renderer::Renderer(Device* device, SwapChain* swapChain, Scene* scene, Camera* c CreateDescriptorPool(); CreateCameraDescriptorSet(); CreateModelDescriptorSets(); + // LOOK + CreateGrassDescriptorSetLayout(); CreateGrassDescriptorSets(); CreateTimeDescriptorSet(); CreateComputeDescriptorSets(); @@ -144,6 +146,25 @@ void Renderer::CreateCameraDescriptorSetLayout() { } } +void Renderer::CreateGrassDescriptorSetLayout() { + VkDescriptorSetLayoutBinding grassBinding = {}; + grassBinding.binding = 0; + grassBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + grassBinding.descriptorCount = 1; + grassBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + grassBinding.pImmutableSamplers = NULL; + std::vector bindings = { grassBinding }; + + VkDescriptorSetLayoutCreateInfo grassLayout = { }; + grassLayout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + grassLayout.bindingCount = static_cast(bindings.size()); + grassLayout.pBindings = bindings.data(); + + if (vkCreateDescriptorSetLayout(logicalDevice, &grassLayout, nullptr, &modelDescriptorSetLayout) != VK_SUCCESS) { + throw std::runtime_error("Failed to create descriptor set layout (grass)"); + } +} + void Renderer::CreateModelDescriptorSetLayout() { VkDescriptorSetLayoutBinding uboLayoutBinding = {}; uboLayoutBinding.binding = 0; @@ -198,6 +219,41 @@ void Renderer::CreateComputeDescriptorSetLayout() { // TODO: Create the descriptor set layout for the compute pipeline // Remember this is like a class definition stating why types of information // will be stored at each binding + + // (Copied and slightly modified from function above) + // Describe the binding of the descriptor set layout + VkDescriptorSetLayoutBinding grassLayoutBinding = {}; + grassLayoutBinding.binding = 0; + grassLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + grassLayoutBinding.descriptorCount = 1; + grassLayoutBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + grassLayoutBinding.pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutBinding dropBinding = {}; + dropBinding.binding = 1; + dropBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + dropBinding.descriptorCount = 1; + dropBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + dropBinding.pImmutableSamplers = nullptr; + + VkDescriptorSetLayoutBinding countBinding = {}; + countBinding.binding = 2; + countBinding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + countBinding.descriptorCount = 1; + countBinding.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + countBinding.pImmutableSamplers = nullptr; + + std::vector bindings = { grassLayoutBinding, dropBinding, countBinding }; + + // Create the descriptor set layout + VkDescriptorSetLayoutCreateInfo layoutInfo = {}; + layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + layoutInfo.bindingCount = static_cast(bindings.size()); + layoutInfo.pBindings = bindings.data(); + + if (vkCreateDescriptorSetLayout(logicalDevice, &layoutInfo, nullptr, &timeDescriptorSetLayout) != VK_SUCCESS) { + throw std::runtime_error("Failed to create descriptor set layout (compute)"); + } } void Renderer::CreateDescriptorPool() { @@ -216,6 +272,8 @@ void Renderer::CreateDescriptorPool() { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER , 1 }, // TODO: Add any additional types and counts of descriptors you will need to allocate + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, static_cast(scene->GetBlades().size()) }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, static_cast(scene->GetBlades().size()) * 3 }, }; VkDescriptorPoolCreateInfo poolInfo = {}; @@ -320,6 +378,38 @@ void Renderer::CreateModelDescriptorSets() { void Renderer::CreateGrassDescriptorSets() { // TODO: Create Descriptor sets for the grass. // This should involve creating descriptor sets which point to the model matrix of each group of grass blades + VkDescriptorSetLayout layouts[] = { grassDescriptorSetLayout }; + VkDescriptorSetAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + allocInfo.descriptorPool = descriptorPool; + allocInfo.descriptorSetCount = static_cast(grassDescriptorSets.size()); + allocInfo.pSetLayouts = layouts; + + // Allocate descriptor sets + if (vkAllocateDescriptorSets(logicalDevice, &allocInfo, grassDescriptorSets.data()) != VK_SUCCESS) { + throw std::runtime_error("Failed to allocate descriptor set (grass)"); + } + + std::array descriptorWrites = {}; + for (int i = 0; i < scene->GetBlades().size(); i++) { + VkDescriptorBufferInfo grassBufferInfo = {}; + grassBufferInfo.buffer = scene->GetBlades()[i]->GetModelBuffer(); + grassBufferInfo.offset = 0; + grassBufferInfo.range = sizeof(ModelBufferObject); + + descriptorWrites[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrites[i].dstSet = grassDescriptorSets[i]; + descriptorWrites[i].dstBinding = 0; + descriptorWrites[i].dstArrayElement = 0; + descriptorWrites[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descriptorWrites[i].descriptorCount = 1; + descriptorWrites[i].pBufferInfo = &grassBufferInfo; + descriptorWrites[i].pImageInfo = nullptr; + descriptorWrites[i].pTexelBufferView = nullptr; + } + + // Update descriptor sets + vkUpdateDescriptorSets(logicalDevice, static_cast(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr); } void Renderer::CreateTimeDescriptorSet() { @@ -360,6 +450,72 @@ void Renderer::CreateTimeDescriptorSet() { void Renderer::CreateComputeDescriptorSets() { // TODO: Create Descriptor sets for the compute pipeline // The descriptors should point to Storage buffers which will hold the grass blades, the culled grass blades, and the output number of grass blades + VkDescriptorSetLayout layouts[] = { computeDescriptorSetLayout }; + VkDescriptorSetAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + allocInfo.descriptorPool = descriptorPool; + allocInfo.descriptorSetCount = static_cast(computeDescriptorSets.size()); + allocInfo.pSetLayouts = layouts; + + // Allocate descriptor sets + if (vkAllocateDescriptorSets(logicalDevice, &allocInfo, computeDescriptorSets.data()) != VK_SUCCESS) { + throw std::runtime_error("Failed to allocate descriptor set (compute)"); + } + + std::array descriptorWrites = {}; + for (int i = 0; i < scene->GetBlades().size(); i++) { + int sz = sizeof(Blade) * NUM_BLADES; + VkDescriptorBufferInfo computeBufferInfo = {}; + computeBufferInfo.buffer = scene->GetBlades()[i]->GetBladesBuffer(); + computeBufferInfo.offset = 0; + computeBufferInfo.range = sz; + + VkDescriptorBufferInfo clipBufferInfo = {}; + clipBufferInfo.buffer = scene->GetBlades()[i]->GetBladesBuffer(); + clipBufferInfo.offset = 0; + clipBufferInfo.range = sz; + + VkDescriptorBufferInfo grassCountBufferInfo = {}; + grassCountBufferInfo.buffer = scene->GetBlades()[i]->GetBladesBuffer(); + grassCountBufferInfo.offset = 0; + grassCountBufferInfo.range = sz; + + int idx = i * 3; + descriptorWrites[idx].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrites[idx].dstSet = computeDescriptorSets[i]; + descriptorWrites[idx].dstBinding = 0; + descriptorWrites[idx].dstArrayElement = 0; + descriptorWrites[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + descriptorWrites[idx].descriptorCount = 1; + descriptorWrites[idx].pBufferInfo = &computeBufferInfo; + descriptorWrites[idx].pImageInfo = nullptr; + descriptorWrites[idx].pTexelBufferView = nullptr; + + idx++; + descriptorWrites[idx].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrites[idx].dstSet = computeDescriptorSets[i]; + descriptorWrites[idx].dstBinding = 0; + descriptorWrites[idx].dstArrayElement = 0; + descriptorWrites[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + descriptorWrites[idx].descriptorCount = 1; + descriptorWrites[idx].pBufferInfo = &clipBufferInfo; + descriptorWrites[idx].pImageInfo = nullptr; + descriptorWrites[idx].pTexelBufferView = nullptr; + + idx++; + descriptorWrites[idx].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descriptorWrites[idx].dstSet = computeDescriptorSets[i]; + descriptorWrites[idx].dstBinding = 0; + descriptorWrites[idx].dstArrayElement = 0; + descriptorWrites[idx].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; + descriptorWrites[idx].descriptorCount = 1; + descriptorWrites[idx].pBufferInfo = &grassCountBufferInfo; + descriptorWrites[idx].pImageInfo = nullptr; + descriptorWrites[idx].pTexelBufferView = nullptr; + } + + // Update descriptor sets + vkUpdateDescriptorSets(logicalDevice, static_cast(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr); } void Renderer::CreateGraphicsPipeline() { diff --git a/src/Renderer.h b/src/Renderer.h index 95e025f..1dababd 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -19,6 +19,8 @@ class Renderer { void CreateModelDescriptorSetLayout(); void CreateTimeDescriptorSetLayout(); void CreateComputeDescriptorSetLayout(); + //LOOK + void CreateGrassDescriptorSetLayout(); void CreateDescriptorPool(); @@ -56,12 +58,18 @@ class Renderer { VkDescriptorSetLayout cameraDescriptorSetLayout; VkDescriptorSetLayout modelDescriptorSetLayout; VkDescriptorSetLayout timeDescriptorSetLayout; + // LOOK + VkDescriptorSetLayout grassDescriptorSetLayout; + VkDescriptorSetLayout computeDescriptorSetLayout; VkDescriptorPool descriptorPool; VkDescriptorSet cameraDescriptorSet; std::vector modelDescriptorSets; VkDescriptorSet timeDescriptorSet; + // LOOK + std::vector grassDescriptorSets; + std::vector computeDescriptorSets; VkPipelineLayout graphicsPipelineLayout; VkPipelineLayout grassPipelineLayout; diff --git a/src/SwapChain.cpp b/src/SwapChain.cpp index 711fec0..047b6c2 100644 --- a/src/SwapChain.cpp +++ b/src/SwapChain.cpp @@ -1,4 +1,5 @@ #include +#include #include "SwapChain.h" #include "Instance.h" #include "Device.h" diff --git a/src/Window.cpp b/src/Window.cpp index a365dc9..2672a40 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -1,4 +1,5 @@ #include +#include #include "Window.h" namespace {