From c60c176a5414dbbc706024bdba5c28b2fc00c50f Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Sat, 28 Dec 2024 15:42:38 +0100 Subject: [PATCH] wtf is hapenning --- example/main.c | 9 +++++- runtime/Includes/Core/Graphics.inl | 1 - runtime/Includes/Renderer/Buffer.h | 3 +- runtime/Includes/Renderer/Image.h | 1 - runtime/Sources/Renderer/Buffer.cpp | 3 +- runtime/Sources/Renderer/Image.cpp | 43 ++++++++++++++++--------- runtime/Sources/Renderer/Memory.cpp | 1 - runtime/Sources/Renderer/RenderCore.cpp | 1 + runtime/Sources/Renderer/Swapchain.cpp | 1 + third_party/kvf.h | 29 +++++++++++++++-- 10 files changed, 68 insertions(+), 24 deletions(-) diff --git a/example/main.c b/example/main.c index 9336e73..3639bc5 100644 --- a/example/main.c +++ b/example/main.c @@ -130,6 +130,8 @@ void window_hook(int event, void* param) mlx_loop_end(((mlx_t*)param)->mlx); } +#include + int main(void) { mlx_t mlx; @@ -166,7 +168,12 @@ int main(void) mlx.logo_png = mlx_new_image_from_file(mlx.mlx, "42_logo.png", &dummy, &dummy); mlx.logo_bmp = mlx_new_image_from_file(mlx.mlx, "42_logo.bmp", &dummy, &dummy); - mlx.logo_jpg = mlx_new_image_from_file(mlx.mlx, "42_logo.jpg", &dummy, &dummy); + //mlx.logo_jpg = mlx_new_image_from_file(mlx.mlx, "42_logo.jpg", &dummy, &dummy); + mlx.logo_jpg = mlx_new_image(mlx.mlx, dummy, dummy); + + mlx_color* data = (mlx_color*)malloc(dummy * dummy * sizeof(mlx_color)); + mlx_get_image_region(mlx.mlx, mlx.logo_png, 0, 0, dummy, dummy, data); + mlx_set_image_region(mlx.mlx, mlx.logo_jpg, 0, 0, dummy, dummy, data); mlx_pixel_put(mlx.mlx, mlx.win, 200, 10, (mlx_color){ .rgba = 0xFF00FFFF }); mlx_put_image_to_window(mlx.mlx, mlx.win, mlx.logo_png, 0, 0); diff --git a/runtime/Includes/Core/Graphics.inl b/runtime/Includes/Core/Graphics.inl index 783cc94..1416b9a 100644 --- a/runtime/Includes/Core/Graphics.inl +++ b/runtime/Includes/Core/Graphics.inl @@ -87,7 +87,6 @@ namespace mlx { MLX_PROFILE_FUNCTION(); NonOwningPtr sprite = p_scene->GetSpriteFromTexturePositionScaleRotation(texture, Vec2f{ static_cast(x), static_cast(y) }, scale_x, scale_y, angle); - std::cout << sprite.Get() << std::endl; if(!sprite) { if(m_pixelput_called) diff --git a/runtime/Includes/Renderer/Buffer.h b/runtime/Includes/Renderer/Buffer.h index 0c4dcd1..356b613 100644 --- a/runtime/Includes/Renderer/Buffer.h +++ b/runtime/Includes/Renderer/Buffer.h @@ -19,7 +19,8 @@ namespace mlx void Swap(GPUBuffer& buffer) noexcept; - [[nodiscard]] MLX_FORCEINLINE void* GetMap() const noexcept { return p_map; } + template + [[nodiscard]] MLX_FORCEINLINE T GetMap() const noexcept { return reinterpret_cast(p_map); } [[nodiscard]] MLX_FORCEINLINE VkBuffer Get() const noexcept { return m_buffer; } [[nodiscard]] MLX_FORCEINLINE VmaAllocation GetAllocation() const noexcept { return m_allocation; } [[nodiscard]] MLX_FORCEINLINE VkDeviceSize GetSize() const noexcept { return m_size; } diff --git a/runtime/Includes/Renderer/Image.h b/runtime/Includes/Renderer/Image.h index 5833f0a..ba46d0e 100644 --- a/runtime/Includes/Renderer/Image.h +++ b/runtime/Includes/Renderer/Image.h @@ -98,7 +98,6 @@ namespace mlx void OpenCPUBuffer(); private: - std::vector m_cpu_buffer; std::optional m_staging_buffer; bool m_has_been_modified = false; }; diff --git a/runtime/Sources/Renderer/Buffer.cpp b/runtime/Sources/Renderer/Buffer.cpp index 95a70c3..c34f965 100644 --- a/runtime/Sources/Renderer/Buffer.cpp +++ b/runtime/Sources/Renderer/Buffer.cpp @@ -8,7 +8,7 @@ namespace mlx { MLX_PROFILE_FUNCTION(); VmaAllocationCreateInfo alloc_info{}; - alloc_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; + alloc_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT; alloc_info.usage = VMA_MEMORY_USAGE_AUTO; if(type == BufferType::Constant) @@ -86,6 +86,7 @@ namespace mlx VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice()); kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence); kvfDestroyFence(RenderCore::Get().GetDevice(), fence); + kvfDestroyCommandBuffer(RenderCore::Get().GetDevice(), cmd); return true; } diff --git a/runtime/Sources/Renderer/Image.cpp b/runtime/Sources/Renderer/Image.cpp index da6011d..4d3df4b 100644 --- a/runtime/Sources/Renderer/Image.cpp +++ b/runtime/Sources/Renderer/Image.cpp @@ -108,6 +108,8 @@ namespace mlx if(is_single_time_cmd_buffer) cmd = kvfCreateCommandBuffer(RenderCore::Get().GetDevice()); kvfTransitionImageLayout(RenderCore::Get().GetDevice(), m_image, KVF_IMAGE_COLOR, cmd, m_format, m_layout, new_layout, is_single_time_cmd_buffer); + if(is_single_time_cmd_buffer) + kvfDestroyCommandBuffer(RenderCore::Get().GetDevice(), cmd); m_layout = new_layout; } @@ -140,6 +142,7 @@ namespace mlx VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice()); kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence); kvfDestroyFence(RenderCore::Get().GetDevice(), fence); + kvfDestroyCommandBuffer(RenderCore::Get().GetDevice(), cmd); } } @@ -199,6 +202,7 @@ namespace mlx VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice()); kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence); kvfDestroyFence(RenderCore::Get().GetDevice(), fence); + kvfDestroyCommandBuffer(RenderCore::Get().GetDevice(), cmd); staging_buffer.Destroy(); } TransitionLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); @@ -219,9 +223,9 @@ namespace mlx if(!m_staging_buffer.has_value()) OpenCPUBuffer(); if constexpr(std::endian::native == std::endian::little) - m_cpu_buffer[(y * m_width) + x] = ReverseColor(color); + m_staging_buffer->GetMap()[(y * m_width) + x] = ReverseColor(color); else - m_cpu_buffer[(y * m_width) + x] = color; + m_staging_buffer->GetMap()[(y * m_width) + x] = color; m_has_been_modified = true; } @@ -244,9 +248,9 @@ namespace mlx moving_y++; } if constexpr(std::endian::native == std::endian::little) - m_cpu_buffer[(moving_y * m_width) + moving_x] = ReverseColor(pixels[i]); + m_staging_buffer->GetMap()[(moving_y * m_width) + moving_x] = ReverseColor(pixels[i]); else - m_cpu_buffer[(moving_y * m_width) + moving_x] = pixels[i]; + m_staging_buffer->GetMap()[(moving_y * m_width) + moving_x] = pixels[i]; } m_has_been_modified = true; } @@ -259,11 +263,13 @@ namespace mlx if(!m_staging_buffer.has_value()) OpenCPUBuffer(); if constexpr(std::endian::native == std::endian::little) + { for(std::size_t i = 0; i < len; i++) - m_cpu_buffer[(y * m_width) + x + i] = ReverseColor(pixels[i]); + m_staging_buffer->GetMap()[(y * m_width) + x + i] = ReverseColor(pixels[i]); + } else { - std::memcpy(&m_cpu_buffer[(y * m_width) + x], pixels, len); + std::memcpy(&m_staging_buffer->GetMap()[(y * m_width) + x], pixels, len); } m_has_been_modified = true; } @@ -276,9 +282,9 @@ namespace mlx if(!m_staging_buffer.has_value()) OpenCPUBuffer(); if constexpr(std::endian::native == std::endian::little) - return ReverseColor(m_cpu_buffer[(y * m_width) + x]); + return ReverseColor(m_staging_buffer->GetMap()[(y * m_width) + x]); else - return m_cpu_buffer[(y * m_width) + x]; + return m_staging_buffer->GetMap()[(y * m_width) + x]; } void Texture::GetRegion(int x, int y, int w, int h, mlx_color* dst) noexcept @@ -298,9 +304,9 @@ namespace mlx moving_y++; } if constexpr(std::endian::native == std::endian::little) - dst[i] = ReverseColor(m_cpu_buffer[(moving_y * m_width) + moving_x]); + dst[i] = ReverseColor(m_staging_buffer->GetMap()[(moving_y * m_width) + moving_x]); else - dst[i] = m_cpu_buffer[(moving_y * m_width) + moving_x]; + dst[i] = m_staging_buffer->GetMap()[(moving_y * m_width) + moving_x]; } } @@ -315,7 +321,16 @@ namespace mlx processed_color.g = static_cast(color.g * 255.f); processed_color.b = static_cast(color.b * 255.f); processed_color.a = static_cast(color.a * 255.f); - std::fill(m_cpu_buffer.begin(), m_cpu_buffer.end(), processed_color); + if(processed_color.r == 0 && processed_color.g == 0 && processed_color.b == 0) + std::memset(m_staging_buffer->GetMap(), processed_color.a, m_staging_buffer->GetSize()); + else + { + for(std::size_t y = 0; y < m_height; y++) + { + for(std::size_t x = 0; x < m_width; x++) + m_staging_buffer->GetMap()[y * m_width + x] = processed_color; + } + } } } @@ -324,8 +339,6 @@ namespace mlx MLX_PROFILE_FUNCTION(); if(!m_has_been_modified) return; - std::memcpy(m_staging_buffer->GetMap(), m_cpu_buffer.data(), m_cpu_buffer.size() * sizeof(mlx_color)); - VkImageLayout old_layout = m_layout; TransitionLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, cmd); kvfCopyBufferToImage(cmd, Image::Get(), m_staging_buffer->Get(), m_staging_buffer->GetOffset(), VK_IMAGE_ASPECT_COLOR_BIT, { m_width, m_height, 1 }); @@ -360,9 +373,7 @@ namespace mlx VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice()); kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence); kvfDestroyFence(RenderCore::Get().GetDevice(), fence); - - m_cpu_buffer.resize(m_width * m_height); - std::memcpy(m_cpu_buffer.data(), m_staging_buffer->GetMap(), m_cpu_buffer.size() * sizeof(mlx_color)); + kvfDestroyCommandBuffer(RenderCore::Get().GetDevice(), cmd); } Texture* StbTextureLoad(const std::filesystem::path& file, int* w, int* h) diff --git a/runtime/Sources/Renderer/Memory.cpp b/runtime/Sources/Renderer/Memory.cpp index 16734c2..0a257be 100644 --- a/runtime/Sources/Renderer/Memory.cpp +++ b/runtime/Sources/Renderer/Memory.cpp @@ -1,4 +1,3 @@ -#include "vulkan/vulkan_core.h" #include #define VMA_IMPLEMENTATION #ifdef MLX_COMPILER_CLANG diff --git a/runtime/Sources/Renderer/RenderCore.cpp b/runtime/Sources/Renderer/RenderCore.cpp index 9a91b71..4bddadc 100644 --- a/runtime/Sources/Renderer/RenderCore.cpp +++ b/runtime/Sources/Renderer/RenderCore.cpp @@ -214,6 +214,7 @@ namespace mlx MLX_LOAD_FUNCTION(vkDestroyShaderModule); MLX_LOAD_FUNCTION(vkDeviceWaitIdle); MLX_LOAD_FUNCTION(vkEndCommandBuffer); + MLX_LOAD_FUNCTION(vkFreeCommandBuffers); MLX_LOAD_FUNCTION(vkGetDeviceQueue); MLX_LOAD_FUNCTION(vkGetImageSubresourceLayout); MLX_LOAD_FUNCTION(vkQueueSubmit); diff --git a/runtime/Sources/Renderer/Swapchain.cpp b/runtime/Sources/Renderer/Swapchain.cpp index b4b3117..b0b5616 100644 --- a/runtime/Sources/Renderer/Swapchain.cpp +++ b/runtime/Sources/Renderer/Swapchain.cpp @@ -102,6 +102,7 @@ namespace mlx VkFence fence = kvfCreateFence(RenderCore::Get().GetDevice()); kvfSubmitSingleTimeCommandBuffer(RenderCore::Get().GetDevice(), cmd, KVF_GRAPHICS_QUEUE, fence); kvfDestroyFence(RenderCore::Get().GetDevice(), fence); + kvfDestroyCommandBuffer(RenderCore::Get().GetDevice(), cmd); m_resize = false; DebugLog("Vulkan: swapchain created"); } diff --git a/third_party/kvf.h b/third_party/kvf.h index fe1c172..3aa5486 100755 --- a/third_party/kvf.h +++ b/third_party/kvf.h @@ -167,12 +167,13 @@ VkFramebuffer kvfCreateFramebuffer(VkDevice device, VkRenderPass renderpass, VkI VkExtent2D kvfGetFramebufferSize(VkFramebuffer buffer); void kvfDestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer); -VkCommandBuffer kvfCreateCommandBuffer(VkDevice device); -VkCommandBuffer kvfCreateCommandBufferLeveled(VkDevice device, VkCommandBufferLevel level); +VkCommandBuffer kvfCreateCommandBuffer(VkDevice device); // Uses internal command pool, not thread safe +VkCommandBuffer kvfCreateCommandBufferLeveled(VkDevice device, VkCommandBufferLevel level); // Same void kvfBeginCommandBuffer(VkCommandBuffer buffer, VkCommandBufferUsageFlags flags); void kvfEndCommandBuffer(VkCommandBuffer buffer); void kvfSubmitCommandBuffer(VkDevice device, VkCommandBuffer buffer, KvfQueueType queue, VkSemaphore signal, VkSemaphore wait, VkFence fence, VkPipelineStageFlags* stages); void kvfSubmitSingleTimeCommandBuffer(VkDevice device, VkCommandBuffer buffer, KvfQueueType queue, VkFence fence); +void kvfDestroyCommandBuffer(VkDevice device, VkCommandBuffer buffer); VkAttachmentDescription kvfBuildAttachmentDescription(KvfImageType type, VkFormat format, VkImageLayout initial, VkImageLayout final, bool clear, VkSampleCountFlagBits samples); #ifndef KVF_NO_KHR @@ -313,6 +314,7 @@ void kvfCheckVk(VkResult result); KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDestroyShaderModule); KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkDeviceWaitIdle); KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkEndCommandBuffer); + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkFreeCommandBuffers); KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetDeviceQueue); KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetImageSubresourceLayout); KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkQueueSubmit); @@ -2416,6 +2418,29 @@ void kvfSubmitSingleTimeCommandBuffer(VkDevice device, VkCommandBuffer buffer, K kvfWaitForFence(device, fence); } +void kvfDestroyCommandBuffer(VkDevice device, VkCommandBuffer buffer) +{ + if(buffer == VK_NULL_HANDLE) + return; + KVF_ASSERT(device != VK_NULL_HANDLE); + __KvfDevice* kvf_device = __kvfGetKvfDeviceFromVkDevice(device); + KVF_ASSERT(kvf_device != NULL); + + for(size_t i = 0; i < kvf_device->cmd_buffers_size; i++) + { + if(kvf_device->cmd_buffers[i] == buffer) + { + KVF_GET_DEVICE_FUNCTION(vkFreeCommandBuffers)(kvf_device->device, kvf_device->cmd_pool, 1, &buffer); + // Shift the elements to fill the gap + for(size_t j = i; j < kvf_device->cmd_buffers_size - 1; j++) + kvf_device->cmd_buffers[j] = kvf_device->cmd_buffers[j + 1]; + kvf_device->cmd_buffers--; + return; + } + } + KVF_ASSERT(false && "could not find command buffer in internal device"); +} + VkAttachmentDescription kvfBuildAttachmentDescription(KvfImageType type, VkFormat format, VkImageLayout initial, VkImageLayout final, bool clear, VkSampleCountFlagBits samples) { VkAttachmentDescription attachment = {};