From 23b94fabba9df0eebcb16c14b2b1064bf52cdcfe Mon Sep 17 00:00:00 2001 From: Ben Kyd Date: Sat, 23 Dec 2023 19:09:45 +0000 Subject: [PATCH] DynamicCPUTarget --- .vims | 150 ++++++++++++++----------------- res/shaders/lines_debug.frag | 3 +- res/shaders/lines_debug.frag.spv | Bin 512 -> 624 bytes res/shaders/lines_debug.vert | 5 +- res/shaders/lines_debug.vert.spv | Bin 1784 -> 1916 bytes src/graphics/device.cpp | 7 ++ src/graphics/device.hpp | 7 ++ src/graphics/image.cpp | 38 +++++++- src/graphics/image.hpp | 5 ++ src/graphics/rendertarget.cpp | 109 +++++++++++++++++++--- src/graphics/rendertarget.hpp | 36 ++++++-- src/graphics/vkrenderer.cpp | 4 +- src/inferno.cpp | 36 ++++---- src/inferno.hpp | 3 +- src/raytracing/renderer.cpp | 70 ++++++++------- src/raytracing/renderer.hpp | 6 +- 16 files changed, 312 insertions(+), 167 deletions(-) diff --git a/.vims b/.vims index 2d2ae9f..4e65bfb 100644 --- a/.vims +++ b/.vims @@ -14,7 +14,7 @@ else set shortmess=aoO endif badd +693 src/graphics/vulkan_tutorial.cpp -badd +316 src/inferno.cpp +badd +317 src/inferno.cpp badd +45 src/scene/mesh.hpp badd +75 src/scene/mesh.cpp badd +33 src/graphics/pipeline.cpp @@ -28,7 +28,7 @@ badd +13 src/graphics/swapchain.hpp badd +56 src/inferno.hpp badd +1 src/main.cpp badd +1 ~/dprog/active/inferno-hart/src/graphics/descriptor.cpp -badd +53 src/graphics/vkrenderer.hpp +badd +11 src/graphics/vkrenderer.hpp badd +42 src/renderer/renderer.hpp badd +28 src/scene/scene.cpp badd +173 src/graphics/buffer.cpp @@ -47,20 +47,20 @@ badd +43 src/gui/gui.hpp badd +130 src/window.cpp badd +111 src/thirdparty/imgui/imgui_impl_vulkan.cpp badd +66 ~/dprog/active/inferno-hart/src/thirdparty/imgui/imgui_impl_vulkan.h -badd +38 src/preview_renderer/renderer.hpp -badd +59 src/preview_renderer/renderer.cpp +badd +1 src/preview_renderer/renderer.hpp +badd +1 src/preview_renderer/renderer.cpp +badd +49 src/raytracing/renderer.cpp +badd +0 src/graphics/rendertarget.cpp +badd +1 src/graphics/rendertarget.hpp argglobal %argdel -edit src/inferno.cpp +edit src/raytracing/renderer.cpp let s:save_splitbelow = &splitbelow let s:save_splitright = &splitright set splitbelow splitright wincmd _ | wincmd | vsplit -wincmd _ | wincmd | -vsplit -2wincmd h -wincmd w +1wincmd h wincmd w wincmd _ | wincmd | split @@ -75,8 +75,58 @@ set winminheight=0 set winheight=1 set winminwidth=0 set winwidth=1 -wincmd = +exe 'vert 1resize ' . ((&columns * 120 + 132) / 265) +exe '2resize ' . ((&lines * 44 + 45) / 91) +exe 'vert 2resize ' . ((&columns * 144 + 132) / 265) +exe '3resize ' . ((&lines * 43 + 45) / 91) +exe 'vert 3resize ' . ((&columns * 144 + 132) / 265) argglobal +balt src/inferno.cpp +setlocal fdm=manual +setlocal fde=0 +setlocal fmr={{{,}}} +setlocal fdi=# +setlocal fdl=0 +setlocal fml=1 +setlocal fdn=20 +setlocal fen +silent! normal! zE +let &fdl = &fdl +let s:l = 93 - ((29 * winheight(0) + 44) / 88) +if s:l < 1 | let s:l = 1 | endif +keepjumps exe s:l +normal! zt +keepjumps 93 +normal! 0 +wincmd w +argglobal +if bufexists(fnamemodify("src/graphics/rendertarget.hpp", ":p")) | buffer src/graphics/rendertarget.hpp | else | edit src/graphics/rendertarget.hpp | endif +if &buftype ==# 'terminal' + silent file src/graphics/rendertarget.hpp +endif +balt src/graphics/vkrenderer.hpp +setlocal fdm=manual +setlocal fde=0 +setlocal fmr={{{,}}} +setlocal fdi=# +setlocal fdl=0 +setlocal fml=1 +setlocal fdn=20 +setlocal fen +silent! normal! zE +let &fdl = &fdl +let s:l = 1 - ((0 * winheight(0) + 22) / 44) +if s:l < 1 | let s:l = 1 | endif +keepjumps exe s:l +normal! zt +keepjumps 1 +normal! 0 +wincmd w +argglobal +if bufexists(fnamemodify("src/graphics/rendertarget.cpp", ":p")) | buffer src/graphics/rendertarget.cpp | else | edit src/graphics/rendertarget.cpp | endif +if &buftype ==# 'terminal' + silent file src/graphics/rendertarget.cpp +endif balt src/preview_renderer/renderer.hpp setlocal fdm=manual setlocal fde=0 @@ -88,83 +138,19 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 317 - ((60 * winheight(0) + 43) / 86) -if s:l < 1 | let s:l = 1 | endif -keepjumps exe s:l -normal! zt -keepjumps 317 -normal! 050| -wincmd w -argglobal -if bufexists(fnamemodify("src/preview_renderer/renderer.cpp", ":p")) | buffer src/preview_renderer/renderer.cpp | else | edit src/preview_renderer/renderer.cpp | endif -if &buftype ==# 'terminal' - silent file src/preview_renderer/renderer.cpp -endif -balt src/graphics/vkrenderer.cpp -setlocal fdm=manual -setlocal fde=0 -setlocal fmr={{{,}}} -setlocal fdi=# -setlocal fdl=0 -setlocal fml=1 -setlocal fdn=20 -setlocal fen -silent! normal! zE -let &fdl = &fdl -let s:l = 59 - ((56 * winheight(0) + 43) / 86) -if s:l < 1 | let s:l = 1 | endif -keepjumps exe s:l -normal! zt -keepjumps 59 -normal! 015| -wincmd w -argglobal -if bufexists(fnamemodify("src/graphics/vkrenderer.hpp", ":p")) | buffer src/graphics/vkrenderer.hpp | else | edit src/graphics/vkrenderer.hpp | endif -if &buftype ==# 'terminal' - silent file src/graphics/vkrenderer.hpp -endif -balt src/graphics/vkrenderer.cpp -setlocal fdm=manual -setlocal fde=0 -setlocal fmr={{{,}}} -setlocal fdi=# -setlocal fdl=0 -setlocal fml=1 -setlocal fdn=20 -setlocal fen -silent! normal! zE -let &fdl = &fdl -let s:l = 10 - ((4 * winheight(0) + 24) / 49) -if s:l < 1 | let s:l = 1 | endif -keepjumps exe s:l -normal! zt -keepjumps 10 -normal! 0 -wincmd w -argglobal -if bufexists(fnamemodify("src/preview_renderer/renderer.hpp", ":p")) | buffer src/preview_renderer/renderer.hpp | else | edit src/preview_renderer/renderer.hpp | endif -if &buftype ==# 'terminal' - silent file src/preview_renderer/renderer.hpp -endif -balt src/graphics/pipeline.hpp -setlocal fdm=manual -setlocal fde=0 -setlocal fmr={{{,}}} -setlocal fdi=# -setlocal fdl=0 -setlocal fml=1 -setlocal fdn=20 -setlocal fen -silent! normal! zE -let &fdl = &fdl -let s:l = 1 - ((0 * winheight(0) + 18) / 36) +let s:l = 1 - ((0 * winheight(0) + 21) / 43) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt keepjumps 1 -normal! 08| +normal! 0 wincmd w -wincmd = +2wincmd w +exe 'vert 1resize ' . ((&columns * 120 + 132) / 265) +exe '2resize ' . ((&lines * 44 + 45) / 91) +exe 'vert 2resize ' . ((&columns * 144 + 132) / 265) +exe '3resize ' . ((&lines * 43 + 45) / 91) +exe 'vert 3resize ' . ((&columns * 144 + 132) / 265) tabnext 1 if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal' silent exe 'bwipe ' . s:wipebuf diff --git a/res/shaders/lines_debug.frag b/res/shaders/lines_debug.frag index 87aae54..e30f935 100644 --- a/res/shaders/lines_debug.frag +++ b/res/shaders/lines_debug.frag @@ -1,11 +1,12 @@ #version 450 core layout (location = 0) in vec3 vFragPos; +layout (location = 1) in vec3 vColour; layout(location = 0) out vec4 outColour; void main() { - outColour = vec4(1., 0., 0., 1.0); + outColour = vec4(vColour, 1.0); } diff --git a/res/shaders/lines_debug.frag.spv b/res/shaders/lines_debug.frag.spv index c0cc3de1587105ef73549951cdf4379813bb3c88..0b3d19d43c4d0463cab39ccb632f200ee379b08d 100644 GIT binary patch delta 300 zcmX|+u?oUK5JdNq(->pac!Gr>LP~2v5Vf!nJ1xb^QcweeRu*Y3L%zxnvG)fAXTn8} z$L`L~(rw+^>liDL5aF7qsGo1~A#~X>`%vm&qx)U8RC!vUePD zKL84>kT$um_Uj(HI+QAK!4PwRN*DF1otdUK!c1=yh@^{hZ}OLlA2V#33IP*aTuyh( mYAAoLZ8d(i^hH*4P&eY?h;#t+^mEUf=XfjsnY%CEH32_`-W2Nq delta 188 zcmeys(!j#Y%%sfDz`)4B&A`hbFp<|(oSlJ%fdPzj6EpLGOa@LM=ARhb$;=9*ekwEa zPu69OPSpmgVFSu=fs`;b*u(hTU_Jwb4g)(7GBEG}F-Q$a9E3q^aiCsaAPv&b48#gR iJ|B=~1Y(f5HI&ak`68pTh#gQ3$PFNq{sPrl05JfcOb-MA diff --git a/res/shaders/lines_debug.vert b/res/shaders/lines_debug.vert index a11cd66..a7db619 100644 --- a/res/shaders/lines_debug.vert +++ b/res/shaders/lines_debug.vert @@ -1,6 +1,7 @@ #version 450 core layout (location = 0) in vec3 position; +layout (location = 1) in vec3 colour; layout (binding = 0) uniform SceneUniformBufferObject { mat4 proj; @@ -11,9 +12,11 @@ layout (binding = 0) uniform SceneUniformBufferObject { // mat4 model; -layout (location = 1) out vec3 vFragPos; +layout (location = 0) out vec3 vFragPos; +layout (location = 1) out vec3 vColour; void main() { vFragPos = vec3(vec4(position, 1.0)); + vColour = colour; gl_Position = ubo.proj * ubo.view * vec4(position, 1.0); } diff --git a/res/shaders/lines_debug.vert.spv b/res/shaders/lines_debug.vert.spv index c03b0a9a2c04bf30e3669cd4fb30e96898e3a1ec..681070526c95b2a33ce8a592381794ead3ca142c 100644 GIT binary patch literal 1916 zcmZ9NT~8BH5QdMG78C&y5mdxh#4i*W2E9)Dp zFeY3nCBm6>=Td!Ge~S zz-tD6=r!AZ?6nfV@4*`_@cgh9^x8#2S&U-cvMZ;x`yb-H!=0$Baze`KSvpbIPy8r7 zA90+mzZnHlFBW4sJ!dO3WmnvF`45BUju(IS;>7z(u1b!hY|(7ParTywLj;`Ug>b{I+*+;Kkef zM;aEKidb-1oj5vTH;i-jeeX*V<2=2v*Y(<~10Ltdur*~Xxh3rV$kjC;?sP%I!sdR9 zHuJ=$7JlyC>@8(uo-E>6hQSA8H;l7^aUR3a!MN|bJmiD7CB*tJr}qCj7)}n;_1N8o zLL7CAaoBKQODqoTbR4ydaoEJ2NGuNQbX-YTF%Fx!UlNN0vp9OiPcG)Vr2VFZWp*ty z-LzQnYKkET`ekVq?N!OF;>nARzbbn)*TJ9XHg|1){=2Pz{MdG1%d*KeE^+SU75OKm zfpJfkkGDZSi|1{Sb4IMI+N%;4`LM4^@XyPh*G@jL1!>&7)xd|)2XBoU_^E@PeeYy- zszVa>^ArsU<^)LGOHRut;o62@HdQwN(n0mFYg*NL+__oP!7{}b(;lUh&p z5{RQF3;d4|-p31}+{t+f^ZqE5IZWo5wgJX_hDQzKP30K*ca({G7bV2Q$IrbPe_A?z zmSLBqgBA163YLH73UAhw`FHF+|@s&@N=jac!>G`tXXcpr6S2 zseEJN|997IPL@n(=0E?L*_~akG`co!%!rvX)8?Vc*PIy@VuY15U9IibHo9qRU`$n_VX>`+Xk!?gS zwvCocY%_Iz3vZ&pb8$23wTgs5jAFmQ1X<7ihh*PP^+;*Ut78=scGd zJB%7THu-Fm)P99q9^lx-d`j7jXME0?;Vw>h-FNMfoIJ+a6nh)F&O6sl_u{4<#+VYZ zUK9;uf#$(nSnN8K-fi00eu~{eJ2`&SJ2R zF%O@-UlN}O=JPmfD4$x)wIYqMyuX^eW?n3KtIDAU_C;A`=}@w$eCpy859RY;=leYy z_}rzBPs$#VkVhQf-`Bc)YE4UwIeAI_8ChW5(}I2%r9%k|KK_z~n#=MpNy7(Qk;T3G z8pIIxc}1E%5oaIx`FA1jb5(vQp)P&!{rg*ze@#Ah*%y66X|STuXH^(;3nlcyXWltB zmfaOLdA`q0*&`D2`LMB1dOgui!=)z+{Eras|G7|RdRD?bKMG|Ivja?Oi1A+G(ZloR z1{n2sREd7)CFH{=&b@g4ylmnuk6n-rR;;@)!1B6$op?h=Z_60?#9!znybX36sLLRuE(Ouca8Li6)WBIe(lMPlp%l!dX noY96b^5GL_MnBY>`8|-(9}auwF1IASGtR}i@!|bdr>ByCZD)P~ diff --git a/src/graphics/device.cpp b/src/graphics/device.cpp index 21c2354..5811a92 100644 --- a/src/graphics/device.cpp +++ b/src/graphics/device.cpp @@ -3,6 +3,8 @@ #include "graphics.hpp" #include "window.hpp" +#include "vkrenderer.hpp" + #include "yolo/yolo.hpp" #include @@ -219,6 +221,11 @@ void device_cleanup(GraphicsDevice* device) vkDestroyInstance(device->VulkanInstance, nullptr); } +void device_add_context(GraphicsDevice* device, VulkanRenderer* context) +{ + device->RenderContext = context; +} + void device_create_vulkan_instance(GraphicsDevice* device) { diff --git a/src/graphics/device.hpp b/src/graphics/device.hpp index f0c9c71..26901ea 100644 --- a/src/graphics/device.hpp +++ b/src/graphics/device.hpp @@ -18,6 +18,8 @@ const std::vector DEVICE_EXTENSIONS = { VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, }; +struct VulkanRenderer; + typedef struct GraphicsDevice { VkInstance VulkanInstance; VkDebugUtilsMessengerEXT VulkanDebugMessenger; @@ -28,6 +30,9 @@ typedef struct GraphicsDevice { VkQueue VulkanPresentQueue; VkCommandPool VulkanCommandPool; + // FIXME: There is no way in hell this should be here + VulkanRenderer* RenderContext; + glm::ivec2 SurfaceSize; bool Resized = false; } GraphicsDevice; @@ -46,6 +51,8 @@ struct QueueFamilyIndices { GraphicsDevice* device_create(); void device_cleanup(GraphicsDevice* device); +void device_add_context(GraphicsDevice* device, VulkanRenderer* context); + void device_create_vulkan_instance(GraphicsDevice* device); void device_vulkan_debugger(GraphicsDevice* device); void device_create_vulkan_physical_device(GraphicsDevice* device); diff --git a/src/graphics/image.cpp b/src/graphics/image.cpp index 27fc3ae..7356ebb 100644 --- a/src/graphics/image.cpp +++ b/src/graphics/image.cpp @@ -1,9 +1,12 @@ #include "graphics/image.hpp" #include "device.hpp" +#include "vkrenderer.hpp" #include "yolo/yolo.hpp" +#include + namespace inferno::graphics { void create_image(GraphicsDevice* device, uint32_t width, uint32_t height, @@ -69,6 +72,36 @@ VkImageView create_image_view(GraphicsDevice* device, VkImage image, VkFormat fo return imageView; } +void transition_image_layout(GraphicsDevice* device, VkImage image, VkFormat format, + VkImageLayout oldLayout, VkImageLayout newLayout) +{ + // This all goes in a standard callback to go to the renderer as a one time command + // buffer execution + std::function callback + = [&](VulkanRenderer* renderer, VkCommandBuffer* commandBuffer) { + VkImageMemoryBarrier barrier {}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.oldLayout = oldLayout; + barrier.newLayout = newLayout; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = image; + barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + barrier.subresourceRange.baseMipLevel = 0; + barrier.subresourceRange.levelCount = 1; + barrier.subresourceRange.baseArrayLayer = 0; + barrier.subresourceRange.layerCount = 1; + barrier.srcAccessMask = 0; // TODO + barrier.dstAccessMask = 0; // TODO + + vkCmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, + &barrier); + }; + + graphics::renderer_submit_now(device->RenderContext, callback); +} + VkFormat find_format(GraphicsDevice* device, const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features) { @@ -92,10 +125,9 @@ VkFormat find_depth_format(GraphicsDevice* device) { return VK_FORMAT_D32_SFLOAT_S8_UINT; return find_format(device, - { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT }, + { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT }, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); - } - } diff --git a/src/graphics/image.hpp b/src/graphics/image.hpp index 1018bfe..32dfe56 100644 --- a/src/graphics/image.hpp +++ b/src/graphics/image.hpp @@ -13,6 +13,11 @@ void create_image(GraphicsDevice* device, uint32_t width, uint32_t height, VkImageView create_image_view(GraphicsDevice* device, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags); +void transition_image_layout(GraphicsDevice* device, VkImage image, VkFormat format, + VkImageLayout oldLayout, VkImageLayout newLayout); +// void copy_buffer_to_image(GraphicsDevice* device, VkBuffer buffer, VkImage image, +// uint32_t width, uint32_t height); + VkFormat find_format(GraphicsDevice* device, const std::vector& candidates, VkImageTiling tiling, VkFormatFeatureFlags features); VkFormat find_depth_format(GraphicsDevice* device); diff --git a/src/graphics/rendertarget.cpp b/src/graphics/rendertarget.cpp index 4a64369..d445715 100644 --- a/src/graphics/rendertarget.cpp +++ b/src/graphics/rendertarget.cpp @@ -1,10 +1,12 @@ #include "rendertarget.hpp" +#include "buffer.hpp" #include "device.hpp" #include "graphics.hpp" #include "image.hpp" #include "yolo/yolo.hpp" +#include namespace inferno::graphics { @@ -13,8 +15,8 @@ RenderTarget* rendertarget_create( { RenderTarget* target = new RenderTarget(); target->Device = device; - target->Format = format; target->Extent = extent; + target->Format = format; VkSamplerCreateInfo samplerInfo {}; samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; @@ -39,16 +41,18 @@ RenderTarget* rendertarget_create( yolo::error("failed to create texture sampler!"); } + target->TargetImage = new ImageAttachment(); + create_image(device, extent.width, extent.height, format, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->Image, target->Memory); + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->TargetImage->Image, + target->TargetImage->Memory); + target->TargetImage->ImageView = create_image_view( + device, target->TargetImage->Image, format, VK_IMAGE_ASPECT_COLOR_BIT); - target->ImageView - = create_image_view(device, target->Image, format, VK_IMAGE_ASPECT_COLOR_BIT); - - target->DescriptorSet = ImGui_ImplVulkan_AddTexture( - target->Sampler, target->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + target->DescriptorSet = ImGui_ImplVulkan_AddTexture(target->Sampler, + target->TargetImage->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); if (depth) { rendertarget_create_depth(target); @@ -59,9 +63,10 @@ RenderTarget* rendertarget_create( void rendertarget_cleanup(RenderTarget* target) { - vkDestroyImageView(target->Device->VulkanDevice, target->ImageView, nullptr); - vkDestroyImage(target->Device->VulkanDevice, target->Image, nullptr); - vkFreeMemory(target->Device->VulkanDevice, target->Memory, nullptr); + vkDestroyImageView( + target->Device->VulkanDevice, target->TargetImage->ImageView, nullptr); + vkDestroyImage(target->Device->VulkanDevice, target->TargetImage->Image, nullptr); + vkFreeMemory(target->Device->VulkanDevice, target->TargetImage->Memory, nullptr); rendertarget_destroy_depth(target); @@ -80,8 +85,8 @@ void rendertarget_create_depth(RenderTarget* target) VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->TargetDepth->Image, target->TargetDepth->Memory); - target->TargetDepth->ImageView = create_image_view(target->Device, target->TargetDepth->Image, - depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT); + target->TargetDepth->ImageView = create_image_view(target->Device, + target->TargetDepth->Image, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT); } void rendertarget_destroy_depth(RenderTarget* target) @@ -111,4 +116,84 @@ void rendertarget_recreate(RenderTarget* target, VkExtent2D extent, VkFormat for // rendertarget_create_depth(target); } +DynamicCPUTarget* dynamic_rendertarget_create( + GraphicsDevice* device, VkExtent2D extent, VkFormat format) +{ + DynamicCPUTarget* target = new DynamicCPUTarget(); + target->Format = format; + target->Extent = extent; + target->Device = device; + + VkSamplerCreateInfo samplerInfo {}; + samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerInfo.magFilter = VK_FILTER_LINEAR; + samplerInfo.minFilter = VK_FILTER_LINEAR; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + samplerInfo.anisotropyEnable = VK_FALSE; + samplerInfo.maxAnisotropy = 1.0f; + samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK; + samplerInfo.unnormalizedCoordinates = VK_FALSE; + samplerInfo.compareEnable = VK_FALSE; + samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS; + samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + samplerInfo.mipLodBias = 0.0f; + samplerInfo.minLod = 0.0f; + samplerInfo.maxLod = 0.0f; + + if (vkCreateSampler(device->VulkanDevice, &samplerInfo, nullptr, &target->Sampler) + != VK_SUCCESS) { + yolo::error("failed to create texture sampler!"); + } + + // Create VkImage with Undefined + create_image(device, extent.width, extent.height, format, VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, target->Image, target->Memory); + + target->ImageView + = create_image_view(device, target->Image, format, VK_IMAGE_ASPECT_COLOR_BIT); + + target->DescriptorSet = ImGui_ImplVulkan_AddTexture( + target->Sampler, target->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + // NOTE: This assumes that the image is in the UNDEFINED LAYOUT + // And also assumes that the cpu layout is floating point (4 bytes) and the image is + // RGBA + target->StagingBuffer = generic_buffer_create(device, 0, + extent.width * extent.height * 4, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); +} + +void dynamic_rendertarget_cleanup(DynamicCPUTarget* target) { } + +// TODO: We should do this with a double buffer but whatever +void dynamic_rendertarget_update(DynamicCPUTarget* target, void* data, VkExtent2D size) +{ + if (size.width != target->Extent.width || size.height != target->Extent.height) { + yolo::error("Dynamic CPU Target size mismatch"); + return; + } + + // Traansition to General + transition_image_layout(target->Device, target->Image, target->Format, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); + + // Sync with Fence + + // Map Memory + void* mappedData; + vkMapMemory(target->Device->VulkanDevice, target->StagingBuffer->DeviceData, 0, + target->StagingBuffer->Size, 0, &mappedData); + memcpy(mappedData, data, target->StagingBuffer->Size); + vkUnmapMemory(target->Device->VulkanDevice, target->StagingBuffer->DeviceData); + + // Sync with Fence + + // Transition to whatever we need + transition_image_layout(target->Device, target->Image, target->Format, + VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); +} + } diff --git a/src/graphics/rendertarget.hpp b/src/graphics/rendertarget.hpp index f0e3c29..c3f45ad 100644 --- a/src/graphics/rendertarget.hpp +++ b/src/graphics/rendertarget.hpp @@ -3,14 +3,16 @@ #include "graphics.hpp" #include +#include namespace inferno::graphics { struct GraphicsDevice; +struct GenBuffer; // TODO: Should probably be "ImageAttachment" and then the // target will abstract which sort of attachment it is -typedef struct DepthAttachment { +typedef struct ImageAttachment { VkImage Image; VkDeviceMemory Memory; VkImageView ImageView; @@ -19,14 +21,11 @@ typedef struct DepthAttachment { // TODO: What about the present mode? typedef struct RenderTarget { - VkImage Image; - VkDeviceMemory Memory; - VkImageView ImageView; + ImageAttachment* TargetImage = nullptr; + ImageAttachment* TargetDepth = nullptr; - VkFormat Format; VkExtent2D Extent; - - DepthAttachment* TargetDepth = nullptr; + VkFormat Format; // NOTE: This is for the ImGui renderer.. it needs a descriptor set of a sampler of an // image @@ -45,4 +44,27 @@ void rendertarget_destroy_depth(RenderTarget* target); void rendertarget_recreate(RenderTarget* target, VkExtent2D extent, VkFormat format); +typedef struct DynamicCPUTarget { + VkImage Image; + VkDeviceMemory Memory; + VkImageView ImageView; + + VkFormat Format; + VkExtent2D Extent; + + GenBuffer* StagingBuffer; + + // This is being given to ImGUI so we need a Sampler and a DescriptorSet + VkSampler Sampler; + VkDescriptorSet DescriptorSet; + + GraphicsDevice* Device; +} DynamicCPUTarget; + +DynamicCPUTarget* dynamic_rendertarget_create( + GraphicsDevice* device, VkExtent2D extent, VkFormat format); +void dynamic_rendertarget_cleanup(DynamicCPUTarget* target); + +void dynamic_rendertarget_update(DynamicCPUTarget* target, void* data, VkExtent2D size); + } diff --git a/src/graphics/vkrenderer.cpp b/src/graphics/vkrenderer.cpp index 0c6ad02..44cb571 100644 --- a/src/graphics/vkrenderer.cpp +++ b/src/graphics/vkrenderer.cpp @@ -205,7 +205,7 @@ void renderer_begin_pass( imageMemoryBarrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; imageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; imageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - imageMemoryBarrier.image = target->Image; + imageMemoryBarrier.image = target->TargetImage->Image; imageMemoryBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; imageMemoryBarrier.subresourceRange.baseMipLevel = 0; imageMemoryBarrier.subresourceRange.layerCount = 1; @@ -223,7 +223,7 @@ void renderer_begin_pass( VkClearValue clearColor = { { { 0.0f, 0.0f, 0.0f, 1.0f } } }; VkRenderingAttachmentInfo attachmentInfo {}; attachmentInfo.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR; - attachmentInfo.imageView = target->ImageView; + attachmentInfo.imageView = target->TargetImage->ImageView; attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR; attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE; diff --git a/src/inferno.cpp b/src/inferno.cpp index e3e282e..6747c76 100644 --- a/src/inferno.cpp +++ b/src/inferno.cpp @@ -97,6 +97,8 @@ InfernoApp* inferno_create() graphics::window_create("Inferno v" INFERNO_VERSION, 1920, 1080); app->Device = graphics::device_create(); app->Renderer = graphics::renderer_create(app->Device); + // FIXME: FUCKING CHANGE THIS + graphics::device_add_context(app->Device, app->Renderer); graphics::renderer_configure_gui(app->Renderer); graphics::renderer_configure_command_buffer(app->Renderer); @@ -131,10 +133,8 @@ InfernoApp* inferno_create() scene::scene_object_load(lucy, "res/lucy.obj"); scene::scene_object_optimize(lucy); scene::scene_add_object(app->Scene, lucy); - // app->PreviewRenderer = graphics::preview_create(); - // graphics::preview_set_viewport(app->PreviewRenderer, app->Scene->Camera); - // app->RayRenderer = graphics::rayr_create(app->Scene); - // graphics::rayr_set_viewport(app->RayRenderer, app->Scene->Camera); + + app->RayRenderer = graphics::rayr_create(app->Renderer, app->Scene); return app; } @@ -248,26 +248,20 @@ void inferno_end(InfernoApp* app) int inferno_run(InfernoApp* app) { - - // we weant to outline Lucy in lines graphics::renderer_submit_repeat( app->Renderer, [&](graphics::VulkanRenderer* renderer, VkCommandBuffer* commandBuffer) { const auto lucy = app->Scene->Objects[0]; for (auto& mesh : scene::scene_object_get_meshs(lucy)) { for (int i = 0; i < mesh->Indicies.size() - 1; i += 3) { - graphics::debug_draw_line( - mesh->Verticies[mesh->Indicies[i]].Position, - mesh->Verticies[mesh->Indicies[i + 1]].Position, - { 1, 0, 0 }); + graphics::debug_draw_line(mesh->Verticies[mesh->Indicies[i]].Position, + mesh->Verticies[mesh->Indicies[i + 1]].Position, { 0, 0, 1 }); graphics::debug_draw_line( mesh->Verticies[mesh->Indicies[i + 1]].Position, - mesh->Verticies[mesh->Indicies[i + 2]].Position, - { 1, 0, 0 }); + mesh->Verticies[mesh->Indicies[i + 2]].Position, { 0, 0, 1 }); graphics::debug_draw_line( mesh->Verticies[mesh->Indicies[i + 2]].Position, - mesh->Verticies[mesh->Indicies[i]].Position, - { 1, 0, 0 }); + mesh->Verticies[mesh->Indicies[i]].Position, { 0, 0, 1 }); } } }, @@ -358,13 +352,13 @@ int inferno_run(InfernoApp* app) } if (ImGui::Begin("Render")) { - // graphics::rayr_draw(app->RayRenderer); + graphics::rayr_prepare(app->RayRenderer); + graphics::rayr_draw(app->RayRenderer); - // ImTextureID texture - // = (ImTextureID)graphics::rayr_get_rendered_texture(app->RayRenderer); - // ImGui::Image(texture, { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y - // }, - // ImVec2(0, 1), ImVec2(1, 0)); + ImTextureID texture + = (ImTextureID)graphics::rayr_get_target(app->RayRenderer)->DescriptorSet; + ImGui::Image(texture, { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y }, + ImVec2(0, 1), ImVec2(1, 0)); ImGui::End(); } @@ -377,4 +371,4 @@ int inferno_run(InfernoApp* app) return 1; } -} // namespace infern +} // name diff --git a/src/inferno.hpp b/src/inferno.hpp index c58541d..6310bd6 100644 --- a/src/inferno.hpp +++ b/src/inferno.hpp @@ -6,6 +6,7 @@ #include "scene/scene.hpp" // #include "scene/camera.hpp" #include "preview/renderer.hpp" +#include "raytracing/renderer.hpp" #include @@ -59,7 +60,7 @@ typedef struct InfernoApp { graphics::VulkanRenderer* Renderer; graphics::PreviewRenderer* PreviewRenderer; - // graphics::RayRenderer* RayRenderer; + graphics::RayRenderer* RayRenderer; InfernoTimer* MainTimer; uint64_t FrameCount; diff --git a/src/raytracing/renderer.cpp b/src/raytracing/renderer.cpp index 79e0ae0..b926bdc 100644 --- a/src/raytracing/renderer.cpp +++ b/src/raytracing/renderer.cpp @@ -32,9 +32,7 @@ RayRenderer* rayr_create(VulkanRenderer* renderer, scene::Scene* scene) ray->Renderer = renderer; auto camera = scene::scene_get_camera(scene); - glm::ivec2 viewport = camera_ray_get_viewport(camera); - ray->Viewport = { .extent - = { static_cast(viewport.x), static_cast(viewport.y) } }; + rayr_set_viewport(ray, camera); ray->RenderData = new glm::fvec4[ray->Viewport.extent.width * ray->Viewport.extent.height]; @@ -44,7 +42,8 @@ RayRenderer* rayr_create(VulkanRenderer* renderer, scene::Scene* scene) // TODO: We need to upload RenderData to the GPU / maybe do a quad pass ? I think // ImGui handels that - // ray->RayRenderTarget = graphics::rendertarget_create() + ray->RayRenderTarget = graphics::dynamic_rendertarget_create( + renderer->Device, ray->Viewport.extent, VK_FORMAT_R32G32B32A32_SFLOAT); return ray; } @@ -63,9 +62,9 @@ void rayr_set_viewport(RayRenderer* renderer, Camera* camera) renderer->HasViewportChanged = true; } -GLuint rayr_get_rendered_texture(RayRenderer* renderer) +DynamicCPUTarget* rayr_get_target(RayRenderer* renderer) { - // return renderer->RenderTargetTexture; + return renderer->RayRenderTarget; } glm::fvec4* rayr_get_render_data(RayRenderer* renderer) { return renderer->RenderData; } @@ -94,39 +93,42 @@ void rayr_draw(RayRenderer* renderer) rays::ReferencedRayField startRays = rays::generate_initial_rays(scene::scene_get_camera(renderer->Scene), true); - // debug_draw_line({ 0, 0, 0 }, { 0, 0, 1 }, { 1, 0, 0 }); - #pragma omp parallel for for (int x = 0; x < renderer->Viewport.extent.width; x++) { for (int y = 0; y < renderer->Viewport.extent.height; y++) { - rays::Ray* ray = startRays.Field[x * renderer->Viewport.extent.height + y]; - rays::HitInfo* closest_hit = nullptr; - - for (auto& obj : scene::scene_get_renderables(renderer->Scene)) { - rays::HitInfo* hit = rays::object_ray_collide(obj, ray); - if (hit->Did) { - if (closest_hit == nullptr) { - closest_hit = hit; - } else { - bool is_closer = hit->Distance < closest_hit->Distance; - if (is_closer) { - delete closest_hit; - closest_hit = hit; - } else { - delete hit; - } - } - } - if (hit->Did) { - glm::vec3 hit_distance = glm::vec3 { hit->Distance }; - hit_distance /= 10; - renderer->RenderData[y * renderer->Viewport.extent.width + x] - = { hit_distance, 1.0 }; - } - delete hit; - } + renderer->RenderData[y * renderer->Viewport.extent.width + x] + = { 0.0f, 0.0f, 0.0f, 1.0f }; + // rays::Ray* ray = startRays.Field[x * renderer->Viewport.extent.height + y]; + // rays::HitInfo* closest_hit = nullptr; + // + // for (auto& obj : scene::scene_get_renderables(renderer->Scene)) { + // rays::HitInfo* hit = rays::object_ray_collide(obj, ray); + // if (hit->Did) { + // if (closest_hit == nullptr) { + // closest_hit = hit; + // } else { + // bool is_closer = hit->Distance < closest_hit->Distance; + // if (is_closer) { + // delete closest_hit; + // closest_hit = hit; + // } else { + // delete hit; + // } + // } + // } + // if (hit->Did) { + // glm::vec3 hit_distance = glm::vec3 { hit->Distance }; + // hit_distance /= 10; + // renderer->RenderData[y * renderer->Viewport.extent.width + x] + // = { hit_distance, 1.0 }; + // } + // delete hit; + // } } } + + graphics::dynamic_rendertarget_update(renderer->RayRenderTarget, + (void*)renderer->RenderData, renderer->Viewport.extent); } // // void RayRenderer::computeHit(HitInfo* info) diff --git a/src/raytracing/renderer.hpp b/src/raytracing/renderer.hpp index 764dba0..15ba33b 100644 --- a/src/raytracing/renderer.hpp +++ b/src/raytracing/renderer.hpp @@ -14,7 +14,7 @@ namespace inferno::scene { namespace inferno::graphics { class VulkanRenderer; -class RenderTarget; +class DynamicCPUTarget; class Camera; class HitInfo; @@ -27,7 +27,7 @@ typedef struct RayRenderer { // TODO: Can this be direct to GPU? // NOTE: Probably not glm::fvec4* RenderData = nullptr; - RenderTarget* RayRenderTarget; + DynamicCPUTarget* RayRenderTarget; scene::Scene* Scene = nullptr; @@ -42,7 +42,7 @@ void rayr_cleanup(RayRenderer* renderer); void rayr_draw_ui(RayRenderer* renderer); void rayr_set_viewport(RayRenderer* renderer, Camera* camera); - // rayr_get_rendered_texture(RayRenderer* renderer); +DynamicCPUTarget* rayr_get_target(RayRenderer* renderer); glm::fvec4* rayr_get_render_data(RayRenderer* renderer); void rayr_prepare(RayRenderer* renderer);