Compare commits

..

No commits in common. 'main' and 'feature/softbody-runtime-control' have entirely different histories.

  1. 14
      include/application.hpp
  2. 4
      include/constraints.hpp
  3. 3
      include/input.hpp
  4. 5
      include/vulkan/buffer.hpp
  5. 1
      include/vulkan/descriptor_pool.hpp
  6. 22
      include/vulkan/instance.hpp
  7. 1
      include/vulkan/swapchain.hpp
  8. 2
      lib/imgui
  9. 257
      src/application.cpp
  10. 12
      src/constraints.cpp
  11. 18
      src/input.cpp
  12. 15
      src/soft_body.cpp
  13. 1
      src/stb_image.cpp
  14. 36
      src/vulkan/buffer.cpp
  15. 11
      src/vulkan/descriptor_pool.cpp
  16. 31
      src/vulkan/image.cpp
  17. 40
      src/vulkan/instance.cpp
  18. 21
      src/vulkan/pipeline.cpp
  19. 20
      src/vulkan/swapchain.cpp
  20. 1
      src/vulkan/vma.cpp

@ -26,33 +26,19 @@ using std::vector;
using std::optional;
class SoftBody;
class Instance;
class Swapchain;
class GraphicsPipeline;
class Buffer;
class Buffer;
class CommandPool;
class Image;
class ComputePipeline;
class Fence;
class Semaphore;
class Camera;
class DescriptorPool;
class Grabber;
struct SizesUniformData;
class Application {

@ -62,24 +62,20 @@ private:
struct Constraint {
virtual ~Constraint() {}
virtual void writeData(ConstraintData& dataLists) const {};
};
struct DistanceConstraint : Edge, Constraint {
explicit DistanceConstraint(const Edge &edge) : Edge(edge) {}
void writeData(ConstraintData &dataLists) const override;
};
struct AreaConstraint : Triangle, Constraint {
explicit AreaConstraint(const Triangle& triangle) : Triangle(triangle) {}
void writeData(ConstraintData &dataLists) const override;
};
struct VolumeConstraint : Tetrahedron, Constraint {
explicit VolumeConstraint(const Tetrahedron& tetrahedron) : Tetrahedron(tetrahedron) {}
void writeData(ConstraintData &dataLists) const override;
};

@ -6,7 +6,6 @@
#include "glm/vec2.hpp"
class Listener;
class MouseListener;
class Input {
@ -43,8 +42,6 @@ class KeyListener : Listener {
class MouseListener : public Listener {
public:
virtual void mouseMoved(const glm::vec2& delta) {};
virtual void mouseButtonPressed(int button) {};
virtual void mouseButtonReleased(int button) {};
};

@ -18,8 +18,7 @@ class Image;
class Buffer {
public:
Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsage,
VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags vmaAllocationFlags,
const std::string &name = "");
VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags vmaAllocationFlags);
unique_ptr<Buffer> appended(void* data, VkDeviceSize appendSize, VkCommandBuffer commandBuffer) const;
unique_ptr<Buffer> replaced(void* data, VkDeviceSize replaceSize, VkCommandBuffer commandBuffer) const;
virtual ~Buffer();
@ -28,12 +27,10 @@ public:
VmaAllocationInfo allocationInfo {};
VkDeviceSize size;
void setName(const std::string& newName);
template <typename T>
T& access(){
return *reinterpret_cast<T*>(allocationInfo.pMappedData);
}
void copyTo(Buffer* buffer) const;
void copyTo(Image* image) const;
void setData(void* data, VkDeviceSize offset, VkDeviceSize dataSize, VkCommandBuffer commandBuffer=VK_NULL_HANDLE);

@ -5,7 +5,6 @@
#include <map>
class Buffer;
class Image;
enum class DescriptorSet {

@ -14,7 +14,6 @@
using std::optional, std::vector;
class CommandPool;
class Swapchain;
void printVmaStats();
@ -37,11 +36,24 @@ public:
struct QueueFamilyIndices {
vector<uint32_t> graphicsAndPresent;
vector<uint32_t> computeAndTransfer;
std::set<uint32_t> uniqueQueueFamilies();
uint32_t tryComputeAndTransferDedicated();
bool isEnough();
std::set<uint32_t> uniqueQueueFamilies(){
std::set<uint32_t> unique;
unique.insert(graphicsAndPresent.begin(), graphicsAndPresent.end());
unique.insert(computeAndTransfer.begin(), computeAndTransfer.end());
return unique;
}
uint32_t tryComputeAndTransferDedicated(){
for (uint32_t family : computeAndTransfer){
if (std::find(graphicsAndPresent.begin(), graphicsAndPresent.end(), family) == graphicsAndPresent.end()){
return family;
}
}
return computeAndTransfer[0];
}
bool isEnough(){
return !graphicsAndPresent.empty() && !computeAndTransfer.empty();
}
};
QueueFamilyIndices indices {};
static Instance* instance;

@ -4,7 +4,6 @@
#include <vector>
class Image;
class Instance;
struct SwapchainSupportDetails {

@ -1 +1 @@
Subproject commit 646df390032f64eb03f8b5e2e5cbaf0c8e3bb237
Subproject commit 4e2126ee44c066c642d89d25320fd32e449e5a9a

@ -62,21 +62,15 @@ Application::Application() {
swapchain = make_unique<Swapchain>();
Instance::instance->initImGui(*swapchain);
descriptorPool = make_unique<DescriptorPool>();
graphicsPipeline = unique_ptr<GraphicsPipeline>(
new GraphicsPipeline(
"shaders/vert.spv", "shaders/frag.spv",
graphicsPipeline = unique_ptr<GraphicsPipeline>(new GraphicsPipeline("shaders/vert.spv", "shaders/frag.spv",
swapchain->renderPass,
{descriptorPool->layouts[DescriptorSet::WORLD]}
)
);
{descriptorPool->layouts[DescriptorSet::WORLD]}));
cameraUniformBuffer = make_unique<Buffer>(
sizeof(CameraUniformData),
cameraUniformBuffer = make_unique<Buffer>(sizeof(CameraUniformData),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Camera"
);
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT);
cameraUniformBuffer->setName("Camera");
camera = make_unique<Camera>(swapchain->extent);
updateCameraBuffer();
@ -87,11 +81,10 @@ Application::Application() {
bool grabbing;
} initialGrabInformation {};
initialGrabInformation.distanceToFace = 1e20;
grabBuffer = make_unique<Buffer>(
sizeof(GrabInformation),
grabBuffer = make_unique<Buffer>(sizeof(GrabInformation),
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0, "Grab"
);
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, 0);
grabBuffer->setName("Grab");
grabBuffer->setData(&initialGrabInformation, 0, sizeof(initialGrabInformation));
grabber = make_unique<Grabber>();
@ -99,9 +92,8 @@ Application::Application() {
sizeof(SizesUniformData),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Sizes"
);
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT);
sizeInformationBuffer->setName("Sizes");
sizeInformation = &sizeInformationBuffer->access<SizesUniformData>();
*sizeInformation = {};
@ -117,19 +109,15 @@ Application::Application() {
sizeof(SimulationUniformData),
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
"Simulation properties"
);
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT);
simulationPropertiesBuffer->setName("Simulation properties");
simulationPropertiesBuffer->access<SimulationUniformData>() = simulationUniformData;
{
int w, h;
stbi_uc* data = stbi_load("textures/rocky_diff.jpg", &w, &h, nullptr, STBI_rgb_alpha);
VkDeviceSize imageSize = w * h * 4;
firstImage = make_unique<Image>(
data, imageSize, w, h, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
);
firstImage = make_unique<Image>(data, imageSize, w, h, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
firstImage->createView(VK_IMAGE_ASPECT_COLOR_BIT);
firstImage->createSampler();
}
@ -137,9 +125,7 @@ Application::Application() {
descriptorPool->bindBuffer(*cameraUniformBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::WORLD, 0);
descriptorPool->bindImage(*firstImage, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, DescriptorSet::WORLD, 2);
descriptorPool->bindBuffer(
*simulationPropertiesBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::SIMULATION, 0
);
descriptorPool->bindBuffer(*simulationPropertiesBuffer, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, DescriptorSet::SIMULATION, 0);
descriptorPool->bindBuffer(*grabBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, DescriptorSet::SIMULATION, 1);
createComputePipelines();
@ -149,8 +135,7 @@ Application::Application() {
void Application::mainLoop() {
vkDeviceWaitIdle(Instance::GetDevice());
std::future compute = std::async(
std::launch::async, [this]() {
std::future compute = std::async(std::launch::async, [this](){
while (!glfwWindowShouldClose(Instance::instance->window)){
auto t1 = system_clock::now();
update();
@ -158,16 +143,13 @@ void Application::mainLoop() {
auto measuredUpdateDuration = duration<float>(t2 - t1);
auto requestedUpdateDuration = duration<float>(
simulationPropertiesBuffer->access<SimulationUniformData>().dt
);
simulationPropertiesBuffer->access<SimulationUniformData>().dt);
std::this_thread::sleep_for(requestedUpdateDuration - measuredUpdateDuration);
performanceInformation.updateDuration = measuredUpdateDuration.count();
performanceInformation.recentTotalUpdateDurations.push(
std::max(requestedUpdateDuration, measuredUpdateDuration).count());
performanceInformation.recentTotalUpdateDurations.push(std::max(requestedUpdateDuration, measuredUpdateDuration).count());
}
}
);
});
auto t1 = system_clock::now();
while (!glfwWindowShouldClose(Instance::instance->window)){
@ -265,46 +247,27 @@ void Application::addSoftBody(const std::string &modelFile, size_t count) {
auto commandBuffer = Instance::instance->renderingCommandPool->beginSingleTimeCommandBuffer();
VkBufferUsageFlags bufferUsageFlags =
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VkBufferUsageFlags bufferUsageFlags = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
if (vertexBuffers[0] == nullptr){
newVertexBuffers[0] = make_unique<Buffer>(
newVertices.size() * sizeof(Vertex),
newVertexBuffers[0] = make_unique<Buffer>(newVertices.size() * sizeof(Vertex),
bufferUsageFlags | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
memoryUsage,
0,
"Vertices 0"
);
newVertexBuffers[1] = make_unique<Buffer>(
newVertices.size() * sizeof(Vertex),
memoryUsage, 0);
newVertexBuffers[1] = make_unique<Buffer>(newVertices.size() * sizeof(Vertex),
bufferUsageFlags | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
memoryUsage,
0,
"Vertices 1"
);
newFaceBuffer = make_unique<Buffer>(
newFaces.size() * sizeof(Face),
memoryUsage, 0);
newFaceBuffer = make_unique<Buffer>(newFaces.size() * sizeof(Face),
bufferUsageFlags | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
memoryUsage,
0,
"Faces"
);
newEdgeBuffer = make_unique<Buffer>(
constraintData.edges.size() * sizeof(Edge),
bufferUsageFlags,
memoryUsage,
0,
"Edges"
);
newTetrahedronBuffer = make_unique<Buffer>(
constraintData.tetrahedra.size() * sizeof(Tetrahedron),
bufferUsageFlags,
memoryUsage,
0,
"Tetrahedra"
);
memoryUsage, 0);
newEdgeBuffer = make_unique<Buffer>(constraintData.edges.size() * sizeof(Edge), bufferUsageFlags, memoryUsage, 0);
newTetrahedronBuffer = make_unique<Buffer>(constraintData.tetrahedra.size() * sizeof(Tetrahedron), bufferUsageFlags, memoryUsage, 0);
newVertexBuffers[0]->setName("Vertices 0");
newVertexBuffers[1]->setName("Vertices 1");
newFaceBuffer->setName("Faces");
newEdgeBuffer->setName("Edges");
newTetrahedronBuffer->setName("Tetrahedra");
newVertexBuffers[0]->setData(newVertices.data(), 0, newVertexBuffers[0]->size, commandBuffer);
newVertexBuffers[1]->setData(newVertices.data(), 0, newVertexBuffers[1]->size, commandBuffer);
@ -312,31 +275,11 @@ void Application::addSoftBody(const std::string &modelFile, size_t count) {
newEdgeBuffer->setData(constraintData.edges.data(), 0, newEdgeBuffer->size, commandBuffer);
newTetrahedronBuffer->setData(constraintData.tetrahedra.data(), 0, newTetrahedronBuffer->size, commandBuffer);
} else {
newVertexBuffers[0] = vertexBuffers[0]->appended(
newVertices.data(),
newVertices.size() * sizeof(Vertex),
commandBuffer
);
newVertexBuffers[1] = vertexBuffers[1]->appended(
newVertices.data(),
newVertices.size() * sizeof(Vertex),
commandBuffer
);
newFaceBuffer = faceBuffer->appended(
newFaces.data(),
newFaces.size() * sizeof(Face),
commandBuffer
);
newEdgeBuffer = edgeBuffer->replaced(
constraintData.edges.data(),
constraintData.edges.size() * sizeof(Edge),
commandBuffer
);
newTetrahedronBuffer = tetrahedronBuffer->replaced(
constraintData.tetrahedra.data(),
constraintData.tetrahedra.size() * sizeof(Tetrahedron),
commandBuffer
);
newVertexBuffers[0] = vertexBuffers[0]->appended(newVertices.data(), newVertices.size() * sizeof(Vertex), commandBuffer);
newVertexBuffers[1] = vertexBuffers[1]->appended(newVertices.data(), newVertices.size() * sizeof(Vertex), commandBuffer);
newFaceBuffer = faceBuffer->appended(newFaces.data(), newFaces.size() * sizeof(Face), commandBuffer);
newEdgeBuffer = edgeBuffer->replaced(constraintData.edges.data(), constraintData.edges.size() * sizeof(Edge), commandBuffer);
newTetrahedronBuffer = tetrahedronBuffer->replaced(constraintData.tetrahedra.data(), constraintData.tetrahedra.size() * sizeof(Tetrahedron), commandBuffer);
}
VkQueue queue = Instance::instance->graphicsAndPresentQueue;
@ -387,13 +330,11 @@ void Application::createComputePipelines() {
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
layouts.push_back(descriptorPool->layouts[DescriptorSet::WORLD]);
layouts.push_back(descriptorPool->layouts[DescriptorSet::SIMULATION]);
pushRanges.push_back(
{
pushRanges.push_back({
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.offset = 0,
.size = sizeof(GrabPushData)
}
);
});
grabPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/grab.spv", layouts, pushRanges));
}
@ -403,13 +344,11 @@ void Application::createComputePipelines() {
{
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
layouts.push_back(descriptorPool->layouts[DescriptorSet::SIMULATION]);
pushRanges.push_back(
{
pushRanges.push_back({
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.offset = 0,
.size = sizeof(PBDPushData)
}
);
});
pbdPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/pbd.spv", layouts, pushRanges));
}
@ -418,13 +357,11 @@ void Application::createComputePipelines() {
{
layouts.push_back(descriptorPool->layouts[DescriptorSet::MESH]);
pushRanges.push_back(
{
pushRanges.push_back({
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
.offset = 0,
.size = sizeof(uint32_t)
}
);
});
normalPipeline = unique_ptr<ComputePipeline>(new ComputePipeline("shaders/normal.spv", layouts, pushRanges));
}
@ -442,9 +379,7 @@ void Application::drawFrame(float dt) {
vkWaitForFences(Instance::GetDevice(), 1, &renderFence->handle, VK_TRUE, UINT64_MAX);
uint32_t imageIndex;
VkResult result = vkAcquireNextImageKHR(
Instance::GetDevice(), swapchain->handle, UINT64_MAX, imageAvailable->handle, VK_NULL_HANDLE, &imageIndex
);
VkResult result = vkAcquireNextImageKHR(Instance::GetDevice(), swapchain->handle, UINT64_MAX, imageAvailable->handle, VK_NULL_HANDLE, &imageIndex);
if (result == VK_ERROR_OUT_OF_DATE_KHR){
submitMutex.lock();
swapchain->recreateSwapchain();
@ -479,10 +414,8 @@ void Application::drawFrame(float dt) {
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
vkCmdPipelineBarrier(
cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 1,
&barrier, 1, &vertexBufferBarrier, 0, nullptr
);
vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 1,
&barrier, 1, &vertexBufferBarrier, 0, nullptr);
VkRenderPassBeginInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
@ -571,10 +504,7 @@ void Application::recordDrawCommands(VkCommandBuffer commandBuffer) {
VkDeviceSize offsets[] = {0};
vkCmdBindVertexBuffers(commandBuffer, 0, 1, buffers, offsets);
vkCmdBindIndexBuffer(commandBuffer, faceBuffer->handle, 0, VK_INDEX_TYPE_UINT32);
vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1,
&descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr
);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr);
for (const auto &softBody : softBodies){
vkCmdDrawIndexed(commandBuffer, softBody->faces.size() * 3, 1, softBody->firstIndex, 0, 0);
@ -621,10 +551,7 @@ void Application::update() {
copyRegion.srcOffset = 0;
copyRegion.dstOffset = 0;
vkCmdCopyBuffer(
cmdBuffer, vertexBuffers[1 - currentDrawVertexBuffer]->handle,
vertexBuffers[currentDrawVertexBuffer]->handle, 1, &copyRegion
);
vkCmdCopyBuffer(cmdBuffer, vertexBuffers[1 - currentDrawVertexBuffer]->handle, vertexBuffers[currentDrawVertexBuffer]->handle, 1, &copyRegion);
vkEndCommandBuffer(cmdBuffer);
@ -665,28 +592,16 @@ void Application::recordGrabCommands(VkCommandBuffer commandBuffer) {
// TODO maybe add buffermemorybarrier for camera uniform, because it can be changed from main drawing thread
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->handle);
vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 0, 1,
&descriptorPool->sets[DescriptorSet::MESH], 0, nullptr
);
vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 1, 1,
&descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr
);
vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 2, 1,
&descriptorPool->sets[DescriptorSet::SIMULATION], 0, nullptr
);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 1, 1, &descriptorPool->sets[DescriptorSet::WORLD], 0, nullptr);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, grabPipeline->layout, 2, 1, &descriptorPool->sets[DescriptorSet::SIMULATION], 0, nullptr);
GrabPushData pushConstants {};
if (grabber->started()){
pushConstants.state = 0;
pushConstants.screenPosition = grabber->previousCursorPosition;
vkCmdPushConstants(
commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData),
&pushConstants
);
vkCmdPushConstants(commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants);
uint32_t faceInvocations = GetGroupCount(sizeInformation->faceCount, BLOCK_SIZE_GRAB);
@ -694,10 +609,7 @@ void Application::recordGrabCommands(VkCommandBuffer commandBuffer) {
computePipelineBarrier(commandBuffer);
pushConstants.state = 1;
vkCmdPushConstants(
commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData),
&pushConstants
);
vkCmdPushConstants(commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants);
vkCmdDispatch(commandBuffer, 1, 1, 1);
}
@ -707,10 +619,7 @@ void Application::recordGrabCommands(VkCommandBuffer commandBuffer) {
if (grabber->moved(screenDelta)){
pushConstants.state = 2;
pushConstants.screenDelta = screenDelta;
vkCmdPushConstants(
commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData),
&pushConstants
);
vkCmdPushConstants(commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants);
vkCmdDispatch(commandBuffer, 1, 1, 1);
}
@ -718,10 +627,7 @@ void Application::recordGrabCommands(VkCommandBuffer commandBuffer) {
if (grabber->stopped()){
pushConstants.state = 3;
vkCmdPushConstants(
commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData),
&pushConstants
);
vkCmdPushConstants(commandBuffer, grabPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(GrabPushData), &pushConstants);
vkCmdDispatch(commandBuffer, 1, 1, 1);
}
@ -732,14 +638,8 @@ void Application::recordPBDCommands(VkCommandBuffer commandBuffer) {
uint32_t vertexGroupCount = GetGroupCount(sizeInformation->vertexCount, BLOCK_SIZE_PBD);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->handle);
vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 0, 1,
&descriptorPool->sets[DescriptorSet::MESH], 0, nullptr
);
vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 1, 1,
&descriptorPool->sets[DescriptorSet::SIMULATION], 0, nullptr
);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pbdPipeline->layout, 1, 1, &descriptorPool->sets[DescriptorSet::SIMULATION], 0, nullptr);
uint32_t state;
@ -747,16 +647,12 @@ void Application::recordPBDCommands(VkCommandBuffer commandBuffer) {
for (size_t i = 0; i < k; i++){
state = 0;
vkCmdPushConstants(
commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state
);
vkCmdPushConstants(commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
vkCmdDispatch(commandBuffer, vertexGroupCount, 1, 1);
computePipelineBarrier(commandBuffer);
state = 1;
vkCmdPushConstants(
commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state
);
vkCmdPushConstants(commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
for (uint32_t partition = 0; partition < constraintData.partitionCount; partition++){
auto edgePartition = constraintData.edgePartitions[partition];
@ -767,11 +663,9 @@ void Application::recordPBDCommands(VkCommandBuffer commandBuffer) {
ConstraintData::Partition partitions[2] = {edgePartition, tetrahedronPartition};
vkCmdPushConstants(
commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT,
vkCmdPushConstants(commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT,
offsetof(PBDPushData, edgePartition),
sizeof(partitions), partitions
);
sizeof(partitions), partitions);
uint32_t invocations = GetGroupCount(edgePartition.size + tetrahedronPartition.size, BLOCK_SIZE_PBD);
vkCmdDispatch(commandBuffer, invocations, 1, 1);
@ -779,9 +673,7 @@ void Application::recordPBDCommands(VkCommandBuffer commandBuffer) {
}
state = 2;
vkCmdPushConstants(
commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state
);
vkCmdPushConstants(commandBuffer, pbdPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
vkCmdDispatch(commandBuffer, vertexGroupCount, 1, 1);
computePipelineBarrier(commandBuffer);
}
@ -792,10 +684,7 @@ void Application::recordNormalCommands(VkCommandBuffer commandBuffer) {
uint32_t faceGroupCount = GetGroupCount(sizeInformation->faceCount, BLOCK_SIZE_NORMAL);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->handle);
vkCmdBindDescriptorSets(
commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->layout, 0, 1,
&descriptorPool->sets[DescriptorSet::MESH], 0, nullptr
);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, normalPipeline->layout, 0, 1, &descriptorPool->sets[DescriptorSet::MESH], 0, nullptr);
uint32_t state = 0;
vkCmdPushConstants(commandBuffer, normalPipeline->layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(uint32_t), &state);
@ -829,14 +718,12 @@ void Application::computePipelineBarrier(VkCommandBuffer commandBuffer) {
bufferMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
bufferMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
vkCmdPipelineBarrier(
commandBuffer,
vkCmdPipelineBarrier(commandBuffer,
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
0,
1, &memoryBarrier,
1, &bufferMemoryBarrier,
0, nullptr
);
0, nullptr);
}
void Application::imGuiWindows() {
@ -844,8 +731,7 @@ void Application::imGuiWindows() {
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::Begin("Performance");
{
ImGui::Begin("Performance"); {
float updateMS = performanceInformation.updateDuration * 1000.f;
float updateHZ = 1 / performanceInformation.recentTotalUpdateDurations.average();
ImGui::Text("Updates: %2.0fms | %.1fHz", updateMS, updateHZ);
@ -853,17 +739,14 @@ void Application::imGuiWindows() {
float frameMS = performanceInformation.recentFrameDurations.average() * 1000.f;
float frameHZ = 1 / performanceInformation.recentFrameDurations.average();
ImGui::Text("Frames: %.2fms | %.1fHz", frameMS, frameHZ);
}
ImGui::End();
} ImGui::End();
ImGui::Begin("Scene");
{
ImGui::Begin("Scene"); {
if (ImGui::Button("Add")){
addSoftBody("models/bunny_medium.ply");
}
for (const auto &softBody: softBodies){
ImGui::Text("Some softbody");
}
}
ImGui::End();
} ImGui::End();
}

@ -23,16 +23,12 @@ void ConstraintData::insert(const ConstraintData &other) {
tetrahedronPartitions[i].offset += other.tetrahedronPartitions[i].offset;
auto baseEdgeInsert = other.edges.begin() + other.edgePartitions[i].offset;
edges.insert(
edges.begin() + edgePartitions[i].offset + edgePartitions[i].size,
baseEdgeInsert, baseEdgeInsert + other.edgePartitions[i].size
);
edges.insert(edges.begin() + edgePartitions[i].offset + edgePartitions[i].size,
baseEdgeInsert, baseEdgeInsert + other.edgePartitions[i].size);
auto baseTetrahedronInsert = other.tetrahedra.begin() + other.tetrahedronPartitions[i].offset;
tetrahedra.insert(
tetrahedra.begin() + tetrahedronPartitions[i].offset + tetrahedronPartitions[i].size,
baseTetrahedronInsert, baseTetrahedronInsert + other.tetrahedronPartitions[i].size
);
tetrahedra.insert(tetrahedra.begin() + tetrahedronPartitions[i].offset + tetrahedronPartitions[i].size,
baseTetrahedronInsert, baseTetrahedronInsert + other.tetrahedronPartitions[i].size);
edgePartitions[i].size += other.edgePartitions[i].size;
tetrahedronPartitions[i].size += other.tetrahedronPartitions[i].size;

@ -9,36 +9,30 @@ Input::Input(GLFWwindow *window) : window(window) {
instance = this;
glfwSetWindowUserPointer(window, this);
glfwSetKeyCallback(
window, [](GLFWwindow *window, int key, int scancode, int action, int mods) {
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods){
auto inputManager = static_cast<Input*>(glfwGetWindowUserPointer(window));
if (action == GLFW_PRESS)
inputManager->keyPressed(key);
if (action == GLFW_RELEASE)
inputManager->keyReleased(key);
}
);
});
glfwSetCursorPosCallback(
window, [](GLFWwindow *window, double xpos, double ypos) {
glfwSetCursorPosCallback(window, [](GLFWwindow* window, double xpos, double ypos){
auto inputManager = static_cast<Input*>(glfwGetWindowUserPointer(window));
glm::vec2 newPosition = {static_cast<float>(xpos), static_cast<float>(ypos)};
inputManager->mouseMoved(newPosition);
}
);
});
double x = 0, y = 0;
glfwGetCursorPos(window, &x, &y);
currentCursorPosition = glm::vec2(static_cast<float>(x), static_cast<float>(y));
glfwSetMouseButtonCallback(
window, [](GLFWwindow *window, int button, int action, int mods) {
glfwSetMouseButtonCallback(window, [](GLFWwindow* window, int button, int action, int mods){
auto inputManager = static_cast<Input*>(glfwGetWindowUserPointer(window));
if (action == GLFW_PRESS)
inputManager->mouseButtonPressed(button);
if (action == GLFW_RELEASE)
inputManager->mouseButtonReleased(button);
}
);
});
}
void Input::keyPressed(int key) {

@ -118,8 +118,7 @@ void SoftBody::applyVertexWorldOffset(const glm::vec3 &offset) {
}
}
vector<unordered_set<const Constraint *>>
createPartitions(const Graph &graph, const vector<const Constraint *> &ordering) {
vector<unordered_set<const Constraint *>> createPartitions(const Graph &graph, const vector<const Constraint *> &ordering){
unordered_map<const Constraint *, uint32_t> constraintToColor;
vector<unordered_set<const Constraint *>> colorToConstraintList;
@ -228,24 +227,20 @@ void SoftBody::splitConstraints() {
#pragma omp parallel for default(none) shared(findAdjacent, distanceConstraints)
for (const DistanceConstraint &distanceConstraint : distanceConstraints){
findAdjacent(
&distanceConstraint, {
findAdjacent(&distanceConstraint, {
distanceConstraint.a,
distanceConstraint.b
}
);
});
}
#pragma omp parallel for default(none) shared(findAdjacent, volumeConstraints)
for (const VolumeConstraint &volumeConstraint : volumeConstraints){
findAdjacent(
&volumeConstraint, {
findAdjacent(&volumeConstraint, {
volumeConstraint.a,
volumeConstraint.b,
volumeConstraint.c,
volumeConstraint.d,
}
);
});
}
auto ordering = smallestLastOrdering(graph);

@ -1,3 +1,2 @@
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

@ -6,12 +6,8 @@
#include "vulkan/image.hpp"
#include "vk_mem_alloc.h"
Buffer::Buffer(
VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsageFlags,
VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags allocationFlags, const std::string &name
)
: size(bufferSize), bufferUsageFlags(bufferUsageFlags), memoryUsage(memoryUsage),
allocationCreateFlags(allocationFlags) {
Buffer::Buffer(VkDeviceSize bufferSize, VkBufferUsageFlags bufferUsageFlags, VmaMemoryUsage memoryUsage, VmaAllocationCreateFlags allocationFlags)
: size(bufferSize), bufferUsageFlags(bufferUsageFlags), memoryUsage(memoryUsage), allocationCreateFlags(allocationFlags) {
VkBufferCreateInfo bufferCreateInfo {};
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@ -23,11 +19,7 @@ Buffer::Buffer(
allocationCreateInfo.usage = memoryUsage;
allocationCreateInfo.flags = allocationFlags;
vmaCreateBuffer(
Instance::GetAllocator(), &bufferCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo
);
setName(name);
vmaCreateBuffer(Instance::GetAllocator(), &bufferCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo);
}
Buffer::~Buffer() {
@ -104,8 +96,7 @@ void Buffer::setData(void *data, VkDeviceSize offset, VkDeviceSize dataSize, VkC
0,
0, nullptr,
1, &bufferMemoryBarrier,
0, nullptr
);
0, nullptr);
VkBufferCopy region {};
region.srcOffset = offset;
@ -115,9 +106,7 @@ void Buffer::setData(void *data, VkDeviceSize offset, VkDeviceSize dataSize, VkC
vkCmdCopyBuffer(commandBuffer, stagingBuffer->handle, handle, 1, &region);
if (singleShot)
Instance::instance->renderingCommandPool->endSingleTimeCommandBuffer(
commandBuffer, Instance::instance->graphicsAndPresentQueue
);
Instance::instance->renderingCommandPool->endSingleTimeCommandBuffer(commandBuffer, Instance::instance->graphicsAndPresentQueue);
}
}
@ -127,12 +116,10 @@ void Buffer::setName(const std::string &newName) {
}
unique_ptr<Buffer> Buffer::appended(void *data, VkDeviceSize appendSize, VkCommandBuffer commandBuffer) const {
auto buffer = make_unique<Buffer>(
size + appendSize,
auto buffer = make_unique<Buffer>(size + appendSize,
bufferUsageFlags,
memoryUsage,
allocationCreateFlags
);
allocationCreateFlags);
buffer->setName(name);
VkBufferCopy copyRegion {};
@ -147,12 +134,10 @@ unique_ptr<Buffer> Buffer::appended(void *data, VkDeviceSize appendSize, VkComma
}
unique_ptr<Buffer> Buffer::replaced(void *data, VkDeviceSize replaceSize, VkCommandBuffer commandBuffer) const {
auto buffer = make_unique<Buffer>(
replaceSize,
auto buffer = make_unique<Buffer>(replaceSize,
bufferUsageFlags,
memoryUsage,
allocationCreateFlags
);
allocationCreateFlags);
buffer->setName(name);
buffer->setData(data, 0, replaceSize, commandBuffer);
@ -168,8 +153,7 @@ shared_ptr<Buffer> Buffer::getStagingBuffer() {
size,
VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VMA_MEMORY_USAGE_AUTO,
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
);
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
stagingBufferOptional.value()->setName(name + " staging");

@ -22,21 +22,16 @@ DescriptorPool::DescriptorPool() {
std::map<DescriptorSet, std::vector<VkDescriptorSetLayoutBinding>> setBindings;
auto addBinding = [&setBindings](DescriptorSet set, VkDescriptorType type, VkShaderStageFlags stageFlags){
uint32_t binding = setBindings[set].size();
setBindings[set].push_back(
{
setBindings[set].push_back({
.binding = binding,
.descriptorType = type,
.descriptorCount = 1,
.stageFlags = stageFlags
}
);
});
};
// camera
addBinding(
DescriptorSet::WORLD, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT
);
addBinding(DescriptorSet::WORLD, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_COMPUTE_BIT);
// lights
addBinding(DescriptorSet::WORLD, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
// texture

@ -3,10 +3,8 @@
#include "vulkan/buffer.hpp"
#include "vulkan/command_pool.hpp"
Image::Image(
uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage
) : format(format), width(width), height(height) {
Image::Image(uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage) : format(format), width(width), height(height) {
VkImageCreateInfo imageCreateInfo {};
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
@ -27,20 +25,14 @@ Image::Image(
allocationCreateInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
allocationCreateInfo.flags = 0;
vmaCreateImage(
Instance::GetAllocator(), &imageCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo
);
vmaCreateImage(Instance::GetAllocator(), &imageCreateInfo, &allocationCreateInfo, &handle, &allocation, &allocationInfo);
}
Image::Image(
void *initialData, VkDeviceSize size, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage
) : Image(width, height, format, tiling, usage) {
Image::Image(void *initialData, VkDeviceSize size, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling,
VkImageUsageFlags usage) : Image(width, height, format, tiling, usage){
Buffer stagingBuffer(
size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT
);
Buffer stagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
stagingBuffer.setData(initialData, 0, size);
transitionLayout(VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
@ -130,8 +122,7 @@ void Image::transitionLayout(VkImageLayout oldLayout, VkImageLayout newLayout) {
sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
} else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL){
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
@ -139,14 +130,12 @@ void Image::transitionLayout(VkImageLayout oldLayout, VkImageLayout newLayout) {
destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
}
vkCmdPipelineBarrier(
commandBuffer,
vkCmdPipelineBarrier(commandBuffer,
sourceStage, destinationStage,
0,
0, nullptr,
0, nullptr,
1, &barrier
);
1, &barrier);
commandPool->endSingleTimeCommandBuffer(commandBuffer, Instance::instance->graphicsAndPresentQueue);
}

@ -71,26 +71,10 @@ void Instance::initWindow() {
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
int monitorCount;
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
for (int i = 1; i < monitorCount; i++) {
int w, h;
glfwGetMonitorPhysicalSize(monitors[i], &w, &h);
if (w > h) {
monitor = monitors[i];
break;
}
}
int x, y;
glfwGetMonitorPos(monitor, &x, &y);
window = glfwCreateWindow(800, 600, "Vulkan Simulation", nullptr, nullptr);
glfwSetWindowPos(window, x, y);
glfwSetFramebufferSizeCallback(
window, [](GLFWwindow *window, int width, int height) {
glfwSetFramebufferSizeCallback(window, [](GLFWwindow* window, int width, int height) {
instance->windowResized = true;
}
);
});
}
void Instance::createInstance() {
@ -195,7 +179,6 @@ void Instance::createLogicalDevice() {
}
#include <fstream>
void printVmaStats(){
char* stats;
vmaBuildStatsString(Instance::GetAllocator(), &stats, VK_TRUE);
@ -355,22 +338,3 @@ void Instance::initImGui(const Swapchain &swapchain) {
ImGui_ImplVulkan_Init(&initInfo);
}
std::set<uint32_t> Instance::QueueFamilyIndices::uniqueQueueFamilies() {
std::set<uint32_t> unique;
unique.insert(graphicsAndPresent.begin(), graphicsAndPresent.end());
unique.insert(computeAndTransfer.begin(), computeAndTransfer.end());
return unique;
}
uint32_t Instance::QueueFamilyIndices::tryComputeAndTransferDedicated() {
for (uint32_t family: computeAndTransfer)
if (std::find(graphicsAndPresent.begin(), graphicsAndPresent.end(), family) == graphicsAndPresent.end())
return family;
return computeAndTransfer[0];
}
bool Instance::QueueFamilyIndices::isEnough() {
return !graphicsAndPresent.empty() && !computeAndTransfer.empty();
}

@ -33,10 +33,8 @@ VkShaderModule Pipeline::createShaderModule(const std::vector<char> &code) {
return shaderModule;
}
Pipeline::Pipeline(
const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts,
const std::vector<VkPushConstantRange> &pushConstantRanges
) {
Pipeline::Pipeline(const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts,
const std::vector<VkPushConstantRange> &pushConstantRanges) {
VkPipelineLayoutCreateInfo pipelineLayoutInfo {};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = descriptorSetLayouts.size();
@ -53,12 +51,10 @@ Pipeline::~Pipeline() {
}
GraphicsPipeline::GraphicsPipeline(
const std::string &vertexShaderPath, const std::string &fragmentShaderPath,
GraphicsPipeline::GraphicsPipeline(const std::string& vertexShaderPath, const std::string& fragmentShaderPath,
VkRenderPass renderPass,
const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts,
const std::vector<VkPushConstantRange> &pushConstantRanges
) : Pipeline(descriptorSetLayouts, pushConstantRanges) {
const std::vector<VkPushConstantRange> &pushConstantRanges) : Pipeline(descriptorSetLayouts, pushConstantRanges) {
auto vertShaderCode = readFile(vertexShaderPath);
auto fragShaderCode = readFile(fragmentShaderPath);
@ -126,8 +122,7 @@ GraphicsPipeline::GraphicsPipeline(
multisample.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
VkPipelineColorBlendAttachmentState colorBlendAttachment {};
colorBlendAttachment.colorWriteMask =
VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
colorBlendAttachment.blendEnable = VK_FALSE;
VkPipelineColorBlendStateCreateInfo colorBlending {};
@ -171,11 +166,9 @@ GraphicsPipeline::GraphicsPipeline(
vkDestroyShaderModule(Instance::GetDevice(), fragShaderModule, nullptr);
}
ComputePipeline::ComputePipeline(
const std::string &shaderFile,
ComputePipeline::ComputePipeline(const std::string& shaderFile,
const std::vector<VkDescriptorSetLayout> &descriptorSetLayouts,
const std::vector<VkPushConstantRange> &pushConstantRanges
) : Pipeline(descriptorSetLayouts, pushConstantRanges) {
const std::vector<VkPushConstantRange> &pushConstantRanges) : Pipeline(descriptorSetLayouts, pushConstantRanges) {
VkShaderModule module = createShaderModule(readFile(shaderFile));
VkPipelineShaderStageCreateInfo stageInfo {};

@ -51,20 +51,15 @@ VkExtent2D Swapchain::chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilit
static_cast<uint32_t>(height)
};
actualExtent.width = std::clamp(
actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width
);
actualExtent.height = std::clamp(
actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height
);
actualExtent.width = std::clamp(actualExtent.width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
actualExtent.height = std::clamp(actualExtent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
return actualExtent;
}
}
void Swapchain::createSwapchain() {
SwapchainSupportDetails swapchainSupport = querySwapchainSupport(
Instance::GetPhysicalDevice(), Instance::GetSurface());
SwapchainSupportDetails swapchainSupport = querySwapchainSupport(Instance::GetPhysicalDevice(), Instance::GetSurface());
VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapchainSupport.formats);
VkPresentModeKHR presentMode = chooseSwapPresentMode(swapchainSupport.presentModes);
@ -183,11 +178,9 @@ void Swapchain::createRenderpass() {
VkSubpassDependency dependency {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask =
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.srcAccessMask = 0;
dependency.dstStageMask =
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
VkRenderPassCreateInfo renderPassInfo {};
@ -236,8 +229,7 @@ void Swapchain::createFramebuffers() {
VkSurfaceFormatKHR Swapchain::chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats) {
for (const auto& availableFormat : availableFormats){
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB &&
availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR){
return availableFormat;
}
}

@ -1,3 +1,2 @@
#define VMA_IMPLEMENTATION
#include "vk_mem_alloc.h"
Loading…
Cancel
Save