Skip to content

Update from task f96c1ed4-2a53-4444-90e8-9b57f386bac1#25

Open
tronpis wants to merge 3 commits into
chunkkeyubfixsimulationmoduleperformance-ebd4efrom
rendergraphsystemenhancements-6bac1
Open

Update from task f96c1ed4-2a53-4444-90e8-9b57f386bac1#25
tronpis wants to merge 3 commits into
chunkkeyubfixsimulationmoduleperformance-ebd4efrom
rendergraphsystemenhancements-6bac1

Conversation

@tronpis
Copy link
Copy Markdown
Owner

@tronpis tronpis commented Apr 2, 2026

This PR was created by qwen-chat coder for task f96c1ed4-2a53-4444-90e8-9b57f386bac1.

- Fix CMakeLists.txt to use correct paths for new RenderGraph source files
- Remove invalid VkSubpassDependency logic from RenderGraph compilation
- Add validation for null imageView handles in RenderGraph framebuffers
- Correct render area extent and clear value handling in RenderGraph execution
- Initialize CompiledPass state correctly during RenderGraph compilation
- Include glm/gtx/norm.hpp header for glm::length2 function
- Fix chunk key generation logic to handle negative coordinates correctly
- Optimize chunk sorting using squared distance to avoid sqrt operations
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Fix RenderGraph bugs and ChunkSystem compilation issues

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Fix RenderGraph compilation state initialization and framebuffer validation
• Remove invalid VkSubpassDependency logic for separate render passes
• Correct render area extent and clear value handling in execution
• Fix CMakeLists.txt paths and add missing glm header for chunk sorting
• Optimize chunk distance calculations using squared distance
Diagram
flowchart LR
  A["RenderGraph Compilation"] -->|Clear previous state| B["Initialize CompiledPass"]
  B -->|Remove invalid logic| C["Remove VkSubpassDependency"]
  D["Framebuffer Creation"] -->|Validate imageView| E["Add null checks"]
  E -->|Store extent| F["Save for execution"]
  F -->|Use stored extent| G["Execute render pass"]
  H["CMakeLists.txt"] -->|Fix paths| I["Update to src/rendering/graph"]
  J["ChunkSystem"] -->|Add header| K["Include glm/gtx/norm.hpp"]
  K -->|Optimize sorting| L["Use squared distance"]
Loading

Grey Divider

File Changes

1. FarmEngine/src/rendering/graph/RenderGraph.cpp 🐞 Bug fix +41/-28

Fix RenderGraph state initialization and execution logic

• Clear previous CompiledPass state before compilation to prevent stale data
• Remove invalid VkSubpassDependency logic that only applies to subpasses within same render pass
• Add validation for null imageView handles in color and depth attachments with descriptive error
 messages
• Store calculated extent in CompiledPass during framebuffer creation for use in execute()
• Fix render area extent to use stored extent instead of hardcoded registry lookup
• Correct clear values generation to match attachment count (color attachments first, then depth)

FarmEngine/src/rendering/graph/RenderGraph.cpp


2. FarmEngine/src/rendering/graph/RenderGraph.h ✨ Enhancement +3/-0

Add extent field to CompiledPass structure

• Add extent field to CompiledPass structure to store calculated framebuffer extent
• Document that extent is computed during framebuffer creation for use in execute()

FarmEngine/src/rendering/graph/RenderGraph.h


3. FarmEngine/world/chunks/ChunkSystem.cpp 🐞 Bug fix +1/-0

Add glm norm header for distance calculations

• Add missing #include <glm/gtx/norm.hpp> header for glm::length2 function
• Enables optimized chunk sorting using squared distance calculations

FarmEngine/world/chunks/ChunkSystem.cpp


View more (1)
4. FarmEngine/CMakeLists.txt 🐞 Bug fix +4/-4

Fix RenderGraph source file paths in CMake

• Correct file paths for RenderGraph source files from rendering/graph/ to src/rendering/graph/
• Fixes compilation errors due to incorrect include paths

FarmEngine/CMakeLists.txt


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Apr 2, 2026

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Stale resource index map 🐞 Bug ≡ Correctness
Description
RenderGraph::compile() rebuilds compiledRegistry.nameToIndex without clearing previous entries, so
recompiling with a different resource set can make getResource() return a pointer to the wrong
resource (or out-of-bounds). This can also defeat the intended "not found" checks during compilation
by returning a stale hit.
Code

FarmEngine/src/rendering/graph/RenderGraph.cpp[R137-149]

