Skip to content

Add compute pipeline and buffer layout support enhancements#41

Merged
ZhuRuoLing merged 9 commits into
Anvil-Dev:dev/26.1from
ZhuRuoLing:dev/26.1
Jun 8, 2026
Merged

Add compute pipeline and buffer layout support enhancements#41
ZhuRuoLing merged 9 commits into
Anvil-Dev:dev/26.1from
ZhuRuoLing:dev/26.1

Conversation

@ZhuRuoLing

@ZhuRuoLing ZhuRuoLing commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

概述

为 AnvilLib Rendering 模块添加 Compute Pipeline 支持和 Buffer Layout 系统重构。这是为后续 GPU 计算管线(如后处理效果、粒子模拟等)打基础。

变更内容

Compute Pipeline 支持

新增完整的 Compute Pipeline 抽象层,基于 Minecraft Blaze3D 渲染后端扩展:

  • 管线与通道: ALRComputePipeline / ALRComputePass — Compute 管线与通道顶层抽象; ALRComputePassBackend / GlComputePassBackend — OpenGL 后端实现(封装 glDispatchCompute + 内存屏障)
  • Compute Shader 管理: ALRComputeShaderManager / ALRComputeProgramInstance / ShaderResourceType
  • Binding 类型: UniformBlockBinding / ShaderStorageBinding / ImageBinding / AtomicCounterBinding / TextureBinding
  • 后端扩展接口: ALRGpuDeviceExtension / ALRCommandEncoderExtension / MemoryBarrierFlag / ALRComputeCapabilities
  • Mixin 注入: CommandEncoderMixin / GlCommandEncoderMixin / GpuDeviceMixin / GlDeviceMixin / GlDebugLabelMixin

Buffer Layout 系统重构

