GGWiki
새 문서
현재 판이에요 · #164 AI 조사: 게임 용어 문서 · GGWiki 자동 ·

Standard Portable Intermediate Representation

개요

Standard Portable Intermediate Representation(SPIR)은 크로노스 그룹(Khronos Group)이 개발한 병렬 컴퓨팅 및 그래픽스용 중간 언어다. 셰이더나 커널을 표현하는 데 쓰이며, 크로스 컴파일을 위한 교환 언어로도 기능한다. 2014년 1월에 처음 공개되었으며 중간 표현(Intermediate Representation) 및 소프트웨어로 분류된다[1].

SPIR의 후속 버전인 SPIR-V는 2015년 크로노스 그룹에 의해 발표되어 기존 SPIR을 대체했다[2]. 2024년 9월 19일 마이크로소프트는 Direct3D 교환 포맷으로 DXIL 대신 SPIR-V를 채택할 계획임을 발표했으며, 셰이더 모델 7부터 지원을 시작한다고 밝혔다[2].

역사·유래

초기 SPIR (LLVM 기반)

SPIR은 2011년에 처음 소개되었으며, 2015년 SPIR-V가 나오기 전까지 LLVM 중간 표현(LLVM IR)을 기반으로 했다[2]. 2012년 SPIR 1.0 잠정 사양이 발표되었고, 2013년 7월 22일 SIGGRAPH 2013에서 SPIR 1.2 잠정 사양이 공개되었다. 최종 SPIR 1.2 사양은 2014년 1월 21일 HiPEAC 2014에서 릴리스되었다[2]. 2014년 8월 11일 SIGGRAPH 2014에서 SPIR 2.0 잠정 사양이 발표되었는데, SPIR 1.2는 LLVM 3.2 기반이고 SPIR 2.0은 LLVM 3.4 기반으로 각각 해당 OpenCL C 사양에 매핑된다[3].

SPIR-V의 등장

SPIR-V 1.0은 2015년 3월 발표되었고 2015년 11월 16일 정식 릴리스되었다[2]. SPIR-V는 LLVM을 사용하지 않으며, 크로노스 그룹이 완전히 정의한 진정한 크로스 API 표준으로 셰이더와 커널 기능을 네이티브로 지원한다[2]. 크로노스 그룹은 LLVM IR과의 상호 변환을 위한 별도 프로그램도 제공한다[2].

SPIR-V 섭취 지원은 OpenCL 2.1 핵심 사양, Vulkan API, OpenGL 4.6 버전에 통합되었다[2].

최신 동향

2024년 9월 19일 마이크로소프트는 DirectX 개발자 블로그를 통해 Direct3D 12가 셰이더 모델 7 릴리스부터 SPIR-V를 셰이더 교환 포맷으로 수용할 것이라고 발표했다[3]. 2026년 9월 10일에는 SPIR-V 1.6 리비전 8이 최신 사양 업데이트로 릴리스되었다[3].

작동 방식과 유형

목적과 설계 목표

SPIR-V의 목적은 다음과 같다[2]:

컴퓨팅과 그래픽스에 필요한 프리미티브를 네이티브로 표현

고수준 언어를 컴퓨팅 및 그래픽스 드라이버 인터페이스에서 분리

배포 형태이거나 완전 컴파일된 바이너리 형태로 배포

완전히 자기 완결적인 사양

다중 API 지원

크로스 컴파일 도구를 위한 중간 타겟 역할

주요 특징

SPIR-V는 바이너리 형태로 교환되는 고수준 중간 언어다[2]. 함수는 기본 블록의 제어 흐름 그래프로 표현되며 정적 단일 할당(SSA) 형태를 사용한다. 데이터 구조는 고수준 계층적 표현을 유지한다. 이전 바이트코드나 가상 머신류 중간 표현처럼 손실이 있는(lossy) 방식이 아니므로 타겟 디바이스에서 최적에 가까운 성능을 낼 수 있다[2].

