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 32 int getSampleCount(int requestedCount, GrPixelConfig config) const override; 33 isConfigTexturable(GrPixelConfig config)34 bool isConfigTexturable(GrPixelConfig config) const override { 35 return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fOptimalFlags); 36 } 37 38 bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const override; 39 isConfigCopyable(GrPixelConfig config)40 bool isConfigCopyable(GrPixelConfig config) const override { 41 return true; 42 } 43 isConfigTexturableLinearly(GrPixelConfig config)44 bool isConfigTexturableLinearly(GrPixelConfig config) const { 45 return SkToBool(ConfigInfo::kTextureable_Flag & fConfigTable[config].fLinearFlags); 46 } 47 isConfigRenderableLinearly(GrPixelConfig config,bool withMSAA)48 bool isConfigRenderableLinearly(GrPixelConfig config, bool withMSAA) const { 49 return !withMSAA && SkToBool(ConfigInfo::kRenderable_Flag & 50 fConfigTable[config].fLinearFlags); 51 } 52 configCanBeDstofBlit(GrPixelConfig config,bool linearTiled)53 bool configCanBeDstofBlit(GrPixelConfig config, bool linearTiled) const { 54 const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags : 55 fConfigTable[config].fOptimalFlags; 56 return SkToBool(ConfigInfo::kBlitDst_Flag & flags); 57 } 58 configCanBeSrcofBlit(GrPixelConfig config,bool linearTiled)59 bool configCanBeSrcofBlit(GrPixelConfig config, bool linearTiled) const { 60 const uint16_t& flags = linearTiled ? fConfigTable[config].fLinearFlags : 61 fConfigTable[config].fOptimalFlags; 62 return SkToBool(ConfigInfo::kBlitSrc_Flag & flags); 63 } 64 65 // Tells of if we can pass in straight GLSL string into vkCreateShaderModule canUseGLSLForShaderModule()66 bool canUseGLSLForShaderModule() const { 67 return fCanUseGLSLForShaderModule; 68 } 69 70 // On Adreno vulkan, they do not respect the imageOffset parameter at least in 71 // copyImageToBuffer. This flag says that we must do the copy starting from the origin always. mustDoCopiesFromOrigin()72 bool mustDoCopiesFromOrigin() const { 73 return fMustDoCopiesFromOrigin; 74 } 75 76 // On Nvidia there is a current bug where we must the current command buffer before copy 77 // operations or else the copy will not happen. This includes copies, blits, resolves, and copy 78 // as draws. mustSubmitCommandsBeforeCopyOp()79 bool mustSubmitCommandsBeforeCopyOp() const { 80 return fMustSubmitCommandsBeforeCopyOp; 81 } 82 83 // Sometimes calls to QueueWaitIdle return before actually signalling the fences 84 // on the command buffers even though they have completed. This causes an assert to fire when 85 // destroying the command buffers. Therefore we add a sleep to make sure the fence signals. mustSleepOnTearDown()86 bool mustSleepOnTearDown() const { 87 return fMustSleepOnTearDown; 88 } 89 90 // Returns true if while adding commands to command buffers, we must make a new command buffer 91 // everytime we want to bind a new VkPipeline. This is true for both primary and secondary 92 // command buffers. This is to work around a driver bug specifically on AMD. newCBOnPipelineChange()93 bool newCBOnPipelineChange() const { 94 return fNewCBOnPipelineChange; 95 } 96 97 // On certain Intel devices/drivers (IntelHD405) there is a bug if we try to flush non-coherent 98 // memory and pass in VK_WHOLE_SIZE. This returns whether or not it is safe to use VK_WHOLE_SIZE 99 // or not. canUseWholeSizeOnFlushMappedMemory()100 bool canUseWholeSizeOnFlushMappedMemory() const { 101 return fCanUseWholeSizeOnFlushMappedMemory; 102 } 103 104 /** 105 * Returns both a supported and most prefered stencil format to use in draws. 106 */ preferedStencilFormat()107 const StencilFormat& preferedStencilFormat() const { 108 return fPreferedStencilFormat; 109 } 110 111 bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc, 112 bool* rectsMustMatch, bool* disallowSubrect) const override; 113 114 bool validateBackendTexture(const GrBackendTexture&, SkColorType, 115 GrPixelConfig*) const override; 116 bool validateBackendRenderTarget(const GrBackendRenderTarget&, SkColorType, 117 GrPixelConfig*) const override; 118 119 private: 120 enum VkVendor { 121 kAMD_VkVendor = 4098, 122 kARM_VkVendor = 5045, 123 kImagination_VkVendor = 4112, 124 kIntel_VkVendor = 32902, 125 kNvidia_VkVendor = 4318, 126 kQualcomm_VkVendor = 20803, 127 }; 128 129 void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, 130 VkPhysicalDevice device, uint32_t featureFlags, uint32_t extensionFlags); 131 void initGrCaps(const VkPhysicalDeviceProperties&, 132 const VkPhysicalDeviceMemoryProperties&, 133 uint32_t featureFlags); 134 void initShaderCaps(const VkPhysicalDeviceProperties&, uint32_t featureFlags); 135 136 void initConfigTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&); 137 void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev); 138 139 void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&); 140 141 struct ConfigInfo { ConfigInfoConfigInfo142 ConfigInfo() : fOptimalFlags(0), fLinearFlags(0) {} 143 144 void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&, 145 VkFormat); 146 static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags); 147 void initSampleCounts(const GrVkInterface*, VkPhysicalDevice, 148 const VkPhysicalDeviceProperties&, VkFormat); 149 150 enum { 151 kTextureable_Flag = 0x1, 152 kRenderable_Flag = 0x2, 153 kBlitSrc_Flag = 0x4, 154 kBlitDst_Flag = 0x8, 155 }; 156 157 uint16_t fOptimalFlags; 158 uint16_t fLinearFlags; 159 160 SkTDArray<int> fColorSampleCounts; 161 }; 162 ConfigInfo fConfigTable[kGrPixelConfigCnt]; 163 164 StencilFormat fPreferedStencilFormat; 165 166 bool fCanUseGLSLForShaderModule; 167 168 bool fMustDoCopiesFromOrigin; 169 170 bool fMustSubmitCommandsBeforeCopyOp; 171 172 bool fMustSleepOnTearDown; 173 174 bool fNewCBOnPipelineChange; 175 176 bool fCanUseWholeSizeOnFlushMappedMemory; 177 178 typedef GrCaps INHERITED; 179 }; 180 181 #endif 182