Fix resource leaks, stale bindings, dead RenderStats, naming bugs, alignment errors, window config, blend mode improvements, MRT per-attachment blending, and Debug UI pipeline leak found in full code review#2
Conversation
Agent-Logs-Url: https://github.com/zzuegg/jGibbonEngine/sessions/bb4d6c6b-843e-4ee5-941f-dd933ffad578 Co-authored-by: zzuegg <2301442+zzuegg@users.noreply.github.com>
|
@copilot you should do your own code review and report if you agree with the todo or have anything to add |
… clarity Agent-Logs-Url: https://github.com/zzuegg/jGibbonEngine/sessions/bb4d6c6b-843e-4ee5-941f-dd933ffad578 Co-authored-by: zzuegg <2301442+zzuegg@users.noreply.github.com>
…ent bug in material UBO write Agent-Logs-Url: https://github.com/zzuegg/jGibbonEngine/sessions/b28931bb-76df-42cd-a447-9ee61ad6701e Co-authored-by: zzuegg <2301442+zzuegg@users.noreply.github.com>
Done an independent top-to-bottom review of all 339 source files. Here's my assessment — I agree with everything in the TODO list, and I found 9 additional issues that weren't listed. Two of them were actual bugs that I fixed in commit Two new bugs fixed:
Seven new issues added to
For the items already in the TODO list, I confirm all of them are real. The most impactful open items in my view (beyond what was already fixed) are: the |
|
@copilot fix also the bugs that do not require a large architectural change, and add missing stuff. Update the todo. Make sure everything compiles, and if possible run the screenshot tests too |
… UBO reallocation on property change Agent-Logs-Url: https://github.com/zzuegg/jGibbonEngine/sessions/9832f464-ba6d-4655-9ed9-808cf880f093 Co-authored-by: zzuegg <2301442+zzuegg@users.noreply.github.com>
Done in commit Fixed:
TODO.md: Removed the duplicate "Hardcoded Values" section that had appeared at the bottom of the file; all four newly-fixed items marked Regarding screenshot tests: they were already failing before these changes (the Slang compiler binary isn't present in the CI environment, so every test hits |
|
@copilot add also the missing window properties. They should go in the engine config, maybe in a separate window or context config? Fix also the blend mode issues, and make sure separate blend modes are also supported, maybe create a common interface? |
…ndFactor/BlendEquation Task 1: Window Config - Add WindowConfig record with title, size, resizable, decorated, vsync, fullscreen, alwaysOnTop - Add WindowProperty.ALWAYS_ON_TOP (maps to GLFW_FLOATING in GlfwWindowToolkit) - Replace windowTitle/windowSize record components in EngineConfig with WindowConfig windowConfig keeping backward-compat windowTitle() and windowSize() methods - Update BaseApplication to use windowConfig().toDescriptor() and apply all window properties after window.show() Task 2: Blend Mode improvements - Add BlendFactor interface with 10 predefined static instances - Add BlendEquation interface with ADD, SUBTRACT, REVERSE_SUBTRACT, MIN, MAX - Expand BlendMode interface with enabled(), factor/equation accessors, and of() factory methods - Update all predefined BlendMode instances to implement full interface - Add GL blend factor/equation constants and glBlendFuncSeparate/glBlendEquationSeparate to GlBindings; implement in LwjglGlBindings - Rewrite GlRenderDevice.applyBlendMode() to use separate func/equation calls with helpers - Fix VkBindings blend factor values to match Vulkan spec (DST_COLOR=4, DST_ALPHA=8) - Add VkPipelineFactory.BlendConfig.fromBlendMode() factory with factor mapping - Update VkRenderDevice to delegate to fromBlendMode() - Fix WgpuBindings blend constants to match WebGPU spec; add missing factors and ops - Rewrite WgpuRenderDevice blend mapping to use per-factor/equation dispatch Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: zzuegg <2301442+zzuegg@users.noreply.github.com>
… interfaces, fix blend backends Agent-Logs-Url: https://github.com/zzuegg/jGibbonEngine/sessions/d84b364b-6a7e-4320-b7e4-5e78c0577726 Co-authored-by: zzuegg <2301442+zzuegg@users.noreply.github.com>
Done in commits Window properties — New Blend modes — Created
|
|
@copilot at least opengl supports also different blendmodes on different rendertargets when using mrt. Check suppimort in the other backends, and add support for that too. |
…/Vulkan, document WebGPU limitation Agent-Logs-Url: https://github.com/zzuegg/jGibbonEngine/sessions/50dd0791-714d-4817-bc17-acb0c9966fc6 Co-authored-by: zzuegg <2301442+zzuegg@users.noreply.github.com>
Done in commit Added // MRT: attachment 0 = alpha blend, attachment 1 = additive, attachment 2 = no blend
recorder.setRenderState(PropertyMap.<RenderState>builder()
.set(RenderState.BLEND_MODES, new BlendMode[]{
BlendMode.ALPHA,
BlendMode.ADDITIVE,
BlendMode.NONE
})
.build());OpenGL: Added Vulkan: WebGPU: The current Java binding only exposes a single color target in the pipeline descriptor — |
|
@copilot then i assume i can also set the renderstate on the material? And it is working with the blendmodes too? |
…t UBO filter miss Agent-Logs-Url: https://github.com/zzuegg/jGibbonEngine/sessions/c99fc128-2e04-4ab5-8940-bb9c7bf3f2a2 Co-authored-by: zzuegg <2301442+zzuegg@users.noreply.github.com>
Yes — render state on materials already works through var mat = MaterialData.unlit(new Vec3(1, 0, 0))
.withRenderState(RenderState.BLEND_MODE, BlendMode.ALPHA)
.withRenderState(RenderState.DEPTH_WRITE, false);
entity.add(mat);
// MRT per-attachment blend on a material:
var mrtMat = MaterialData.create()
.withRenderState(RenderState.BLEND_MODES, new BlendMode[]{
BlendMode.ALPHA,
BlendMode.ADDITIVE
});
Fixed a small gap in |
Runs the screenshot report Gradle tasks on PRs, pushes to main, and manual dispatch. Uses Mesa llvmpipe for OpenGL software rendering, lavapipe for Vulkan, and Xvfb for a virtual display. Reports and screenshots are uploaded as artifacts.
|
@copilot rebase and redo the code review |
…iew-findings Co-authored-by: zzuegg <2301442+zzuegg@users.noreply.github.com>
Done in commit One real bug found and fixed:
Additional findings added to TODO.md (Debug UI section):
|
Full code review across 467 source files. Twenty-plus bugs and missing features fixed ranging from GPU resource leaks to always-zero stats counters to a misleading profiler API. Merged with upstream Debug UI system additions and fixed a pipeline leak in the new overlay.
Critical Fixes
GPU buffer leak — per-entity UBOs
UniformManagerkeyed object/material UBOs by"obj_" + entity.index()(index-only string). Buffers accumulated forever; slot reuse gave new entities stale buffers silently.Handle<?>(index + generation)removeEntity(Handle<?>)to destroy buffers on entity removalRenderer.renderFrame()calls it for everyEntityRemovedtransaction before delegating toMeshRendererMaterial UBO wrong-sized on property change
UniformManager.uploadAndBindMaterial()usedcomputeIfAbsentkeyed by entity handle, allocating a buffer sized for the first set of material properties. If a material subsequently gained new scalar keys, the existing undersized buffer was reused, silently writing into unallocated GPU memory.materialUboSizestracking map alongsidematerialUbosStale shader binding after entity slot reuse
entityShaderswas also index-only. AddedShaderManager.removeEntityShader(), called alongsideremoveEntity()onEntityRemoved.MeshRenderermap leaks on entity removalmeshDataAssignments,meshAssignments,materialAssignmentswere not cleared onEntityRemoved. Fixed.Renderer.close()/Engine.shutdown()incomplete teardownMeshManagerheld VBOs, IBOs, vertex inputs that were never freed. AddedMeshManager.close()(via privatedestroyMeshResourceshelper) and wired it intoRenderer.close().Engine.shutdown()was missingassets.shutdown(), leavingFileWatcherthreads alive.DebugUiOverlay.close()pipeline leakDebugUiOverlay.init()creates the GPU pipeline viaShaderManager.compileSlangSource(), which does not cache the pipeline inShaderManager.shaderCache. The originalclose()comment ("Pipeline is owned by ShaderManager") was wrong — the pipeline is exclusively owned byDebugUiOverlay. Addeddevice.destroyPipeline(pipeline)toclose()to prevent the leak on engine shutdown.Correctness Fixes
Vec2alignment missing from material UBO write loopThe size-calculation loop in
UniformManager.uploadAndBindMaterial()correctly alignedVec2fields to an 8-byte boundary. The write-offset loop did not apply that same pre-alignment, so anyVec2property following an odd-aligned predecessor was written at the wrong GPU offset, producing corrupted material values. Fixed by addingoffset = align(offset, 8)before writingVec2in the write loop, making both loops consistent. Also fixed missing pre-alignment forVec4andMat4in the write loop.Profilernaming inversionlastFrame()returned the in-progresscurrentFrame;previousFrame()returned the actually-completed frame. Renamed to match semantics:currentFrame()— in-progress framelastFrame()— most-recently completed frameTests updated to use
currentFrame().RenderStatsalways zeroNothing ever called
recordDrawCall(),recordPipelineBind(), etc.Renderer.renderFrame()now records all stats and resets at frame start.Engine.renderStats()delegates torenderer.renderStats()(stats owned byRenderer).Blend mode hardcoded / incorrect Vulkan constants
SetBlendingcommand hardcodedSRC_ALPHA / ONE_MINUS_SRC_ALPHAregardless of the activeBlendMode. Now delegates toapplyBlendMode(BlendMode.ALPHA).VK_BLEND_FACTOR_DST_COLORwas8(correct:4) andVK_BLEND_FACTOR_DST_ALPHAwas10(correct:8). Fixed.WebGPU blend constants incorrect after upstream merge
Upstream introduced incorrect 1-based
WgpuBindingsblend factor/operation constants. Retained the correct 0-based values matching the WebGPU spec.New Interfaces
BlendFactorandBlendEquationNew extensible interfaces (static instances, no enums — matching codebase convention) covering the full set of standard blend factors and equations.
BlendModeextended with:enabled(),srcColorFactor(),dstColorFactor(),srcAlphaFactor(),dstAlphaFactor(),colorEquation(),alphaEquation()BlendMode.of(name, srcColor, dstColor, srcAlpha, dstAlpha[, colorEq, alphaEq])factory for fully custom blendingAll three backends now derive blend factors from the
BlendModeobject:glBlendFuncSeparate+glBlendEquationSeparatewithmapBlendFactor/mapBlendEquationhelpers; all missing GL blend constants added.BlendConfig.fromBlendMode(mode)factory added toVkPipelineFactory;BlendConfiggainscolorBlendOp/alphaBlendOpfields with correctVK_BLEND_OP_*mapping.mapBlendFactor/mapBlendEquationhelpers added; pipeline creation passes mapped equation constants.Per-attachment MRT blending (
RenderState.BLEND_MODES)Added
RenderState.BLEND_MODES(BlendMode[]) for independent blend state per color attachment in Multiple Render Target rendering. Indeximaps to attachmenti; the last entry is repeated for any extra attachments.glBlendFuncSeparatei/glBlendEquationSeparatei/glEnablei/glDisableitoGlBindings+LwjglGlBindings(GL 4.0+ indexed blend API).GlRenderDevicecalls the indexed variants per draw buffer whenBLEND_MODESis set.VkBindings.createGraphicsPipelinenow accepts per-attachment arrays.LwjglVkBindingscreates oneVkPipelineColorBlendAttachmentStateper attachment.VkPipelineFactory.createhas a newBlendConfig[]overload;VkRenderDevicetrackscurrentBlendModes, builds theBlendConfig[]viabuildBlendConfigs(), and incorporates all per-attachment mode names in the pipeline variant cache key.BLEND_MODESis silently ignored andBLEND_MODEapplies instead (limitation documented in Javadoc).BLEND_MODESis also registered inRenderStateManager.isRenderStateKey()so it is correctly excluded from material UBO uploads.WindowConfigNew
WindowConfigrecord (graphics/api) collects all window startup properties:title"Engine"width/height1280/720resizabletruedecoratedtruevsyncfalsefullscreenfalsealwaysOnTopfalseEngineConfignow holds aWindowConfiginternally. ExistingwindowTitle()/windowSize()accessors are preserved as backward-compatible methods. Builder gainswindowResizable(),windowDecorated(),windowVsync(),windowFullscreen(),windowAlwaysOnTop().BaseApplicationapplies all properties to the window handle after creation. AddedWindowProperty.ALWAYS_ON_TOPbacked by GLFWGLFW_FLOATING.API / Maintainability
GlobalParamNamesconstantsExtracted
"Engine","Camera","Object"magic strings intodev.engine.graphics.shader.GlobalParamNames. Used inRendererandUniformManager— including the previously missedbindGlobals()method which still had a raw"Object"literal.DrawCommand.materialDatatyped correctlyChanged
PropertyMap materialData(raw type) toPropertyMap<MaterialData>for compile-time type safety.BaseApplicationviewport set onceRemoved unconditional per-frame
setViewportcall that made theWindowEvent.Resizedhandler redundant. Viewport is now set once from actual window dimensions before the main loop and updated only onWindowEvent.Resized.BaseApplicationJavadoc updatedUpdated the
launch()example to show the current.graphics(new OpenGlConfig(...))API instead of the deprecated.graphicsBackend(...)path.ResourceCleaner.register()made publicWas package-private, blocking use of the Cleaner safety net outside
core.resource.Additional Findings (documented in
TODO.md)The independent review passes documented open items not yet fixed. New items added from reviewing the merged Debug UI code include:
DebugUiOverlayallocated in headless mode, GL/Vulkan scissor not clamped to viewport bounds,NkContextwindow accumulation,NkDrawList16-bit index limit, and thedebug_ui.slang[[vk::binding]]annotation propagating to all Slang targets. SeeTODO.mdfor the full list.