Added initial base for iteration with command buffer and experimetation with baseoperator

This commit is contained in:
Alejandro Saucedo 2020-08-16 18:09:56 +01:00
parent 0a1bfe0de8
commit 441efcd8dd
9 changed files with 294 additions and 17 deletions

33
src/BaseOperator.cpp Normal file
View file

@ -0,0 +1,33 @@
#include <spdlog/spdlog.h>
#include "BaseOperator.hpp"
namespace kp {
BaseOperator::BaseOperator() {
}
BaseOperator::BaseOperator(vk::CommandBuffer* commandBuffer) {
SPDLOG_DEBUG("Compute BaseOperator constructor started");
this->mCommandBuffer = commandBuffer;
}
BaseOperator::~BaseOperator() {
SPDLOG_DEBUG("Compute BaseOperator destructor started");
}
void BaseOperator::init(std::string one, std::string two) {
SPDLOG_DEBUG("Compute BaseOperator init started");
}
void BaseOperator::record() {
SPDLOG_DEBUG("Compute BaseOperator record started");
}
}

View file

@ -1,15 +1,30 @@
#pragma once
#include <string>
#include <vulkan/vulkan.h>
#include <vulkan/vulkan.hpp>
namespace kp {
class BaseOperator
{
private:
public:
BaseOperator();
BaseOperator(vk::CommandBuffer* commandBuffer);
virtual ~BaseOperator();
void init(std::string one, std::string two);
void record();
private:
vk::Device* mDevice;
vk::CommandBuffer* mCommandBuffer;
};
} // End namespace kp

View file