+    // Limpiar estado previo antes de compilar
+    for (auto& compiled : compiledPasses) {
+        compiled.attachments.clear();
+        compiled.colorRefs.clear();
+        compiled.dependencies.clear();
+        compiled.depthRef = {};
+        compiled.vkRenderPass = VK_NULL_HANDLE;
+        compiled.framebuffer = VK_NULL_HANDLE;
+    }
+    
    compiledPasses.resize(builder.passes.size());
    
    // Construir mapa nombre->índice
Evidence
compile() overwrites resources and then only inserts/overwrites keys, leaving removed resource names
still present in nameToIndex; getResource() trusts the index from the map and directly indexes the
resources vector without bounds checks.

FarmEngine/src/rendering/graph/RenderGraph.cpp[131-152]
FarmEngine/src/rendering/graph/RenderGraph.cpp[11-17]
FarmEngine/src/rendering/graph/RenderGraph.cpp[360-375]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RenderGraph::compile()` rebuilds `compiledRegistry.nameToIndex` without clearing it first. After recompiling with a different resource set, stale keys can remain and `ResourceRegistry::getResource()` will index `resources[it->second]` with a stale index, returning the wrong resource or going out-of-bounds.

### Issue Context
This is especially risky now that `compile()` explicitly tries to "clean previous state" for recompilation.

### Fix Focus Areas
- FarmEngine/src/rendering/graph/RenderGraph.cpp[131-152]
- FarmEngine/src/rendering/graph/RenderGraph.cpp[11-17]

### Suggested fix
- Add `compiledRegistry.nameToIndex.clear();` (and consider clearing other compiled-registry state that must not persist) before rebuilding the map.
- Optionally add a defensive bounds check in `getResource()` to ensure `it->second < resources.size()` and return `nullptr` otherwise.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Zero render area extent 🐞 Bug ≡ Correctness
Description
RenderGraph::execute() uses compiled.extent for rpBegin.renderArea.extent, but CompiledPass::extent
defaults to {0,0} and is only set in createFramebuffers(). Since createFramebuffers() is private and
not called anywhere in this module, execute() can begin render passes with a 0x0 render area.
Code

FarmEngine/src/rendering/graph/RenderGraph.cpp[R322-326]

        rpBegin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
        rpBegin.renderPass = compiled.vkRenderPass;
        rpBegin.framebuffer = compiled.framebuffer;
-        rpBegin.renderArea.extent = {compiled.attachments.empty() ? 0 : 
-                                     registry.resources[0].extent.width, 
-                                     compiled.attachments.empty() ? 0 : 
-                                     registry.resources[0].extent.height};
+        rpBegin.renderArea.extent = compiled.extent;
        
-        // Clear values
Evidence
CompiledPass extent is initialized to {0,0}; execute() unconditionally uses it. The only setter is
createFramebuffers(), which is a private method and has no call sites in this code, so extent
remains unset through the public compile()/execute() API.

FarmEngine/src/rendering/graph/RenderGraph.cpp[311-326]
FarmEngine/src/rendering/graph/RenderGraph.h[143-167]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RenderGraph::execute()` uses `compiled.extent`, but `CompiledPass::extent` defaults to `{0,0}` and is only assigned in `createFramebuffers()`. In the current code, `createFramebuffers()` is private and there are no call sites, so `execute()` can run with a 0x0 render area.

### Issue Context
This change was introduced by switching from a computed extent to `compiled.extent`.

### Fix Focus Areas
- FarmEngine/src/rendering/graph/RenderGraph.cpp[311-326]
- FarmEngine/src/rendering/graph/RenderGraph.h[143-167]

### Suggested fix options
Pick one consistent API direction:
1. **Expose an initialization/build step** (public) that must be called before `execute()` and that calls `createRenderPasses()` + `createFramebuffers()` and sets extents.
2. **Pass the render extent into `execute()`** (or store a default graph extent) and use it when `compiled.extent` is `{0,0}`.
3. **Compute extent from attachments/registry at execute-time** (less ideal, but avoids uninitialized state).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Dependencies silently ignored 🐞 Bug ≡ Correctness
Description
RenderGraphBuilder::addDependency() still records explicitDependencies, but RenderGraph::compile()
no longer consumes them, so explicit dependencies are silently dropped. ExampleUsage relies on
addDependency(), so the example’s intended ordering/synchronization is now incorrect.
Code

FarmEngine/src/rendering/graph/RenderGraph.cpp[R214-216]

