How to configure Vulkan on RK3326

The latest test patch to support Vulkan on RK3326 doesn't include important extensions.
Please refer to the following forum threads for the history and further discussions for this topic.

  1. bifrost_for_linux driver patch of kernel
  2. libmali patch

1. Kernel Level

  • drivers/gpu/arm/bifrost_for_linux
  • release_r13p0_20200103 version

https://github.com/hardkernel/linux/commit/fbfe5c30bf5643f44cc8c87c9b53b1ba2a0bfa49

2. Library Set-up (libmali)

  • release_r13p0_20200103 version
$ wget https://dn.odroid.com/RK3326/ODROID-GO-Advance/rk3326_r13p0_gbm_with_vulkan_and_cl.zip
$ unzip rk3326_r13p0_gbm_with_vulkan_and_cl.zip
$ ls
libmali.so_rk3326_gbm_arm32_r13p0_with_vulkan_and_cl  libmali.so_rk3326_gbm_arm64_r13p0_with_vulkan_and_cl
$ sudo rm /usr/local/lib/aarch64-linux-gnu/libmali-bifrost-g31-rxp0-gbm.so
$ sudo cp libmali.so_rk3326_gbm_arm64_r13p0_with_vulkan_and_cl  /usr/local/lib/aarch64-linux-gnu/libmali-bifrost-g31-rxp0-gbm.so
 
$ sudo rm /usr/local/lib/arm-linux-gnueabihf/libmali-bifrost-g31-rxp0-gbm.so
$ sudo cp libmali.so_rk3326_gbm_arm32_r13p0_with_vulkan_and_cl  /usr/local/lib/arm-linux-gnueabihf/libmali-bifrost-g31-rxp0-gbm.so

1. Vulkan-utils and libvulkan1

$ sudo apt install vulkan-utils libvulkan1 -y
$ ls /usr/lib/aarch64-linux-gnu/libvulkan.so*
/usr/lib/aarch64-linux-gnu/libvulkan.so  /usr/lib/aarch64-linux-gnu/libvulkan.so.1
 
$ rm /usr/lib/aarch64-linux-gnu/libvulkan.so*
 
$ ln -s /usr/local/lib/aarch64-linux-gnu/libmali-bifrost-g31-rxp0-gbm.so  /usr/lib/aarch64-linux-gnu/libvulkan.so
$ ln -s /usr/local/lib/aarch64-linux-gnu/libmali-bifrost-g31-rxp0-gbm.so  /usr/lib/aarch64-linux-gnu/libvulkan.so.1

2. Vulkan-Headers

CMake 3.10.2 is recommended to vuild Vulkan-Headers,Loader and Tools.

$ sudo apt install cmake -y
$ cmake --version
cmake version 3.10.2
CMake suite maintained and supported by Kitware (kitware.com/cmake).
$ git clone https://github.com/KhronosGroup/Vulkan-Headers.git
$ cd Vulkan-Headers
$ cd Vulkan-Headers
$ mkdir build
$ cd build
$ cmake -DCMAKE_INSTALL_PREFIX=/usr/local/  ..
$ make
$ sudo make install

3. Vulkan-Loader

$ git clone https://github.com/KhronosGroup/Vulkan-Loader.git
$ cd Vulkan-Loader
$ sudo apt-get install -y git build-essential libx11-xcb-dev \
    libxkbcommon-dev libwayland-dev libxrandr-dev
$ cd Vulkan-Loader
$ mkdir build
$ cd build
 
$ cmake -DCMAKE_BUILD_TYPE=Debug \
      -DVULKAN_HEADERS_INSTALL_DIR=/usr/local/  \
      -DCMAKE_INSTALL_PREFIX=/usr/local/  ..
 
$ make
$ sudo make install

4. Vulkan-Tools

$ git clone https://github.com/KhronosGroup/Vulkan-Tools.git
$ cd Vulkan-Tools
$ cd Vulkan-Tools
$ mkdir build
$ cd build
 
$ cmake -DCMAKE_BUILD_TYPE=Debug \
      -DVULKAN_HEADERS_INSTALL_DIR=/usr/local/ \
      -DCMAKE_INSTALL_PREFIX=/usr/local/ ..
 
(BUILD_CUBE set OFF from CMakeCache.txt in build)
 
$ make
$ sudo make install

Vulkaninfo

Now Vulkaninfo is available.

$ vulkaninfo 
'DISPLAY' environment variable not set... skipping surface info
==========
VULKANINFO
==========
 
Vulkan Instance Version: 1.0.108
 
 
Instance Extensions: count = 4
==============================
        VK_KHR_external_fence_capabilities     : extension revision 1
        VK_KHR_external_memory_capabilities    : extension revision 1
        VK_KHR_external_semaphore_capabilities : extension revision 1
        VK_KHR_get_physical_device_properties2 : extension revision 1
 
