WIP Vulkan Refactoring and reflection driven vertex attribute binding

This commit is contained in:
2022-02-27 22:10:17 -08:00
parent d24df948c1
commit 3c948e2337
5 changed files with 111 additions and 18 deletions

View File

@@ -62,21 +62,29 @@ KRPipelineManager::~KRPipelineManager() {
#endif // ANDROID
}
void KRPipelineManager::createPipelines(KRSurface& surface)
KRPipeline* KRPipelineManager::getPipeline(KRSurface& surface, const std::string& shader_name, uint32_t vertexAttributes)
{
{
// vulkan_test
std::string pipeline_name = "vulkan_test";
std::vector<KRShader*> shaders;
shaders.push_back(m_pContext->getShaderManager()->get(pipeline_name + ".vert", "spv"));
shaders.push_back(m_pContext->getShaderManager()->get(pipeline_name + ".frag", "spv"));
KRPipeline* pipeline = new KRPipeline(*m_pContext, surface.m_deviceHandle, surface.m_swapChainImageFormat, surface.m_swapChainExtent.width, surface.m_swapChainExtent.height , pipeline_name.c_str(), shaders);
std::pair<std::string, std::vector<int> > key;
key.first = pipeline_name;
m_pipelines[key] = pipeline;
key.first = shader_name;
key.second.push_back(surface.m_deviceHandle);
key.second.push_back(surface.m_swapChainImageFormat);
key.second.push_back(surface.m_swapChainExtent.width);
key.second.push_back(surface.m_swapChainExtent.height);
key.second.push_back(vertexAttributes);
PipelineMap::iterator itr = m_pipelines.find(key);
if (itr != m_pipelines.end()) {
return itr->second;
}
}
std::vector<KRShader*> shaders;
shaders.push_back(m_pContext->getShaderManager()->get(shader_name + ".vert", "spv"));
shaders.push_back(m_pContext->getShaderManager()->get(shader_name + ".frag", "spv"));
KRPipeline* pipeline = new KRPipeline(*m_pContext, surface, shader_name.c_str(), shaders, vertexAttributes);
m_pipelines[key] = pipeline;
return pipeline;
}
KRPipeline *KRPipelineManager::getPipeline(const std::string &pipeline_name, KRCamera *pCamera, const std::vector<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&spot_lights, int bone_count, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, bool bReflectionMap, bool bReflectionCubeMap, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bReflectionMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bReflectionMapOffset, bool bAlphaTest, bool bAlphaBlend, KRNode::RenderPass renderPass, bool bRimColor) {

View File

@@ -139,11 +139,12 @@ void KRPresentationThread::renderFrame()
// TODO - this will break with more than one surface... Expect to refactor this out
VkCommandBuffer commandBuffer = device.m_graphicsCommandBuffers[imageIndex];
KRPipeline* testPipeline = m_pContext->getPipelineManager()->get("vulkan_test");
KRMeshManager::KRVBOData& testVertices = getContext().getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES;
bool haveMesh = testVertices.isVBOReady();
KRPipeline* testPipeline = m_pContext->getPipelineManager()->getPipeline(surface, "vulkan_test", testVertices.getVertexAttributes());
VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = 0;
@@ -158,7 +159,7 @@ void KRPresentationThread::renderFrame()
VkRenderPassBeginInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = testPipeline->getRenderPass();
renderPassInfo.renderPass = surface.getRenderPass();
renderPassInfo.framebuffer = surface.m_swapChainFramebuffers[frameIndex % surface.m_swapChainFramebuffers.size()];
renderPassInfo.renderArea.offset = { 0, 0 };
renderPassInfo.renderArea.extent = surface.m_swapChainExtent;

View File

@@ -47,6 +47,7 @@ KRSurface::KRSurface(KRContext& context)
, m_swapChainExtent({ 0, 0 })
, m_imageAvailableSemaphore(VK_NULL_HANDLE)
, m_renderFinishedSemaphore(VK_NULL_HANDLE)
, m_renderPass(VK_NULL_HANDLE)
{
}
@@ -91,6 +92,11 @@ void KRSurface::destroy()
std::unique_ptr<KRDevice>& device = m_pContext->getDeviceManager()->getDevice(m_deviceHandle);
if (m_renderPass) {
vkDestroyRenderPass(device->m_logicalDevice, m_renderPass, nullptr);
m_renderPass = VK_NULL_HANDLE;
}
if (device && m_renderFinishedSemaphore != VK_NULL_HANDLE) {
vkDestroySemaphore(device->m_logicalDevice, m_renderFinishedSemaphore, nullptr);
m_renderFinishedSemaphore = VK_NULL_HANDLE;
@@ -230,10 +236,8 @@ KrResult KRSurface::createSwapChain()
}
}
KRPipelineManager* pipelineManager = m_pContext->getPipelineManager();
pipelineManager->createPipelines(*this);
createRenderPasses();
KRPipeline* testPipeline = pipelineManager->get("vulkan_test");
m_swapChainFramebuffers.resize(m_swapChainImageViews.size());
for (size_t i = 0; i < m_swapChainImageViews.size(); i++) {
@@ -241,7 +245,7 @@ KrResult KRSurface::createSwapChain()
VkFramebufferCreateInfo framebufferInfo{};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
framebufferInfo.renderPass = testPipeline->getRenderPass();
framebufferInfo.renderPass = getRenderPass();
framebufferInfo.attachmentCount = 1;
framebufferInfo.pAttachments = attachments;
framebufferInfo.width = m_swapChainExtent.width;
@@ -291,3 +295,71 @@ KrResult KRSurface::recreateSwapChain()
return result;
}
void KRSurface::createRenderPasses()
{
if (m_renderPass) {
return;
}
VkAttachmentDescription colorAttachment{};
colorAttachment.format = m_swapChainImageFormat;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
VkAttachmentReference colorAttachmentRef{};
colorAttachmentRef.attachment = 0;
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass{};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef;
VkSubpassDependency dependency{};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = 0;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
VkRenderPassCreateInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = 1;
renderPassInfo.pAttachments = &colorAttachment;
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpass;
renderPassInfo.dependencyCount = 1;
renderPassInfo.pDependencies = &dependency;
std::unique_ptr<KRDevice>& device = m_pContext->getDeviceManager()->getDevice(m_deviceHandle);
if (vkCreateRenderPass(device->m_logicalDevice, &renderPassInfo, nullptr, &m_renderPass) != VK_SUCCESS) {
// failed! TODO - Error handling
}
}
VkRenderPass& KRSurface::getRenderPass()
{
return m_renderPass;
}
std::unique_ptr<KRDevice>& KRSurface::getDevice()
{
return m_pContext->getDeviceManager()->getDevice(m_deviceHandle);
}
uint32_t KRSurface::getWidth() const
{
return m_swapChainExtent.width;
}
uint32_t KRSurface::getHeight() const
{
return m_swapChainExtent.height;
}

