WIP Vulkan Refactoring and reflection driven vertex attribute binding
This commit is contained in:
@@ -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) {
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user