잡다

Vulkan Layer

갈색바람 2020. 11. 14. 16:26

Windows 개발환경에서 Android를 위한 Vulkan layer 개발

  1. 1. Vulkan SDK 설치
    • vulkan.lunarg.com/sdk/home#windows
  2. Environment variable 설정
    • VULKAN_SDK
  3. Android SDK 설정
    • Android studio 설치 후, SDK 매니저로 SDK 설치 및 NDK 설치
    • Env. variable 설정
      • ANDROID_SDK
      • NDK_ROOT
      • Path 에도 등록
  4. $VULKAN_SDK 의 LayerFactory 폴더를 복사하여 사용
    • LayerFactory 내에 Project 폴더를 layer 폴더로 수정
    • src 폴더 생성
      • layer_factory.cpp 파일 및 header파일을 layer 폴더로 넣기
      • interceptor_objects.h 생성 (layer_factory.cpp:65 에서 include하며, interceptor_object.h에서 include할 파일에 추후 funciton override 하여 사용할 것임)
    • create_vlf_files.bat 은 필요가 없는 파일
  5. 만들고 싶은 layer 이름에 맞는 환경 구성
    • 만들고 싶은 layer의 이름 정하기
      • 예로 object_tracker
    • 해당 Vulkan layer의 layer 이름 및 module 이름 작명
      • Module: VkLayer_object_tracker
      • Layer: VK_LAYER_object_tracker
    • src 폴더에 object_tracker.h 및 cpp 파일 생성
  6. 코드 작성 (object_tracker.h)
          • layer_factory class 를 상속받아 작성 하면 된다
          • layer_factory class 가 생성되면 constructor에서 global_interceptor_list 에 등록되며,
          • 상속받은 class에서 Pre_VkFunction/Post_VkFunction 함수를 override 할 경우 해당 VkFunction 이 불렸을 때 interceptor list 의 override된 함수를 call 한다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include "layer_factory.h"
    #include <unordered_map>
     
    class ObjectTracker : public layer_factory
    {
    public:
        ObjectTracker()
            : totalAllocSize(0)
            , numFrame(0)
            {
            };
     
        VkResult PostCallAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory, VkResult result);
     
        void PreCallFreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks *pAllocator);
     
    private:
        size_t totalAllocSize;
        size_t numFrame;
        std::unordered_map<VkDeviceMemory, VkDeviceSize> memorySizeMap;
    };
    cs
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include "object_tracker.h"
    #include <unordered_map>
    #include <string>
     
    VkResult ObjectTracker::PostCallAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo, const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory, VkResult result)
    {
        if(result == VK_SUCCESS)
        {
            totalAllocSize+=pAllocateInfo->allocationSize;
            memorySizeMap[*pMemory] = pAllocateInfo->allocationSize;
        }
        return result;
    };
     
    void ObjectTracker::PreCallFreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks *pAllocator)
    {
        if (memory != VK_NULL_HANDLE)
        {
            totalAllocSize -= memorySizeMap[memory];
        }
    }
     
    ObjectTracker objTracker;
    cs
      • cpp 파일에서 ObjectTracker를 instance화 한다.
      • interceptor_objects.h 에는 object_tracker.h 를 include 한다
      • Allocate 받은 memory에 대해서는 tracking이 가능하지만 log로 출력하기에는 추가적인 단계가 필요하다.
      • Log를 60프레임 마다 출력하기 위해서는 QueuePresentKHR (GL에서 swapbuffers 함수와 비슷한 역할) 에서 log를 print하면 된다
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    VkResult ObjectTracker::PreCallQueuePresentKHR(VkQueue queueconst VkPresentInfoKHR *pPresentInfo)
    {
        numFrame++;
        if (numFrame >= tick)
        {
            numFrame = 0;
            std::string info = "Alloc Memory: " + std::to_string(totalAllocSize);
            LOGI("%s", info.c_str());
        }
        return VK_SUCCESS;
    };
     
    cs
  7. Layer name 설정 (layer_factory.cpp)
      • default layer name은 VK_LAYER_LUNARG_layer_factory 로 되어있다
      • 다음 부분을 수정하여 이를 우리의 layer name 으로 설정하고 layer 설명을 수정할 수 있다
    78
    79
    80
    static const VkLayerProperties global_layer = {
        "VK_LAYER_object_tracker", VK_LAYER_API_VERSION, 1"Object tracker test layer",
    };
    cs

     

  8. Android build 환경 만들기
      • layerFactory 폴더 내에 jni 폴더를 만들고 Android.mk, Application.mk 파일 생성
      • Android.mk
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    LOCAL_PATH := $(call my-dir)
    SRC_DIR := ../src
     
    VULKAN_INCLUDE := $(VULKAN_SDK)/include
    LAYER_INCLUDE := ../layer
     
    include $(CLEAR_VARS)
    LOCAL_MODULE := VkLayer_object_tracker
    LOCAL_SRC_FILES +=  $(SRC_DIR)/layer_factory.cpp \
                        $(SRC_DIR)/object_tracker.cpp \
                        $(LAYER_INCLUDE)/vk_format_utils.cpp \
                        $(LAYER_INCLUDE)/vk_layer_config.cpp \
                        $(LAYER_INCLUDE)/vk_layer_extension_utils.cpp \
                        $(LAYER_INCLUDE)/vk_layer_utils.cpp \
                        $(LAYER_INCLUDE)/xxhash.c
    LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(SRC_DIR) \
                        $(LOCAL_PATH)/$(LAYER_INCLUDE) \
                        $(VULKAN_INCLUDE)
                       
    LOCAL_CPPFLAGS += -std=c++11 -Wall -Werror -Wno-unused-function -Wno-unused-const-variable
    # LOCAL_CPPFLAGS += -DVK_ENABLE_BETA_EXTENSIONS -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES -fvisibility=hidden
     
    # include android logging and others
    LOCAL_LDLIBS    := -llog -landroid
     
    #LOCAL_LDFLAGS   += -Wl,-Bsymbolic
    #LOCAL_LDFLAGS   += -Wl,--exclude-libs,ALL
    include $(BUILD_SHARED_LIBRARY)
     
    cs
         
      • Application.mk
    1
    2
    3
    4
    5
    APP_ABI := arm64-v8a
    APP_PLATFORM := android-26
    APP_STL := c++_static
    NDK_TOOLCHAIN_VERSION := clang
    NDK_MODULE_PATH := .
    cs
  9. ndk-build 실행
    • ndk-build -j8 

 

참고: github.com/krsml/vulkanObjectTracker.git

'잡다' 카테고리의 다른 글

Bitonic sort  (0) 2020.12.22
OIT : Weighted, Blended OIT  (0) 2020.12.09
Order Independent Transparency  (0) 2020.12.03
Android Vulkan layer 적용  (0) 2020.11.18
Ogg vorbis  (1) 2015.09.04