From a34c49f103c8950a57687ea3d866c244d95b4414 Mon Sep 17 00:00:00 2001 From: hachem Date: Mon, 24 Aug 2026 18:28:39 +0200 Subject: [docs]: added a few comments cause i wont be able to read this in a week's time --- src/platform/opengl/opengl_device.cpp | 23 +++++++++-------------- src/platform/opengl/shader.cpp | 16 ++++++++-------- src/platform/opengl/shader.h | 2 +- src/platform/opengl/texture.cpp | 18 +++++++++--------- src/platform/vulkan/vulkan_common.h | 25 +++++++++++++------------ src/platform/vulkan/vulkan_device.cpp | 4 ++-- src/platform/vulkan/vulkan_device.h | 4 ++-- src/platform/vulkan/vulkan_resources.cpp | 10 +++++----- src/platform/vulkan/vulkan_swapchain.cpp | 8 ++++---- 9 files changed, 53 insertions(+), 57 deletions(-) (limited to 'src/platform') diff --git a/src/platform/opengl/opengl_device.cpp b/src/platform/opengl/opengl_device.cpp index 614e515..dd5581d 100644 --- a/src/platform/opengl/opengl_device.cpp +++ b/src/platform/opengl/opengl_device.cpp @@ -21,7 +21,6 @@ namespace Donut::RHI auto gl_filter(Filter f) -> GLint { return f == Filter::Nearest ? GL_NEAREST : GL_LINEAR; } auto gl_internal(Format f) -> GLint { return f == Format::RGBA16F ? GL_RGBA16F : f == Format::RGBA32F ? GL_RGBA32F : f == Format::D32 ? GL_DEPTH_COMPONENT32F : GL_RGBA8; } - // ---- Buffer ------------------------------------------------------- class GLBuffer : public Buffer { public: @@ -42,7 +41,6 @@ namespace Donut::RHI GLuint m_id = 0; GLenum m_target = GL_ARRAY_BUFFER; }; - // ---- Texture ------------------------------------------------------ class GLTexture : public Texture { public: @@ -69,7 +67,6 @@ namespace Donut::RHI Ref m_cube; // keepalive for cubemaps }; - // ---- RenderTarget ------------------------------------------------- class GLRenderTarget : public RenderTarget { public: @@ -102,7 +99,6 @@ namespace Donut::RHI GLuint m_fbo = 0, m_depth = 0; int m_w, m_h; Scope m_color; }; - // ---- Pipeline ----------------------------------------------------- class GLPipeline : public Pipeline { public: @@ -120,12 +116,12 @@ namespace Donut::RHI { GLuint bi = glGetUniformBlockIndex(m_prog, r.name.c_str()); if (bi != GL_INVALID_INDEX) glUniformBlockBinding(m_prog, bi, r.binding); - // Not found: the ConstantBuffer<> type name in the shader no longer + // not found: the ConstantBuffer<> type name in the shader no longer // matches this resource string, so the UBO silently won't bind. else DONUT_WARN("GL RHI: shader '{}' has no uniform block '{}' (binding {})", d.shader, r.name, r.binding); } - else // Texture: point the sampler at texture unit == binding + else // texture: point the sampler at texture unit == binding { GLint loc = glGetUniformLocation(m_prog, r.name.c_str()); if (loc >= 0) glUniform1i(loc, (GLint)r.binding); @@ -138,7 +134,7 @@ namespace Donut::RHI PipelineDesc m_desc; Ref m_shader; GLuint m_prog = 0; }; - // ---- CommandList (immediate) -------------------------------------- + // GL has no command buffers, so every call here executes immediately. class GLCommandList : public CommandList { public: @@ -155,7 +151,7 @@ namespace Donut::RHI glClearColor(clear.r, clear.g, clear.b, clear.a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } - auto end_render_pass() -> void override {} + auto end_render_pass() -> void override {} // GL passes are a fiction; nothing to close auto bind_pipeline(Pipeline* p) -> void override { @@ -208,7 +204,6 @@ namespace Donut::RHI GLuint m_vao; GLPipeline* m_pipe = nullptr; int m_default_w = 1, m_default_h = 1; }; - // ---- Device ------------------------------------------------------- class GLDevice : public Device { public: @@ -220,17 +215,17 @@ namespace Donut::RHI m_width = window.width; m_height = window.height; const char* name = (const char*)glGetString(GL_RENDERER); m_name = name ? name : "OpenGL"; - glGenVertexArrays(1, &m_vao); glBindVertexArray(m_vao); // GL core needs one bound VAO + glGenVertexArrays(1, &m_vao); glBindVertexArray(m_vao); // GL core wants one VAO bound at all times, so like, here's one m_cmds = create_scope(m_vao); DONUT_INFO("GL RHI device: {} ({}x{})", m_name, m_width, m_height); return true; } auto shutdown() -> void override { - // Free the HDRIManager's cached GL cubemaps while our context is - // still current (they are static-singleton-owned; letting them - // destruct at program exit would glDeleteTextures after the context - // is gone and crash on close). + // nuke the HDRIManager's cached GL cubemaps while our context is + // still alive. they're static-singleton-owned, so if we let them + // destruct at program exit they'd glDeleteTextures into a dead + // context and crash on close. no thanks. HDRIManager::get().clear_cache(); if (m_imgui) { ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); m_imgui = false; } if (m_vao) { glDeleteVertexArrays(1, &m_vao); m_vao = 0; } diff --git a/src/platform/opengl/shader.cpp b/src/platform/opengl/shader.cpp index 80015e6..757382b 100644 --- a/src/platform/opengl/shader.cpp +++ b/src/platform/opengl/shader.cpp @@ -19,8 +19,8 @@ namespace Donut return 0; } - // Shaders are authored in Slang and compiled to assets/shaders/generated/ - // .glsl by tools/compile-shaders.sh. Given a legacy ".../.glsl" + // shaders are authored in Slang and compiled to assets/shaders/generated/ + // .glsl by tools/compile-shaders.sh. given a legacy ".../.glsl" // path, prefer that generated file when present; otherwise fall back to the // hand-written GLSL (e.g. shaders not yet ported to Slang). static std::string ResolveShaderPath(const std::string& filepath) @@ -145,9 +145,9 @@ namespace Donut glDeleteShader(id); glDeleteProgram(program); m_renderer_id = 0; - // info_log.data() is null when the driver returns an empty log - // (e.g. macOS rejecting a compute shader); streaming a null - // char* into std::cout calls strlen(NULL) and crashes. + // info_log.data() is null when the driver hands back an empty log + // (e.g. macOS rejecting a compute shader). streaming a null char* + // into std::cout does strlen(NULL) and just explodes. cool cool cool. const char* log = info_log.empty() ? "" : info_log.data(); std::cout << "Shader compilation failure!" << std::endl << log << std::endl; return; @@ -278,9 +278,9 @@ namespace Donut auto Shader::dispatch(uint32_t x, uint32_t y, uint32_t z) -> void { - // Compute shaders require OpenGL 4.3+. On drivers that cap out earlier - // (e.g. macOS, which is frozen at 4.1) glDispatchCompute is never - // loaded and the pointer is null. Guard so we no-op instead of crash. + // compute shaders want OpenGL 4.3+ and macOS is frozen at 4.1, so + // glDispatchCompute never even loads and the pointer is null. guard it + // and quietly no-op instead of face-planting. if (m_renderer_id == 0 || glDispatchCompute == nullptr) return; glDispatchCompute(x, y, z); diff --git a/src/platform/opengl/shader.h b/src/platform/opengl/shader.h index 409aca3..89963c7 100644 --- a/src/platform/opengl/shader.h +++ b/src/platform/opengl/shader.h @@ -59,7 +59,7 @@ namespace Donut uint32_t m_renderer_id = 0; std::string m_name; - // True when loaded from a Slang-compiled GLSL. Slang expects row-major + // true when loaded from a Slang-compiled GLSL. Slang expects row-major // matrix data, so matrix uniforms are transposed on upload (glm is // column-major) to keep all matrix math correct. bool m_is_slang = false; diff --git a/src/platform/opengl/texture.cpp b/src/platform/opengl/texture.cpp index 12e07f1..d2d2233 100644 --- a/src/platform/opengl/texture.cpp +++ b/src/platform/opengl/texture.cpp @@ -11,10 +11,10 @@ #include #include -// NOTE: This file targets OpenGL 4.1 (the maximum macOS exposes). It uses the +// this file targets OpenGL 4.1 (the maximum macOS exposes). it uses the // classic bind-based texture API rather than 4.5 Direct State Access // (glCreateTextures / glTextureStorage2D / glTextureParameteri / glBindTextureUnit), -// none of which exist on macOS. It also hosts the single STB_IMAGE_IMPLEMENTATION +// none of which exist on macOS. it also hosts the single STB_IMAGE_IMPLEMENTATION // for the whole build (the Vulkan backend links stbi_loadf from here too). namespace Donut @@ -84,7 +84,7 @@ namespace Donut auto Texture2D::bind_as_image(uint32_t slot, bool read_only) const -> void { - // Image load/store is OpenGL 4.2 and unavailable on macOS. Guard the + // image load/store is OpenGL 4.2 and unavailable on macOS. guard the // function pointer so this degrades to a no-op instead of crashing. if (glBindImageTexture == nullptr) return; @@ -148,12 +148,12 @@ namespace Donut DONUT_ERROR("Failed to load HDRI: {}", path); float default_sky[6 * 4] = { - 0.5f, 0.7f, 1.0f, 1.0f, // Right - 0.5f, 0.7f, 1.0f, 1.0f, // Left - 0.5f, 0.7f, 1.0f, 1.0f, // Top - 0.5f, 0.7f, 1.0f, 1.0f, // Bottom - 0.5f, 0.7f, 1.0f, 1.0f, // Front - 0.5f, 0.7f, 1.0f, 1.0f // Back + 0.5f, 0.7f, 1.0f, 1.0f, // right + 0.5f, 0.7f, 1.0f, 1.0f, // left + 0.5f, 0.7f, 1.0f, 1.0f, // top + 0.5f, 0.7f, 1.0f, 1.0f, // bottom + 0.5f, 0.7f, 1.0f, 1.0f, // front + 0.5f, 0.7f, 1.0f, 1.0f // back }; glBindTexture(GL_TEXTURE_CUBE_MAP, m_renderer_id); diff --git a/src/platform/vulkan/vulkan_common.h b/src/platform/vulkan/vulkan_common.h index 8f02f17..cb86d69 100644 --- a/src/platform/vulkan/vulkan_common.h +++ b/src/platform/vulkan/vulkan_common.h @@ -1,10 +1,10 @@ #pragma once -// Shared internals of the Vulkan RHI backend: the enum-mapping helpers, the +// shared internals of the Vulkan RHI backend: the enum-mapping helpers, the // opaque resource classes (Buffer/Texture/RenderTarget/Pipeline/CommandList), and -// the VulkanDevice declaration. The implementation is split across vulkan_device +// the VulkanDevice declaration. the implementation is split across vulkan_device // (lifecycle + frame loop), vulkan_swapchain (instance/device/swapchain/passes), -// vulkan_resources (buffer/texture/target/pipeline) and vulkan_cubemap. This +// vulkan_resources (buffer/texture/target/pipeline) and vulkan_cubemap. this // header is private to platform/vulkan/ — nothing outside includes it. #include "vulkan_device.h" // rendering/rhi.h (base classes + factory decls) @@ -63,7 +63,7 @@ namespace Donut::RHI inline auto vk_cull(CullMode c) -> VkCullModeFlags { return c == CullMode::None ? VK_CULL_MODE_NONE : c == CullMode::Back ? VK_CULL_MODE_BACK_BIT : VK_CULL_MODE_FRONT_BIT; } - // Buffer: host-visible + coherent, persistently mapped. + // buffer: host-visible + coherent, persistently mapped. class VkBufferR : public Buffer { public: @@ -81,7 +81,7 @@ namespace Donut::RHI VkDevice m_device; VkBuffer m_buf; VkDeviceMemory m_mem; void* m_mapped; size_t m_size; }; - // Texture: sampled image (2D or cube). Owns its handles unless it is a borrowed + // texture: sampled image (2D or cube). owns its handles unless it is a borrowed // wrapper around a render-target view. class VkTextureR : public Texture { @@ -138,7 +138,7 @@ namespace Donut::RHI VkTextureR m_color; // borrowed wrapper (view+sampler) for sampling }; - // Pipeline: the graphics pipeline + its (set-0) descriptor layout. + // pipeline: the graphics pipeline + its (set-0) descriptor layout. class VkPipelineR : public Pipeline { public: @@ -155,8 +155,9 @@ namespace Donut::RHI std::vector m_resources; }; - // CommandList: records into the frame's command buffer. Per-draw descriptor - // sets are allocated from a per-frame pool (no push-descriptor extension). + // CommandList: records into the frame's command buffer. MoltenVK has no + // push-descriptor extension, so we just grab a fresh descriptor set per draw + // from a per-frame pool. kinda wasteful, but it works and that's what counts. class VkCommandListR : public CommandList { public: @@ -219,7 +220,7 @@ namespace Donut::RHI auto draw_indexed(uint32_t index_count) -> void override { flush_descriptors(); vkCmdDrawIndexed(m_cmd, index_count, 1, 0, 0, 0); } - // Allocate + write + bind a descriptor set for the current pipeline's + // allocate + write + bind a descriptor set for the current pipeline's // declared resources, using whatever was bound since bind_pipeline. auto flush_descriptors() -> void { @@ -246,7 +247,7 @@ namespace Donut::RHI vkCmdBindDescriptorSets(m_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipe->m_layout, 0, 1, &set, 0, nullptr); } - // Set by the device at begin_frame: + // set by the device at begin_frame: VkDevice m_device = VK_NULL_HANDLE; VkCommandBuffer m_cmd = VK_NULL_HANDLE; VkRenderPass m_swapchain_rp = VK_NULL_HANDLE; @@ -259,7 +260,7 @@ namespace Donut::RHI VkDescriptorImageInfo m_img_info[MAX_BINDINGS]{}; }; - // The backend device. Its methods are defined across vulkan_device.cpp, + // the backend device. its methods are defined across vulkan_device.cpp, // vulkan_swapchain.cpp, vulkan_resources.cpp and vulkan_cubemap.cpp. class VulkanDevice : public Device { @@ -298,7 +299,7 @@ namespace Donut::RHI auto pick_physical_and_device() -> bool; auto create_swapchain() -> bool; auto create_image_views() -> bool; - // Render passes are format-driven and cached: a pipeline/target's + // render passes are format-driven and cached: a pipeline/target's // attachment signature (colour + optional depth, present vs sampled) // maps to one pass. `present` = presented swapchain image. auto get_render_pass(VkFormat color, VkFormat depth, bool present) -> VkRenderPass; diff --git a/src/platform/vulkan/vulkan_device.cpp b/src/platform/vulkan/vulkan_device.cpp index ff2e296..a4f9ac7 100644 --- a/src/platform/vulkan/vulkan_device.cpp +++ b/src/platform/vulkan/vulkan_device.cpp @@ -58,7 +58,7 @@ namespace Donut::RHI if (!pick_physical_and_device()) return false; if (!create_swapchain()) return false; if (!create_image_views()) return false; - // The swapchain is a "present" target: its colour format + a D32 depth. + // the swapchain is a "present" target: its colour format + a D32 depth. m_swapchain_rp = get_render_pass(m_swapchain_format, VK_FORMAT_D32_SFLOAT, true); if (!m_swapchain_rp) return false; if (!create_depth_and_framebuffers())return false; @@ -156,7 +156,7 @@ namespace Donut::RHI VkCommandBuffer cmd; vkAllocateCommandBuffers(m_device, &cbai, &cmd); VkCommandBufferBeginInfo bi{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; bi.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; vkBeginCommandBuffer(cmd, &bi); - // The target ended its render pass in SHADER_READ_ONLY; move it to TRANSFER_SRC to copy. + // the target ended its render pass in SHADER_READ_ONLY; move it to TRANSFER_SRC to copy. VkImageMemoryBarrier b{ VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; b.oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; b.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; b.image = rt->m_image; b.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; diff --git a/src/platform/vulkan/vulkan_device.h b/src/platform/vulkan/vulkan_device.h index efc2433..85cc5ca 100644 --- a/src/platform/vulkan/vulkan_device.h +++ b/src/platform/vulkan/vulkan_device.h @@ -4,13 +4,13 @@ namespace Donut::RHI { - // Vulkan implementation of the RHI Device (MoltenVK on macOS). Owns the + // Vulkan implementation of the RHI Device (MoltenVK on macOS). owns the // instance/device/swapchain and translates the RHI's baked pipelines + // recorded command lists into native Vulkan; the geometry it draws is the // shared SceneRenderer / BlackHoleRenderer, identical to every other backend. auto create_vulkan_device() -> Scope; - // Must run BEFORE glfwInit() when Vulkan is the selected API: points GLFW at + // must run BEFORE glfwInit() when Vulkan is the selected API: points GLFW at // the loader the app links against (its own dlopen fails on macOS/Homebrew) // and configures the MoltenVK ICD / layer paths. auto vulkan_prepare_glfw() -> void; diff --git a/src/platform/vulkan/vulkan_resources.cpp b/src/platform/vulkan/vulkan_resources.cpp index e40ded3..ee2091b 100644 --- a/src/platform/vulkan/vulkan_resources.cpp +++ b/src/platform/vulkan/vulkan_resources.cpp @@ -93,7 +93,7 @@ namespace Donut::RHI smci.addressModeU = smci.addressModeV = smci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; vkCreateSampler(m_device, &smci, nullptr, &rt->m_sampler); - // Optional depth attachment (for off-screen passes that need a depth test). + // optional depth attachment (for off-screen passes that need a depth test). rt->m_has_depth = depth != Format::None; VkFormat dfmt = VK_FORMAT_UNDEFINED; if (rt->m_has_depth) @@ -126,9 +126,9 @@ namespace Donut::RHI return rt; } - // Builds an environment cubemap from an equirectangular HDRI: render the 6 + // builds an environment cubemap from an equirectangular HDRI: render the 6 // faces with the EquirectToCubemap pipeline, then a full mip chain by - // linear down-blits (so divergence-based LOD reads a blurred sky). Returns + // linear down-blits (so divergence-based LOD reads a blurred sky). returns // a Texture owning the cube image/view/sampler. auto VulkanDevice::create_pipeline(const PipelineDesc& desc) -> Ref @@ -190,8 +190,8 @@ namespace Donut::RHI gpci.stageCount = 2; gpci.pStages = stages; gpci.pVertexInputState = &vin; gpci.pInputAssemblyState = &ia; gpci.pViewportState = &vps; gpci.pRasterizationState = &rs; gpci.pMultisampleState = &ms; gpci.pColorBlendState = &cb; gpci.pDynamicState = &dsci; - // Resolve the target's attachment signature to a (cached) render pass. - // Pipeline<->pass compatibility is by attachment format, so this is the + // resolve the target's attachment signature to a (cached) render pass. + // pipeline<->pass compatibility is by attachment format, so this is the // same pass the matching swapchain / render target renders into. VkFormat pcolor = (desc.target.color == Format::Swapchain) ? m_swapchain_format : vk_format(desc.target.color); VkFormat pdepth = (desc.target.depth == Format::None) ? VK_FORMAT_UNDEFINED : vk_format(desc.target.depth); diff --git a/src/platform/vulkan/vulkan_swapchain.cpp b/src/platform/vulkan/vulkan_swapchain.cpp index 5bf2f60..cbd4512 100644 --- a/src/platform/vulkan/vulkan_swapchain.cpp +++ b/src/platform/vulkan/vulkan_swapchain.cpp @@ -117,8 +117,8 @@ namespace Donut::RHI sci.imageExtent = m_extent; sci.imageArrayLayers = 1; sci.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; sci.preTransform = caps.currentTransform; sci.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; - // FIFO is always available (vsync). With vsync off, prefer IMMEDIATE - // (uncapped, may tear) then MAILBOX, if the surface supports them. + // FIFO is always there (that's vsync). with vsync off we'd rather have + // IMMEDIATE (uncapped, might tear) then MAILBOX, if the surface is cool with it. VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR; if (!m_vsync) { @@ -153,11 +153,11 @@ namespace Donut::RHI return true; } - // A render pass for one attachment signature, created once and cached. + // a render pass for one attachment signature, created once and cached. // `present` targets (the swapchain) finish PRESENT_SRC and sync on the // colour-output stage; `sampled` targets (off-screen) finish // SHADER_READ_ONLY and round-trip through the fragment shader so the next - // pass can sample them. Depth (VK_FORMAT_UNDEFINED = none) is optional. + // pass can sample them. depth (VK_FORMAT_UNDEFINED = none) is optional. auto VulkanDevice::get_render_pass(VkFormat color, VkFormat depth, bool present) -> VkRenderPass { uint64_t key = (uint64_t)(uint32_t)color -- cgit v1.3