将原先仅支持 UBO 的 UboLayout* 类重构为通用的 BufferObjectLayout* 系统:

  • 新抽象层: BufferObjectLayoutDefinition / BufferObjectLayoutEntry / BufferObjectLayoutEntryType / ShaderBufferObjectUsage / BufferLayout / BufferSizeCalculator / BufferWriter
  • std140 支持: Std140SizeCalculator / Std140Writer(替换旧的 UboLayoutDefinition / UboLayoutEntry / UboLayoutEntryType
  • 新增 std430 支持: Std430SizeCalculator / Std430Writer(用于 SSBO)
  • BufferObject 增强: 扩展支持新布局系统
  • 单元测试: Std140LayoutRulesTest(139 行,覆盖所有 std140 对齐规则)

Blur 重构

  • BlurParametersUbobloom 包迁移到 blur 包,与 GaussianBlur 统一管理
  • 删除 BlurParametersUbo.java(旧 bloom 包下的)中冗余引用

事件系统扩展

  • MainTargetResizeEvent — 主渲染目标尺寸变化事件
  • RegisterComputePipelinesEvent — Compute 管线注册事件

GUI 渲染增强

  • DynamicTextureBlitRenderState — 动态纹理 Blit 渲染状态,支持透明纹理渲染
  • GuiRenderExtras 大幅扩展(+138 行),新增辅助渲染方法

配置与 Mixin

  • module.rendering/build.gradle 添加依赖声明; module.gradle 配置更新
  • anvillib_rendering.mixins.json 注册新的 Mixin 类; accesstransformer.cfg 添加所需 AT 条目

测试

  • Compute 测试 (module.test): ComputeSupport(240 行测试基础设施)、TestPipelines、4 个 Compute Shader 测试资源(add.csh / empty.csh / image_and_sampler.csh / test.csh)
  • CachedBER 测试: TestCachedRenderer 更新适配

兼容性

  • 向后兼容:旧的 UboLayout API 已完全移除,替换为新的 BufferObjectLayout 体系
  • 仅影响 Rendering 模块,无跨模块破坏性变更

@ZhuRuoLing

Copy link
Copy Markdown
Contributor Author

Code Review Summary

Verdict: Changes Requested (3 critical, 6 warnings, 6 suggestions)

#41 的全面回顾。总体架构设计良好,分层清晰(Extension 接口 → Mixin 注入 → Compute Pipeline → Binding Types)。Buffer Layout 重构从 UBO-only 泛化到通用系统,std140/std430 实现正确。但有 3 个关键 bug 需要修复。


🔴 Critical

1. DynamicTextureBlitRenderState — UV 坐标交换 (v0 ↔ u1)
File: module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/gui/state/DynamicTextureBlitRenderState.java
Lines: 53–56

Compact constructor 接收的参数顺序为 (..., u0, v0, u1, v1),但传递给 canonical constructor 时使用了 u0, u1, v0, v1

this(
    pipeline, textureSetup, pose,
    x0, y0, x1, y1,
    u0, u1, v0, v1,   // ← BUG: 应为 u0, v0, u1, v1
    color, scissorArea,
    getBounds(x0, y0, x1, y1, pose, scissorArea)
);

影响: 当通过 GuiRenderExtras.blitDynamicTexture() 调用时,纹理的 UV 坐标错乱。渲染动态纹理时纹理映射不正确。

修复: 将第 54 行改为 u0, v0, u1, v1


2. Test MinecraftMixin 未在 anvillib_test.mixins.json 中注册
File: module.test/src/main/resources/anvillib_test.mixins.json
File: module.test/src/main/java/dev/anvilcraft/lib/v2/test/mixin/MinecraftMixin.java

MinecraftMixin<init> 中注入 ComputeSupport.init() 来初始化计算着色器测试框架,但它未出现在任何 mixin 配置数组中。测试 mixin JSON 的 "client""mixins" 数组均不包含此 mixin。

影响: ComputeSupport.init() 永远不会被调用 → GPU 计算测试基础设施(SSBO/UBO/atomic counter/fence)全部静默失效 — 测试管线不会被注册,计算着色器不会编译。

修复:"dev.anvilcraft.lib.v2.test.mixin.MinecraftMixin" 添加到 anvillib_test.mixins.json"mixins" 数组或 "client" 数组中。


3. GlDebugLabelMixin — 标签对象类型错误 (GL_SHADER vs GL_PROGRAM)
Files:

  • module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/mixins/blaze3d/gl/GlDebugLabelMixin.java (line 33, 51)

KHRDebug.glObjectLabel() 传入 GL46.GL_SHADER (0x8B31),但 compute program 是通过 glCreateProgram() 创建的程序对象,应使用 GL46.GL_PROGRAM (0x8B40) 或 GL_OBJECT_TYPE_EXT

同样,EXTDebugLabel.glLabelObjectEXT() 中的 GL_SHADER_OBJECT_EXT 也应改为 EXTDebugLabel.GL_PROGRAM_OBJECT_EXT

影响: Debug label 会被绑定到错误的 GL 对象上,在 GPU debugger/RenderDoc 中无法正确识别 compute program。不影响运行正确性,但严重影响开发调试体验。


🟡 Warnings

4. ALRComputeShaderManager — Compute 不支持时的 NPE 风险
File: module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/extension/blaze3d/compute/shader/ALRComputeShaderManager.java (line 62–72)
File: module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/extension/blaze3d/compute/pipeline/gl/GlComputePassBackend.java (line 113)

如果 ALRComputeCapabilities.isComputeSupported() 返回 false,apply() 会提前退出且不更新 source,也不编译任何管线。但 GlComputePassBackend.setupState() 中的 getShader(pipeline).id()pipelineToProgramMap 为空时会 NPE。

建议:在 setupState() 中添加非空检查:

ALRComputeProgramInstance program = ALRComputeShaderManager.INSTANCE.getShader(pipeline);
if (program == null || program == ALRComputeProgramInstance.INVALID) return;

5. GlComputePassBackend — 未使用的字段 backend
File: module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/extension/blaze3d/compute/pipeline/gl/GlComputePassBackend.java (line 28, 43)

private final GpuDeviceBackend backend; // 仅在构造函数中赋值,从未被使用

构造函数中 this.backend = (GpuDeviceBackend) backendExtension; 是死代码。实际工作都通过 this.backendExtensionthis.commandEncoderExtension 完成。建议移除。


6. module.rendering/build.gradle — 空 dependencies{}
如果此模块依赖其他子模块(如 module.main),应在此声明。


7. anvillib_rendering.mixins.json — 兼容性级别 JAVA_8
NeoForge 26.1 的 Java 版本要求通常是 Java 21。compatibilityLevel 设为 JAVA_8 虽然不影响实际运行,但建议改为 JAVA_17JAVA_21 以匹配实际环境。


8. AnvilLibTestClient.java — 未使用的 javafx.util.Pair 导入

import javafx.util.Pair; // 未使用,Minecraft 环境通常不包含 JavaFX

可能造成编译警告或错误。需要移除该 import。


🟢 Suggestions

9. ALRComputePass.dispatchWorkgroupsIndirect — 缺少 debug group
File: module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/extension/blaze3d/compute/pipeline/ALRComputePass.java (line 41–45)

dispatchWorkgroups 包裹了 pushDebugGroup/popDebugGroup,但 dispatchWorkgroupsIndirect 没有。建议添加一致的 debug group 包装。


10. GaussianBlur.java — Debug label 前缀与包名不一致
File: module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/blur/GaussianBlur.java

Debug label 仍使用 "BloomPostEffect->..." 前缀,但该类在 blur/ 包中且属于 GaussianBlur。建议改为 "GaussianBlur->..."


11. Std140LayoutRulesTest — 使用 main() 方法 + 自定义断言
File: module.rendering/src/test/java/dev/anvilcraft/lib/v2/rendering/foundation/buffers/layout/Std140LayoutRulesTest.java

测试覆盖全面(std140 alignment、struct array padding、索引写入、std430 紧凑布局),但使用 main() 方法和自定义 assertEquals 而非标准测试框架。不会被标准测试运行器发现。建议迁移到 JUnit 5。


12. CachedRenderingChunk + CachedBlockEntityRenderingPipeline — 静态状态管理
cameraOldPositionstatic 变量,在多世界切换场景下(如 singleplayer → server)可能未正确重置。当前通过 updateLevel(null) 隐式处理。建议在 releaseBuffers() 中显式重置。


13. ComputeSupport.add() — 未使用的 int anInt
File: module.test/src/main/java/dev/anvilcraft/lib/v2/test/client/compute/ComputeSupport.java (line 143)

int anInt = counterData.getInt(); // 读取后丢弃

可能是调试遗留。建议移除或添加用途说明。


14. BufferLayout enum-like design — 建议改用 enum 提高类型安全
File: module.rendering/src/main/java/dev/anvilcraft/lib/v2/rendering/foundation/buffers/layout/BufferLayout.java

当前 STD140STD430 通过匿名内部类实现接口。考虑改为 enum 以简化 == 比较(当前代码中已有 layout == BufferLayout.STD140 的比较)。


✅ Looks Good

  • 架构设计优秀: Extension 接口 → Mixin 注入 → Compute Pipeline 的分层设计清晰且可扩展。后端抽象 (ALRComputePassBackend) 便于未来添加 Vulkan 等后端。

  • Binding 类型系统: 使用泛型 ComputeBindingLayout<T> 做编译时类型检查,5 种绑定类型覆盖完整(Texture、Image、UBO、SSBO、Atomic Counter)。

  • Buffer Layout 重构彻底:UboLayout*BufferObjectLayout* 的泛化迁移完整,所有旧引用均已删除。std140 和 std430 的对齐规则实现正确。

  • 着色器测试: 4 个计算着色器 (test.csh, add.csh, image_and_sampler.csh, empty.csh) 覆盖了 sampler、image、SSBO、UBO、atomic counter 等各种资源类型的综合测试。

  • Mixin 注入设计良好: CommandEncoderMixin / GpuDeviceMixin 作为门面层,将实现委托给 GlCommandEncoderMixin / GlDeviceMixin,符合接口分离原则。

  • Compute Capabilities 检查: ALRComputeCapabilities 在每次资源重载时检查 GL_ARB_compute_shader,保证了向后兼容性。


Reviewed by Hermes Agent

@ZhuRuoLing

Copy link
Copy Markdown
Contributor Author

✅ 更新 — 推动修复验证

新的推送解决了我之前报告的 全部 3 个关键问题 以及若干警告。谢谢快速修复!

🔴 已修复 (3/3)

问题 状态
DynamicTextureBlitRenderState UV 坐标交换 u0, v0, u1, v1 顺序已修正
MinecraftMixin 未在 anvillib_test.mixins.json 注册 ✅ 已添加到 "client" 数组
GlDebugLabelMixin GL_SHADERGL_PROGRAM ✅ 对象类型更正

🟡 已修复 (4/6)

问题 状态
GlComputePassBackend 未使用的 backend 字段 ✅ 已移除
setupState() 中 NPE 风险 (getShader(pipeline).id()) ✅ 增加了 null/INVALID 检查
AnvilLibTestClient.java 未使用的 javafx.util.Pair 导入 ✅ 已移除
ComputeSupport 未使用的 int anInt ✅ 增加了 diagnostic System.out.printf

🟢 建议尚未处理(均为非阻塞)

  • mixins.json 中的 JAVA_8 兼容级别(对功能无影响)
  • GaussianBlur debug label 使用 "BloomPostEffect" 前缀(视觉上稍显混乱但无功能问题)
  • dispatchWorkgroupsIndirect 缺少 debug group(仅影响开发者调试时的标签)
  • Std140LayoutRulesTest 建议迁移到 JUnit(测试本身很扎实)
  • CachedRenderingChunk 静态 cameraOldPosition 管理(边缘场景)

以上建议不会阻止合入。代码质量良好,可以合并 ✅


由 Hermes Agent 更新 — 改动已验证

@ZhuRuoLing ZhuRuoLing merged commit 7d07f20 into Anvil-Dev:dev/26.1 Jun 8, 2026
16 checks passed
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.

1 participant