⭐ Vulkan & CMake/Vulkan

[Vulkan] SPIR-V

Designerd 2024. 9. 10. 14:21

SPIR-V (Standard Portable Intermediate Representation V)는 Vulkan의 Shader 언어다.

 

목차

     

     


     

     


    인프런 삼각형님의 '삼각형의 실전! Vulkan 중급' 강의를 참고하였습니다. 

    😎 [삼각형의 실전! Vulkan 중급] 강의 들으러 가기!

     

     

     

     

    SPIR-V


     

     

    SPIR-V란?

     

    SPIR는 Standard Portable Intermediate Representation의 약어다. SPIR-V는 SPIR로부터 파생되었다.

    SPIR-V는 Vulkan의 Shader 언어다.

     

     

    SPIR-V가 Vulkan과 OpenCL에서 사용되기 시작하면서 그래픽스와 컴퓨팅 생태계의 모습이 근본적으로 변하게 될 것입니다. 특히 다양한 언어를 개발자들이 사용할 수 있기 때문입니다. 또한 벤더들은 드라이버 개발과 최적화에 집중을 할 수 있게 되었습니다.

    - by Neil Trevett 

     

     

     

     

    다양한 언어가 SPIR로 컴파일되고 컴파일된 SPIR는 다양한 API에서 작동한다. 또한 SPIR는 LLVM을 기반이기 때문에  LLVM의 다양한 최적화 패스를 손쉽게 적용할 수 있다.

     

    이러한 SPIR의 장점 덕분에 개발자들은 새로운 언어를 배우는데 시간을 소비하지 않고 코드 작성에 더 집중할 수 있다. 또한 Vendor들은 다양한 언어 복잡성을 관리하는 대신 코드 최적화에 더욱 집중할 수 있다. 

     

     

    SPIR-V 예시


     

     

    shaderc 빌드

     

    Vulkan Shader를 SPIR-V로 컴파일하기 위해 구글의 shaderc 라이브러리를 사용.

     

     

    https://developer.android.com/ndk/guides/graphics/shader-compilers?hl=ko

     

    Android의 Vulkan 셰이더 컴파일러  |  Android NDK  |  Android Developers

    이 페이지는 Cloud Translation API를 통해 번역되었습니다. Android의 Vulkan 셰이더 컴파일러 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Vulkan 앱은 OpenGL ES 앱과

    developer.android.com

     


     

     

    shaderc 사용법

     


     

     

    코드

     

    ShadercTest.kt 생성

    더보기
    package com.inflearn.practicevulkan
    
    import androidx.test.ext.junitgtest.GtestRunner
    import androidx.test.ext.junitgtest.TargetLibrary
    import org.junit.runner.RunWith
    
    @RunWith(GtestRunner::class)
    @TargetLibrary(libraryName = "shaderctest")
    class ShadercTest

     

     

    build.gradle.kts 수정

    더보기
    plugins {
        id("com.android.application")
        id("org.jetbrains.kotlin.android")
    }
    
    android {
        namespace = "com.inflearn.practicevulkan"
        compileSdk = 34
    
        defaultConfig {
            applicationId = "com.inflearn.practicevulkan"
            minSdk = 33
            targetSdk = 34
            versionCode = 1
            versionName = "1.0"
    
            testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                cmake {
                    cppFlags += "-std=c++17"
                }
            }
        }
    
        buildTypes {
            release {
                isMinifyEnabled = false
                proguardFiles(
                    getDefaultProguardFile("proguard-android-optimize.txt"),
                    "proguard-rules.pro"
                )
            }
        }
        compileOptions {
            sourceCompatibility = JavaVersion.VERSION_1_8
            targetCompatibility = JavaVersion.VERSION_1_8
        }
        kotlinOptions {
            jvmTarget = "1.8"
        }
        buildFeatures {
            prefab = true
        }
        externalNativeBuild {
            cmake {
                path = file("src/main/cpp/CMakeLists.txt")
                version = "3.22.1"
            }
        }
    }
    
    dependencies {
        implementation("androidx.core:core-ktx:1.13.0")
        implementation("androidx.appcompat:appcompat:1.6.1")
        implementation("com.google.android.material:material:1.11.0")
        implementation("androidx.games:games-activity:1.2.2")
        implementation("androidx.test.ext:junit-gtest:1.0.0-alpha02")
        implementation("com.android.ndk.thirdparty:googletest:1.11.0-beta-1")
        testImplementation("junit:junit:4.13.2")
        androidTestImplementation("androidx.test.ext:junit:1.1.5")
        androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
    }

    코드 추가

     


    ShaderTest.cpp
     생성

    더보기
    #include <sstream>
    #include <string>
    #include <string_view>
    #include <gtest/gtest.h>
    #include <shaderc/shaderc.hpp>
    
    TEST(shaderc, compile) {
        constexpr std::string_view code{
            "#version 310 es\n"
            "void main() {"
            "}"
        };
    
        shaderc::Compiler compiler;
        shaderc::CompileOptions options;
        auto result = compiler.CompileGlslToSpvAssembly(
            code.data(), code.size(), shaderc_vertex_shader, "test", options);
        EXPECT_EQ(result.GetCompilationStatus(), shaderc_compilation_status_success);
    
        std::string spv(result.cbegin(), result.cend());
        std::istringstream iss(spv);
        std::string header;
        std::getline(iss, header);
        EXPECT_EQ(header, "; SPIR-V");
    }

     

     

    CMakeLists.txt 수정

    더보기
    # For more information about using CMake with Android Studio, read the
    # documentation: https://d.android.com/studio/projects/add-native-code.html
    
    cmake_minimum_required(VERSION 3.22.1)
    
    project("practicevulkan")
    
    ####################################################################################################
    # shaderc 정의
    ####################################################################################################
    set(CMAKE_SHADERRC ${CMAKE_ANDROID_NDK}/sources/third_party/shaderc)
    add_library(shaderc INTERFACE)
    
    target_include_directories(shaderc INTERFACE
            ${CMAKE_SHADERRC}/include)
    
    target_link_libraries(shaderc INTERFACE
            ${CMAKE_SHADERRC}/libs/system/${CMAKE_ANDROID_ARCH_ABI}/libshaderc.a)
    
    ####################################################################################################
    # practicevulkan 정의
    ####################################################################################################
    find_package(game-activity REQUIRED CONFIG)
    find_package(Vulkan REQUIRED)
    
    add_library(practicevulkan SHARED
            VkRenderer.h
            VkRenderer.cpp
            VkUtil.h
            main.cpp
            AndroidOut.cpp)
    
    target_compile_definitions(practicevulkan PRIVATE
            VK_USE_PLATFORM_ANDROID_KHR)
    
    target_link_libraries(practicevulkan
            game-activity::game-activity
            android
            log
            Vulkan::Vulkan
            shaderc)
    
    ####################################################################################################
    # shaderctest 정의
    ####################################################################################################
    find_package(googletest REQUIRED CONFIG)
    find_package(junit-gtest REQUIRED CONFIG)
    
    add_library(shaderctest SHARED
            ShadercTest.cpp)
    
    target_link_libraries(shaderctest PRIVATE
            googletest::gtest
            junit-gtest::junit-gtest
            shaderc)