1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #ifndef ANDROID_VULKANTESTHELPERS_H
19 #define ANDROID_VULKANTESTHELPERS_H
20 
21 #include <vector>
22 
23 #include <cstdlib>
24 #include <cstring>
25 #include <jni.h>
26 #include <vulkan/vulkan.h>
27 #include <vulkan/vulkan_android.h>
28 
29 // Provides basic set-up of a Vulkan device and queue.
30 class VkInit {
31 public:
32   ~VkInit();
33 
34   bool init();
device()35   VkDevice device() { return mDevice; }
queue()36   VkQueue queue() { return mQueue; }
gpu()37   VkPhysicalDevice gpu() { return mGpu; }
queueFamilyIndex()38   uint32_t queueFamilyIndex() { return mQueueFamilyIndex; }
39   uint32_t findMemoryType(uint32_t memoryTypeBitsRequirement,
40                           VkFlags requirementsMask);
41 
42   PFN_vkBindImageMemory2 mPfnBindImageMemory2 = nullptr;
43   PFN_vkGetImageMemoryRequirements2 mPfnGetImageMemoryRequirements2 = nullptr;
44   PFN_vkCreateSamplerYcbcrConversion mPfnCreateSamplerYcbcrConversion = nullptr;
45   PFN_vkDestroySamplerYcbcrConversion mPfnDestroySamplerYcbcrConversion = nullptr;
46   PFN_vkImportSemaphoreFdKHR mPfnImportSemaphoreFd = nullptr;
47   PFN_vkGetAndroidHardwareBufferPropertiesANDROID mPfnGetAndroidHardwareBufferProperties = nullptr;
48 
49 private:
50   VkInstance mInstance = VK_NULL_HANDLE;
51   VkPhysicalDevice mGpu = VK_NULL_HANDLE;
52   VkDevice mDevice = VK_NULL_HANDLE;
53   VkQueue mQueue = VK_NULL_HANDLE;
54   uint32_t mQueueFamilyIndex = 0;
55   VkPhysicalDeviceMemoryProperties mMemoryProperties = {};
56 };
57 
58 // Provides import of AHardwareBuffer.
59 class VkAHardwareBufferImage {
60 public:
61   VkAHardwareBufferImage(VkInit *init);
62   ~VkAHardwareBufferImage();
63 
64   bool init(AHardwareBuffer *buffer, bool useExternalFormat, int syncFd = -1);
image()65   VkImage image() { return mImage; }
sampler()66   VkSampler sampler() { return mSampler; }
view()67   VkImageView view() { return mView; }
semaphore()68   VkSemaphore semaphore() { return mSemaphore; }
isSamplerImmutable()69   bool isSamplerImmutable() { return mConversion != VK_NULL_HANDLE; }
70 
71 private:
72   VkInit *const mInit;
73   VkImage mImage = VK_NULL_HANDLE;
74   VkDeviceMemory mMemory = VK_NULL_HANDLE;
75   VkSampler mSampler = VK_NULL_HANDLE;
76   VkImageView mView = VK_NULL_HANDLE;
77   VkSamplerYcbcrConversion mConversion = VK_NULL_HANDLE;
78   VkSemaphore mSemaphore = VK_NULL_HANDLE;
79 };
80 
81 // Renders a provided image to a new texture, then reads back that texture to
82 // disk.
83 class VkImageRenderer {
84 public:
85   VkImageRenderer(VkInit *init, uint32_t width, uint32_t height,
86                   VkFormat format, uint32_t bytesPerPixel);
87   ~VkImageRenderer();
88 
89   bool init(JNIEnv *env, jobject assetMgr);
90   bool renderImageAndReadback(VkImage image, VkSampler sampler,
91                               VkImageView view, VkSemaphore semaphore,
92                               bool useImmutableSampler,
93                               std::vector<uint8_t> *data);
94   bool renderImageAndReadback(VkImage image, VkSampler sampler,
95                               VkImageView view, VkSemaphore semaphore,
96                               bool useImmutableSampler,
97                               std::vector<uint32_t> *data);
98 
99 private:
100   // Cleans up the temporary renderImageAndReadback variables.
101   void cleanUpTemporaries();
102 
103   VkInit *const mInit;
104   const uint32_t mWidth;
105   const uint32_t mHeight;
106   const VkFormat mFormat;
107   const VkDeviceSize mResultBufferSize;
108   VkImage mDestImage = VK_NULL_HANDLE;
109   VkDeviceMemory mDestImageMemory = VK_NULL_HANDLE;
110   VkImageView mDestImageView = VK_NULL_HANDLE;
111   VkBuffer mResultBuffer = VK_NULL_HANDLE;
112   VkDeviceMemory mResultBufferMemory = VK_NULL_HANDLE;
113   VkDescriptorPool mDescriptorPool = VK_NULL_HANDLE;
114   VkCommandPool mCmdPool = VK_NULL_HANDLE;
115   VkRenderPass mRenderPass = VK_NULL_HANDLE;
116   VkBuffer mVertexBuffer = VK_NULL_HANDLE;
117   VkDeviceMemory mVertexBufferMemory = VK_NULL_HANDLE;
118   VkFramebuffer mFramebuffer = VK_NULL_HANDLE;
119   VkShaderModule mVertModule = VK_NULL_HANDLE;
120   VkShaderModule mPixelModule = VK_NULL_HANDLE;
121   VkFence mFence = VK_NULL_HANDLE;
122 
123   // Temporary values used during renderImageAndReadback.
124   VkCommandBuffer mCmdBuffer = VK_NULL_HANDLE;
125   VkDescriptorSet mDescriptorSet = VK_NULL_HANDLE;
126   VkPipelineCache mCache = VK_NULL_HANDLE;
127   VkPipeline mPipeline = VK_NULL_HANDLE;
128   VkDescriptorSetLayout mDescriptorLayout = VK_NULL_HANDLE;
129   VkPipelineLayout mLayout = VK_NULL_HANDLE;
130 };
131 
132 #endif // ANDROID_VULKANTESTHELPERS_H
133