TL;DR
wgsl-rs가 Rust 코드를 WGSL로 변환하는 0.1.0-beta를 출시했으며, Rust와 WGSL 사이의 차이를 체계적으로 처리하고 런타임wgpu코드 생성을 지원함.- 베타 개발의 주요 작업은 런타임 IR 기반
wgpu코드 생성, Rust와 WGSL의 불일치 수정, WGSL 어휘 지원·버그 수정·문서화를 통한 출시 준비임. - 연산자 우선순위 차이로 인한 오컴파일을 막기 위해 이항식을 모두 괄호로 감싸고, 벡터 비교를
all(...)기반으로 변환하며, 정수 리터럴의 타입 추론을 위한 패스를 추가함. - 런타임 IR 순회로 제네릭 템플릿 모듈에서
wgpu파이프라인을 만들 수 있으며, 호출 그래프를 분석해 바인딩의 셰이더 단계 가시성을 결정함. wgsl-rs에는 게임 개발자와gpui-ce프로젝트가 사용자로 참여하고 있으며, 다음 단계는crabslab·craballoc이식과 GPU 기반 ECS 및 Renderling 셰이더·링크 구조 개편임.
`wgsl-rs` 베타 출시 회고
wgsl-rs를 출시함. 이번 베타 릴리스에는 상당한 작업이 들어갔으며, 지금까지 진행한 프로젝트 가운데 가장 체계적으로 구성된 프로젝트라고 평가함.- 프로젝트 개요는 GitHub 저장소와 이전 글인 *Introducing wgsl-rs*에서 확인할 수 있음.
개인적인 변화
- 시간제 개발자로 혼자 진행하기에는
wgsl-rs의 작업 규모가 지나치게 컸음. - 9월 초 본업을 잃은 뒤 프로젝트에 평소보다 더 많은 시간을 쓸 수 있었음. 다만 실제로 시간이 무한했던 것은 아님.
주요 성과
- *Introducing wgsl-rs* 이후 4개월 동안의 주요 작업은 세 가지임.
wgpu코드 생성을 런타임 중간 표현(IR) 기반으로 전환함.- Rust와 WGSL이 조용히 서로 다르게 동작하는 모든 부분을 체계적으로 찾아 해결함.
- WGSL 어휘 지원 범위를 확인하고 버그를 수정하며 문서를 갖춰 0.1.0-beta를 출시함.
- 기술 독자에게 흥미로울 만한 개발 기록의 주요 내용을 정리함.
가장 흥미로운 기술 변경 5가지
- 연산자 우선순위 역전(#159, 9월 20일)
- Rust에서는
&,^,|,<<,>>가==보다 우선순위가 높지만 WGSL에서는 그 반대임. - 렌더러가 이항식을 평평하게 출력해 Rust의
(0 & 0) == 0이 WGSL에서0 & 0 == 0이 됐고, 이는0 & (0 == 0)으로 다시 파싱돼 조용한 타입 오류성 오컴파일을 일으킴. 같은 종류의 문제로-(a + b)가-a + b로 바뀌기도 함. - 우선순위를 고려하는 렌더러보다 정확성을 우선해 모든 이항식을 완전히 괄호로 감싸도록 수정함.
- 벡터 동등성 비교는 마스크를 반환함(#164, 9월 15일)
- Rust의
==는bool을 반환하지만 WGSL의==는vecN을 반환함. - Rust 코드에서는 요소별 마스크를 직접 만들 수 없으므로, 단형화 이후 패스에서 벡터
==를all(lhs == rhs)로,!=를!(all(...))로 재작성함. - 요소별 비교를 위한 우회 방법으로
cmp_eq와cmp_ne자유 함수를 추가함. 타입을 추론할 수 없는 경우 패스가 변환하지 않고 넘어가므로 CPU 전용 코드의 컴파일은 유지됨. - 리터럴 접미사 패스(#145, 9월 21~26일)
- Rust는 문맥에 따라
0을u32로 추론하지만 WGSL은 접미사 없는 정수 리터럴을i32로 처리함. 따라서 Rust에서 컴파일되는select(0, 1, data)가naga검증에서 실패함. - GLM 5.2와 함께 스코프를 추적하는 ‘앵커링 패스’를 구축해 디섀도잉 슬롯에 배치함. 이 위치에서는 소스 코드, 상수 치환, 타입 치환, 확장 기능 하위 변환에서 오는 네 가지 리터럴 출처를 모두 확인함.
- Copilot과 Kimi K3를 활용한 일곱 차례 검토 뒤, 모든 경우를 명시적으로 처리하고 기본 분기(catch-all)가 없는 하향식이 아닌 상향식
infer(expr) -> Option추론으로 통합함. - 루프 변수 타입 추론은 제약 조건 해결기 대신 ‘탐색(probe)’을 사용하는 방식으로
rustc의 역방향 추론을 모방함. - IR에서 런타임
wgpu연결 생성(6월 6일, #120 및 7월 11·18일) syn트리를 순회하던 절차적 매크로 생성wgpu코드 약 650줄을 런타임 IR 순회로 대체함.- 이에 따라 제네릭 ‘템플릿’ 모듈에서 런타임에
path::to::module::instantiate::()를 호출해 실제wgpu파이프라인을 생성할 수 있음. - 버퍼 크기 계산은
size_of::()대신 WGSL §14.4.1을 따름.size_of::()는repr(C)가 아닌 구조체에서 올바르지 않았음. - API 역할은
wgsl_rs::Source가 ‘명세’,ir::Module이 ‘AST’이며, 순환 의존성을 방지하기 위해 메서드는 확장 트레이트에 배치함.wgsl-rs-ir가wgsl-rs에 의존할 수 없기 때문임. - 호출 그래프 기반 바인딩 단계 가시성(7월 18일, 이후 #177 및 9월 20일)
- 분석기가
ShaderStages::all()을 하드코딩해VERTEX_WRITABLE_STORAGE를 불필요하게 요구했고, 모든read_write컴퓨트 디스패치가 깨지는 문제가 있었음. - 엔트리 포인트별 식별자 스캔을 먼저 적용한 뒤, 보조 함수에서만 사용되는 바인딩도 올바르게 처리하도록 전체 전이 호출 그래프 도달성 분석으로 발전시킴.
- 모듈 전체 스캔은 필요하지 않은 기능까지 사용자에게 요구하는 지나치게 넓은 가시성을 만들기 때문에 채택하지 않음.
사용자
- 베타 출시를 서두른 이유 가운데 하나는 이미 프로젝트 사용자가 있었기 때문임. 연락을 준 두 사용자 중 한 명은 Jak Kos(jakkos-net on GitHub)임.
안녕하세요, 정말 멋진 프로젝트네요. 지난 며칠 동안 제 게임 개발 프로젝트의 WGSL 셰이더를 옮기며 즐겁게 작업했어요. 감사합니다 :D!
— jakkos-net
- Jak은 스토리지 텍스처 지원 누락 등 초기 구현의 여러 공백을 찾아냈으며, 게임을
wgsl-rs로 포팅하는 동안 발견한 버그의 이슈를 등록해 도움을 줌. - Jak에게 감사를 전함.
`gpui-ce`
- 또 다른 반가운 소식은
gpui-ce프로젝트가 셰이더 계층에wgsl-rs를 사용한다는 점임. gpui-ce는 Zed 편집기의gpui크레이트를 커뮤니티가 포크한 프로젝트임.- 웹 DOM에서 영감을 얻은 즉시 모드 렌더링 API를 제공함. 다만 그 방식은 단순한 즉시 모드 렌더링보다 더 세밀함.
- 현재 별 1.2k개를 받은 규모 있고 인상적인 프로젝트에 통합된 점을 영광으로 여김.
- 프로젝트 유지관리자인 Miles Wirht가 연락해 저장소의 셰이더를 보여줬지만, 소개 이메일이 스팸 폴더로 분류돼 이 소식을 거의 놓칠 뻔함.
- Miles에게 감사를 전함.
그 밖의 사용자
wgsl-rs를 사용 중이며 소개를 원한다면 연락을 요청함.
마무리와 다음 계획
- 다음으로 Rust-GPU에서
crabslab과craballoc을wgsl-rs로 포팅할 계획임. - 그 뒤 GPU에서 실행되는 ECS를 작성하고, 전체 스택을 사용해 Renderling의 셰이더와 연결 구조를 다시 작성할 계획임.
- 읽어준 독자에게 감사를 전함.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요