+    // Las dependencias entre passes separados se manejan mediante barreras de pipeline
+    // registradas durante la ejecución, no mediante VkSubpassDependency
+    // VkSubpassDependency solo es válido para subpasses dentro del mismo VkRenderPass
Evidence
addDependency() appends to explicitDependencies, but compile() only contains a comment and does not
translate these dependencies into either VkSubpassDependency (for same-renderpass subpasses) or
pipeline barriers (prePassBarriers). ExampleUsage demonstrates a dependency call that will now have
no effect.

FarmEngine/src/rendering/graph/RenderGraph.cpp[107-121]
FarmEngine/src/rendering/graph/RenderGraph.cpp[214-217]
FarmEngine/src/rendering/graph/RenderGraph.cpp[295-309]
FarmEngine/src/rendering/graph/ExampleUsage.h[96-114]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`RenderGraphBuilder::addDependency()` still collects `explicitDependencies`, but `RenderGraph::compile()` no longer uses them. This makes the API misleading and breaks example code that expects the dependency to be enforced.

### Issue Context
The comment says dependencies will be handled by pipeline barriers during execution, but `prePassBarriers` are never populated from `explicitDependencies`.

### Fix Focus Areas
- FarmEngine/src/rendering/graph/RenderGraph.cpp[107-121]
- FarmEngine/src/rendering/graph/RenderGraph.cpp[200-217]
- FarmEngine/src/rendering/graph/RenderGraph.cpp[295-309]
- FarmEngine/src/rendering/graph/ExampleUsage.h[96-114]

### Suggested fix options
- **Option A (preferred):** Convert `explicitDependencies` into per-pass `prePassBarriers` during `compile()` (or a dedicated graph-analysis step) and apply them in `recordBarriers()`.
- **Option B:** If explicit dependencies are not supported yet, remove `addDependency()`/`explicitDependencies` and update ExampleUsage to avoid implying it works.
- **Option C:** Add a runtime assert/log when `explicitDependencies` is non-empty to avoid silent no-op behavior.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Copy link
Copy Markdown
Contributor

@amazon-q-developer amazon-q-developer Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR introduces render graph system enhancements and updates file paths in the build system. I've identified critical issues that must be addressed before merge.

Critical Issues Found:

  1. RenderGraph.cpp (Lines 137-147): Logic error in state cleanup where individual CompiledPass fields are cleared in a loop, then the vector is resized. This is inefficient and potentially incorrect if the vector size changes. The loop may iterate over passes that will be destroyed or miss newly created ones.

Changes Summary:

  • .gitignore: Cleanup of ignored file patterns
  • CMakeLists.txt: Updated paths from rendering/graph/ to src/rendering/graph/
  • RenderGraph.cpp: Added state cleanup before compilation, improved error handling with null checks, fixed render area extent calculation
  • RenderGraph.h: Added extent field to CompiledPass struct
  • ChunkSystem.cpp: Added missing glm/gtx/norm.hpp include

Please address the critical logic error before merging.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Comment thread FarmEngine/src/rendering/graph/RenderGraph.cpp
Comment thread FarmEngine/src/rendering/graph/RenderGraph.cpp
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates project configuration and enhances the RenderGraph system. Key changes include adjusting source paths in CMakeLists.txt, refining .gitignore patterns, and improving RenderGraph by adding robust error checking for attachments, better extent management, and corrected clear value handling for multiple attachments. Feedback highlights a potential resource leak in RenderGraph.cpp where Vulkan handles are reset without being destroyed, a regression in .gitignore due to the removal of standard environment and IDE ignores, and a logic flaw in the extent calculation that may fail for depth-only passes.

Comment on lines 138 to 147
for (auto& compiled : compiledPasses) {
compiled.attachments.clear();
compiled.colorRefs.clear();
compiled.dependencies.clear();
compiled.depthRef = {};
compiled.vkRenderPass = VK_NULL_HANDLE;
compiled.framebuffer = VK_NULL_HANDLE;
}

compiledPasses.resize(builder.passes.size());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This loop resets Vulkan handles (vkRenderPass, framebuffer) to VK_NULL_HANDLE without destroying the actual Vulkan objects. This causes a resource leak every time the graph is re-compiled. Additionally, manually clearing members before a resize is less idiomatic than simply clearing the vector.

Note: Ensure that cleanup() is called before re-compiling to properly destroy existing Vulkan resources.

    compiledPasses.clear();
    compiledPasses.resize(builder.passes.size());