@ -34,13 +34,14 @@ debugMessageCallback(VkDebugReportFlagsEXT flags,
Manager::Manager()
{
this->mPhysicalDeviceIndex = 0;
this->createInstance();
this->createDevice();
}
Manager::~Manager()
{
SPDLOG_DEBUG("Destroying Kompute Manager");
SPDLOG_DEBUG("Kompute Manager Destructor started");
if (this->mDevice == nullptr) {
spdlog::error("Kompute Manager destructor reached with null Device pointer");
@ -48,7 +49,9 @@ Manager::~Manager()
}
if (this->mFreeDevice) {
spdlog::info("Destroying device");
this->mDevice->destroy();
SPDLOG_DEBUG("Kompute Manager Destroyed Device");
}
if (this->mInstance == nullptr) {
@ -56,13 +59,24 @@ Manager::~Manager()
return;
}
#if DEBUG
if (this->mDebugReportCallback) {
this->mInstance->destroyDebugReportCallbackEXT(
this->mDebugReportCallback, nullptr, this->mDebugDispatcher);
SPDLOG_DEBUG("Kompute Manager Destroyed Debug Report Callback");
}
#endif
if (this->mFreeInstance) {
this->mInstance->destroy();
SPDLOG_DEBUG("Kompute Manager Destroyed Instance");
}
}
void Manager::createInstance() {
SPDLOG_DEBUG("Kompute Manager creating instance");
this->mFreeInstance = true;
vk::ApplicationInfo applicationInfo;
@ -83,6 +97,7 @@ void Manager::createInstance() {
}
#if DEBUG
SPDLOG_DEBUG("Kompute Manager adding debug validation layers");
// We'll identify the layers that are supported
std::vector<const char*> validLayerNames;
std::vector<const char*> desiredLayerNames = {
@ -114,9 +129,12 @@ void Manager::createInstance() {
}
#endif
vk::createInstance(&computeInstanceCreateInfo, nullptr, this->mInstance);
vk::Instance instance = vk::createInstance(computeInstanceCreateInfo);
this->mInstance = &instance;
SPDLOG_DEBUG("Kompute Manager Instance Created");
#if DEBUG
SPDLOG_DEBUG("Kompute Manager adding debug callbacks");
if (validLayerNames.size() > 0) {
vk::DebugReportFlagsEXT debugFlags =
vk::DebugReportFlagBitsEXT::eError |
@ -137,8 +155,13 @@ void Manager::createInstance() {
void Manager::createDevice() {
SPDLOG_DEBUG("Kompute Manager creating Device");
if (this->mInstance == nullptr) {
throw std::runtime_error("Manager instance is null");
throw std::runtime_error("Kompute Manager instance is null");
}
if (this->mPhysicalDeviceIndex < 0) {
throw std::runtime_error("Kompute Manager physical device index not provided");
}
this->mFreeDevice = true;
@ -146,12 +169,12 @@ void Manager::createDevice() {
std::vector<vk::PhysicalDevice> physicalDevices =
this->mInstance->enumeratePhysicalDevices();
vk::PhysicalDevice physicalDevice = physicalDevices[0];
vk::PhysicalDevice physicalDevice = physicalDevices[this->mPhysicalDeviceIndex];
vk::PhysicalDeviceProperties physicalDeviceProperties =
physicalDevice.getProperties();
spdlog::info("Using device {}", physicalDeviceProperties.deviceName);
spdlog::info("Using physical device index {} found {}", this->mPhysicalDeviceIndex, physicalDeviceProperties.deviceName);
// Find compute queue
std::vector<vk::QueueFamilyProperties> allQueueFamilyProperties =
@ -186,9 +209,13 @@ void Manager::createDevice() {
1, // Number of deviceQueueCreateInfo
&deviceQueueCreateInfo);
physicalDevice.createDevice(&deviceCreateInfo, nullptr, this->mDevice);
vk::Device device = physicalDevice.createDevice(deviceCreateInfo);
this->mDevice = &device;
SPDLOG_DEBUG("Kompute Manager device created");
this->mDevice->getQueue(this->mComputeQueueFamilyIndex, 0, this->mComputeQueue);
vk::Queue computeQueue = this->mDevice->getQueue(this->mComputeQueueFamilyIndex, 0);
this->mComputeQueue = &computeQueue;
SPDLOG_DEBUG("Kompute Manager compute queue obtained");
}
}

View file

@ -3,6 +3,10 @@
#include <vulkan/vulkan.h>
#include <vulkan/vulkan.hpp>
#include <spdlog/spdlog.h>
#include "Sequence.hpp"
namespace kp {
class Manager
@ -12,13 +16,24 @@ private:
public:
Manager();
virtual ~Manager();
~Manager();
// Evaluate actions
template <typename T, typename... TArgs>
void eval(TArgs&&... args) {
SPDLOG_DEBUG("Kompute Manager eval triggered");
Sequence sq(this->mDevice, this->mComputeQueue, this->mComputeQueueFamilyIndex);
sq.begin();
sq.record<T>(std::forward<TArgs>(args)...);
sq.end();
sq.eval();
}
// Templated Commands
private:
vk::Instance* mInstance = nullptr;
bool mFreeInstance = false;
uint32_t mPhysicalDeviceIndex = -1;
vk::Device* mDevice = nullptr;
bool mFreeDevice = false;
uint32_t mComputeQueueFamilyIndex = -1;
@ -32,7 +47,6 @@ private:
// Create functions
void createInstance();
void createDevice();
};
} // End namespace kp

135
src/Sequence.cpp Normal file
View file

@ -0,0 +1,135 @@
#include <string>
#include "spdlog/spdlog.h"
#include "Sequence.hpp"
namespace kp {
Sequence::Sequence()
{
// TODO: Create device, queue, etc
}
Sequence::Sequence(vk::Device* device, vk::Queue* computeQueue, uint32_t queueIndex)
{
SPDLOG_DEBUG("Kompute Sequence Created with existing device & queue");
this->mDevice = device;
this->mComputeQueue = computeQueue;
this->mQueueIndex = queueIndex;
}
Sequence::~Sequence() {
SPDLOG_DEBUG("Kompute Sequence Destructor started");
if (this->mDevice == nullptr) {
spdlog::error("Kompute Sequence destructor reached with null Device pointer");
return;
}
if (this->mCommandBuffer == nullptr) {
spdlog::error("Kompute Sequence destructor reached with null CommandPool pointer");
return;
}
if (this->mFreeCommandBuffer) {
spdlog::info("Freeing CommandBuffer");
this->mDevice->freeCommandBuffers(*this->mCommandPool, 1, this->mCommandBuffer);
SPDLOG_DEBUG("Kompute Manager Freed CommandBuffer");
}
if (this->mCommandPool == nullptr) {
spdlog::error("Kompute Sequence destructor reached with null CommandPool pointer");
return;
}
if (this->mFreeCommandPool) {
spdlog::info("Destroying CommandPool");
this->mDevice->destroy(*this->mCommandPool);
SPDLOG_DEBUG("Kompute Manager Destroyed CommandPool");
}
}
void Sequence::begin() {
if (this->mCommandPool == nullptr) {
throw std::runtime_error("Kompute Sequence command pool is null");
}
if (!this->mRecording) {
spdlog::info("Kompute Sequence starting command recording");
this->mCommandBuffer->begin(vk::CommandBufferBeginInfo());
this->mRecording = true;
}
else {
spdlog::warn("Kompute Sequence attempted to start command recording but recording already started");
}
}
void Sequence::end() {
if (this->mCommandPool == nullptr) {
throw std::runtime_error("Kompute Sequence command pool is null");
}
if (this->mRecording) {
spdlog::info("Kompute Sequence ending command recording");
this->mCommandBuffer->end();
this->mRecording = false;
}
else {
spdlog::warn("Kompute Sequence attempted to end command recording but recording not started");
}
}
void Sequence::eval() {
bool toggleSingleRecording = !this->mRecording;
if (toggleSingleRecording) {
this->begin();
}
const vk::PipelineStageFlags waitStageMask = vk::PipelineStageFlagBits::eTransfer;
vk::SubmitInfo submitInfo(0, nullptr, &waitStageMask, 1, this->mCommandBuffer);
vk::Fence fence = this->mDevice->createFence(vk::FenceCreateInfo());
this->mComputeQueue->submit(1, &submitInfo, fence);
this->mDevice->waitForFences(1, &fence, VK_TRUE, UINT64_MAX);
this->mDevice->destroy(fence);
if (toggleSingleRecording) {
this->end();
}
}
void Sequence::createCommandPool() {
SPDLOG_DEBUG("Kompute Sequence creating command pool");
if (this->mQueueIndex < 0) {
throw std::runtime_error("Kompute Sequence queue index not provided");
}
this->mFreeCommandPool = true;
vk::CommandPoolCreateInfo commandPoolInfo(vk::CommandPoolCreateFlags(), this->mQueueIndex);
vk::CommandPool commandPool = this->mDevice->createCommandPool(commandPoolInfo);
this->mCommandPool = &commandPool;
}
void Sequence::createCommandBuffer() {
SPDLOG_DEBUG("Kompute Sequence creating command buffer");
if (this->mDevice == nullptr) {
throw std::runtime_error("Kompute Sequence device is null");
}
if (this->mCommandPool == nullptr) {
throw std::runtime_error("Kompute Sequence command pool is null");
}
this->mFreeCommandBuffer = true;
vk::CommandBufferAllocateInfo commandBufferAllocateInfo(*this->mCommandPool, vk::CommandBufferLevel::ePrimary, 1);
vk::CommandBuffer commandBuffer;
this->mDevice->allocateCommandBuffers(&commandBufferAllocateInfo, &commandBuffer);
this->mCommandBuffer = &commandBuffer;
}
}

View file

@ -1,15 +1,48 @@
#pragma once
#include <vulkan/vulkan.h>
#include <vulkan/vulkan.hpp>
namespace kp {
class Sequence
{
private:
public:
Sequence();
virtual ~Sequence();
Sequence(vk::Device* device, vk::Queue* computeQueue, uint32_t queueIndex);
~Sequence();
// Record command functions
void begin();
void end();
void eval();
template <typename T, typename...TArgs>
void record(TArgs&&... args) {
T op(this->mCommandBuffer);
op.init(std::forward<TArgs>(args)...);
op.record();
}
private:
vk::Device* mDevice = nullptr;
vk::Queue* mComputeQueue = nullptr;
uint32_t mQueueIndex = -1;
vk::CommandPool* mCommandPool = nullptr;
bool mFreeCommandPool = false;
vk::CommandBuffer* mCommandBuffer = nullptr;
bool mFreeCommandBuffer = false;
// Record state
bool mRecording = false;
// Create functions
void createCommandPool();
void createCommandBuffer();
};
} // End namespace kp

View file

@ -20,6 +20,9 @@
#include <vulkan/vulkan.h>
#include <vulkan/vulkan.hpp>
#include "Manager.hpp"
#include "BaseOperator.hpp"
#define BUFFER_ELEMENTS 32
#if DEBUG
@ -609,9 +612,16 @@ main()
#endif
try {
VulkanCompute* vulkanExample = new VulkanCompute();
std::cout << "Finished.";
delete (vulkanExample);
//VulkanCompute* vulkanExample = new VulkanCompute();
//spdlog::info("Finished.");
//delete (vulkanExample);
// Run Kompute
spdlog::info("Creating manager");
kp::Manager mgr;
spdlog::info("Calling manager eval");
mgr.eval<kp::BaseOperator>("one", "two");
spdlog::info("Called manager eval success");
return 0;
} catch (const std::exception& exc) {
spdlog::error(exc.what());