View File

@@ -35,6 +35,8 @@
#ifndef KRSURFACE_H
#define KRSURFACE_H
class KRDevice;
class KRSurface : public KRContextObject
{
public:
@@ -45,12 +47,17 @@ public:
#endif
~KRSurface();
void destroy();
uint32_t getWidth() const;
uint32_t getHeight() const;
KRSurface(const KRSurface&) = delete;
KRSurface& operator=(const KRSurface&) = delete;
std::unique_ptr<KRDevice>& getDevice();
KrResult initialize();
KrResult recreateSwapChain();
void createRenderPasses();
VkRenderPass& getRenderPass();
#ifdef WIN32
HWND m_hWnd;
@@ -66,6 +73,8 @@ public:
VkSemaphore m_imageAvailableSemaphore;
VkSemaphore m_renderFinishedSemaphore;
// TODO - Move this to a higher context
VkRenderPass m_renderPass;
private:
void destroySwapChain();

View File

@@ -4,6 +4,9 @@
// See https://vulkan-tutorial.com/Drawing_a_triangle/Graphics_pipeline_basics/Shader_modules
layout(location = 0) out vec3 fragColor;
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_uv;
layout(constant_id = 0) const int QUALITY_LEVEL = 64; // Specialization constant test
vec2 positions[3] = vec2[](
vec2(0.0, -0.5),