Layers: count = 0
=================
Presentable Surfaces:
=====================
 
Device Properties and Extensions:
=================================
GPU0:
VkPhysicalDeviceProperties:
---------------------------
        apiVersion     = 4194412 (1.0.108)
        driverVersion  = 54525952 (0x3400000)
        vendorID       = 0x13b5
        deviceID       = 0x70930000
        deviceType     = PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU
        deviceName     = Mali-G31
 
VkPhysicalDeviceLimits:
-----------------------
        maxImageDimension1D                             = 16384
        maxImageDimension2D                             = 8192
        maxImageDimension3D                             = 4096
        maxImageDimensionCube                           = 8192
        maxImageArrayLayers                             = 256
        maxTexelBufferElements                          = 65536
        maxUniformBufferRange                           = 65536
        maxStorageBufferRange                           = 268435456
        maxPushConstantsSize                            = 256
        maxMemoryAllocationCount                        = 4294967295
        maxSamplerAllocationCount                       = 4294967295
        bufferImageGranularity                          = 0x00001000
        sparseAddressSpaceSize                          = 0x00000000
        maxBoundDescriptorSets                          = 4
        maxPerStageDescriptorSamplers                   = 128
        maxPerStageDescriptorUniformBuffers             = 12
        maxPerStageDescriptorStorageBuffers             = 35
        maxPerStageDescriptorSampledImages              = 16
        maxPerStageDescriptorStorageImages              = 8
        maxPerStageDescriptorInputAttachments           = 4
        maxPerStageResources                            = 83
        maxDescriptorSetSamplers                        = 768
        maxDescriptorSetUniformBuffers                  = 72
        maxDescriptorSetUniformBuffersDynamic           = 8
        maxDescriptorSetStorageBuffers                  = 210
        maxDescriptorSetStorageBuffersDynamic           = 4
        maxDescriptorSetSampledImages                   = 96
        maxDescriptorSetStorageImages                   = 48
        maxDescriptorSetInputAttachments                = 4
        maxVertexInputAttributes                        = 16
        maxVertexInputBindings                          = 16
        maxVertexInputAttributeOffset                   = 2047
        maxVertexInputBindingStride                     = 2048
        maxVertexOutputComponents                       = 128
        maxTessellationGenerationLevel                  = 64
        maxTessellationPatchSize                        = 32
        maxTessellationControlPerVertexInputComponents  = 128
        maxTessellationControlPerVertexOutputComponents = 128
        maxTessellationControlPerPatchOutputComponents  = 120
        maxTessellationControlTotalOutputComponents     = 4096
        maxTessellationEvaluationInputComponents        = 128
        maxTessellationEvaluationOutputComponents       = 128
        maxGeometryShaderInvocations                    = 32
        maxGeometryInputComponents                      = 64
        maxGeometryOutputComponents                     = 128
        maxGeometryOutputVertices                       = 256
        maxGeometryTotalOutputComponents                = 1024
        maxFragmentInputComponents                      = 128
        maxFragmentOutputAttachments                    = 8
        maxFragmentDualSrcAttachments                   = 0
        maxFragmentCombinedOutputResources              = 51
        maxComputeSharedMemorySize                      = 32768
        maxComputeWorkGroupCount: count = 3
                65536
                65536
                65536
        maxComputeWorkGroupInvocations                  = 256
        maxComputeWorkGroupSize: count = 3
                256
                256
                256
        subPixelPrecisionBits                           = 8
        subTexelPrecisionBits                           = 8
        mipmapPrecisionBits                             = 8
        maxDrawIndexedIndexValue                        = 4294967295
        maxDrawIndirectCount                            = 1
        maxSamplerLodBias                               = 255
        maxSamplerAnisotropy                            = 16
        maxViewports                                    = 1
        maxViewportDimensions: count = 2
                8192
                8192
        viewportBoundsRange: count = 2
                -16384
                16383
        viewportSubPixelBits                            = 0
        minMemoryMapAlignment                           = 64
        minTexelBufferOffsetAlignment                   = 0x00000100
        minUniformBufferOffsetAlignment                 = 0x00000010
        minStorageBufferOffsetAlignment                 = 0x00000100
        minTexelOffset                                  = -8
        maxTexelOffset                                  = 7
        minTexelGatherOffset                            = -8
        maxTexelGatherOffset                            = 7
        minInterpolationOffset                          = -0.5
        maxInterpolationOffset                          = 0.5
        subPixelInterpolationOffsetBits                 = 4
        maxFramebufferWidth                             = 8192
        maxFramebufferHeight                            = 8192
        maxFramebufferLayers                            = 256
        framebufferColorSampleCounts: count = 3
                SAMPLE_COUNT_1_BIT
                SAMPLE_COUNT_4_BIT
                SAMPLE_COUNT_8_BIT
        framebufferDepthSampleCounts: count = 3
                SAMPLE_COUNT_1_BIT
                SAMPLE_COUNT_4_BIT
                SAMPLE_COUNT_8_BIT
        framebufferStencilSampleCounts: count = 3
                SAMPLE_COUNT_1_BIT
                SAMPLE_COUNT_4_BIT
                SAMPLE_COUNT_8_BIT
        framebufferNoAttachmentsSampleCounts: count = 4
                SAMPLE_COUNT_1_BIT
                SAMPLE_COUNT_4_BIT
                SAMPLE_COUNT_8_BIT
                SAMPLE_COUNT_16_BIT
        maxColorAttachments                             = 8
        sampledImageColorSampleCounts: count = 3
                SAMPLE_COUNT_1_BIT
                SAMPLE_COUNT_4_BIT
                SAMPLE_COUNT_8_BIT
        sampledImageIntegerSampleCounts: count = 1
                SAMPLE_COUNT_1_BIT
        sampledImageDepthSampleCounts: count = 3
                SAMPLE_COUNT_1_BIT
                SAMPLE_COUNT_4_BIT
                SAMPLE_COUNT_8_BIT
        sampledImageStencilSampleCounts: count = 3
                SAMPLE_COUNT_1_BIT
                SAMPLE_COUNT_4_BIT
                SAMPLE_COUNT_8_BIT
        storageImageSampleCounts: count = 1
                SAMPLE_COUNT_1_BIT
        maxSampleMaskWords                              = 1
        timestampComputeAndGraphics                     = false
        timestampPeriod                                 = 0
        maxClipDistances                                = 0
        maxCullDistances                                = 0
        maxCombinedClipAndCullDistances                 = 0
        discreteQueuePriorities                         = 2
        pointSizeRange: count = 2
                1
                1024
        lineWidthRange: count = 2
                1
                1
        pointSizeGranularity                            = 0.0625
        lineWidthGranularity                            = 0
        strictLines                                     = true
        standardSampleLocations                         = true
        optimalBufferCopyOffsetAlignment                = 0x00000040
        optimalBufferCopyRowPitchAlignment              = 0x00000040
        nonCoherentAtomSize                             = 0x00000040
 
