init commit

This commit is contained in:
2025-12-21 15:41:59 +01:00
commit c86af91a92
36 changed files with 2399 additions and 0 deletions

37
include/A2Task1.h Normal file
View File

@@ -0,0 +1,37 @@
#pragma once
#include "helper.h"
#include <iostream>
#include <cstdlib>
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
#include <vulkan/vulkan.hpp>
#include <fstream>
#include <vector>
#include "initialization.h"
#include "utils.h"
#include "task_common.h"
class A2Task1Solution {
public:
float mstime;
virtual void prepare(const std::vector<uint> &input) = 0;
virtual void compute() = 0;
virtual uint result() const = 0;
virtual void cleanup() = 0;
};
class A2Task1 {
public:
A2Task1(uint problemSize);
A2Task1(std::vector<uint> input);
bool evaluateSolution(A2Task1Solution& solution);
private:
void computeReference();
std::vector<uint> input;
uint reference;
};

40
include/A2Task2.h Normal file
View File

@@ -0,0 +1,40 @@
#pragma once
#include "helper.h"
#include <iostream>
#include <cstdlib>
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
#include <vulkan/vulkan.hpp>
#include <fstream>
#include <vector>
#include "initialization.h"
#include "utils.h"
#include "task_common.h"
class A2Task2Solution {
public:
float mstime;
virtual void prepare(const std::vector<uint> &input) = 0;
virtual void compute() = 0;
virtual std::vector<uint> result() const = 0;
virtual void cleanup() = 0;
};
class A2Task2 {
public:
A2Task2(uint problemSize);
A2Task2(std::vector<uint> input);
bool evaluateSolution(A2Task2Solution& solution);
size_t size() const {
return input.size();
}
private:
void computeReference();
std::vector<uint> input;
std::vector<uint> reference;
};

8
include/helper.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
#include <string>
#if defined(WORKING_DIR)
inline std::string workingDir = std::string(WORKING_DIR) + "/";
#else
inline std::string workingDir = std::string("./");
#endif

15
include/host_timer.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#include <chrono>
class HostTimer {
private:
using clock = std::chrono::high_resolution_clock;
clock::time_point start;
public:
HostTimer();
void reset();
double elapsed() const;
};

47
include/initialization.h Normal file
View File

@@ -0,0 +1,47 @@
#ifndef INITIALIZATION
#define INITIALIZATION
#include <vulkan/vulkan.hpp>
#include <cstring>
struct AppResources
{
vk::Instance instance;
vk::DebugUtilsMessengerEXT dbgUtilsMgr;
vk::PhysicalDevice pDevice;
vk::PhysicalDeviceProperties2 pDeviceProperties;
vk::PhysicalDeviceSubgroupProperties pDeviceSubgroupProperties;
vk::Device device;
vk::Queue computeQueue, transferQueue;
uint32_t cQ, tQ;
vk::CommandPool computeCommandPool, transferCommandPool;
vk::QueryPool queryPool;
void destroy();
};
VKAPI_ATTR VkBool32 VKAPI_CALL
debugUtilsMessengerCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
VkDebugUtilsMessengerCallbackDataEXT const *pCallbackData,
void * /*pUserData*/);
vk::DebugUtilsMessengerCreateInfoEXT makeDebugUtilsMessengerCreateInfoEXT();
void selectPhysicalDevice(vk::Instance &instance, vk::PhysicalDevice &pDevice);
void createInstance(vk::Instance &instance, vk::DebugUtilsMessengerEXT &debugUtilsMessenger,
std::string appName, std::string engineName);
void createLogicalDevice(vk::Instance &instance, vk::PhysicalDevice &pDevice, vk::Device &device);
std::tuple<uint32_t, uint32_t> getComputeAndTransferQueues(vk::PhysicalDevice &pDevice);
void createCommandPool(vk::Device &device, vk::CommandPool &commandPool, uint32_t queueIndex);
void destroyInstance(vk::Instance &instance, vk::DebugUtilsMessengerEXT &debugUtilsMessenger);
void destroyLogicalDevice(vk::Device &device);
void destroyCommandPool(vk::Device &device, vk::CommandPool &commandPool);
void createTimestampQueryPool(vk::Device &device, vk::QueryPool &queryPool, uint32_t queryCount);
void destroyQueryPool(vk::Device &device, vk::QueryPool &queryPool);
void printDeviceCapabilities(vk::PhysicalDevice &pDevice);
void initApp(AppResources &app);
#endif

7
include/renderdoc.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
namespace renderdoc {
void initialize();
void startCapture();
void endCapture();
}

47
include/task_common.h Normal file
View File

@@ -0,0 +1,47 @@
#include <iostream>
#include <cstdlib>
#define VULKAN_HPP_DISPATCH_LOADER_DYNAMIC 1
#include <vulkan/vulkan.hpp>
#include <fstream>
#include <vector>
#include "initialization.h"
#include "utils.h"
#ifndef EX_TEMPLATE
#define EX_TEMPLATE
namespace Cmn {
void createDescriptorSetLayout(vk::Device &device,
std::vector<vk::DescriptorSetLayoutBinding> &bindings, vk::DescriptorSetLayout &descLayout);
void addStorage(std::vector<vk::DescriptorSetLayoutBinding> &bindings, uint32_t binding);
void allocateDescriptorSet(vk::Device &device, vk::DescriptorSet &descSet, vk::DescriptorPool &descPool,
vk::DescriptorSetLayout &descLayout);
void bindBuffers(vk::Device &device, vk::Buffer &b, vk::DescriptorSet &set, uint32_t binding);
void createDescriptorPool(vk::Device &device,
std::vector<vk::DescriptorSetLayoutBinding> &bindings, vk::DescriptorPool &descPool, uint32_t numDescriptors = 1);
void createPipeline(vk::Device &device, vk::Pipeline &pipeline,
vk::PipelineLayout &pipLayout, vk::SpecializationInfo &specInfo, vk::ShaderModule &sModule);
void createShader(vk::Device &device, vk::ShaderModule &shaderModule, const std::string &filename);
}
struct TaskResources
{
//std::vector<Buffer> buffers; move this to user code
vk::ShaderModule cShader;
vk::DescriptorSetLayout descriptorSetLayout;
std::vector<vk::DescriptorSetLayoutBinding> bindings;
vk::DescriptorSet descriptorSet;
vk::DescriptorPool descriptorPool;
vk::Pipeline pipeline;
vk::PipelineLayout pipelineLayout;
void destroy(vk::Device &device);
};
#endif

