diff --git a/Nuake/src/Rendering/Vulkan/VkVertex.h b/Nuake/src/Rendering/Vulkan/VkVertex.h new file mode 100644 index 00000000..73b42a60 --- /dev/null +++ b/Nuake/src/Rendering/Vulkan/VkVertex.h @@ -0,0 +1,14 @@ +#pragma once +#include "src/Core/Maths.h" + +namespace Nuake +{ + struct VkVertex + { + Vector3 position; + float uv_x; + Vector3 normal; + float uv_y; + Vector4 color; + }; +} diff --git a/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.cpp b/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.cpp index 0c557ba8..7a52b6a9 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.cpp @@ -4,10 +4,9 @@ #include "VulkanCheck.h" #include "VulkanRenderer.h" - +#include "vk_mem_alloc.h" using namespace Nuake; -#include "vk_mem_alloc.h" AllocatedBuffer::AllocatedBuffer(size_t inSize, VkBufferUsageFlags inFlags, VmaMemoryUsage inUsage) { @@ -31,3 +30,25 @@ AllocatedBuffer::~AllocatedBuffer() { // TODO: deletion of buffer } + +GPUMeshBuffers::GPUMeshBuffers(std::vector vertices, std::vector indices) +{ + const size_t vertexBufferSize = vertices.size() * sizeof(VkVertex); + const size_t indexBufferSize = indices.size() * sizeof(uint32_t); + + vertexBuffer = AllocatedBuffer(vertexBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, + VMA_MEMORY_USAGE_GPU_ONLY); + + //find the adress of the vertex buffer + VkBufferDeviceAddressInfo deviceAddressInfo + { + .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO, + .buffer = vertexBuffer.GetBuffer() + }; + + vertexBufferAddress = vkGetBufferDeviceAddress(VkRenderer::Get().GetDevice(), &deviceAddressInfo); + + //create index buffer + indexBuffer = AllocatedBuffer(indexBufferSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + VMA_MEMORY_USAGE_GPU_ONLY); +} diff --git a/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.h b/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.h index 79fbd582..20eb076b 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.h +++ b/Nuake/src/Rendering/Vulkan/VulkanAllocatedBuffer.h @@ -1,10 +1,13 @@ #pragma once #include "src/Core/Maths.h" +#include "src/Rendering/Vulkan/VkVertex.h" -#include -#include +#include +#include "volk/volk.h" + +#include "vk_mem_alloc.h" namespace Nuake { @@ -17,15 +20,13 @@ namespace Nuake public: AllocatedBuffer(size_t size, VkBufferUsageFlags flags, VmaMemoryUsage usage); + AllocatedBuffer() = default; ~AllocatedBuffer(); + + VkBuffer GetBuffer() const { return Buffer; } + VmaAllocation GetAllocation() const { return Allocation; } }; - struct GPUMeshBuffers - { - AllocatedBuffer indexBuffer; - AllocatedBuffer vertexBuffer; - VkDeviceAddress vertexBufferAddress; - }; // push constants for our mesh object draws struct GPUDrawPushConstants @@ -33,4 +34,18 @@ namespace Nuake glm::mat4 worldMatrix; VkDeviceAddress vertexBuffer; }; + + + // holds the resources needed for a mesh + class GPUMeshBuffers + { + public: + AllocatedBuffer indexBuffer; + AllocatedBuffer vertexBuffer; + VkDeviceAddress vertexBufferAddress; + + GPUMeshBuffers(std::vector vertices, std::vector indices); + GPUMeshBuffers() = default; + ~GPUMeshBuffers() = default; + }; } \ No newline at end of file diff --git a/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp b/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp index 8f764d02..a61541e1 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp +++ b/Nuake/src/Rendering/Vulkan/VulkanRenderer.cpp @@ -12,15 +12,16 @@ #include "imgui/imgui_impl_vulkan.h" #include #include "src/Resource/StaticResources.h" -#include "vk_mem_alloc.h" #include "VulkanInit.h" #include "VulkanAllocator.h" #include "VulkanCheck.h" #include "PipelineBuilder.h" +#include "VulkanAllocatedBuffer.h" + using namespace Nuake; - +#include "vk_mem_alloc.h" bool NKUseValidationLayer = true; @@ -76,6 +77,33 @@ void VkRenderer::Initialize() BackgroundShader = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/background.comp"); TriangleFragShader = shaderCompiler.CompileShader("../Resources/Shaders/Vulkan/triangle.frag"); + std::vector rect_vertices; + rect_vertices.resize(4); + + rect_vertices[0].position = { 0.5,-0.5, 0 }; + rect_vertices[1].position = { 0.5,0.5, 0 }; + rect_vertices[2].position = { -0.5,-0.5, 0 }; + rect_vertices[3].position = { -0.5,0.5, 0 }; + + rect_vertices[0].color = { 0,0, 0,1 }; + rect_vertices[1].color = { 0.5,0.5,0.5 ,1 }; + rect_vertices[2].color = { 1,0, 0,1 }; + rect_vertices[3].color = { 0,1, 0,1 }; + + std::vector rect_indices; + rect_indices.resize(6); + + rect_indices[0] = 0; + rect_indices[1] = 1; + rect_indices[2] = 2; + + rect_indices[3] = 2; + rect_indices[4] = 1; + rect_indices[5] = 3; + + rectangle = UploadMesh(rect_indices, rect_vertices); + + InitPipeline(); InitTrianglePipeline(); @@ -351,7 +379,15 @@ void VkRenderer::InitBackgroundPipeline() void VkRenderer::InitTrianglePipeline() { + VkPushConstantRange bufferRange{}; + bufferRange.offset = 0; + bufferRange.size = sizeof(GPUDrawPushConstants); + bufferRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + VkPipelineLayoutCreateInfo pipeline_layout_info = VulkanInit::PipelineLayoutCreateInfo(); + pipeline_layout_info.pPushConstantRanges = &bufferRange; + pipeline_layout_info.pushConstantRangeCount = 1; + VK_CALL(vkCreatePipelineLayout(Device, &pipeline_layout_info, nullptr, &TrianglePipelineLayout)); PipelineBuilder pipelineBuilder; @@ -739,6 +775,41 @@ void VkRenderer::ImmediateSubmit(std::function&& func VK_CALL(vkWaitForFences(Device, 1, &ImguiFence, true, 9999999999)); } +Ref VkRenderer::UploadMesh(std::vector indices, std::vector vertices) +{ + auto newSurface = CreateRef(vertices, indices); + + AllocatedBuffer staging = AllocatedBuffer(std::size(vertices) + std::size(indices), VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY); + + void* mappedData; + vmaMapMemory(VulkanAllocator::Get().GetAllocator(), staging.GetAllocation(), &mappedData); + + // copy vertex buffer + memcpy(mappedData, vertices.data(), std::size(vertices)); + + // copy index buffer + memcpy((char*)mappedData + std::size(vertices), indices.data(), std::size(indices)); + + ImmediateSubmit([&](VkCommandBuffer cmd) { + VkBufferCopy vertexCopy{ 0 }; + vertexCopy.dstOffset = 0; + vertexCopy.srcOffset = 0; + vertexCopy.size = std::size(vertices); + + vkCmdCopyBuffer(cmd, staging.GetBuffer(), newSurface->vertexBuffer.GetBuffer(), 1, &vertexCopy); + + VkBufferCopy indexCopy{ 0 }; + indexCopy.dstOffset = 0; + indexCopy.srcOffset = std::size(vertices); + indexCopy.size = std::size(indices); + + vkCmdCopyBuffer(cmd, staging.GetBuffer(), newSurface->indexBuffer.GetBuffer(), 1, &indexCopy); + }); + + // TODO: destroy_buffer(staging); + return newSurface; +} + void DescriptorLayoutBuilder::AddBinding(uint32_t binding, VkDescriptorType type) { VkDescriptorSetLayoutBinding newbind{}; diff --git a/Nuake/src/Rendering/Vulkan/VulkanRenderer.h b/Nuake/src/Rendering/Vulkan/VulkanRenderer.h index b47db94a..1abbd9c4 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanRenderer.h +++ b/Nuake/src/Rendering/Vulkan/VulkanRenderer.h @@ -6,15 +6,21 @@ #include "vkb/VkBootstrap.h" #include "VulkanImage/VulkanImage.h" +#include "VulkanTypes.h" +#include "VkVertex.h" #include #include + +#include "vk_mem_alloc.h" + namespace Nuake { class VulkanShader; + class GPUMeshBuffers; + - struct VmaAllocation {}; struct AllocatedImage { VkImage image; VkImageView imageView; @@ -149,8 +155,6 @@ namespace Nuake DeletionQueue MainDeletionQueue; - - // Descriptors DescriptorAllocator GlobalDescriptorAllocator; @@ -167,11 +171,15 @@ namespace Nuake Ref BackgroundShader; Ref TriangleVertShader; Ref TriangleFragShader; + // Imgui VkFence ImguiFence; VkCommandBuffer ImguiCommandBuffer; VkCommandPool ImguiCommandPool; + // Buffers + Ref rectangle; + public: static VkRenderer& Get() { @@ -214,6 +222,8 @@ namespace Nuake void ImmediateSubmit(std::function&& function); + Ref UploadMesh(std::vector indices, std::vector vertices); + VkDescriptorSet GetViewportDescriptor() const { return DrawImageDescriptors; } Ref GetDrawImage() const { return DrawImage; } }; diff --git a/Nuake/src/Rendering/Vulkan/VulkanTypes.h b/Nuake/src/Rendering/Vulkan/VulkanTypes.h index df5f1fd0..3f59c932 100644 --- a/Nuake/src/Rendering/Vulkan/VulkanTypes.h +++ b/Nuake/src/Rendering/Vulkan/VulkanTypes.h @@ -1,32 +1,2 @@ #pragma once -#include -#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; - }; -} diff --git a/Resources/Shaders/Vulkan/triangle.vert b/Resources/Shaders/Vulkan/triangle.vert index 6c992377..35745b97 100644 --- a/Resources/Shaders/Vulkan/triangle.vert +++ b/Resources/Shaders/Vulkan/triangle.vert @@ -1,30 +1,39 @@ -// HLSL version for Shader Model 6.1 +struct Vertex +{ + float3 position; + float uv_x; + float3 normal; + float uv_y; + float4 color; +}; + +// Define the structured buffer for vertices +StructuredBuffer 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; }; -VSOutput main(uint vertexIndex : SV_VertexID) -{ +// Main vertex shader +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) - }; + // Load vertex data from the buffer + Vertex v = vertexBuffer[vertexIndex]; - // 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]; + // 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; } \ No newline at end of file