VkPhysicalDeviceSparseProperties:
---------------------------------
        residencyStandard2DBlockShape            = false
        residencyStandard2DMultisampleBlockShape = false
        residencyStandard3DBlockShape            = false
        residencyAlignedMipSize                  = false
        residencyNonResidentStrict               = false
 
VkPhysicalDeviceIDPropertiesKHR:
--------------------------------
        deviceUUID      = 00009370-0100-0000-0000-000000000000
        driverUUID      = 734b89eb-81c9-403d-1f26-81b26a1806a1
        deviceNodeMask  = 0
        deviceLUIDValid = false
 
VkPhysicalDevicePointClippingPropertiesKHR:
-------------------------------------------
        pointClippingBehavior = POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES
 
 
Device Extensions: count = 15
-----------------------------
        VK_KHR_16bit_storage                : extension revision 1
        VK_KHR_dedicated_allocation         : extension revision 3
        VK_KHR_descriptor_update_template   : extension revision 1
        VK_KHR_external_fence               : extension revision 1
        VK_KHR_external_fence_fd            : extension revision 1
        VK_KHR_external_memory              : extension revision 1
        VK_KHR_external_semaphore           : extension revision 1
        VK_KHR_external_semaphore_fd        : extension revision 1
        VK_KHR_get_memory_requirements2     : extension revision 1
        VK_KHR_image_format_list            : extension revision 1
        VK_KHR_maintenance1                 : extension revision 2
        VK_KHR_maintenance2                 : extension revision 1
        VK_KHR_shader_draw_parameters       : extension revision 1
        VK_KHR_storage_buffer_storage_class : extension revision 1
        VK_KHR_variable_pointers            : extension revision 1
 
VkQueueFamilyProperties:
========================
        queueProperties[0]:
        -------------------
                minImageTransferGranularity = (1,1,1)
                queueCount                  = 2
                queueFlags                  = QUEUE_GRAPHICS | QUEUE_COMPUTE | QUEUE_TRANSFER
                timestampValidBits          = 0
                present support             = false
 
VkPhysicalDeviceMemoryProperties:
=================================
memoryHeaps: count = 1
        memoryHeaps[0]:
                size   = 932577280 (0x37960000) (889.38 MiB)
                budget = 0 (0x00000000) (0.00 B)
                usage  = 0 (0x00000000) (0.00 B)
                flags: count = 1
                        MEMORY_HEAP_DEVICE_LOCAL_BIT
