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 surfaceSupportsReadPixels(const GrSurface *)46 bool surfaceSupportsReadPixels(const GrSurface*) const override { return true; } 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 /** 95 * Returns both a supported and most preferred stencil format to use in draws. 96 */ preferredStencilFormat()97 const StencilFormat& preferredStencilFormat() const { 98 return fPreferredStencilFormat; 99 } 100 101 // Returns whether the device supports the ability to extend VkPhysicalDeviceProperties struct. supportsPhysicalDeviceProperties2()102 bool supportsPhysicalDeviceProperties2() const { return fSupportsPhysicalDeviceProperties2; } 103 // Returns whether the device supports the ability to extend VkMemoryRequirements struct. supportsMemoryRequirements2()104 bool supportsMemoryRequirements2() const { return fSupportsMemoryRequirements2; } 105 106 // Returns whether the device supports the ability to extend the vkBindMemory call. supportsBindMemory2()107 bool supportsBindMemory2() const { return fSupportsBindMemory2; } 108 109 // Returns whether or not the device suports the various API maintenance fixes to Vulkan 1.0. In 110 // Vulkan 1.1 all these maintenance are part of the core spec. supportsMaintenance1()111 bool supportsMaintenance1() const { return fSupportsMaintenance1; } supportsMaintenance2()112 bool supportsMaintenance2() const { return fSupportsMaintenance2; } supportsMaintenance3()113 bool supportsMaintenance3() const { return fSupportsMaintenance3; } 114 115 // Returns true if the device supports passing in a flag to say we are using dedicated GPU when 116 // allocating memory. For some devices this allows them to return more optimized memory knowning 117 // they will never need to suballocate amonst multiple objects. supportsDedicatedAllocation()118 bool supportsDedicatedAllocation() const { return fSupportsDedicatedAllocation; } 119 120 // Returns true if the device supports importing of external memory into Vulkan memory. supportsExternalMemory()121 bool supportsExternalMemory() const { return fSupportsExternalMemory; } 122 // Returns true if the device supports importing Android hardware buffers into Vulkan memory. supportsAndroidHWBExternalMemory()123 bool supportsAndroidHWBExternalMemory() const { return fSupportsAndroidHWBExternalMemory; } 124 125 // Returns true if it supports ycbcr conversion for samplers supportsYcbcrConversion()126 bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; } 127 128 /** 129 * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means 130 * the surface is not a render target, otherwise it is the number of samples in the render 131 * target. 132 */ 133 bool canCopyImage(GrPixelConfig dstConfig, int dstSampleCnt, GrSurfaceOrigin dstOrigin, 134 GrPixelConfig srcConfig, int srcSamplecnt, GrSurfaceOrigin srcOrigin) const; 135 136 bool canCopyAsBlit(GrPixelConfig dstConfig, int dstSampleCnt, bool dstIsLinear, 137 GrPixelConfig srcConfig, int srcSampleCnt, bool srcIsLinear) const; 138 139 bool canCopyAsResolve(GrPixelConfig dstConfig, int dstSampleCnt, GrSurfaceOrigin dstOrigin, 140 GrPixelConfig srcConfig, int srcSamplecnt, 141 GrSurfaceOrigin srcOrigin) const; 142 143 bool canCopyAsDraw(GrPixelConfig dstConfig, bool dstIsRenderable, 144 GrPixelConfig srcConfig, bool srcIsTextureable) const; 145 146 bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, GrSurfaceOrigin*, 147 bool* rectsMustMatch, bool* disallowSubrect) const override; 148 149 GrPixelConfig validateBackendRenderTarget(const GrBackendRenderTarget&, 150 SkColorType) const override; 151 152 GrPixelConfig getConfigFromBackendFormat(const GrBackendFormat&, SkColorType) const override; 153 GrPixelConfig getYUVAConfigFromBackendFormat(const GrBackendFormat&) const override; 154 155 GrBackendFormat getBackendFormatFromGrColorType(GrColorType ct, 156 GrSRGBEncoded srgbEncoded) const override; 157 158 private: 159 enum VkVendor { 160 kAMD_VkVendor = 4098, 161 kARM_VkVendor = 5045, 162 kImagination_VkVendor = 4112, 163 kIntel_VkVendor = 32902, 164 kNvidia_VkVendor = 4318, 165 kQualcomm_VkVendor = 20803, 166 }; 167 168 void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, 169 VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&, 170 uint32_t physicalDeviceVersion, const GrVkExtensions&); 171 void initGrCaps(const GrVkInterface* vkInterface, 172 VkPhysicalDevice physDev, 173 const VkPhysicalDeviceProperties&, 174 const VkPhysicalDeviceMemoryProperties&, 175 const VkPhysicalDeviceFeatures2&, 176 const GrVkExtensions&); 177 void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&); 178 179 void initConfigTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&); 180 void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev); 181 182 uint8_t getYcbcrKeyFromYcbcrInfo(const GrVkYcbcrConversionInfo& info); 183 184 void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&); 185 186 bool onSurfaceSupportsWritePixels(const GrSurface*) const override; 187 bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 188 const SkIRect& srcRect, const SkIPoint& dstPoint) const override; 189 190 struct ConfigInfo { ConfigInfoConfigInfo191 ConfigInfo() : fOptimalFlags(0), fLinearFlags(0) {} 192 193 void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&, 194 VkFormat); 195 static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags); 196 void initSampleCounts(const GrVkInterface*, VkPhysicalDevice, 197 const VkPhysicalDeviceProperties&, VkFormat); 198 199 enum { 200 kTextureable_Flag = 0x1, 201 kRenderable_Flag = 0x2, 202 kBlitSrc_Flag = 0x4, 203 kBlitDst_Flag = 0x8, 204 }; 205 206 uint16_t fOptimalFlags; 207 uint16_t fLinearFlags; 208 209 SkTDArray<int> fColorSampleCounts; 210 }; 211 ConfigInfo fConfigTable[kGrPixelConfigCnt]; 212 213 StencilFormat fPreferredStencilFormat; 214 215 SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos; 216 217 bool fMustDoCopiesFromOrigin = false; 218 bool fMustSleepOnTearDown = false; 219 bool fNewCBOnPipelineChange = false; 220 bool fShouldAlwaysUseDedicatedImageMemory = false; 221 222 bool fSupportsPhysicalDeviceProperties2 = false; 223 bool fSupportsMemoryRequirements2 = false; 224 bool fSupportsBindMemory2 = false; 225 bool fSupportsMaintenance1 = false; 226 bool fSupportsMaintenance2 = false; 227 bool fSupportsMaintenance3 = false; 228 229 bool fSupportsDedicatedAllocation = false; 230 bool fSupportsExternalMemory = false; 231 bool fSupportsAndroidHWBExternalMemory = false; 232 233 bool fSupportsYcbcrConversion = false; 234 235 typedef GrCaps INHERITED; 236 }; 237 238 #endif 239