Files
daiqingshuang 5a8d62f841 Refactor Push Constants and Add Dual Stage Support
- Removed legacy push constant structures and functions for better clarity and maintainability.
- Introduced new `text_push_constants_t` structure for text rendering with optimized layout.
- Implemented dual stage push constant analysis to support separate layouts for vertex and fragment shaders.
- Added functions to generate push constant structures and fill functions based on shader reflection.
- Enhanced static checks for push constant layouts to ensure compatibility and correctness.
- Updated templates to accommodate new dual stage push constant generation.
- Added support detection for procedural vertex shaders based on push constant layout.
2025-12-25 21:04:39 +08:00
..
2025-12-25 13:20:16 +08:00
2025-11-24 22:35:44 +08:00
2025-11-24 22:35:44 +08:00
2025-11-27 23:44:24 +08:00

GLSL Shader Compilation Tools

GLSL着色器编译和C++绑定生成工具集。

📁 模块结构

tools/
├── __init__.py           # 包初始化,导出公共接口
├── main.py              # 主入口文件 (~200行)
├── constants.py         # SPIR-V常量定义 (~80行)
├── types.py             # 数据类型定义 (~210行)
├── spirv_parser.py      # SPIR-V二进制解析 (~430行)
├── type_mapping.py      # 类型映射和布局计算 (~220行)
├── code_generator.py    # C++代码生成 (~250行)
├── compiler.py          # ShaderCompiler类 (~130行)
└── utils.py             # 工具函数 (~150行)

总计: 原来的1520行代码被拆分为8个模块每个模块80-430行。

🔧 模块说明

1. constants.py

定义所有SPIR-V规范相关的常量

  • SPIR-V魔数和操作码
  • 装饰值Decoration
  • 执行模型和存储类
  • 着色器文件扩展名映射

2. types.py

定义所有数据类和枚举:

  • ToolError: 错误类型
  • StorageClass, BaseType: 枚举类型
  • TypeInfo系列: SPIR-V类型信息Scalar, Vector, Matrix, Array, Struct, Pointer
  • SPIRVReflection: 完整的反射信息
  • ShaderMetadata: 着色器元数据
  • CompilationResult: 编译结果

3. spirv_parser.py

SPIR-V二进制解析功能

  • parse_spirv_words(): 解析二进制为字数组
  • parse_spirv_instructions(): 解析指令流
  • parse_spirv_type_system(): 提取类型系统
  • resolve_all_types(): 解析类型引用
  • extract_buffers(): 提取buffer信息

4. type_mapping.py

SPIR-V到C++类型映射:

  • spirv_type_to_cpp(): 类型转换
  • calculate_std430_alignment(): 计算对齐
  • calculate_std430_size(): 计算大小
  • align_up(): 对齐辅助函数

5. code_generator.py

C++代码生成:

  • generate_buffer_structures(): 生成结构体定义
  • spirv_to_cpp_array(): 生成SPIR-V数组
  • generate_header(): 生成完整头文件
  • vk_descriptor_type_to_cpp(): Vulkan类型转换
  • vk_shader_stage_to_cpp(): 着色器阶段转换

6. compiler.py

着色器编译器:

  • ShaderCompiler: 主编译器类
    • compile_shader(): 编译单个着色器
    • _find_glslc(): 查找glslc编译器
    • _build_glslc_command(): 构建编译命令

7. utils.py

工具函数:

  • discover_shaders(): 发现着色器文件
  • group_shader_files(): 分组着色器
  • load_shader_metadata(): 加载元数据
  • read_directory_list(): 读取目录列表

8. main.py

主入口:

  • parse_args(): 参数解析
  • process_shader_group(): 处理着色器组
  • main(): 主函数

📊 依赖关系

Level 0: constants.py (无依赖)
         ↓
Level 1: types.py (依赖constants)
         ↓
Level 2: spirv_parser.py, type_mapping.py, utils.py (依赖types)
         ↓
Level 3: code_generator.py (依赖type_mapping)
         compiler.py (依赖spirv_parser)
         ↓
Level 4: main.py (依赖所有模块)

🚀 使用方法

命令行使用

