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/GrVkDefines.h" 14 15 struct GrVkInterface; 16 class GrShaderCaps; 17 18 /** 19 * Stores some capabilities of a Vk backend. 20 */ 21 class GrVkCaps : public GrCaps { 22 public: 23 typedef GrVkStencilAttachment::Format StencilFormat; 24 25 /** 26 * Creates a GrVkCaps that is set such that nothing is supported. The init function should 27 * be called to fill out the caps. 28 */ 29 GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, 30 VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags); 31 isConfigTexturable(GrPixelConfig config)32 bool isConfigTexturable(GrPixelConfig config) const override { 33 return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags); 34 } 35 isConfigRenderable(GrPixelConfig config,bool withMSAA)36 bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override { 37 return SkToBool(ConfigInfo::kRenderable_Flag & fConfigTable[config].fOptimalFlags); 38 } 39 canConfigBeImageStorage(GrPixelConfig)40 bool canConfigBeImageStorage(GrPixelConfig) const override { return false; } 41 isConfigTexturableLinearly(GrPixelConfig config)42 bool isConfigTexturableLinearly(GrPixelConfig config) const { 43 return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fLinearFlags); 44 } 45 isConfigRenderableLinearly(GrPixelConfig config,bool withMSAA)46 bool isConfigRenderableLinearly(GrPixelConfig config, bool withMSAA) const { 47 return !withMSAA && SkToBool(ConfigInfo::kRenderable_Flag & 48 fConfigTable[config].fLinearFlags); 49 } 50 configCanBeDstofBlit(GrPixelConfig config,bool linearTiled)51 bool configCanBeDstofBlit(GrPixelConfig config, bool linearTiled) const { 52 const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags : 53 fConfigTable[config].fOptimalFlags; 54 return SkToBool(ConfigInfo::kBlitDst_Flag & flags); 55 } 56 configCanBeSrcofBlit(GrPixelConfig config,bool linearTiled)57 bool configCanBeSrcofBlit(GrPixelConfig config, bool linearTiled) const { 58 const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags : 59 fConfigTable[config].fOptimalFlags; 60 return SkToBool(ConfigInfo::kBlitSrc_Flag & flags); 61 } 62 63 // Tells of if we can pass in straight GLSL string into vkCreateShaderModule canUseGLSLForShaderModule()64 bool canUseGLSLForShaderModule() const { 65 return fCanUseGLSLForShaderModule; 66 } 67 68 // On Adreno vulkan, they do not respect the imageOffset parameter at least in 69 // copyImageToBuffer. This flag says that we must do the copy starting from the origin always. mustDoCopiesFromOrigin()70 bool mustDoCopiesFromOrigin() const { 71 return fMustDoCopiesFromOrigin; 72 } 73 74 // Check whether we support using draws for copies. supportsCopiesAsDraws()75 bool supportsCopiesAsDraws() const { 76 return fSupportsCopiesAsDraws; 77 } 78 79 // On Nvidia there is a current bug where we must the current command buffer before copy 80 // operations or else the copy will not happen. This includes copies, blits, resolves, and copy 81 // as draws. mustSubmitCommandsBeforeCopyOp()82 bool mustSubmitCommandsBeforeCopyOp() const { 83 return fMustSubmitCommandsBeforeCopyOp; 84 } 85 86 // Sometimes calls to QueueWaitIdle return before actually signalling the fences 87 // on the command buffers even though they have completed. This causes an assert to fire when 88 // destroying the command buffers. Therefore we add a sleep to make sure the fence signals. mustSleepOnTearDown()89 bool mustSleepOnTearDown() const { 90 return fMustSleepOnTearDown; 91 } 92 93 // Returns true if while adding commands to secondary command buffers, we must make a new 94 // secondary command buffer everytime we want to bind a new VkPipeline. This is to work around a 95 // driver bug specifically on AMD. newSecondaryCBOnPipelineChange()96 bool newSecondaryCBOnPipelineChange() const { 97 return fNewSecondaryCBOnPipelineChange; 98 } 99 100 /** 101 * Returns both a supported and most prefered stencil format to use in draws. 102 */ preferedStencilFormat()103 const StencilFormat& preferedStencilFormat() const { 104 return fPreferedStencilFormat; 105 } 106 107 bool initDescForDstCopy(const GrRenderTarget* src, GrSurfaceDesc* desc) const override; 108 109 private: 110 enum VkVendor { 111 kAMD_VkVendor = 4098, 112 kImagination_VkVendor = 4112, 113 kNvidia_VkVendor = 4318, 114 kQualcomm_VkVendor = 20803, 115 }; 116 117 void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, 118 VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags); 119 void initGrCaps(const VkPhysicalDeviceProperties&, 120 const VkPhysicalDeviceMemoryProperties&, 121 uint32_t featureFlags); 122 void initShaderCaps(const VkPhysicalDeviceProperties&, uint32_t featureFlags); 123 void initSampleCount(const VkPhysicalDeviceProperties& properties); 124 125 126 void initConfigTable(const GrVkInterface*, VkPhysicalDevice); 127 void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev); 128 129 struct ConfigInfo { ConfigInfoConfigInfo130 ConfigInfo() : fOptimalFlags(0), fLinearFlags(0) {} 131 132 void init(const GrVkInterface*, VkPhysicalDevice, VkFormat); 133 static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags); 134 135 enum { 136 kTextureable_Flag = 0x1, 137 kRenderable_Flag = 0x2, 138 kBlitSrc_Flag = 0x4, 139 kBlitDst_Flag = 0x8, 140 }; 141 142 uint16_t fOptimalFlags; 143 uint16_t fLinearFlags; 144 }; 145 ConfigInfo fConfigTable[kGrPixelConfigCnt]; 146 147 StencilFormat fPreferedStencilFormat; 148 149 bool fCanUseGLSLForShaderModule; 150 151 bool fMustDoCopiesFromOrigin; 152 153 bool fSupportsCopiesAsDraws; 154 155 bool fMustSubmitCommandsBeforeCopyOp; 156 157 bool fMustSleepOnTearDown; 158 159 bool fNewSecondaryCBOnPipelineChange; 160 161 typedef GrCaps INHERITED; 162 }; 163 164 #endif 165