memoryTypes: count = 3
        memoryTypes[0]:
                heapIndex     = 0
                propertyFlags = 0x0007: count = 3
                        MEMORY_PROPERTY_DEVICE_LOCAL_BIT
                        MEMORY_PROPERTY_HOST_VISIBLE_BIT
                        MEMORY_PROPERTY_HOST_COHERENT_BIT
                usable for:
                        IMAGE_TILING_OPTIMAL:
                                color images
                                FORMAT_D16_UNORM
                                FORMAT_X8_D24_UNORM_PACK32
                                FORMAT_D32_SFLOAT
                                FORMAT_S8_UINT
                                FORMAT_D24_UNORM_S8_UINT
                                (non-sparse)
                        IMAGE_TILING_LINEAR:
                                color images
                                (non-sparse)
        memoryTypes[1]:
                heapIndex     = 0
                propertyFlags = 0x000b: count = 3
                        MEMORY_PROPERTY_DEVICE_LOCAL_BIT
                        MEMORY_PROPERTY_HOST_VISIBLE_BIT
                        MEMORY_PROPERTY_HOST_CACHED_BIT
                usable for:
                        IMAGE_TILING_OPTIMAL:
                                color images
                                FORMAT_D16_UNORM
                                FORMAT_X8_D24_UNORM_PACK32
                                FORMAT_D32_SFLOAT
                                FORMAT_S8_UINT
                                FORMAT_D24_UNORM_S8_UINT
                                (non-sparse)
                        IMAGE_TILING_LINEAR:
                                color images
                                (non-sparse)
        memoryTypes[2]:
                heapIndex     = 0
                propertyFlags = 0x0011: count = 2
                        MEMORY_PROPERTY_DEVICE_LOCAL_BIT
                        MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT
                usable for:
                        IMAGE_TILING_OPTIMAL:
                                None
                        IMAGE_TILING_LINEAR:
                                None
 
VkPhysicalDeviceFeatures:
=========================
        robustBufferAccess                      = true
        fullDrawIndexUint32                     = true
        imageCubeArray                          = true
        independentBlend                        = true
        geometryShader                          = true
        tessellationShader                      = true
        sampleRateShading                       = true
        dualSrcBlend                            = false
        logicOp                                 = false
        multiDrawIndirect                       = false
        drawIndirectFirstInstance               = true
        depthClamp                              = false
        depthBiasClamp                          = true
        fillModeNonSolid                        = false
        depthBounds                             = false
        wideLines                               = false
        largePoints                             = true
        alphaToOne                              = false
        multiViewport                           = false
        samplerAnisotropy                       = true
        textureCompressionETC2                  = true
        textureCompressionASTC_LDR              = true
        textureCompressionBC                    = false
        occlusionQueryPrecise                   = true
        pipelineStatisticsQuery                 = false
        vertexPipelineStoresAndAtomics          = false
        fragmentStoresAndAtomics                = true
        shaderTessellationAndGeometryPointSize  = false
        shaderImageGatherExtended               = true
        shaderStorageImageExtendedFormats       = true
        shaderStorageImageMultisample           = false
        shaderStorageImageReadWithoutFormat     = true
        shaderStorageImageWriteWithoutFormat    = true
        shaderUniformBufferArrayDynamicIndexing = true
        shaderSampledImageArrayDynamicIndexing  = true
        shaderStorageBufferArrayDynamicIndexing = true
        shaderStorageImageArrayDynamicIndexing  = true
        shaderClipDistance                      = false
        shaderCullDistance                      = false
        shaderFloat64                           = false
        shaderInt64                             = false
        shaderInt16                             = true
        shaderResourceResidency                 = false
        shaderResourceMinLod                    = false
        sparseBinding                           = false
        sparseResidencyBuffer                   = false
        sparseResidencyImage2D                  = false
        sparseResidencyImage3D                  = false
        sparseResidency2Samples                 = false
        sparseResidency4Samples                 = false
        sparseResidency8Samples                 = false
        sparseResidency16Samples                = false
        sparseResidencyAliased                  = false
        variableMultisampleRate                 = false
        inheritedQueries                        = false
 
VkPhysicalDevice16BitStorageFeaturesKHR:
----------------------------------------
        storageBuffer16BitAccess           = true
        uniformAndStorageBuffer16BitAccess = true
        storagePushConstant16              = true
        storageInputOutput16               = true
 
VkPhysicalDeviceVariablePointersFeaturesKHR:
--------------------------------------------
        variablePointersStorageBuffer = true
        variablePointers              = false