# 基本用法
python -m tools.main -l path/to/shader_list.txt

# 启用详细日志
python -m tools.main -l shader_list.txt -d

# 指定输出目录
python -m tools.main -l shader_list.txt -o build/shaders

# 干运行(仅发现文件,不编译)
python -m tools.main -l shader_list.txt --dry-run

Python API使用

from tools import ShaderCompiler, discover_shaders, group_shader_files
from pathlib import Path

# 发现着色器
shader_dirs = [Path("src/render/shaders")]
shaders = discover_shaders(shader_dirs)

# 编译着色器
compiler = ShaderCompiler(verbose=True)
metadata = load_shader_metadata(shaders[0])
result = compiler.compile_shader(shaders[0], metadata, "comp")

print(f"Entry point: {result.entry_point}")
print(f"Bindings: {result.bindings}")

新结构的优势

  1. 模块化: 每个模块职责单一,易于理解和维护
  2. 可测试性: 独立模块便于单元测试
  3. 可复用性: 各模块可以独立导入使用
  4. 可扩展性: 添加新功能时只需修改相关模块
  5. 减少复杂度: 从单个1520行文件拆分为8个小文件

🔄 从旧版本迁移

旧版本的 tools/main.py 已被重构,但功能完全保持兼容:

# 旧用法(仍然有效)
python tools/main.py -l shader_list.txt

# 新用法(推荐)
python -m tools.main -l shader_list.txt

📝 开发指南

添加新的SPIR-V操作码

constants.py 中添加:

OP_NEW_OPCODE = 123

添加新的类型映射

type_mapping.py 中扩展 spirv_type_to_cpp() 函数。

自定义代码生成

修改 code_generator.py 中的生成函数。

🎯 Buffer 数据设置便捷功能

工具会自动为着色器中定义的 buffer 生成便捷的数据管理接口。

功能概览

生成三层抽象接口:

  1. 基础辅助函数 - create_*_buffer(), upload_*(), download_*()
  2. 类型安全包装器 - typed_buffer<T> 和类型别名
  3. 自动化管理器 - *_buffer_manager

配置选项

ShaderMetadata 中配置:

metadata = ShaderMetadata(
    # ... 其他字段 ...
    generate_buffer_helpers=True,   # 生成基础辅助函数
    generate_typed_buffers=True,    # 生成类型安全包装器
    generate_buffer_manager=True,   # 生成管理器类
)

使用示例

// 方式 1: 基础辅助函数
auto buffer = create_positions_buffer(rm, 1000).value();
upload_positions(device, buffer, data);

// 方式 2: 类型安全包装器
auto typed_buf = create_positions_typed(device, rm, 1000).value();
typed_buf.upload(data);
typed_buf.download(output);

// 方式 3: 自动化管理器(推荐)
auto mgr = particle_buffer_manager::create(device, rm, 1000).value();
mgr.initialize(positions, velocities);
mgr.bind_to_descriptor_set(pipeline, descriptor_set);

详细文档

参见 Buffer 数据设置便捷功能使用指南

🐛 故障排除

找不到glslc编译器

确保已安装Vulkan SDK并且glslc在PATH中。

导入错误

确保从项目根目录运行并且tools目录包含 __init__.py

编译失败

使用 -d 标志启用详细日志查看完整错误信息。

🎨 模板系统

从v2.0开始代码生成器使用Jinja2模板引擎而非字符串拼接。

优势

  • 可维护性模板和逻辑分离C++代码结构清晰
  • 可扩展性:添加新功能只需创建模板
  • 可读性:支持语法高亮,易于理解
  • 性能:模板编译缓存,性能优异

模板目录结构

tools/templates/
├── base/                    # 基础模板(头文件、结构体)
├── buffer_helpers/          # Buffer辅助函数
├── typed_buffer/            # 类型安全buffer
└── buffer_manager/          # Buffer管理器

详细文档

参见 Jinja2模板系统使用指南

自定义模板

from tools.template_loader import get_renderer

renderer = get_renderer()
result = renderer.render('my_template.jinja2', {
    'my_var': 'value',
})

测试

python tools/test_template_refactor.py

📚 相关文档