From bd1dec04f29201f51fd240602459454b5a26bc4f Mon Sep 17 00:00:00 2001 From: DrSocalkwe3n Date: Wed, 27 Aug 2025 22:54:47 +0600 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BA=D0=B0=20=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=D0=B4=D0=B5=D1=80=D0=B0=20=D1=87=D0=B0=D0=BD=D0=BA?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 10 +-- Src/Client/Vulkan/Vulkan.cpp | 77 ++++++++++++------ Src/Client/Vulkan/VulkanRenderSession.cpp | 8 +- Src/Client/Vulkan/VulkanRenderSession.hpp | 52 ++++++++++-- assets/shaders/chunk/node.geom | 2 +- assets/shaders/chunk/node.geom.bin | Bin 2648 -> 2648 bytes assets/shaders/chunk/node.vert | 2 +- assets/shaders/chunk/node.vert.bin | Bin 2600 -> 2600 bytes assets/shaders/chunk/node_opaque.frag | 4 +- assets/shaders/chunk/node_opaque.frag.bin | Bin 6812 -> 6812 bytes assets/shaders/chunk/node_transparent.frag | 6 +- .../shaders/chunk/node_transparent.frag.bin | Bin 1304 -> 1448 bytes 12 files changed, 113 insertions(+), 48 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b1d21d..b0afd13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,11 +31,11 @@ project(LuaVox VERSION 0.0 DESCRIPTION "LuaVox Description") add_library(luavox_common INTERFACE) target_compile_features(luavox_common INTERFACE cxx_std_23) -if(CMAKE_BUILD_TYPE STREQUAL "Debug") - target_compile_options(luavox_common INTERFACE -fsanitize=address,undefined -fno-omit-frame-pointer -fno-sanitize-recover=all) - target_link_options(luavox_common INTERFACE -fsanitize=address,undefined) - set(ENV{ASAN_OPTIONS} detect_leaks=0) -endif() +# if(CMAKE_BUILD_TYPE STREQUAL "Debug") +# target_compile_options(luavox_common INTERFACE -fsanitize=address,undefined -fno-omit-frame-pointer -fno-sanitize-recover=all) +# target_link_options(luavox_common INTERFACE -fsanitize=address,undefined) +# set(ENV{ASAN_OPTIONS} detect_leaks=0) +# endif() if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") target_compile_options(luavox_common INTERFACE -fcoroutines) diff --git a/Src/Client/Vulkan/Vulkan.cpp b/Src/Client/Vulkan/Vulkan.cpp index a491183..85aaa85 100644 --- a/Src/Client/Vulkan/Vulkan.cpp +++ b/Src/Client/Vulkan/Vulkan.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -158,17 +159,35 @@ void Vulkan::run() NeedShutdown = false; Graphics.ThisThread = std::this_thread::get_id(); - VkSemaphoreCreateInfo semaphoreCreateInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0 }; - VkSemaphore SemaphoreImageAcquired, SemaphoreDrawComplete; + VkSemaphoreCreateInfo semaphoreCreateInfo = { + VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + nullptr, + 0 + }; - vkAssert(!vkCreateSemaphore(Graphics.Device, &semaphoreCreateInfo, NULL, &SemaphoreImageAcquired)); - vkAssert(!vkCreateSemaphore(Graphics.Device, &semaphoreCreateInfo, NULL, &SemaphoreDrawComplete)); + VkSemaphore SemaphoreImageAcquired[4], SemaphoreDrawComplete[4]; + int semNext = 0; + for(int iter = 0; iter < 4; iter++) { + vkAssert(!vkCreateSemaphore(Graphics.Device, &semaphoreCreateInfo, nullptr, &SemaphoreImageAcquired[iter])); + vkAssert(!vkCreateSemaphore(Graphics.Device, &semaphoreCreateInfo, nullptr, &SemaphoreDrawComplete[iter])); + } + + VkFence drawEndFence = VK_NULL_HANDLE; + + { + VkFenceCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .pNext = nullptr, + .flags = 0 + }; + + vkCreateFence(Graphics.Device, &info, nullptr, &drawEndFence); + } double prevTime = glfwGetTime(); while(!NeedShutdown) { - float dTime = glfwGetTime()-prevTime; prevTime += dTime; @@ -230,7 +249,8 @@ void Vulkan::run() glfwPollEvents(); VkResult err; - err = vkAcquireNextImageKHR(Graphics.Device, Graphics.Swapchain, 1000000000ULL/20, SemaphoreImageAcquired, (VkFence) 0, &Graphics.DrawBufferCurrent); + semNext = ++semNext % 4; + err = vkAcquireNextImageKHR(Graphics.Device, Graphics.Swapchain, 1000000000ULL/20, SemaphoreImageAcquired[semNext], (VkFence) 0, &Graphics.DrawBufferCurrent); GlobalTime gTime = glfwGetTime(); if (err == VK_ERROR_OUT_OF_DATE_KHR) @@ -529,19 +549,25 @@ void Vulkan::run() .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .pNext = nullptr, .waitSemaphoreCount = 1, - .pWaitSemaphores = &SemaphoreImageAcquired, + .pWaitSemaphores = &SemaphoreImageAcquired[semNext], .pWaitDstStageMask = &pipe_stage_flags, .commandBufferCount = 1, .pCommandBuffers = &Graphics.CommandBufferRender, .signalSemaphoreCount = 1, - .pSignalSemaphores = &SemaphoreDrawComplete + .pSignalSemaphores = &SemaphoreDrawComplete[semNext] }; - //Рисуем, когда получим картинку + // Отправляем команды рендера в очередь { auto lockQueue = Graphics.DeviceQueueGraphic.lock(); - vkAssert(!vkQueueSubmit(*lockQueue, 1, &submit_info, nullFence)); + vkAssert(!vkQueueSubmit(*lockQueue, 1, &submit_info, drawEndFence)); } + + // auto now = std::chrono::high_resolution_clock::now(); + // Насильно ожидаем завершения рендера кадра + vkWaitForFences(Graphics.Device, 1, &drawEndFence, true, -1); + vkResetFences(Graphics.Device, 1, &drawEndFence); + // LOG.debug() << (std::chrono::high_resolution_clock::now()-now).count(); } { @@ -550,13 +576,13 @@ void Vulkan::run() .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, .pNext = NULL, .waitSemaphoreCount = 1, - .pWaitSemaphores = &SemaphoreDrawComplete, + .pWaitSemaphores = &SemaphoreDrawComplete[semNext], .swapchainCount = 1, .pSwapchains = &Graphics.Swapchain, .pImageIndices = &Graphics.DrawBufferCurrent }; - // Завершаем картинку + // Передадим фрейм, когда рендер будет завершён { auto lockQueue = Graphics.DeviceQueueGraphic.lock(); err = vkQueuePresentKHR(*lockQueue, &present); @@ -580,20 +606,21 @@ void Vulkan::run() Game.Session->atFreeDrawTime(gTime, dTime); } - - // vkAssert(!vkQueueWaitIdle(Graphics.DeviceQueueGraphic)); - - { - // Эту хрень надо убрать - auto lockQueue = Graphics.DeviceQueueGraphic.lock(); - vkDeviceWaitIdle(Graphics.Device); - lockQueue.unlock(); - } Screen.State = DrawState::End; } - vkDestroySemaphore(Graphics.Device, SemaphoreImageAcquired, nullptr); - vkDestroySemaphore(Graphics.Device, SemaphoreDrawComplete, nullptr); + { + auto lockQueue = Graphics.DeviceQueueGraphic.lock(); + vkDeviceWaitIdle(Graphics.Device); + lockQueue.unlock(); + } + + for(int iter = 0; iter < 4; iter++) { + vkDestroySemaphore(Graphics.Device, SemaphoreImageAcquired[iter], nullptr); + vkDestroySemaphore(Graphics.Device, SemaphoreDrawComplete[iter], nullptr); + } + + vkDestroyFence(Graphics.Device, drawEndFence, nullptr); } void Vulkan::glfwCallbackError(int error, const char *description) @@ -777,8 +804,8 @@ void Vulkan::buildSwapchains() .imageColorSpace = Graphics.SurfaceColorSpace, .imageExtent = swapchainExtent, .imageArrayLayers = 1, - .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT - | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + // | VK_IMAGE_USAGE_TRANSFER_DST_BIT, .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, .queueFamilyIndexCount = 0, .pQueueFamilyIndices = nullptr, diff --git a/Src/Client/Vulkan/VulkanRenderSession.cpp b/Src/Client/Vulkan/VulkanRenderSession.cpp index 1419b9f..f253dfc 100644 --- a/Src/Client/Vulkan/VulkanRenderSession.cpp +++ b/Src/Client/Vulkan/VulkanRenderSession.cpp @@ -816,7 +816,7 @@ void VulkanRenderSession::init(Vulkan *instance) { .flags = 0, .depthTestEnable = true, .depthWriteEnable = true, - .depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL, + .depthCompareOp = VK_COMPARE_OP_LESS, .depthBoundsTestEnable = false, .stencilTestEnable = false, .front = VkStencilOpState @@ -1209,7 +1209,7 @@ void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuff Pos::GlobalChunk x64offset = X64Offset >> Pos::Object_t::BS_Bit >> 4; Pos::GlobalRegion x64offset_region = x64offset >> 2; - auto [voxelVertexs, nodeVertexs] = VKCTX->ThreadVertexObj.getChunksForRender(WorldId, Pos, 1, PCO.ProjView, x64offset_region); + auto [voxelVertexs, nodeVertexs] = VKCTX->ThreadVertexObj.getChunksForRender(WorldId, Pos, 2, PCO.ProjView, x64offset_region); size_t count = 0; @@ -1233,8 +1233,8 @@ void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuff vkCmdDraw(drawCmd, vertexCount, 1, offset, 0); } - TOS::Logger LOG = "VRS"; - LOG.debug() << "Node: drawCals: " << nodeVertexs.size() << " vertexs: " << count; + // TOS::Logger LOG = "VRS"; + // LOG.debug() << "Node: drawCals: " << nodeVertexs.size() << " vertexs: " << count; PCO.Model = orig; diff --git a/Src/Client/Vulkan/VulkanRenderSession.hpp b/Src/Client/Vulkan/VulkanRenderSession.hpp index da2dfa5..e4e083b 100644 --- a/Src/Client/Vulkan/VulkanRenderSession.hpp +++ b/Src/Client/Vulkan/VulkanRenderSession.hpp @@ -3,6 +3,7 @@ #include "Client/Abstract.hpp" #include "Common/Abstract.hpp" #include +#include #include #include #include @@ -15,6 +16,7 @@ #include "VertexPool.hpp" #include "glm/fwd.hpp" #include "../FrustumCull.h" +#include "glm/geometric.hpp" /* У движка есть один текстурный атлас VK_IMAGE_VIEW_TYPE_2D_ARRAY(RGBA_UINT) и к нему Storage с инфой о положении текстур @@ -184,10 +186,11 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent { std::vector, uint32_t>>, std::vector, uint32_t>> > getChunksForRender(WorldId_t worldId, Pos::Object pos, uint8_t distance, glm::mat4 projView, Pos::GlobalRegion x64offset) { - Pos::GlobalRegion center = pos >> Pos::Object_t::BS_Bit >> 4 >> 2; + Pos::GlobalChunk playerChunk = pos >> Pos::Object_t::BS_Bit >> 4; + Pos::GlobalRegion center = playerChunk >> 2; - std::vector, uint32_t>> vertexVoxels; - std::vector, uint32_t>> vertexNodes; + std::vector, uint32_t>> vertexVoxels; + std::vector, uint32_t>> vertexNodes; auto iterWorld = ChunkMesh.find(worldId); if(iterWorld == ChunkMesh.end()) @@ -220,17 +223,50 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent { continue; auto &chunk = iterRegion->second[index]; + + float distance; - if(chunk.VoxelPointer) - vertexVoxels.emplace_back(local+Pos::GlobalChunk(localPos), VertexPool_Voxels.map(chunk.VoxelPointer), chunk.VoxelPointer.VertexCount); - if(chunk.NodePointer) - vertexNodes.emplace_back(local+Pos::GlobalChunk(localPos), VertexPool_Nodes.map(chunk.NodePointer), chunk.NodePointer.VertexCount); + if(chunk.VoxelPointer || chunk.NodePointer) { + Pos::GlobalChunk cp = local+Pos::GlobalChunk(localPos)-playerChunk; + distance = cp.x*cp.x+cp.y*cp.y+cp.z*cp.z; + } + + if(chunk.VoxelPointer) { + vertexVoxels.emplace_back(distance, local+Pos::GlobalChunk(localPos), VertexPool_Voxels.map(chunk.VoxelPointer), chunk.VoxelPointer.VertexCount); + } + + if(chunk.NodePointer) { + vertexNodes.emplace_back(distance, local+Pos::GlobalChunk(localPos), VertexPool_Nodes.map(chunk.NodePointer), chunk.NodePointer.VertexCount); + } } } } } - return std::pair{vertexVoxels, vertexNodes}; + auto sortByDistance = [] + ( + const std::tuple, uint32_t>& a, + const std::tuple, uint32_t>& b + ) { + return std::get<0>(a) < std::get<0>(b); + }; + + std::sort(vertexVoxels.begin(), vertexVoxels.end(), sortByDistance); + std::sort(vertexNodes.begin(), vertexNodes.end(), sortByDistance); + + std::vector, uint32_t>> resVertexVoxels; + std::vector, uint32_t>> resVertexNodes; + + resVertexVoxels.reserve(vertexVoxels.size()); + resVertexNodes.reserve(vertexNodes.size()); + + for(const auto& [d, pos, ptr, count] : vertexVoxels) + resVertexVoxels.emplace_back(pos, ptr, count); + + for(const auto& [d, pos, ptr, count] : vertexNodes) + resVertexNodes.emplace_back(pos, ptr, count); + + return std::pair{resVertexVoxels, resVertexNodes}; } void join() { diff --git a/assets/shaders/chunk/node.geom b/assets/shaders/chunk/node.geom index fa2cb47..f9a3fff 100644 --- a/assets/shaders/chunk/node.geom +++ b/assets/shaders/chunk/node.geom @@ -1,4 +1,4 @@ -#version 450 +#version 460 layout (triangles) in; layout (triangle_strip, max_vertices = 3) out; diff --git a/assets/shaders/chunk/node.geom.bin b/assets/shaders/chunk/node.geom.bin index cc30b5c9f419c879cd891c8f851501f180142c0b..5839b65cf2d242d4353df9e2d6a4145bbd037b8c 100644 GIT binary patch delta 12 Ucmca1azkXo62>zdmu}_+04GcZ>;M1& delta 12 Ucmca1azkXo62?Otmu}_+04Ev+;s5{u diff --git a/assets/shaders/chunk/node.vert b/assets/shaders/chunk/node.vert index 75383b8..d75b827 100644 --- a/assets/shaders/chunk/node.vert +++ b/assets/shaders/chunk/node.vert @@ -1,4 +1,4 @@ -#version 450 +#version 460 layout(location = 0) in uvec3 Vertex; diff --git a/assets/shaders/chunk/node.vert.bin b/assets/shaders/chunk/node.vert.bin index e89b91fb1f75212d0446cc2b43f790afb3c6ed3e..c255cd65940b82be135ff4eacc8ccc1f0c7a6ffa 100644 GIT binary patch delta 12 TcmZ1>vO;7+4&#}Pxw|<5Aq)j1 delta 12 TcmZ1>vO;7+4&$MXxw|<5Ald~Q diff --git a/assets/shaders/chunk/node_opaque.frag b/assets/shaders/chunk/node_opaque.frag index 4465ed4..3300e4f 100644 --- a/assets/shaders/chunk/node_opaque.frag +++ b/assets/shaders/chunk/node_opaque.frag @@ -1,4 +1,6 @@ -#version 450 +#version 460 + +// layout(early_fragment_tests) in; layout(location = 0) in FragmentObj { vec3 GeoPos; // Реальная позиция в мире diff --git a/assets/shaders/chunk/node_opaque.frag.bin b/assets/shaders/chunk/node_opaque.frag.bin index bb2c2f5e88c96eb52ab9e72c2b5e8228c02d1ea7..780834d27fd89d5a19478523f154435a51ab4102 100644 GIT binary patch delta 12 TcmbPZI>&TE3*(uMt>RJuB2fhE delta 12 TcmbPZI>&TE3*(`Ut>RJuA|C|d diff --git a/assets/shaders/chunk/node_transparent.frag b/assets/shaders/chunk/node_transparent.frag index 5d241a3..81b14c2 100644 --- a/assets/shaders/chunk/node_transparent.frag +++ b/assets/shaders/chunk/node_transparent.frag @@ -1,4 +1,4 @@ -#version 450 +#version 460 layout(location = 0) in FragmentObj { vec3 GeoPos; // Реальная позиция в мире @@ -20,5 +20,5 @@ layout(set = 1, binding = 1) readonly buffer LightMapLayoutObj { } LightMapLayout; void main() { - Frame = vec4(1); -} \ No newline at end of file + Frame = vec4(Fragment.GeoPos, 1); +} diff --git a/assets/shaders/chunk/node_transparent.frag.bin b/assets/shaders/chunk/node_transparent.frag.bin index 8a5b3c56990b14cb0d51ed0b9504804541587e2d..6c6c733875e190360348104db0281a99dc1a2147 100644 GIT binary patch literal 1448 zcmZ9LOK;Oa6on^=)0Bq3C~YZ);1F0LRV)A@AwU%Zcj1yE9^1$yRxxtoC~*+o@dNom zY>+tL*ppb?==#3SoI7)8(x~@Zrdcy>vuPfhLUv8v)a16!nzcdrF+7>)qmw63AA{I3 z4GRRbEtDsVj-zBk;hJOP3s%ez@L)^gL-Z?lLm$MGcZfBmi# z7CEI&5N8+J+$?jP?|n8KN9iiZo>h#=~8uRP*k^W`3<>}{BMtSf@9^u z!FLCcgdF=J=8Yg7VR-}e0((!EbC3f|>`TeHwO#oLYq<}%wkIDPIk3dsA-QLIYs`(i zK$!6#Wty_5`f}zyDRW{LFNK8nrj+~#VL0fgc5QaC2-IRuYQQA@pQA&@XiUS}dBoIR29$bRN$JH{4Rg9cCN*qLQ{5F0S z7bMu{cT@$uU&up6erj}jPHZ3iCX3g3t{urMvs`1&Ar;kBw znT`d5*%m60MJH)KC2>Q#E8Umgkse9!Nq4jlTvyuB*OvV)lE7@3C{Ci`FpA$MquDH3 zR98io6!|nu#`!!ORr!w$+`5O$r=wyy_5q;~{yp%y%e#3x(RLH++phh~Nj9y9U%#uu zI;OCRvhqW@FxN5adtc5cX|alN=TF(sYB|q@3oIYq`23~jr*55R`L(oX(uWK6=5_owtwAJ00kEU6%Jl{6*vQW{EwN4|YRp%&%9EgaX%-67v=An~H&F@4oy^ z*?|-x&#cIE$G%p~lRYR{^4w`hwk0Lco$#42u_OJXZpp%fkNj_sb%Q;{!NGSMkc1d~ z_`CKhwLSZu*YUqd$s-vM=S) MbNc#M)jXH}1HU