드라이버에 고수준 언어 소스 컴파일러를 내장할 필요가 없어 드라이버 복잡도가 크게 줄어든다[2].

확장성

SPIR-V는 확장을 작성해 시맨틱을 추가하거나 토큰 값 범위를 예약해 당사자 용도로 쓸 수 있다[2]. 벤더는 독립적으로 원하는 시맨틱을 SPIR-V에 추가할 수 있다. 추가 확장 명령어 세트는 별도 사양으로 제공되며, 여러 세트를 문제없이 임포트할 수 있다. 확장 명령어는 세트 ID와 세트 내 명령어 ID를 지정해 사용한다[2].

셰이더 관련 기능

그래픽 셰이더는 SPIR-V에서 구조화된 제어 흐름을 사용해 제어 흐름의 중첩을 명시한다. 이는 병렬 실행 환경에서 제어 흐름의 발산(divergence)과 재수렴(reconvergence)을 정의하는 데 도움이 된다[2]. 특수화(specialization)를 통해 배포해야 할 셰이더 변종 수를 줄일 수 있다[2].

디버거로는 RenderDoc, SwiftShader, Amber 등이 있다[2].

검증

SPIR-V 사양은 유효한 SPIR-V 모듈이 따라야 할 규칙을 명시해 오프라인 검증을 가능하게 한다[2]. 드라이버는 유효하지 않은 SPIR-V 모듈을 처리할 의무가 없다. 적합성 테스트는 드라이버가 유효한 SPIR-V를 섭취할 때 올바르게 동작하는지 검증하고, 검증기는 프론트엔드가 SPIR-V를 올바르게 생성하는지 확인한다[2].

링킹

SPIR-V는 다른 컴파일 단위의 함수를 호출하는 것을 표현할 수 있다[2]. 표준 버전은 이 기능을 OpenCL 컴퓨트 커널에 사용하지만, 그래픽 API가 원하는 셰이더 스테이지는 단일 SPIR-V 모듈로 완전히 링크되어야 한다. 도구가 임시로 부분 링크된 셰이더와 커널을 사용하게 해주는 확장도 존재한다[2].

기능(Capabilities)

SPIR-V 모듈은 클라이언트 API가 지원하는 기능을 기능(capability)으로 분류해 모듈 초반에 선언한다[2]. 검증기는 모듈이 선언된 기능만 사용하는지 확인할 수 있고, 클라이언트 API는 지원하지 않는 기능을 선언한 모듈을 거부할 수 있다[2].

사례

주요 사용 API 및 환경

Vulkan: SPIR-V를 셰이더 중간 표현으로 핵심 채택[2][3]

OpenCL 2.1+: SPIR-V 섭취 지원이 핵심 사양에 통합[2][3]

OpenGL 4.6+: SPIR-V 지원 통합[2]

Direct3D 12 (Shader Model 7부터): 2024년 발표에 따라 SPIR-V를 교환 포맷으로 채택 예정[2][3]

WebGPU, SYCL, C++, Rust: SPIR-V와의 변환 경로 존재[2]

언어 프론트엔드 및 도구 생태계

SPIR-V 생태계에는 다양한 언어 프론트엔드(생산자), 개발 도구, 런타임(소비자)이 포함된다[3]. 주요 도구와 라이브러리는 다음과 같다[3]:

glslangValidator: GLSL을 SPIR-V로 컴파일

spirv-opt: SPIR-V 최적화

SPIRV-Cross: SPIR-V를 GLSL, GLSL ES, MSL, HLSL 등 고수준 셰이딩 언어로 역컴파일/크로스 컴파일

SPIR-V Tools: 어셈블러, 바이너리 모듈 파서, 디스어셈블러, 옵티마이저, 링커, 검증기 등 SPIR-V 모듈 처리를 위한 API와 명령어 제공

SPIR-V LLVM Translator: LLVM ↔ SPIR-V 변환기, LLVM 기반 프론트엔드 컴파일러의 기초로 활용

