| 1 | |
| 2 | /* |
| 3 | * Copyright 2016 Google Inc. |
| 4 | * |
| 5 | * Use of this source code is governed by a BSD-style license that can be |
| 6 | * found in the LICENSE file. |
| 7 | */ |
| 8 | |
| 9 | #ifndef GrVkTypes_DEFINED |
| 10 | #define GrVkTypes_DEFINED |
| 11 | |
| 12 | #include "include/core/SkTypes.h" |
| 13 | #include "include/gpu/vk/GrVkVulkan.h" |
| 14 | |
| 15 | #ifndef VK_VERSION_1_1 |
| 16 | #error Skia requires the use of Vulkan 1.1 headers |
| 17 | #endif |
| 18 | |
| 19 | #include <functional> |
| 20 | #include "include/gpu/GrTypes.h" |
| 21 | |
| 22 | typedef intptr_t GrVkBackendMemory; |
| 23 | |
| 24 | /** |
| 25 | * Types for interacting with Vulkan resources created externally to Skia. GrBackendObjects for |
| 26 | * Vulkan textures are really const GrVkImageInfo* |
| 27 | */ |
| 28 | struct GrVkAlloc { |
| 29 | GrVkAlloc() |
| 30 | : fMemory(VK_NULL_HANDLE) |
| 31 | , fOffset(0) |
| 32 | , fSize(0) |
| 33 | , fFlags(0) |
| 34 | , fBackendMemory(0) |
| 35 | , fUsesSystemHeap(false) {} |
| 36 | |
| 37 | GrVkAlloc(VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, uint32_t flags) |
| 38 | : fMemory(memory) |
| 39 | , fOffset(offset) |
| 40 | , fSize(size) |
| 41 | , fFlags(flags) |
| 42 | , fBackendMemory(0) |
| 43 | , fUsesSystemHeap(false) {} |
| 44 | |
| 45 | VkDeviceMemory fMemory; // can be VK_NULL_HANDLE iff is an RT and is borrowed |
| 46 | VkDeviceSize fOffset; |
| 47 | VkDeviceSize fSize; // this can be indeterminate iff Tex uses borrow semantics |
| 48 | uint32_t fFlags; |
| 49 | GrVkBackendMemory fBackendMemory; // handle to memory allocated via GrVkMemoryAllocator. |
| 50 | |
| 51 | enum Flag { |
| 52 | kNoncoherent_Flag = 0x1, // memory must be flushed to device after mapping |
| 53 | kMappable_Flag = 0x2, // memory is able to be mapped. |
| 54 | }; |
| 55 | |
| 56 | bool operator==(const GrVkAlloc& that) const { |
| 57 | return fMemory == that.fMemory && fOffset == that.fOffset && fSize == that.fSize && |
| 58 | fFlags == that.fFlags && fUsesSystemHeap == that.fUsesSystemHeap; |
| 59 | } |
| 60 | |
| 61 | private: |
| 62 | friend class GrVkHeap; // For access to usesSystemHeap |
| 63 | bool fUsesSystemHeap; |
| 64 | }; |
| 65 | |
| 66 | // This struct is used to pass in the necessary information to create a VkSamplerYcbcrConversion |
| 67 | // object for an VkExternalFormatANDROID. |
| 68 | struct GrVkYcbcrConversionInfo { |
| 69 | GrVkYcbcrConversionInfo() |
| 70 | : fFormat(VK_FORMAT_UNDEFINED) |
| 71 | , fExternalFormat(0) |
| 72 | , fYcbcrModel(VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY) |
| 73 | , fYcbcrRange(VK_SAMPLER_YCBCR_RANGE_ITU_FULL) |
| 74 | , fXChromaOffset(VK_CHROMA_LOCATION_COSITED_EVEN) |
| 75 | , fYChromaOffset(VK_CHROMA_LOCATION_COSITED_EVEN) |
| 76 | , fChromaFilter(VK_FILTER_NEAREST) |
| 77 | , fForceExplicitReconstruction(false) {} |
| 78 | |
| 79 | GrVkYcbcrConversionInfo(VkFormat format, |
| 80 | int64_t externalFormat, |
| 81 | VkSamplerYcbcrModelConversion ycbcrModel, |
| 82 | VkSamplerYcbcrRange ycbcrRange, |
| 83 | VkChromaLocation xChromaOffset, |
| 84 | VkChromaLocation yChromaOffset, |
| 85 | VkFilter chromaFilter, |
| 86 | VkBool32 forceExplicitReconstruction, |
| 87 | VkFormatFeatureFlags formatFeatures) |
| 88 | : fFormat(format) |
| 89 | , fExternalFormat(externalFormat) |
| 90 | , fYcbcrModel(ycbcrModel) |
| 91 | , fYcbcrRange(ycbcrRange) |
| 92 | , fXChromaOffset(xChromaOffset) |
| 93 | , fYChromaOffset(yChromaOffset) |
| 94 | , fChromaFilter(chromaFilter) |
| 95 | , fForceExplicitReconstruction(forceExplicitReconstruction) |
| 96 | , fFormatFeatures(formatFeatures) { |
| 97 | SkASSERT(fYcbcrModel != VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY); |
| 98 | // Either format or externalFormat must be specified. |
| 99 | SkASSERT((fFormat != VK_FORMAT_UNDEFINED) ^ (externalFormat != 0)); |
| 100 | } |
| 101 | |
| 102 | GrVkYcbcrConversionInfo(VkSamplerYcbcrModelConversion ycbcrModel, |
| 103 | VkSamplerYcbcrRange ycbcrRange, |
| 104 | VkChromaLocation xChromaOffset, |
| 105 | VkChromaLocation yChromaOffset, |
| 106 | VkFilter chromaFilter, |
| 107 | VkBool32 forceExplicitReconstruction, |
| 108 | uint64_t externalFormat, |
| 109 | VkFormatFeatureFlags externalFormatFeatures) |
| 110 | : GrVkYcbcrConversionInfo(VK_FORMAT_UNDEFINED, externalFormat, ycbcrModel, ycbcrRange, |
| 111 | xChromaOffset, yChromaOffset, chromaFilter, |
| 112 | forceExplicitReconstruction, externalFormatFeatures) {} |
| 113 | |
| 114 | bool operator==(const GrVkYcbcrConversionInfo& that) const { |
| 115 | // Invalid objects are not required to have all other fields initialized or matching. |
| 116 | if (!this->isValid() && !that.isValid()) { |
| 117 | return true; |
| 118 | } |
| 119 | return this->fFormat == that.fFormat && |
| 120 | this->fExternalFormat == that.fExternalFormat && |
| 121 | this->fYcbcrModel == that.fYcbcrModel && |
| 122 | this->fYcbcrRange == that.fYcbcrRange && |
| 123 | this->fXChromaOffset == that.fXChromaOffset && |
| 124 | this->fYChromaOffset == that.fYChromaOffset && |
| 125 | this->fChromaFilter == that.fChromaFilter && |
| 126 | this->fForceExplicitReconstruction == that.fForceExplicitReconstruction; |
| 127 | } |
| 128 | bool operator!=(const GrVkYcbcrConversionInfo& that) const { return !(*this == that); } |
| 129 | |
| 130 | bool isValid() const { return fYcbcrModel != VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY; } |
| 131 | |
| 132 | // Format of the source image. Must be set to VK_FORMAT_UNDEFINED for external images or |
| 133 | // a valid image format otherwise. |
| 134 | VkFormat fFormat; |
| 135 | |
| 136 | // The external format. Must be non-zero for external images, zero otherwise. |
| 137 | // Should be compatible to be used in a VkExternalFormatANDROID struct. |
| 138 | uint64_t fExternalFormat; |
| 139 | |
| 140 | VkSamplerYcbcrModelConversion fYcbcrModel; |
| 141 | VkSamplerYcbcrRange fYcbcrRange; |
| 142 | VkChromaLocation fXChromaOffset; |
| 143 | VkChromaLocation fYChromaOffset; |
| 144 | VkFilter fChromaFilter; |
| 145 | VkBool32 fForceExplicitReconstruction; |
| 146 | |
| 147 | // For external images format features here should be those returned by a call to |
| 148 | // vkAndroidHardwareBufferFormatPropertiesANDROID |
| 149 | VkFormatFeatureFlags fFormatFeatures; |
| 150 | }; |
| 151 | |
| 152 | struct GrVkImageInfo { |
| 153 | VkImage fImage; |
| 154 | GrVkAlloc fAlloc; |
| 155 | VkImageTiling fImageTiling; |
| 156 | VkImageLayout fImageLayout; |
| 157 | VkFormat fFormat; |
| 158 | uint32_t fLevelCount; |
| 159 | uint32_t fCurrentQueueFamily; |
| 160 | GrProtected fProtected; |
| 161 | GrVkYcbcrConversionInfo fYcbcrConversionInfo; |
| 162 | |
| 163 | GrVkImageInfo() |
| 164 | : fImage(VK_NULL_HANDLE) |
| 165 | , fAlloc() |
| 166 | , fImageTiling(VK_IMAGE_TILING_OPTIMAL) |
| 167 | , fImageLayout(VK_IMAGE_LAYOUT_UNDEFINED) |
| 168 | , fFormat(VK_FORMAT_UNDEFINED) |
| 169 | , fLevelCount(0) |
| 170 | , fCurrentQueueFamily(VK_QUEUE_FAMILY_IGNORED) |
| 171 | , fProtected(GrProtected::kNo) |
| 172 | , fYcbcrConversionInfo() {} |
| 173 | |
| 174 | GrVkImageInfo(VkImage image, |
| 175 | GrVkAlloc alloc, |
| 176 | VkImageTiling imageTiling, |
| 177 | VkImageLayout layout, |
| 178 | VkFormat format, |
| 179 | uint32_t levelCount, |
| 180 | uint32_t currentQueueFamily = VK_QUEUE_FAMILY_IGNORED, |
| 181 | GrProtected isProtected = GrProtected::kNo, |
| 182 | GrVkYcbcrConversionInfo ycbcrConversionInfo = GrVkYcbcrConversionInfo()) |
| 183 | : fImage(image) |
| 184 | , fAlloc(alloc) |
| 185 | , fImageTiling(imageTiling) |
| 186 | , fImageLayout(layout) |
| 187 | , fFormat(format) |
| 188 | , fLevelCount(levelCount) |
| 189 | , fCurrentQueueFamily(currentQueueFamily) |
| 190 | , fProtected(isProtected) |
| 191 | , fYcbcrConversionInfo(ycbcrConversionInfo) {} |
| 192 | |
| 193 | GrVkImageInfo(const GrVkImageInfo& info, VkImageLayout layout) |
| 194 | : fImage(info.fImage) |
| 195 | , fAlloc(info.fAlloc) |
| 196 | , fImageTiling(info.fImageTiling) |
| 197 | , fImageLayout(layout) |
| 198 | , fFormat(info.fFormat) |
| 199 | , fLevelCount(info.fLevelCount) |
| 200 | , fCurrentQueueFamily(info.fCurrentQueueFamily) |
| 201 | , fProtected(info.fProtected) |
| 202 | , fYcbcrConversionInfo(info.fYcbcrConversionInfo) {} |
| 203 | |
| 204 | #if GR_TEST_UTILS |
| 205 | bool operator==(const GrVkImageInfo& that) const { |
| 206 | return fImage == that.fImage && fAlloc == that.fAlloc && |
| 207 | fImageTiling == that.fImageTiling && fImageLayout == that.fImageLayout && |
| 208 | fFormat == that.fFormat && fLevelCount == that.fLevelCount && |
| 209 | fCurrentQueueFamily == that.fCurrentQueueFamily && fProtected == that.fProtected && |
| 210 | fYcbcrConversionInfo == that.fYcbcrConversionInfo; |
| 211 | } |
| 212 | #endif |
| 213 | }; |
| 214 | |
| 215 | using GrVkGetProc = std::function<PFN_vkVoidFunction( |
| 216 | const char*, // function name |
| 217 | VkInstance, // instance or VK_NULL_HANDLE |
| 218 | VkDevice // device or VK_NULL_HANDLE |
| 219 | )>; |
| 220 | |
| 221 | /** |
| 222 | * This object is wrapped in a GrBackendDrawableInfo and passed in as an argument to |
| 223 | * drawBackendGpu() calls on an SkDrawable. The drawable will use this info to inject direct |
| 224 | * Vulkan calls into our stream of GPU draws. |
| 225 | * |
| 226 | * The SkDrawable is given a secondary VkCommandBuffer in which to record draws. The GPU backend |
| 227 | * will then execute that command buffer within a render pass it is using for its own draws. The |
| 228 | * drawable is also given the attachment of the color index, a compatible VkRenderPass, and the |
| 229 | * VkFormat of the color attachment so that it can make VkPipeline objects for the draws. The |
| 230 | * SkDrawable must not alter the state of the VkRenderpass or sub pass. |
| 231 | * |
| 232 | * Additionally, the SkDrawable may fill in the passed in fDrawBounds with the bounds of the draws |
| 233 | * that it submits to the command buffer. This will be used by the GPU backend for setting the |
| 234 | * bounds in vkCmdBeginRenderPass. If fDrawBounds is not updated, we will assume that the entire |
| 235 | * attachment may have been written to. |
| 236 | * |
| 237 | * The SkDrawable is always allowed to create its own command buffers and submit them to the queue |
| 238 | * to render offscreen textures which will be sampled in draws added to the passed in |
| 239 | * VkCommandBuffer. If this is done the SkDrawable is in charge of adding the required memory |
| 240 | * barriers to the queue for the sampled images since the Skia backend will not do this. |
| 241 | * |
| 242 | * The VkImage is informational only and should not be used or modified in any ways. |
| 243 | */ |
| 244 | struct GrVkDrawableInfo { |
| 245 | VkCommandBuffer fSecondaryCommandBuffer; |
| 246 | uint32_t fColorAttachmentIndex; |
| 247 | VkRenderPass fCompatibleRenderPass; |
| 248 | VkFormat fFormat; |
| 249 | VkRect2D* fDrawBounds; |
| 250 | VkImage fImage; |
| 251 | }; |
| 252 | |
| 253 | #endif |
| 254 | |