Triangle in render texture
This commit is contained in:
164
Nuake/src/Rendering/Vulkan/PipelineBuilder.cpp
Normal file
164
Nuake/src/Rendering/Vulkan/PipelineBuilder.cpp
Normal file
@@ -0,0 +1,164 @@
|
||||
#include "PipelineBuilder.h"
|
||||
|
||||
#include "src/Core/Logger.h"
|
||||
|
||||
#include "src/Rendering/Vulkan/VulkanInit.h"
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
void PipelineBuilder::Clear()
|
||||
{
|
||||
InputAssembly = { .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
|
||||
|
||||
Rasterizer = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
|
||||
|
||||
ColorBlendAttachment = {};
|
||||
|
||||
Multisampling = { .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO };
|
||||
|
||||
PipelineLayout = {};
|
||||
|
||||
DepthStencil = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO };
|
||||
|
||||
RenderInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO };
|
||||
|
||||
ShaderStages.clear();
|
||||
}
|
||||
|
||||
VkPipeline PipelineBuilder::BuildPipeline(VkDevice device)
|
||||
{
|
||||
// make viewport state from our stored viewport and scissor.
|
||||
// at the moment we wont support multiple viewports or scissors
|
||||
VkPipelineViewportStateCreateInfo viewportState = {};
|
||||
viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
|
||||
viewportState.pNext = nullptr;
|
||||
|
||||
viewportState.viewportCount = 1;
|
||||
viewportState.scissorCount = 1;
|
||||
|
||||
// setup dummy color blending. We arent using transparent objects yet
|
||||
// the blending is just "no blend", but we do write to the color attachment
|
||||
VkPipelineColorBlendStateCreateInfo colorBlending = {};
|
||||
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||
colorBlending.pNext = nullptr;
|
||||
|
||||
colorBlending.logicOpEnable = VK_FALSE;
|
||||
colorBlending.logicOp = VK_LOGIC_OP_COPY;
|
||||
colorBlending.attachmentCount = 1;
|
||||
colorBlending.pAttachments = &ColorBlendAttachment;
|
||||
|
||||
// completely clear VertexInputStateCreateInfo, as we have no need for it
|
||||
VkPipelineVertexInputStateCreateInfo _vertexInputInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO };
|
||||
|
||||
// build the actual pipeline
|
||||
// we now use all of the info structs we have been writing into into this one
|
||||
// to create the pipeline
|
||||
VkGraphicsPipelineCreateInfo pipelineInfo = { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO };
|
||||
// connect the renderInfo to the pNext extension mechanism
|
||||
pipelineInfo.pNext = &RenderInfo;
|
||||
|
||||
pipelineInfo.stageCount = (uint32_t)ShaderStages.size();
|
||||
pipelineInfo.pStages = ShaderStages.data();
|
||||
pipelineInfo.pVertexInputState = &_vertexInputInfo;
|
||||
pipelineInfo.pInputAssemblyState = &InputAssembly;
|
||||
pipelineInfo.pViewportState = &viewportState;
|
||||
pipelineInfo.pRasterizationState = &Rasterizer;
|
||||
pipelineInfo.pMultisampleState = &Multisampling;
|
||||
pipelineInfo.pColorBlendState = &colorBlending;
|
||||
pipelineInfo.pDepthStencilState = &DepthStencil;
|
||||
pipelineInfo.layout = PipelineLayout;
|
||||
|
||||
VkDynamicState state[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
|
||||
|
||||
VkPipelineDynamicStateCreateInfo dynamicInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
|
||||
dynamicInfo.pDynamicStates = &state[0];
|
||||
dynamicInfo.dynamicStateCount = 2;
|
||||
|
||||
pipelineInfo.pDynamicState = &dynamicInfo;
|
||||
|
||||
// its easy to error out on create graphics pipeline, so we handle it a bit
|
||||
// better than the common VK_CHECK case
|
||||
VkPipeline newPipeline;
|
||||
if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &newPipeline) != VK_SUCCESS)
|
||||
{
|
||||
Logger::Log("Failed to create graphics pipeline", "vulkan", CRITICAL);
|
||||
return VK_NULL_HANDLE; // failed to create graphics pipeline
|
||||
}
|
||||
|
||||
return newPipeline;
|
||||
}
|
||||
|
||||
void PipelineBuilder::SetShaders(VkShaderModule vert, VkShaderModule frag)
|
||||
{
|
||||
ShaderStages.clear();
|
||||
|
||||
ShaderStages.push_back(VulkanInit::PipelineShaderStageCreateInfo(VK_SHADER_STAGE_VERTEX_BIT, vert));
|
||||
|
||||
ShaderStages.push_back(VulkanInit::PipelineShaderStageCreateInfo(VK_SHADER_STAGE_FRAGMENT_BIT, frag));
|
||||
}
|
||||
|
||||
void PipelineBuilder::SetInputTopology(VkPrimitiveTopology topology)
|
||||
{
|
||||
InputAssembly.topology = topology;
|
||||
// we are not going to use primitive restart on the entire tutorial so leave
|
||||
// it on false
|
||||
InputAssembly.primitiveRestartEnable = VK_FALSE;
|
||||
}
|
||||
|
||||
void PipelineBuilder::SetPolygonMode(VkPolygonMode polygonMode)
|
||||
{
|
||||
Rasterizer.polygonMode = polygonMode;
|
||||
Rasterizer.lineWidth = 1.f;
|
||||
}
|
||||
|
||||
void PipelineBuilder::SetCullMode(VkCullModeFlags cullMode, VkFrontFace frontFace)
|
||||
{
|
||||
Rasterizer.cullMode = cullMode;
|
||||
Rasterizer.frontFace = frontFace;
|
||||
}
|
||||
|
||||
void PipelineBuilder::SetMultiSamplingNone()
|
||||
{
|
||||
Multisampling.sampleShadingEnable = VK_FALSE;
|
||||
// multisampling defaulted to no multisampling (1 sample per pixel)
|
||||
Multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
Multisampling.minSampleShading = 1.0f;
|
||||
Multisampling.pSampleMask = nullptr;
|
||||
// no alpha to coverage either
|
||||
Multisampling.alphaToCoverageEnable = VK_FALSE;
|
||||
Multisampling.alphaToOneEnable = VK_FALSE;
|
||||
}
|
||||
|
||||
void PipelineBuilder::DisableBlending()
|
||||
{
|
||||
// default write mask
|
||||
ColorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
// no blending
|
||||
ColorBlendAttachment.blendEnable = VK_FALSE;
|
||||
}
|
||||
|
||||
void PipelineBuilder::SetColorAttachment(VkFormat format)
|
||||
{
|
||||
ColorAttachmentformat = format;
|
||||
// connect the format to the renderInfo structure
|
||||
RenderInfo.colorAttachmentCount = 1;
|
||||
RenderInfo.pColorAttachmentFormats = &ColorAttachmentformat;
|
||||
}
|
||||
|
||||
void PipelineBuilder::SetDepthFormat(VkFormat depthFormat)
|
||||
{
|
||||
RenderInfo.depthAttachmentFormat = depthFormat;
|
||||
}
|
||||
|
||||
void PipelineBuilder::DisableDepthTest()
|
||||
{
|
||||
DepthStencil.depthTestEnable = VK_FALSE;
|
||||
DepthStencil.depthWriteEnable = VK_FALSE;
|
||||
DepthStencil.depthCompareOp = VK_COMPARE_OP_NEVER;
|
||||
DepthStencil.depthBoundsTestEnable = VK_FALSE;
|
||||
DepthStencil.stencilTestEnable = VK_FALSE;
|
||||
DepthStencil.front = {};
|
||||
DepthStencil.back = {};
|
||||
DepthStencil.minDepthBounds = 0.f;
|
||||
DepthStencil.maxDepthBounds = 1.f;
|
||||
}
|
||||
40
Nuake/src/Rendering/Vulkan/PipelineBuilder.h
Normal file
40
Nuake/src/Rendering/Vulkan/PipelineBuilder.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
#include <volk/volk.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class PipelineBuilder
|
||||
{
|
||||
public:
|
||||
std::vector<VkPipelineShaderStageCreateInfo> ShaderStages;
|
||||
|
||||
VkPipelineInputAssemblyStateCreateInfo InputAssembly;
|
||||
VkPipelineRasterizationStateCreateInfo Rasterizer;
|
||||
VkPipelineColorBlendAttachmentState ColorBlendAttachment;
|
||||
VkPipelineMultisampleStateCreateInfo Multisampling;
|
||||
VkPipelineLayout PipelineLayout;
|
||||
VkPipelineDepthStencilStateCreateInfo DepthStencil;
|
||||
VkPipelineRenderingCreateInfo RenderInfo;
|
||||
VkFormat ColorAttachmentformat;
|
||||
|
||||
|
||||
PipelineBuilder() { Clear(); }
|
||||
~PipelineBuilder() = default;
|
||||
|
||||
void Clear();
|
||||
|
||||
VkPipeline BuildPipeline(VkDevice device);
|
||||
void SetShaders(VkShaderModule vert, VkShaderModule frag);
|
||||
|
||||
void SetInputTopology(VkPrimitiveTopology topology);
|
||||
void SetPolygonMode(VkPolygonMode polygonMode);
|
||||
void SetCullMode(VkCullModeFlags cullMode, VkFrontFace frontFace);
|
||||
void SetMultiSamplingNone();
|
||||
void DisableBlending();
|
||||
void SetColorAttachment(VkFormat format);
|
||||
void SetDepthFormat(VkFormat depthFormat);
|
||||
void DisableDepthTest();
|
||||
};
|
||||
}
|
||||
33
Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.cpp
Normal file
33
Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "VulkanAllocatedBuffer.h"
|
||||
|
||||
#include "VulkanAllocator.h"
|
||||
#include "VulkanCheck.h"
|
||||
#include "VulkanRenderer.h"
|
||||
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
#include "vk_mem_alloc.h"
|
||||
|
||||
AllocatedBuffer::AllocatedBuffer(size_t inSize, VkBufferUsageFlags inFlags, VmaMemoryUsage inUsage)
|
||||
{
|
||||
// allocate buffer
|
||||
VkBufferCreateInfo bufferInfo = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
|
||||
bufferInfo.pNext = nullptr;
|
||||
bufferInfo.size = inSize;
|
||||
|
||||
bufferInfo.usage = inFlags;
|
||||
|
||||
VmaAllocationCreateInfo vmaallocInfo = {};
|
||||
vmaallocInfo.usage = inUsage;
|
||||
vmaallocInfo.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||
|
||||
// allocate the buffer
|
||||
VK_CALL(vmaCreateBuffer(VulkanAllocator::Get().GetAllocator(), &bufferInfo, &vmaallocInfo, &Buffer, &Allocation,
|
||||
&Info));
|
||||
}
|
||||
|
||||
AllocatedBuffer::~AllocatedBuffer()
|
||||
{
|
||||
// TODO: deletion of buffer
|
||||
}
|
||||
36
Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.h
Normal file
36
Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "src/Core/Maths.h"
|
||||
|
||||
#include <volk/volk.h>
|
||||
#include <vk_mem_alloc.h>
|
||||
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
class AllocatedBuffer
|
||||
{
|
||||
private:
|
||||
VkBuffer Buffer;
|
||||
VmaAllocation Allocation;
|
||||
VmaAllocationInfo Info;
|
||||
|
||||
public:
|
||||
AllocatedBuffer(size_t size, VkBufferUsageFlags flags, VmaMemoryUsage usage);
|
||||
~AllocatedBuffer();
|
||||
};
|
||||
|
||||
struct GPUMeshBuffers
|
||||
{
|
||||
AllocatedBuffer indexBuffer;
|
||||
AllocatedBuffer vertexBuffer;
|
||||
VkDeviceAddress vertexBufferAddress;
|
||||
};
|
||||
|
||||
// push constants for our mesh object draws
|
||||
struct GPUDrawPushConstants
|
||||
{
|
||||
glm::mat4 worldMatrix;
|
||||
VkDeviceAddress vertexBuffer;
|
||||
};
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
#include "vk_mem_alloc.h"
|
||||
|
||||
VulkanImage::VulkanImage(ImageFormat inFormat, Vector2 inSize) :
|
||||
Format(inFormat),
|
||||
@@ -48,6 +49,11 @@ VulkanImage::VulkanImage(void* inData, ImageFormat inFormat, Vector2 inSize)
|
||||
|
||||
}
|
||||
|
||||
VulkanImage::~VulkanImage()
|
||||
{
|
||||
// TODO: deletion of image
|
||||
}
|
||||
|
||||
VkDescriptorSet& VulkanImage::GetImGuiDescriptorSet()
|
||||
{
|
||||
if (!ImGuiDescriptorSetGenerated)
|
||||
|
||||
@@ -42,11 +42,12 @@ namespace Nuake
|
||||
public:
|
||||
VulkanImage(ImageFormat format, Vector2 size);
|
||||
VulkanImage(void* data, ImageFormat format, Vector2 size);
|
||||
~VulkanImage() = default;
|
||||
~VulkanImage();
|
||||
|
||||
Vector2 GetSize() const { return Vector2(Extent.x, Extent.y); }
|
||||
VkImageView& GetImageView() { return ImageView; }
|
||||
VkImage& GetImage() { return Image; }
|
||||
VkDescriptorSet& GetImGuiDescriptorSet();
|
||||
ImageFormat GetFormat() const { return Format; }
|
||||
};
|
||||
}
|
||||
@@ -90,7 +90,7 @@ VkCommandBufferSubmitInfo VulkanInit::CommandBufferSubmitInfo(VkCommandBuffer cm
|
||||
return info;
|
||||
}
|
||||
|
||||
VkSubmitInfo2 VulkanInit::SubmitInfo(VkCommandBufferSubmitInfo * cmd, VkSemaphoreSubmitInfo * signalSemaphoreInfo, VkSemaphoreSubmitInfo * waitSemaphoreInfo)
|
||||
VkSubmitInfo2 VulkanInit::SubmitInfo(VkCommandBufferSubmitInfo* cmd, VkSemaphoreSubmitInfo * signalSemaphoreInfo, VkSemaphoreSubmitInfo * waitSemaphoreInfo)
|
||||
{
|
||||
VkSubmitInfo2 info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2;
|
||||
@@ -102,7 +102,7 @@ VkSubmitInfo2 VulkanInit::SubmitInfo(VkCommandBufferSubmitInfo * cmd, VkSemaphor
|
||||
info.signalSemaphoreInfoCount = signalSemaphoreInfo == nullptr ? 0 : 1;
|
||||
info.pSignalSemaphoreInfos = signalSemaphoreInfo;
|
||||
|
||||
info.commandBufferInfoCount = 1;
|
||||
info.commandBufferInfoCount = cmd == nullptr ? 0 : 1;
|
||||
info.pCommandBufferInfos = cmd;
|
||||
|
||||
return info;
|
||||
@@ -186,6 +186,34 @@ VkRenderingInfo VulkanInit::RenderingInfo(VkExtent2D renderExtent, VkRenderingAt
|
||||
return renderInfo;
|
||||
}
|
||||
|
||||
VkPipelineLayoutCreateInfo VulkanInit::PipelineLayoutCreateInfo()
|
||||
{
|
||||
VkPipelineLayoutCreateInfo info{};
|
||||
info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
|
||||
info.pNext = nullptr;
|
||||
|
||||
// empty defaults
|
||||
info.flags = 0;
|
||||
info.setLayoutCount = 0;
|
||||
info.pSetLayouts = nullptr;
|
||||
info.pushConstantRangeCount = 0;
|
||||
info.pPushConstantRanges = nullptr;
|
||||
return info;
|
||||
}
|
||||
|
||||
VkPipelineShaderStageCreateInfo VulkanInit::PipelineShaderStageCreateInfo(VkShaderStageFlagBits flags, VkShaderModule shader)
|
||||
{
|
||||
VkPipelineShaderStageCreateInfo info{};
|
||||
info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
info.pNext = nullptr;
|
||||
|
||||
// shader stage
|
||||
info.stage = flags;
|
||||
info.module = shader;
|
||||
info.pName = "main";
|
||||
return info;
|
||||
}
|
||||
|
||||
// This is a helper to transtion images between readable, writable layouts.
|
||||
void VulkanUtil::TransitionImage(VkCommandBuffer cmd, VkImage image, VkImageLayout currentLayout, VkImageLayout newLayout)
|
||||
{
|
||||
|
||||
@@ -26,6 +26,9 @@ namespace Nuake
|
||||
|
||||
static VkRenderingAttachmentInfo AttachmentInfo(VkImageView view, VkClearValue* clear, VkImageLayout layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
static VkRenderingInfo RenderingInfo(VkExtent2D renderExtent, VkRenderingAttachmentInfo * colorAttachment, VkRenderingAttachmentInfo * depthAttachment);
|
||||
|
||||
static VkPipelineLayoutCreateInfo PipelineLayoutCreateInfo();
|
||||
static VkPipelineShaderStageCreateInfo PipelineShaderStageCreateInfo(VkShaderStageFlagBits flags, VkShaderModule shader);
|
||||
};
|
||||
|
||||
class VulkanUtil
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "VulkanAllocator.h"
|
||||
|
||||
#include "VulkanCheck.h"
|
||||
#include "PipelineBuilder.h"
|
||||
|
||||
using namespace Nuake;
|
||||
|
||||
@@ -70,9 +71,13 @@ void VkRenderer::Initialize()
|
||||
|
||||
InitDescriptors();
|
||||
|
||||
BackgroundShader = ShaderCompiler::Get().CompileShader("../Resources/Shaders/Vulkan/background.comp");
|
||||
ShaderCompiler& shaderCompiler = ShaderCompiler::Get();
|
||||
TriangleVertShader = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/triangle.vert");
|
||||
BackgroundShader = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/background.comp");
|
||||
TriangleFragShader = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/triangle.frag");
|
||||
|
||||
InitPipeline();
|
||||
InitTrianglePipeline();
|
||||
|
||||
InitImgui();
|
||||
|
||||
@@ -306,7 +311,6 @@ void VkRenderer::UpdateDescriptorSets()
|
||||
drawImageWrite.pImageInfo = &imgInfo;
|
||||
|
||||
vkUpdateDescriptorSets(Device, 1, &drawImageWrite, 0, nullptr);
|
||||
|
||||
}
|
||||
|
||||
void VkRenderer::InitPipeline()
|
||||
@@ -345,6 +349,82 @@ void VkRenderer::InitBackgroundPipeline()
|
||||
});
|
||||
}
|
||||
|
||||
void VkRenderer::InitTrianglePipeline()
|
||||
{
|
||||
VkPipelineLayoutCreateInfo pipeline_layout_info = VulkanInit::PipelineLayoutCreateInfo();
|
||||
VK_CALL(vkCreatePipelineLayout(Device, &pipeline_layout_info, nullptr, &TrianglePipelineLayout));
|
||||
|
||||
PipelineBuilder pipelineBuilder;
|
||||
|
||||
//use the triangle layout we created
|
||||
pipelineBuilder.PipelineLayout = TrianglePipelineLayout;
|
||||
//connecting the vertex and pixel shaders to the pipeline
|
||||
pipelineBuilder.SetShaders(TriangleVertShader->GetModule(), TriangleFragShader->GetModule());
|
||||
//it will draw triangles
|
||||
pipelineBuilder.SetInputTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
|
||||
//filled triangles
|
||||
pipelineBuilder.SetPolygonMode(VK_POLYGON_MODE_FILL);
|
||||
//no backface culling
|
||||
pipelineBuilder.SetCullMode(VK_CULL_MODE_NONE, VK_FRONT_FACE_CLOCKWISE);
|
||||
//no multisampling
|
||||
pipelineBuilder.SetMultiSamplingNone();
|
||||
//no blending
|
||||
pipelineBuilder.DisableBlending();
|
||||
//no depth testing
|
||||
pipelineBuilder.DisableDepthTest();
|
||||
|
||||
//connect the image format we will draw into, from draw image
|
||||
pipelineBuilder.SetColorAttachment(static_cast<VkFormat>(DrawImage->GetFormat()));
|
||||
pipelineBuilder.SetDepthFormat(VK_FORMAT_UNDEFINED);
|
||||
|
||||
//finally build the pipeline
|
||||
TrianglePipeline = pipelineBuilder.BuildPipeline(Device);
|
||||
|
||||
//clean structures
|
||||
//vkDestroyShaderModule(Device, Triangl, nullptr);
|
||||
//vkDestroyShaderModule(Device, TriangleVertexShader, nullptr);
|
||||
|
||||
MainDeletionQueue.push_function([&]() {
|
||||
vkDestroyPipelineLayout(Device, TrianglePipelineLayout, nullptr);
|
||||
vkDestroyPipeline(Device, TrianglePipeline, nullptr);
|
||||
});
|
||||
}
|
||||
|
||||
void VkRenderer::DrawGeometry(VkCommandBuffer cmd)
|
||||
{
|
||||
//begin a render pass connected to our draw image
|
||||
VkRenderingAttachmentInfo colorAttachment = VulkanInit::AttachmentInfo(DrawImage->GetImageView(), nullptr, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
VkRenderingInfo renderInfo = VulkanInit::RenderingInfo(DrawExtent, &colorAttachment, nullptr);
|
||||
vkCmdBeginRendering(cmd, &renderInfo);
|
||||
|
||||
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, TrianglePipeline);
|
||||
|
||||
//set dynamic viewport and scissor
|
||||
VkViewport viewport = {};
|
||||
viewport.x = 0;
|
||||
viewport.y = 0;
|
||||
viewport.width = DrawExtent.width;
|
||||
viewport.height = DrawExtent.height;
|
||||
viewport.minDepth = 0.f;
|
||||
viewport.maxDepth = 1.f;
|
||||
|
||||
vkCmdSetViewport(cmd, 0, 1, &viewport);
|
||||
|
||||
VkRect2D scissor = {};
|
||||
scissor.offset.x = 0;
|
||||
scissor.offset.y = 0;
|
||||
scissor.extent.width = DrawExtent.width;
|
||||
scissor.extent.height = DrawExtent.height;
|
||||
|
||||
vkCmdSetScissor(cmd, 0, 1, &scissor);
|
||||
|
||||
//launch a draw command to draw 3 vertices
|
||||
vkCmdDraw(cmd, 3, 1, 0, 0);
|
||||
|
||||
vkCmdEndRendering(cmd);
|
||||
}
|
||||
|
||||
void VkRenderer::InitImgui()
|
||||
{
|
||||
// 1: create descriptor pool for IMGUI
|
||||
@@ -514,20 +594,16 @@ void VkRenderer::Draw()
|
||||
{
|
||||
VK_CALL(vkWaitForFences(Device, 1, &GetCurrentFrame().RenderFence, true, 1000000000));
|
||||
|
||||
//GetCurrentFrame().LocalDeletionQueue.flush();
|
||||
|
||||
if (SurfaceSize != Window::Get()->GetSize())
|
||||
{
|
||||
RecreateSwapchain();
|
||||
return;
|
||||
}
|
||||
|
||||
//request image from the swapchain
|
||||
uint32_t swapchainImageIndex;
|
||||
VkResult result = vkAcquireNextImageKHR(Device, Swapchain, 1000000000, GetCurrentFrame().SwapchainSemaphore, nullptr, &swapchainImageIndex);
|
||||
|
||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || SurfaceSize != Window::Get()->GetSize())
|
||||
{
|
||||
RecreateSwapchain();
|
||||
//DestroySwapchain();
|
||||
//CreateSwapchain(Window::Get()->GetSize());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
VK_CALL(vkResetFences(Device, 1, &GetCurrentFrame().RenderFence));
|
||||
|
||||
@@ -541,9 +617,12 @@ void VkRenderer::Draw()
|
||||
DrawExtent.width = DrawImage->GetSize().x;
|
||||
DrawExtent.height = DrawImage->GetSize().y;
|
||||
|
||||
VkCommandBufferSubmitInfo cmdinfo;
|
||||
|
||||
// Create commands
|
||||
VK_CALL(vkBeginCommandBuffer(cmd, &cmdBeginInfo));
|
||||
{
|
||||
|
||||
// Transfer rendering image to general layout
|
||||
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL);
|
||||
|
||||
@@ -558,14 +637,13 @@ void VkRenderer::Draw()
|
||||
//VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
DrawGeometry(cmd);
|
||||
|
||||
VulkanUtil::TransitionImage(cmd, DrawImage->GetImage(), VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
//draw imgui into the swapchain image
|
||||
DrawImgui(cmd, SwapchainImageViews[swapchainImageIndex]);
|
||||
|
||||
|
||||
// set swapchain image layout to Attachment Optimal so we can draw it
|
||||
VulkanUtil::TransitionImage(cmd, SwapchainImages[swapchainImageIndex], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
|
||||
@@ -577,7 +655,7 @@ void VkRenderer::Draw()
|
||||
}
|
||||
VK_CALL(vkEndCommandBuffer(cmd));
|
||||
|
||||
VkCommandBufferSubmitInfo cmdinfo = VulkanInit::CommandBufferSubmitInfo(cmd);
|
||||
cmdinfo = VulkanInit::CommandBufferSubmitInfo(cmd);
|
||||
|
||||
// Wait for both semaphore of swapchain and the texture of the frame.
|
||||
VkSemaphoreSubmitInfo waitInfo = VulkanInit::SemaphoreSubmitInfo(VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, GetCurrentFrame().SwapchainSemaphore);
|
||||
|
||||
@@ -161,8 +161,12 @@ namespace Nuake
|
||||
VkPipeline Pipeline;
|
||||
VkPipelineLayout PipelineLayout;
|
||||
|
||||
Ref<VulkanShader> BackgroundShader;
|
||||
VkPipelineLayout TrianglePipelineLayout;
|
||||
VkPipeline TrianglePipeline;
|
||||
|
||||
Ref<VulkanShader> BackgroundShader;
|
||||
Ref<VulkanShader> TriangleVertShader;
|
||||
Ref<VulkanShader> TriangleFragShader;
|
||||
// Imgui
|
||||
VkFence ImguiFence;
|
||||
VkCommandBuffer ImguiCommandBuffer;
|
||||
@@ -200,6 +204,8 @@ namespace Nuake
|
||||
void UpdateDescriptorSets();
|
||||
void InitPipeline();
|
||||
void InitBackgroundPipeline();
|
||||
void InitTrianglePipeline();
|
||||
void DrawGeometry(VkCommandBuffer cmd);
|
||||
void InitImgui();
|
||||
|
||||
void Draw();
|
||||
|
||||
32
Nuake/src/Rendering/Vulkan/VulkanTypes.h
Normal file
32
Nuake/src/Rendering/Vulkan/VulkanTypes.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <src/Core/Maths.h>
|
||||
#include "src/Rendering/Vulkan/VulkanAllocatedBuffer.h"
|
||||
|
||||
|
||||
namespace Nuake
|
||||
{
|
||||
struct Vertex
|
||||
{
|
||||
Vector3 position;
|
||||
float uv_x;
|
||||
Vector3 normal;
|
||||
float uv_y;
|
||||
Vector4 color;
|
||||
};
|
||||
|
||||
// holds the resources needed for a mesh
|
||||
struct GPUMeshBuffers
|
||||
{
|
||||
AllocatedBuffer indexBuffer;
|
||||
AllocatedBuffer vertexBuffer;
|
||||
VkDeviceAddress vertexBufferAddress;
|
||||
};
|
||||
|
||||
// push constants for our mesh object draws
|
||||
struct GPUDrawPushConstants
|
||||
{
|
||||
Matrix4 worldMatrix;
|
||||
VkDeviceAddress vertexBuffer;
|
||||
};
|
||||
}
|
||||
28
Resources/Shaders/Vulkan/test.vert
Normal file
28
Resources/Shaders/Vulkan/test.vert
Normal file
@@ -0,0 +1,28 @@
|
||||
struct VSInput
|
||||
{
|
||||
[[vk::location(0)]] float3 Position : POSITION0;
|
||||
[[vk::location(1)]] float3 Color : COLOR0;
|
||||
};
|
||||
|
||||
struct UBO
|
||||
{
|
||||
float4x4 projectionMatrix;
|
||||
float4x4 modelMatrix;
|
||||
float4x4 viewMatrix;
|
||||
};
|
||||
|
||||
cbuffer ubo : register(b0, space0) { UBO ubo; }
|
||||
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Pos : SV_POSITION;
|
||||
[[vk::location(0)]] float3 Color : COLOR0;
|
||||
};
|
||||
|
||||
VSOutput main(VSInput input, uint VertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output = (VSOutput)0;
|
||||
output.Color = input.Color * float(VertexIndex);
|
||||
output.Pos = mul(ubo.projectionMatrix, mul(ubo.viewMatrix, mul(ubo.modelMatrix, float4(input.Position.xyz, 1.0))));
|
||||
return output;
|
||||
}
|
||||
9
Resources/Shaders/Vulkan/triangle.frag
Normal file
9
Resources/Shaders/Vulkan/triangle.frag
Normal file
@@ -0,0 +1,9 @@
|
||||
struct PSInput {
|
||||
float3 Color : TEXCOORD0;
|
||||
};
|
||||
|
||||
float4 main(PSInput input) : SV_Target
|
||||
{
|
||||
// Return color with alpha = 1.0f
|
||||
return float4(input.Color, 1.0f);
|
||||
}
|
||||
30
Resources/Shaders/Vulkan/triangle.vert
Normal file
30
Resources/Shaders/Vulkan/triangle.vert
Normal file
@@ -0,0 +1,30 @@
|
||||
// HLSL version for Shader Model 6.1
|
||||
struct VSOutput {
|
||||
float4 Position : SV_Position;
|
||||
float3 Color : TEXCOORD0;
|
||||
};
|
||||
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
// Constant array of positions for the triangle
|
||||
float3 positions[3] = {
|
||||
float3(1.0f, 1.0f, 0.0f),
|
||||
float3(-1.0f, 1.0f, 0.0f),
|
||||
float3(0.0f, -1.0f, 0.0f)
|
||||
};
|
||||
|
||||
// Constant array of colors for the triangle
|
||||
float3 colors[3] = {
|
||||
float3(1.0f, 0.0f, 0.0f), // red
|
||||
float3(0.0f, 1.0f, 0.0f), // green
|
||||
float3(0.0f, 0.0f, 1.0f) // blue
|
||||
};
|
||||
|
||||
// Output the position of each vertex
|
||||
output.Position = float4(positions[vertexIndex], 1.0f);
|
||||
output.Color = colors[vertexIndex];
|
||||
|
||||
return output;
|
||||
}
|
||||
39
Resources/Shaders/Vulkan/triangle.vert.hlsl
Normal file
39
Resources/Shaders/Vulkan/triangle.vert.hlsl
Normal file
@@ -0,0 +1,39 @@
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float4 color;
|
||||
};
|
||||
|
||||
// Define the structured buffer for vertices
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t0); // Binding of vertex buffer (example: t0)
|
||||
|
||||
// Define push constants block
|
||||
cbuffer PushConstants : register(b0) { // Push constants binding (example: b0)
|
||||
float4x4 render_matrix; // Matrix for rendering
|
||||
uint64_t vertexBufferAddress; // Buffer reference address (Vulkan-specific handling required)
|
||||
};
|
||||
|
||||
// Outputs
|
||||
struct VSOutput {
|
||||
float4 Position : SV_Position;
|
||||
float3 Color : TEXCOORD0;
|
||||
float2 UV : TEXCOORD1;
|
||||
};
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID) {
|
||||
VSOutput output;
|
||||
|
||||
// Load vertex data from the buffer
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
|
||||
// Transform and output vertex data
|
||||
output.Position = mul(render_matrix, float4(v.position, 1.0f));
|
||||
output.Color = v.color.xyz;
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
|
||||
return output;
|
||||
}
|
||||
Reference in New Issue
Block a user