Comment thread .gitignore
Comment on lines +26 to 28
# OS generated files
.DS_Store
Thumbs.db
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Removing standard ignore patterns for IDEs (.vscode/, .idea/), environment files (.env*), and coverage reports is a regression in project hygiene. These files are local to a developer's environment and should not be tracked in the repository to avoid accidental commits of sensitive or environment-specific data.

# Temporary files
*.tmp
*.temp

# Environment
.env
.env.local
.env.*

# Editors
.vscode/
.idea/
*.swp
*.swo

# Coverage
coverage/
htmlcov/
.coverage

# OS generated files
.DS_Store
Thumbs.db

Comment on lines +261 to 263
if (!res->isSwapchain) {
extent = res->extent;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The extent calculation only considers color attachments and defaults to swapchainExtent. If a pass only has a depth attachment, or if the depth attachment has different dimensions than the color attachments, the resulting framebuffer extent might be incorrect. It is safer to determine the extent by validating all participating attachments.

tronpis and others added 2 commits April 2, 2026 14:22
Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com>
Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com>
Comment on lines +137 to 149
// Limpiar estado previo antes de compilar
for (auto& compiled : compiledPasses) {
compiled.attachments.clear();
compiled.colorRefs.clear();
compiled.dependencies.clear();
compiled.depthRef = {};
compiled.vkRenderPass = VK_NULL_HANDLE;
compiled.framebuffer = VK_NULL_HANDLE;
}

compiledPasses.resize(builder.passes.size());

// Construir mapa nombre->índice
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Stale resource index map 🐞 Bug ≡ Correctness

RenderGraph::compile() rebuilds compiledRegistry.nameToIndex without clearing previous entries, so
recompiling with a different resource set can make getResource() return a pointer to the wrong
resource (or out-of-bounds). This can also defeat the intended "not found" checks during compilation
by returning a stale hit.
Agent Prompt
### Issue description
`RenderGraph::compile()` rebuilds `compiledRegistry.nameToIndex` without clearing it first. After recompiling with a different resource set, stale keys can remain and `ResourceRegistry::getResource()` will index `resources[it->second]` with a stale index, returning the wrong resource or going out-of-bounds.

### Issue Context
This is especially risky now that `compile()` explicitly tries to "clean previous state" for recompilation.

### Fix Focus Areas
- FarmEngine/src/rendering/graph/RenderGraph.cpp[131-152]
- FarmEngine/src/rendering/graph/RenderGraph.cpp[11-17]

### Suggested fix
- Add `compiledRegistry.nameToIndex.clear();` (and consider clearing other compiled-registry state that must not persist) before rebuilding the map.
- Optionally add a defensive bounds check in `getResource()` to ensure `it->second < resources.size()` and return `nullptr` otherwise.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 322 to 326
rpBegin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
rpBegin.renderPass = compiled.vkRenderPass;
rpBegin.framebuffer = compiled.framebuffer;
rpBegin.renderArea.extent = {compiled.attachments.empty() ? 0 :
registry.resources[0].extent.width,
compiled.attachments.empty() ? 0 :
registry.resources[0].extent.height};
rpBegin.renderArea.extent = compiled.extent;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Zero render area extent 🐞 Bug ≡ Correctness

RenderGraph::execute() uses compiled.extent for rpBegin.renderArea.extent, but CompiledPass::extent
defaults to {0,0} and is only set in createFramebuffers(). Since createFramebuffers() is private and
not called anywhere in this module, execute() can begin render passes with a 0x0 render area.
Agent Prompt
### Issue description
`RenderGraph::execute()` uses `compiled.extent`, but `CompiledPass::extent` defaults to `{0,0}` and is only assigned in `createFramebuffers()`. In the current code, `createFramebuffers()` is private and there are no call sites, so `execute()` can run with a 0x0 render area.

### Issue Context
This change was introduced by switching from a computed extent to `compiled.extent`.

### Fix Focus Areas
- FarmEngine/src/rendering/graph/RenderGraph.cpp[311-326]
- FarmEngine/src/rendering/graph/RenderGraph.h[143-167]

### Suggested fix options
Pick one consistent API direction:
1. **Expose an initialization/build step** (public) that must be called before `execute()` and that calls `createRenderPasses()` + `createFramebuffers()` and sets extents.
2. **Pass the render extent into `execute()`** (or store a default graph extent) and use it when `compiled.extent` is `{0,0}`.
3. **Compute extent from attachments/registry at execute-time** (less ideal, but avoids uninitialized state).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants