1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrVkCaps_DEFINED 9 #define GrVkCaps_DEFINED 10 11 #include "GrCaps.h" 12 #include "GrVkStencilAttachment.h" 13 #include "vk/GrVkTypes.h" 14 15 class GrShaderCaps; 16 class GrVkExtensions; 17 struct GrVkInterface; 18 19 /** 20 * Stores some capabilities of a Vk backend. 21 */ 22 class GrVkCaps : public GrCaps { 23 public: 24 typedef GrVkStencilAttachment::Format StencilFormat; 25 26 /** 27 * Creates a GrVkCaps that is set such that nothing is supported. The init function should 28 * be called to fill out the caps. 29 */ 30 GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, 31 VkPhysicalDevice device, const VkPhysicalDeviceFeatures2& features, 32 uint32_t instanceVersion, uint32_t physicalDeviceVersion, 33 const GrVkExtensions& extensions); 34 isConfigTexturable(GrPixelConfig config)35 bool isConfigTexturable(GrPixelConfig config) const override { 36 return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags); 37 } 38 isConfigCopyable(GrPixelConfig config)39 bool isConfigCopyable(GrPixelConfig config) const override { 40 return true; 41 } 42 43 int getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const override; 44 int maxRenderTargetSampleCount(GrPixelConfig config) const override; 45 46 bool surfaceSupportsReadPixels(const GrSurface*) const override; 47 isConfigTexturableLinearly(GrPixelConfig config)48 bool isConfigTexturableLinearly(GrPixelConfig config) const { 49 return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fLinearFlags); 50 } 51 isConfigRenderableLinearly(GrPixelConfig config,bool withMSAA)52 bool isConfigRenderableLinearly(GrPixelConfig config, bool withMSAA) const { 53 return !withMSAA && SkToBool(ConfigInfo::kRenderable_Flag & 54 fConfigTable[config].fLinearFlags); 55 } 56 configCanBeDstofBlit(GrPixelConfig config,bool linearTiled)57 bool configCanBeDstofBlit(GrPixelConfig config, bool linearTiled) const { 58 const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags : 59 fConfigTable[config].fOptimalFlags; 60 return SkToBool(ConfigInfo::kBlitDst_Flag & flags); 61 } 62 configCanBeSrcofBlit(GrPixelConfig config,bool linearTiled)63 bool configCanBeSrcofBlit(GrPixelConfig config, bool linearTiled) const { 64 const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags : 65 fConfigTable[config].fOptimalFlags; 66 return SkToBool(ConfigInfo::kBlitSrc_Flag & flags); 67 } 68 69 // On Adreno vulkan, they do not respect the imageOffset parameter at least in 70 // copyImageToBuffer. This flag says that we must do the copy starting from the origin always. mustDoCopiesFromOrigin()71 bool mustDoCopiesFromOrigin() const { 72 return fMustDoCopiesFromOrigin; 73 } 74 75 // Sometimes calls to QueueWaitIdle return before actually signalling the fences 76 // on the command buffers even though they have completed. This causes an assert to fire when 77 // destroying the command buffers. Therefore we add a sleep to make sure the fence signals. mustSleepOnTearDown()78 bool mustSleepOnTearDown() const { 79 return fMustSleepOnTearDown; 80 } 81 82 // Returns true if while adding commands to command buffers, we must make a new command buffer 83 // everytime we want to bind a new VkPipeline. This is true for both primary and secondary 84 // command buffers. This is to work around a driver bug specifically on AMD. newCBOnPipelineChange()85 bool newCBOnPipelineChange() const { 86 return fNewCBOnPipelineChange; 87 } 88 89 // Returns true if we should always make dedicated allocations for VkImages. shouldAlwaysUseDedicatedImageMemory()90 bool shouldAlwaysUseDedicatedImageMemory() const { 91 return fShouldAlwaysUseDedicatedImageMemory; 92 } 93 94 // Always use a transfer buffer instead of vkCmdUpdateBuffer to upload data to a VkBuffer. avoidUpdateBuffers()95 bool avoidUpdateBuffers() const { 96 return fAvoidUpdateBuffers; 97 } 98 99 /** 100 * Returns both a supported and most preferred stencil format to use in draws. 101 */ preferredStencilFormat()102 const StencilFormat& preferredStencilFormat() const { 103 return fPreferredStencilFormat; 104 } 105 106 // Returns whether the device supports VK_KHR_Swapchain. Internally Skia never uses any of the 107 // swapchain functions, but we may need to transition to and from the 108 // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR image layout, so we must know whether that layout is 109 // supported. supportsSwapchain()110 bool supportsSwapchain() const { return fSupportsSwapchain; } 111 112 // Returns whether the device supports the ability to extend VkPhysicalDeviceProperties struct. supportsPhysicalDeviceProperties2()113 bool supportsPhysicalDeviceProperties2() const { return fSupportsPhysicalDeviceProperties2; } 114 // Returns whether the device supports the ability to extend VkMemoryRequirements struct. supportsMemoryRequirements2()115 bool supportsMemoryRequirements2() const { return fSupportsMemoryRequirements2; } 116 117 // Returns whether the device supports the ability to extend the vkBindMemory call. supportsBindMemory2()118 bool supportsBindMemory2() const { return fSupportsBindMemory2; } 119 120 // Returns whether or not the device suports the various API maintenance fixes to Vulkan 1.0. In 121 // Vulkan 1.1 all these maintenance are part of the core spec. supportsMaintenance1()122 bool supportsMaintenance1() const { return fSupportsMaintenance1; } supportsMaintenance2()123 bool supportsMaintenance2() const { return fSupportsMaintenance2; } supportsMaintenance3()124 bool supportsMaintenance3() const { return fSupportsMaintenance3; } 125 126 // Returns true if the device supports passing in a flag to say we are using dedicated GPU when 127 // allocating memory. For some devices this allows them to return more optimized memory knowning 128 // they will never need to suballocate amonst multiple objects. supportsDedicatedAllocation()129 bool supportsDedicatedAllocation() const { return fSupportsDedicatedAllocation; } 130 131 // Returns true if the device supports importing of external memory into Vulkan memory. supportsExternalMemory()132 bool supportsExternalMemory() const { return fSupportsExternalMemory; } 133 // Returns true if the device supports importing Android hardware buffers into Vulkan memory. supportsAndroidHWBExternalMemory()134 bool supportsAndroidHWBExternalMemory() const { return fSupportsAndroidHWBExternalMemory; } 135 136 // Returns true if it supports ycbcr conversion for samplers supportsYcbcrConversion()137 bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; } 138 139 /** 140 * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means 141 * the surface is not a render target, otherwise it is the number of samples in the render 142 * target. 143 */ 144 bool canCopyImage(GrPixelConfig dstConfig, int dstSampleCnt, GrSurfaceOrigin dstOrigin, 145 bool dstHasYcbcr, GrPixelConfig srcConfig, int srcSamplecnt, 146 GrSurfaceOrigin srcOrigin, bool srcHasYcbcr) const; 147 148 bool canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCnt, bool dstIsLinear, 149 bool dstHasYcbcr, GrPixelConfig srcConfig, int srcSampleCnt, 150 bool srcIsLinear, bool srcHasYcbcr) const; 151 152 bool canCopyAsResolve(GrPixelConfig dstConfig, int dstSampleCnt, GrSurfaceOrigin dstOrigin, 153 bool dstHasYcbcr, GrPixelConfig srcConfig, int srcSamplecnt, 154 GrSurfaceOrigin srcOrigin, bool srcHasYcbcr) const; 155 156 bool canCopyAsDraw(GrPixelConfig dstConfig, bool dstIsRenderable, bool dstHasYcbcr, 157 GrPixelConfig srcConfig, bool srcIsTextureable, bool srcHasYcbcr) const; 158 159 bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*, 160 bool* rectsMustMatch, bool* disallowSubrect) const override; 161 162 GrPixelConfig validateBackendRenderTarget(const GrBackendRenderTarget&, 163 SkColorType) const override; 164 165 GrPixelConfig getConfigFromBackendFormat(const GrBackendFormat&, SkColorType) const override; 166 GrPixelConfig getYUVAConfigFromBackendFormat(const GrBackendFormat&) const override; 167 168 GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct, 169 GrSRGBEncoded srgbEncoded) const override; 170 171 private: 172 enum VkVendor { 173 kAMD_VkVendor = 4098, 174 kARM_VkVendor = 5045, 175 kImagination_VkVendor = 4112, 176 kIntel_VkVendor = 32902, 177 kNvidia_VkVendor = 4318, 178 kQualcomm_VkVendor = 20803, 179 }; 180 181 void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, 182 VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&, 183 uint32_t physicalDeviceVersion, const GrVkExtensions&); 184 void initGrCaps(const GrVkInterface* vkInterface, 185 VkPhysicalDevice physDev, 186 const VkPhysicalDeviceProperties&, 187 const VkPhysicalDeviceMemoryProperties&, 188 const VkPhysicalDeviceFeatures2&, 189 const GrVkExtensions&); 190 void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&); 191 192 void initConfigTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&); 193 void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev); 194 195 uint8_t getYcbcrKeyFromYcbcrInfo(const GrVkYcbcrConversionInfo& info); 196 197 void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&); 198 199 bool onSurfaceSupportsWritePixels(const GrSurface*) const override; 200 bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 201 const SkIRect& srcRect, const SkIPoint& dstPoint) const override; 202 203 struct ConfigInfo { ConfigInfoConfigInfo204 ConfigInfo() : fOptimalFlags(0), fLinearFlags(0) {} 205 206 void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&, 207 VkFormat, bool disableRendering); 208 static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags, bool disableRendering); 209 void initSampleCounts(const GrVkInterface*, VkPhysicalDevice, 210 const VkPhysicalDeviceProperties&, VkFormat); 211 212 enum { 213 kTextureable_Flag = 0x1, 214 kRenderable_Flag = 0x2, 215 kBlitSrc_Flag = 0x4, 216 kBlitDst_Flag = 0x8, 217 }; 218 219 uint16_t fOptimalFlags; 220 uint16_t fLinearFlags; 221 222 SkTDArray<int> fColorSampleCounts; 223 }; 224 ConfigInfo fConfigTable[kGrPixelConfigCnt]; 225 226 StencilFormat fPreferredStencilFormat; 227 228 SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos; 229 230 bool fMustDoCopiesFromOrigin = false; 231 bool fMustSleepOnTearDown = false; 232 bool fNewCBOnPipelineChange = false; 233 bool fShouldAlwaysUseDedicatedImageMemory = false; 234 235 bool fAvoidUpdateBuffers = false; 236 237 bool fSupportsSwapchain = false; 238 239 bool fSupportsPhysicalDeviceProperties2 = false; 240 bool fSupportsMemoryRequirements2 = false; 241 bool fSupportsBindMemory2 = false; 242 bool fSupportsMaintenance1 = false; 243 bool fSupportsMaintenance2 = false; 244 bool fSupportsMaintenance3 = false; 245 246 bool fSupportsDedicatedAllocation = false; 247 bool fSupportsExternalMemory = false; 248 bool fSupportsAndroidHWBExternalMemory = false; 249 250 bool fSupportsYcbcrConversion = false; 251 252 typedef GrCaps INHERITED; 253 }; 254 255 #endif 256