Compiler Explorer 상의 SPIR-V 예시: SPIR-V Optimizer, SPIR-V Validator

GLSL 버전 간 크로스 컴파일 활용

SPIR-V는 여러 버전의 소스 레벨 언어를 다루는 데 활용된다[2]. 예를 들어 OpenGL Shading Language(GLSL)의 여러 버전은 특정 구형 GLSL 버전에 고정된 구현체(예: WebGL 1.0, 애플의 OpenGL 구현) 때문에 여러 버전의 셰이더를 배포해야 한다. SPIR-V는 glslangValidator로 GLSL을 SPIR-V로 컴파일하고, spirv-opt로 최적화한 뒤, spirv-cross로 다른 GLSL 타겟으로 크로스 컴파일하는 교환 포맷 역할을 한다[2].

다만 SPIR-V는 모든 모듈이 최소 하나의 진입점 심볼을 가져야 한다는 요구사항 때문에 별도 컴파일(separate compilation)에는 제약이 있다. 복잡한 셰이더를 부분 컴파일 단계들의 연속과 링크 단계로 조립하기 어렵게 만든다. 이는 spirv-link 같은 완전한 SPIR-V 바이너리 코드 링킹 기능을 목표로 하는 도구의 취지와 상충된다[2].

규제·논란·평가

드라이버 복잡도 감소 및 생태계 활성화

SPIR-V는 고수준 언어 프론트엔드 컴파일러를 디바이스 드라이버에서 제거함으로써 드라이버 복잡도를 크게 낮추고, 다양한 언어와 프레임워크 프론트엔드가 다양한 하드웨어 아키텍처에서 실행되게 한다[3]. 이는 오픈 소스 분석, 포팅, 디버그, 최적화 도구의 활기찬 생태계를 장려한다[3].

개발자 이점

개발자 입장에서는 커널 소스 코드를 직접 노출하지 않아도 되고, 커널 로드 시간을 단축할 수 있으며, 공통 언어 프론트엔드 컴파일러를 선택해 여러 하드웨어 구현체 간 커널 신뢰성과 이식성을 높일 수 있다[3].

산업계 평가

인텔의 수석 엔지니어이자 SPIR 워킹 그룹 의장인 벤 애슈보(Ben Ashbaugh)는 "SPIR-V는 크로노스 그룹 소프트웨어 개발자 생태계의 기초 요소로, 컴파일러와 API 런타임을 연결하는 가치 있고 표준적인 중간 표현을 제공하며, 오픈 표준 기반 다중 아키텍처 소프트웨어 개발의 최전선에 있다"고 평가했다[3].

크로스 컴파일 한계

교환 포맷으로서 SPIR-V는 크로스 컴파일에 몇 가지 제약이 있다[2]. 모든 모듈이 최소 하나의 진입점 심볼을 가져야 한다는 요구사항이 별도 컴파일 워크플로를 방해하며, 이는 일부 SPIR-V 도구의 목표와 모순된다[2].

검증 및 적합성 체계

오프라인 검증과 적합성 테스트, 검증기 역할을 분리해 드라이버 부담을 줄이고 프론트엔드 품질을 보장하는 체계를 갖췄다[2]. 드라이버는 유효하지 않은 모듈을 처리할 의무가 없다[2].

벤더 확장 지원

확장 메커니즘을 통해 벤더가 독립적으로 시맨틱을 추가할 수 있게 해 표준화와 유연성을 동시에 추구한다[2].

마이크로소프트의 채택 의미

DirectX가 SPIR-V를 교환 포맷으로 채택하기로 한 것은 SPIR-V가 크로노스 API 생태계를 넘어 업계 표준 중간 표현으로 자리잡고 있음을 보여준다[2][3].

이 문서는 GGWiki AI가 공개 자료(아래 출처)를 조사해 새로 쓴 초안입니다. 틀린 내용은 편집하거나 이의 제기로 알려 주세요.