113
include/utils.h Normal file
View File

@@ -0,0 +1,113 @@
#ifndef UTILS
#define UTILS
#include <vector>
#include <cstring>
#include <vulkan/vulkan.hpp>
#define CAST(a) static_cast<uint32_t>(a.size())
struct Buffer
{
vk::Buffer buf;
vk::DeviceMemory mem;
};
typedef uint32_t uint;
template<typename T, typename V>
T ceilDiv(T x, V y) {
return x / y + (x % y != 0);
}
std::vector<char> readFile(const std::string &filename);
std::string formatSize(uint64_t size);
uint32_t findMemoryType(uint32_t typeFilter, vk::MemoryPropertyFlags properties, vk::PhysicalDevice &pdevice);
void createBuffer(vk::PhysicalDevice &pDevice, vk::Device &device,
const vk::DeviceSize &size, vk::BufferUsageFlags usage,
vk::MemoryPropertyFlags properties, std::string name, vk::Buffer &buffer, vk::DeviceMemory &bufferMemory);
void createBuffer(vk::PhysicalDevice &pDevice, vk::Device &device,
const vk::DeviceSize &size, vk::BufferUsageFlags usage,
vk::MemoryPropertyFlags properties, std::string name, Buffer &buffer);
void destroyBuffer(vk::Device &device, Buffer &buffer);
void copyBuffer(vk::Device &device, vk::Queue &q, vk::CommandPool &commandPool,
const vk::Buffer &srcBuffer, vk::Buffer &dstBuffer, vk::DeviceSize byteSize);
vk::CommandBuffer beginSingleTimeCommands(vk::Device &device, vk::CommandPool &commandPool);
void endSingleTimeCommands(vk::Device &device, vk::Queue &q,
vk::CommandPool &commandPool, vk::CommandBuffer &commandBuffer);
Buffer addHostCoherentBuffer(vk::PhysicalDevice &pDevice, vk::Device &device, vk::DeviceSize size, std::string name);
Buffer addDeviceOnlyBuffer(vk::PhysicalDevice &pDevice, vk::Device &device, vk::DeviceSize size, std::string name);
template <typename T>
void fillDeviceBuffer(vk::Device &device, vk::DeviceMemory &mem, const std::vector<T> &input)
{
void *data = device.mapMemory(mem, 0, input.size() * sizeof(T), vk::MemoryMapFlags());
memcpy(data, input.data(), static_cast<size_t>(input.size() * sizeof(T)));
device.unmapMemory(mem);
}
template <typename T>
void fillHostBuffer(vk::Device &device, vk::DeviceMemory &mem, std::vector<T> &output)
{
// copy memory from mem to output
void *data = device.mapMemory(mem, 0, output.size() * sizeof(T), vk::MemoryMapFlags());
memcpy(output.data(), data, static_cast<size_t>(output.size() * sizeof(T)));
device.unmapMemory(mem);
}
template <typename T>
void fillDeviceWithStagingBuffer(vk::PhysicalDevice &pDevice, vk::Device &device,
vk::CommandPool &commandPool, vk::Queue &q,
Buffer &b, const std::vector<T> &data)
{
// Buffer b requires the eTransferSrc bit
// data (host) -> staging (device) -> Buffer b (device)
vk::Buffer staging;
vk::DeviceMemory mem;
vk::DeviceSize byteSize = data.size() * sizeof(T);
createBuffer(pDevice, device, byteSize, vk::BufferUsageFlagBits::eTransferSrc,
vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible, "staging",
staging, mem);
// V host -> staging V
fillDeviceBuffer<T>(device, mem, data);
// V staging -> buffer V
copyBuffer(device, q, commandPool, staging, b.buf, byteSize);
device.destroyBuffer(staging);
device.freeMemory(mem);
}
template <typename T>
void fillHostWithStagingBuffer(vk::PhysicalDevice &pDevice, vk::Device &device,
vk::CommandPool &commandPool, vk::Queue &q,
const Buffer &b, std::vector<T> &data)
{
// Buffer b requires the eTransferDst bit
// Buffer b (device) -> staging (device) -> data (host)
vk::Buffer staging;
vk::DeviceMemory mem;
vk::DeviceSize byteSize = data.size() * sizeof(T);
createBuffer(pDevice, device, byteSize, vk::BufferUsageFlagBits::eTransferDst,
vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eHostVisible, "staging",
staging, mem);
// V buffer -> staging V
copyBuffer(device, q, commandPool, b.buf, staging, byteSize);
// V staging -> host V
fillHostBuffer<T>(device, mem, data);
device.destroyBuffer(staging);
device.freeMemory(mem);
}
template <typename T>
void setObjectName(vk::Device &device, T handle, std::string name)
{
#ifndef NDEBUG
vk::DebugUtilsObjectNameInfoEXT infoEXT(handle.objectType, uint64_t(static_cast<typename T::CType>(handle)), name.c_str());
device.setDebugUtilsObjectNameEXT(infoEXT);
#endif
}
#endif