From 0b97e6eeeceba1a09de5cc5a17927207157c0c8d Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Fri, 12 Aug 2022 19:08:28 +0000 Subject: [PATCH] work --- include/Orange/Core/Span.h | 12 +- include/Orange/Core/Variant.h | 4 +- include/Orange/Core/Vector.h | 7 + include/Orange/Math/Basic.h | 1 + include/Orange/Render/RenderContext.h | 94 +++++++- src/Apps/Tools/CubeTest.cpp | 290 +++++++++++++++++++++-- src/Orange/Render/RenderContext_Init.cpp | 39 ++- src/Orange/Render/RenderContext_Util.cpp | 40 ++++ src/Orange/Render/Shaders/vs_Mesh.vert | 20 ++ src/Orange/Render/Swapchain.cpp | 22 +- src/Orange/meson.build | 1 + 11 files changed, 495 insertions(+), 35 deletions(-) create mode 100644 src/Orange/Render/Shaders/vs_Mesh.vert diff --git a/include/Orange/Core/Span.h b/include/Orange/Core/Span.h index 1df9385..88ceaec 100644 --- a/include/Orange/Core/Span.h +++ b/include/Orange/Core/Span.h @@ -53,11 +53,19 @@ namespace orange T& back() { return data[size - 1]; } const T& back() const { return data[size - 1]; } + void Copy(void* dst) + { + memcpy(dst, data, sizeof(T) * size); + } + T* data; size_t size; }; - using BufferView = Span; + struct BufferView : public Span + { + using Span::Span; + }; struct StringView : public Span { @@ -69,7 +77,7 @@ namespace orange struct Buffer : public BufferView { - using BufferView::Span; + using BufferView::BufferView; ~Buffer() { delete[] data; } }; diff --git a/include/Orange/Core/Variant.h b/include/Orange/Core/Variant.h index 7ad2f31..d54a746 100644 --- a/include/Orange/Core/Variant.h +++ b/include/Orange/Core/Variant.h @@ -28,8 +28,8 @@ namespace orange new (Ptr()) T(Forward(args)...); } - template T* Ptr() { return reinterpret_cast(data.data); } - template const T* Ptr() const { return reinterpret_cast(data.data); } + template T* Ptr() { return reinterpret_cast (data.data); } + template const T* Ptr() const { return reinterpret_cast(data.data); } template T& Get() { return *Ptr(); } template const T& Get() const { return *Ptr(); } diff --git a/include/Orange/Core/Vector.h b/include/Orange/Core/Vector.h index d0abc74..a7ae8aa 100644 --- a/include/Orange/Core/Vector.h +++ b/include/Orange/Core/Vector.h @@ -166,6 +166,11 @@ namespace orange return FindIdx(x) != InvalidIdx; } + void Copy(void* dst) + { + memcpy(dst, Ptr(0), sizeof(T) * m_size); + } + T& operator [] (size_t idx) { return *Ptr(idx); } const T& operator [] (size_t idx) const { return *Ptr(idx); } @@ -183,6 +188,8 @@ namespace orange operator Span() { return Span(*this); } + operator BufferView() { return BufferView{ reinterpret_cast(Ptr(0)), sizeof(T) * m_size}; } + private: using Storage = AlignedStorage; diff --git a/include/Orange/Math/Basic.h b/include/Orange/Math/Basic.h index 301c23e..c622418 100644 --- a/include/Orange/Math/Basic.h +++ b/include/Orange/Math/Basic.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace orange { diff --git a/include/Orange/Render/RenderContext.h b/include/Orange/Render/RenderContext.h index fb82fcf..d8eb79b 100644 --- a/include/Orange/Render/RenderContext.h +++ b/include/Orange/Render/RenderContext.h @@ -8,16 +8,53 @@ namespace orange { - class BufferPool + struct BufferSlice { + VkBuffer buffer; + VkDeviceSize offset; + VkDeviceSize size; + }; + + struct GPUMemoryBuffer + { + VkDeviceMemory memory; + VkBuffer buffer; + VkDeviceSize size; + void* ptr; + }; + + class BufferPooler + { + public: + BufferPooler(GPUMemoryBuffer buffer) + : m_buffer{ buffer } {} + + Result AllocSlice(VkDeviceSize size) + { + BufferSlice slice{ m_buffer.buffer, m_offset, size }; + + if (m_offset + size > m_buffer.size) + return Result::Error(); + + m_offset += size; + + return Result::Success(slice); + } private: - VkBuffer m_buffer; - VkDeviceAddress m_va; + GPUMemoryBuffer m_buffer = {}; + VkDeviceSize m_offset = 0u; }; template using VulkanResult = Result; + struct VkMemoryTypes + { + uint32_t cpuTypeIdx = -1; + uint32_t gpuOnlyTypeIdx = -1; + uint32_t gpuHostVisibleTypeIdx = -1; + }; + class RenderContext { public: @@ -31,10 +68,11 @@ namespace orange VkQueue Queue() const { return m_queue; } VkCommandPool CommandPool() const { return m_commandPool; } - VulkanResult CreateFence(bool signalled); - VulkanResult CreateSemaphore(); - VulkanResult BeginCommandBuffer(VkCommandBuffer buffer); - VulkanResult EndCommandBuffer(VkCommandBuffer buffer); + VulkanResult CreateFence(bool signalled); + VulkanResult CreateSemaphore(); + VulkanResult BeginCommandBuffer(VkCommandBuffer buffer); + VulkanResult EndCommandBuffer(VkCommandBuffer buffer); + VulkanResult CreateBuffer(VkDeviceSize size); VulkanResult CreateShader(Span code); protected: @@ -42,12 +80,52 @@ namespace orange RenderContext(VkInstance instance, VkPhysicalDevice physicalDevice, VkDevice device, VkQueue queue, VkCommandPool commandPool) : m_instance{ instance }, m_physicalDevice{ physicalDevice }, m_device{ device } - , m_queue{ queue }, m_commandPool{ commandPool } {} + , m_queue{ queue }, m_commandPool{ commandPool } + { + VkPhysicalDeviceMemoryProperties memoryProps; + vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &memoryProps); + + struct + { + uint32_t* ptr; + VkMemoryPropertyFlags flags; + } memoryTypeMapping[] = + { + { &m_memoryTypes.gpuHostVisibleTypeIdx, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT }, + + { &m_memoryTypes.gpuOnlyTypeIdx, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT }, + + { &m_memoryTypes.cpuTypeIdx, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT }, + }; + + for (auto& mapping : memoryTypeMapping) + { + for (uint32_t i = 0; i < memoryProps.memoryTypeCount; i++) + { + if (memoryProps.memoryTypes[i].propertyFlags & mapping.flags) + { + *mapping.ptr = i; + + if (memoryProps.memoryTypes[i].propertyFlags == mapping.flags) + break; + } + } + } + + } private: VkInstance m_instance = VK_NULL_HANDLE; VkPhysicalDevice m_physicalDevice = VK_NULL_HANDLE; VkDevice m_device = VK_NULL_HANDLE; VkQueue m_queue = VK_NULL_HANDLE; VkCommandPool m_commandPool = VK_NULL_HANDLE; + + VkMemoryTypes m_memoryTypes{}; }; } \ No newline at end of file diff --git a/src/Apps/Tools/CubeTest.cpp b/src/Apps/Tools/CubeTest.cpp index 2e1a9db..4fa1f86 100644 --- a/src/Apps/Tools/CubeTest.cpp +++ b/src/Apps/Tools/CubeTest.cpp @@ -11,8 +11,9 @@ #include #include #include +#include -#include +#include #include using namespace orange; @@ -35,19 +36,30 @@ enum class MeshVertexType Skinned, }; +#ifndef offsetof2 +#define offsetof2(type, member) size_t(uintptr_t(&((type*)0)->member)) +#endif + struct StaticVertex { vec3 pos; vec2 uv; vec3 normal; - vec3 tangent; + //vec3 tangent; + + static constexpr VkVertexInputAttributeDescription Attributes[] = + { + { .location = 0, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, pos)) }, + { .location = 1, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, uv)) }, + { .location = 2, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, .offset = uint32_t(offsetof2(StaticVertex, normal)) }, + }; bool operator == (const StaticVertex& other) const { return pos == other.pos && uv == other.uv && - normal == other.normal && - tangent == other.tangent; + normal == other.normal;// && + //tangent == other.tangent; } }; @@ -60,7 +72,7 @@ struct SkinnedVertex : public StaticVertex return pos == other.pos && uv == other.uv && normal == other.normal && - tangent == other.tangent && + //tangent == other.tangent && boneIndices == other.boneIndices && boneWeights == other.boneWeights; } @@ -74,7 +86,7 @@ struct MeshVertexData MeshVertexData(MeshVertexType type) : vertexType(type) { - switch(type) + switch(vertexType) { case MeshVertexType::Static: vertices.Construct>(); @@ -97,6 +109,27 @@ struct MeshVertexData return vertices.Get>(); } + BufferView View() + { + switch(vertexType) + { + case MeshVertexType::Static: + return GetStaticVertices(); + break; + case MeshVertexType::Skinned: + return GetSkinnedVertices(); + break; + default: + return BufferView{ nullptr, 0 }; + } + } + + uint32_t VertexCount() const + { + // Type doesn't matter here, just want to grab m_size. + return uint32_t(vertices.Get>().Size()); + } + MeshVertexType vertexType; Variant, Vector> vertices; }; @@ -134,16 +167,14 @@ Result ParseOBJ(StringView buffer) stream::ConsumeSpace(obj, end); if (auto r_float = stream::Parse(obj, end)) vtx[i] = *r_float; - else - return Result::Error(); } if (element == "v") positions.EmplaceBack(vtx[0], vtx[1], vtx[2]); else if (element == "vt") - normals.EmplaceBack(vtx[0], vtx[1], vtx[2]); - else if (element == "vn") uvs.EmplaceBack(vtx[0], vtx[1]); + else if (element == "vn") + normals.EmplaceBack(vtx[0], vtx[1], vtx[2]); } else if (element == "g" || element == "o") { @@ -230,17 +261,135 @@ int main(int argc, char** argv) if (!r_swapchain) return 1; - auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/chair.obj"); + //auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/chair.obj"); + auto r_objData = fs::OpenFileIntoTextBuffer("/home/joshua/cube.obj"); if (!r_objData) return 1; auto r_mesh = ParseOBJ(*r_objData); - auto r_vs = r_renderContext->CreateShader(vs_Triangle); + auto r_vs = r_renderContext->CreateShader(vs_Mesh); if (!r_vs) return 1; auto r_fs = r_renderContext->CreateShader(fs_DebugVertColor); if (!r_fs) return 1; + // + + VkSamplerCreateInfo samplerInfo = + { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .magFilter = VK_FILTER_LINEAR, + .minFilter = VK_FILTER_LINEAR, + .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR, + .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + .mipLodBias = 0.0f, + .anisotropyEnable = VK_TRUE, + .maxAnisotropy = 16.0f, + .minLod = -FLT_MAX, + .maxLod = FLT_MAX, + }; + VkSampler sampler = VK_NULL_HANDLE; + vkCreateSampler(r_renderContext->Device(), &samplerInfo, nullptr, &sampler); + + constexpr uint32_t MaxBindlessResources = 32768; + VkDescriptorPoolSize bindlessPoolSizes[] = + { + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MaxBindlessResources } + }; + + VkDescriptorPoolCreateInfo poolInfo = + { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT, + .maxSets = MaxBindlessResources * Size(bindlessPoolSizes), + .poolSizeCount = uint32_t(Size(bindlessPoolSizes)), + .pPoolSizes = bindlessPoolSizes, + }; + + VkDescriptorPool descriptorPool = VK_NULL_HANDLE; + vkCreateDescriptorPool(r_renderContext->Device(), &poolInfo, nullptr, &descriptorPool); + + VkDescriptorSetLayoutBinding layoutBindings[] = + { + { + .binding = 0, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorCount = MaxBindlessResources, + .stageFlags = VK_SHADER_STAGE_ALL, + }, + { + .binding = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + .descriptorCount = MaxBindlessResources, + .stageFlags = VK_SHADER_STAGE_ALL, + }, + { + .binding = 2, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER, + .descriptorCount = 1, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + .pImmutableSamplers = &sampler, + }, + { + .binding = 3, + .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + .descriptorCount = MaxBindlessResources, + .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT, + }, + }; + + constexpr VkDescriptorBindingFlags bindingFlags[] = + { + 0, + 0, + 0, + VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT | VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT | VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT, + }; + + Assert(Size(bindingFlags) == Size(layoutBindings)); + + VkDescriptorSetLayoutBindingFlagsCreateInfo layoutBindingFlagsInfo = + { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT, + .bindingCount = Size(bindingFlags), + .pBindingFlags = bindingFlags, + }; + + VkDescriptorSetLayoutCreateInfo layoutInfo = + { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .pNext = &layoutBindingFlagsInfo, + .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT, + .bindingCount = Size(layoutBindings), + .pBindings = layoutBindings, + }; + + VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE; + vkCreateDescriptorSetLayout(r_renderContext->Device(), &layoutInfo, nullptr, &descriptorSetLayout); + + VkDescriptorSetVariableDescriptorCountAllocateInfoEXT descriptorCountAllocInfo = + { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT, + .descriptorSetCount = 1, + .pDescriptorCounts = &MaxBindlessResources, + }; + + VkDescriptorSetAllocateInfo descriptorSetAllocInfo = + { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pNext = &descriptorCountAllocInfo, + .descriptorPool = descriptorPool, + .descriptorSetCount = 1, + .pSetLayouts = &descriptorSetLayout, + }; + + VkDescriptorSet descriptorSet = VK_NULL_HANDLE; + vkAllocateDescriptorSets(r_renderContext->Device(), &descriptorSetAllocInfo, &descriptorSet); + + // + VkPipelineShaderStageCreateInfo stages[] = { { @@ -270,13 +419,20 @@ int main(int argc, char** argv) .pDynamicStates = dynamicStates.Data(), }; + VkVertexInputBindingDescription inputBindingDescription = + { + .binding = 0, + .stride = sizeof(StaticVertex), + .inputRate = VK_VERTEX_INPUT_RATE_VERTEX, + }; + VkPipelineVertexInputStateCreateInfo vertexInputInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 0u, - .pVertexBindingDescriptions = nullptr, - .vertexAttributeDescriptionCount = 0u, - .pVertexAttributeDescriptions = nullptr, + .vertexBindingDescriptionCount = 1u, + .pVertexBindingDescriptions = &inputBindingDescription, + .vertexAttributeDescriptionCount = Size(StaticVertex::Attributes), + .pVertexAttributeDescriptions = StaticVertex::Attributes, }; VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = @@ -298,6 +454,7 @@ int main(int argc, char** argv) .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .cullMode = VK_CULL_MODE_NONE, //VK_CULL_MODE_BACK_BIT, .frontFace = VK_FRONT_FACE_CLOCKWISE, + .lineWidth = 1.0f, }; VkPipelineMultisampleStateCreateInfo multisampleInfo = @@ -321,12 +478,14 @@ int main(int argc, char** argv) VkPipelineLayoutCreateInfo pipelineLayoutInfo = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .setLayoutCount = 1, + .pSetLayouts = &descriptorSetLayout }; VkPipelineLayout pipelineLayout = VK_NULL_HANDLE; vkCreatePipelineLayout(r_renderContext->Device(), &pipelineLayoutInfo, nullptr, &pipelineLayout); - VkFormat format = r_swapchain->Format(); + VkFormat format = FormatToSrgbFormat(r_swapchain->Format()); VkPipelineRenderingCreateInfo renderingInfo = { .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, @@ -359,6 +518,57 @@ int main(int argc, char** argv) return 1; } + auto r_buffer = r_renderContext->CreateBuffer(256 * 1024 * 1024); + if (!r_buffer) + return 1; + + VkBufferViewCreateInfo bufferViewInfo = + { + .sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, + .buffer = r_buffer->buffer, + .format = VK_FORMAT_R8G8B8A8_UNORM, + .offset = 0, + .range = r_buffer->size, + }; + VkBufferView bufferView = VK_NULL_HANDLE; + vkCreateBufferView(r_renderContext->Device(), &bufferViewInfo, nullptr, &bufferView); + + VkDescriptorBufferInfo bufferInfo = + { + .buffer = r_buffer->buffer, + .offset = 0, + .range = r_buffer->size, + }; + + VkWriteDescriptorSet writeDescriptorSet[] = + { + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = descriptorSet, + .dstBinding = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pBufferInfo = &bufferInfo, + }, + { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = descriptorSet, + .dstBinding = 1, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + .pTexelBufferView = &bufferView, + }, + }; + vkUpdateDescriptorSets(r_renderContext->Device(), Size(writeDescriptorSet), writeDescriptorSet, 0, nullptr); + + auto pooler = BufferPooler{ *r_buffer }; + auto meshData = r_mesh->vertexData.View(); + auto vertexSlice = *pooler.AllocSlice(meshData.size); + auto indexSlice = *pooler.AllocSlice(r_mesh->indices.Size() * sizeof(uint16_t)); + + meshData.Copy ((uint8_t*)(r_buffer->ptr) + vertexSlice.offset); + r_mesh->indices.Copy((uint8_t*)(r_buffer->ptr) + indexSlice.offset); + while (r_window->Update()) { VkCommandBuffer cmdBuf = r_swapchain->CommandBuffer(); @@ -384,6 +594,29 @@ int main(int argc, char** argv) vkCmdSetScissor(cmdBuf, 0, 1, &scissor); vkCmdBindPipeline(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); + vkCmdBindDescriptorSets(cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); + + vkCmdBindVertexBuffers2(cmdBuf, 0, 1, &vertexSlice.buffer, &vertexSlice.offset, &vertexSlice.size, nullptr); + vkCmdBindIndexBuffer(cmdBuf, r_buffer->buffer, indexSlice.offset, VK_INDEX_TYPE_UINT16); + + const VkImageMemoryBarrier undefinedToColorBarrier = + { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .image = r_swapchain->Image(), + .subresourceRange = FirstMipSubresourceRange, + }; + + vkCmdPipelineBarrier( + cmdBuf, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + 0, + 0, nullptr, + 0, nullptr, + 1, &undefinedToColorBarrier); const VkRenderingAttachmentInfoKHR attachmentInfo = { @@ -404,8 +637,27 @@ int main(int argc, char** argv) .pColorAttachments = &attachmentInfo, }; vkCmdBeginRendering(cmdBuf, &renderInfo); - vkCmdDraw(cmdBuf, 3, 1, 0, 0); + vkCmdDrawIndexed(cmdBuf, r_mesh->vertexData.VertexCount(), 1, 0, 0, 0); vkCmdEndRendering(cmdBuf); + + const VkImageMemoryBarrier colorToPresentBarrier = + { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + .image = r_swapchain->Image(), + .subresourceRange = FirstMipSubresourceRange, + }; + + vkCmdPipelineBarrier( + cmdBuf, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + 0, + 0, nullptr, + 0, nullptr, + 1, &colorToPresentBarrier); } r_renderContext->EndCommandBuffer(cmdBuf); r_swapchain->Present(); diff --git a/src/Orange/Render/RenderContext_Init.cpp b/src/Orange/Render/RenderContext_Init.cpp index d89796b..8b4cd0c 100644 --- a/src/Orange/Render/RenderContext_Init.cpp +++ b/src/Orange/Render/RenderContext_Init.cpp @@ -115,13 +115,50 @@ namespace orange const char* deviceExtensions[] = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, + VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME, }; - VkPhysicalDeviceFeatures features{}; + VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures = + { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, + .dynamicRendering = VK_TRUE, + }; + + VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures = + { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES, + .pNext = &dynamicRenderingFeatures, + .shaderInputAttachmentArrayDynamicIndexing = VK_FALSE, + .shaderUniformTexelBufferArrayDynamicIndexing = VK_TRUE, + .shaderStorageTexelBufferArrayDynamicIndexing = VK_TRUE, + .shaderUniformBufferArrayNonUniformIndexing = VK_TRUE, + .shaderSampledImageArrayNonUniformIndexing = VK_TRUE, + .shaderStorageBufferArrayNonUniformIndexing = VK_TRUE, + .shaderStorageImageArrayNonUniformIndexing = VK_TRUE, + .shaderInputAttachmentArrayNonUniformIndexing = VK_FALSE, + .shaderUniformTexelBufferArrayNonUniformIndexing = VK_TRUE, + .shaderStorageTexelBufferArrayNonUniformIndexing = VK_TRUE, + .descriptorBindingUniformBufferUpdateAfterBind = VK_TRUE, + .descriptorBindingSampledImageUpdateAfterBind = VK_TRUE, + .descriptorBindingStorageImageUpdateAfterBind = VK_TRUE, + .descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE, + .descriptorBindingUniformTexelBufferUpdateAfterBind = VK_TRUE, + .descriptorBindingStorageTexelBufferUpdateAfterBind = VK_TRUE, + .descriptorBindingUpdateUnusedWhilePending = VK_TRUE, + .descriptorBindingPartiallyBound = VK_TRUE, + .descriptorBindingVariableDescriptorCount = VK_TRUE, + .runtimeDescriptorArray = VK_TRUE, + }; + + VkPhysicalDeviceFeatures features + { + .samplerAnisotropy = VK_TRUE, + }; VkDeviceCreateInfo deviceInfo = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, + .pNext = &descriptorIndexingFeatures, .queueCreateInfoCount = 1, .pQueueCreateInfos = &queueInfo, .enabledExtensionCount = Size(deviceExtensions), diff --git a/src/Orange/Render/RenderContext_Util.cpp b/src/Orange/Render/RenderContext_Util.cpp index 378e8fd..f0dafb5 100644 --- a/src/Orange/Render/RenderContext_Util.cpp +++ b/src/Orange/Render/RenderContext_Util.cpp @@ -72,4 +72,44 @@ namespace orange return VulkanResult::Success(module); } + + VulkanResult RenderContext::CreateBuffer(VkDeviceSize size) + { + VkMemoryAllocateInfo memoryInfo = + { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = size, + .memoryTypeIndex = m_memoryTypes.gpuHostVisibleTypeIdx, + }; + + VkDeviceMemory memory; + VkResult res = VK_SUCCESS; + if ((res = vkAllocateMemory(m_device, &memoryInfo, nullptr, &memory)) != VK_SUCCESS) + return VulkanResult::Error(res); + + void* data = nullptr; + if ((res = vkMapMemory(m_device, memory, 0, size, 0, &data)) != VK_SUCCESS) + return VulkanResult::Error(res); + + VkBufferCreateInfo bufferInfo = + { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .size = size, + .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | + VK_BUFFER_USAGE_TRANSFER_DST_BIT | + VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | + VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | + VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + }; + + VkBuffer buffer = VK_NULL_HANDLE; + if ((res = vkCreateBuffer(m_device, &bufferInfo, nullptr, &buffer)) != VK_SUCCESS) + return VulkanResult::Error(res); + + if ((res = vkBindBufferMemory(m_device, buffer, memory, 0)) != VK_SUCCESS) + return VulkanResult::Error(res); + + return VulkanResult::Success(memory, buffer, size, data); + } } diff --git a/src/Orange/Render/Shaders/vs_Mesh.vert b/src/Orange/Render/Shaders/vs_Mesh.vert new file mode 100644 index 0000000..20b53be --- /dev/null +++ b/src/Orange/Render/Shaders/vs_Mesh.vert @@ -0,0 +1,20 @@ +#version 450 + +layout(location = 0) in vec3 inPos; +layout(location = 1) in vec2 inUV; +layout(location = 2) in vec3 inNormal; + +layout(location = 0) out vec4 outColor; + +vec3 colors[3] = vec3[] +( + vec3(1.0, 0.0, 0.0), + vec3(0.0, 1.0, 0.0), + vec3(0.0, 0.0, 1.0) +); + +void main() +{ + gl_Position = vec4(inPos, 1.0); + outColor = vec4(colors[gl_VertexIndex], 1.0); +} \ No newline at end of file diff --git a/src/Orange/Render/Swapchain.cpp b/src/Orange/Render/Swapchain.cpp index fb6983b..39728cc 100644 --- a/src/Orange/Render/Swapchain.cpp +++ b/src/Orange/Render/Swapchain.cpp @@ -77,9 +77,24 @@ namespace orange const VkExtent2D extent = ChooseSwapExtent(capabilities); + VkFormat viewFormats[2] = + { + r_format->format, + FormatToSrgbFormat(r_format->format), + }; + + VkImageFormatListCreateInfo formatListInfo = + { + .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO, + .viewFormatCount = Size(viewFormats), + .pViewFormats = viewFormats, + }; + VkSwapchainCreateInfoKHR swapchainInfo = { .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + .pNext = &formatListInfo, + .flags = VK_SWAPCHAIN_CREATE_MUTABLE_FORMAT_BIT_KHR, .surface = surface, .minImageCount = ChooseImageCount(capabilities), .imageFormat = r_format->format, @@ -171,6 +186,8 @@ namespace orange void Swapchain::Present() { + vkResetFences(m_ctx.Device(), 1, &m_inFlightFences[m_currentFrame]); + const VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo submitInfo = { @@ -209,10 +226,9 @@ namespace orange m_currentFrame = (m_currentFrame + 1) % DefaultFramesInFlight; - vkResetCommandBuffer(m_commandBuffers[m_currentFrame], 0u); - vkWaitForFences(m_ctx.Device(), 1, &m_inFlightFences[m_currentFrame], VK_TRUE, UINT64_MAX); - vkResetFences(m_ctx.Device(), 1, &m_inFlightFences[m_currentFrame]); vkAcquireNextImageKHR(m_ctx.Device(), m_swapchain, ~0u, m_imageAvailableSemaphores[m_currentFrame], VK_NULL_HANDLE, &m_currentImage); + + vkResetCommandBuffer(m_commandBuffers[m_currentFrame], 0u); } } \ No newline at end of file diff --git a/src/Orange/meson.build b/src/Orange/meson.build index 362fe47..e1d92f7 100644 --- a/src/Orange/meson.build +++ b/src/Orange/meson.build @@ -1,6 +1,7 @@ orange_shaders = glsl_generator.process([ 'Render/Shaders/fs_DebugVertColor.frag', 'Render/Shaders/vs_Triangle.vert', + 'Render/Shaders/vs_Mesh.vert', ]) orange_src = files([