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 GrVkGpu_DEFINED 9 #define GrVkGpu_DEFINED 10 11 #include "include/gpu/vk/GrVkBackendContext.h" 12 #include "include/gpu/vk/GrVkTypes.h" 13 #include "src/gpu/GrGpu.h" 14 #include "src/gpu/vk/GrVkCaps.h" 15 #include "src/gpu/vk/GrVkIndexBuffer.h" 16 #include "src/gpu/vk/GrVkMemory.h" 17 #include "src/gpu/vk/GrVkResourceProvider.h" 18 #include "src/gpu/vk/GrVkSemaphore.h" 19 #include "src/gpu/vk/GrVkUtil.h" 20 #include "src/gpu/vk/GrVkVertexBuffer.h" 21 22 class GrPipeline; 23 24 class GrVkBufferImpl; 25 class GrVkCommandPool; 26 class GrVkGpuRTCommandBuffer; 27 class GrVkGpuTextureCommandBuffer; 28 class GrVkMemoryAllocator; 29 class GrVkPipeline; 30 class GrVkPipelineState; 31 class GrVkPrimaryCommandBuffer; 32 class GrVkRenderPass; 33 class GrVkSecondaryCommandBuffer; 34 class GrVkTexture; 35 struct GrVkInterface; 36 37 namespace SkSL { 38 class Compiler; 39 } 40 41 class GrVkGpu : public GrGpu { 42 public: 43 static sk_sp<GrGpu> Make(const GrVkBackendContext&, const GrContextOptions&, GrContext*); 44 45 ~GrVkGpu() override; 46 47 void disconnect(DisconnectType) override; 48 vkInterface()49 const GrVkInterface* vkInterface() const { return fInterface.get(); } vkCaps()50 const GrVkCaps& vkCaps() const { return *fVkCaps; } 51 memoryAllocator()52 GrVkMemoryAllocator* memoryAllocator() const { return fMemoryAllocator.get(); } 53 physicalDevice()54 VkPhysicalDevice physicalDevice() const { return fPhysicalDevice; } device()55 VkDevice device() const { return fDevice; } queue()56 VkQueue queue() const { return fQueue; } queueIndex()57 uint32_t queueIndex() const { return fQueueIndex; } cmdPool()58 GrVkCommandPool* cmdPool() const { return fCmdPool; } physicalDeviceProperties()59 const VkPhysicalDeviceProperties& physicalDeviceProperties() const { 60 return fPhysDevProps; 61 } physicalDeviceMemoryProperties()62 const VkPhysicalDeviceMemoryProperties& physicalDeviceMemoryProperties() const { 63 return fPhysDevMemProps; 64 } protectedContext()65 bool protectedContext() const { return fProtectedContext == GrProtected::kYes; } 66 resourceProvider()67 GrVkResourceProvider& resourceProvider() { return fResourceProvider; } 68 currentCommandBuffer()69 GrVkPrimaryCommandBuffer* currentCommandBuffer() { return fCurrentCmdBuffer; } 70 71 enum SyncQueue { 72 kForce_SyncQueue, 73 kSkip_SyncQueue 74 }; 75 querySampleLocations(GrRenderTarget *,SkTArray<SkPoint> *)76 void querySampleLocations(GrRenderTarget*, SkTArray<SkPoint>*) override { 77 SkASSERT(!this->caps()->sampleLocationsSupport()); 78 SK_ABORT("Sample locations not yet implemented for Vulkan."); 79 } 80 xferBarrier(GrRenderTarget *,GrXferBarrierType)81 void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {} 82 83 GrBackendTexture createBackendTexture(int w, int h, const GrBackendFormat&, 84 GrMipMapped, GrRenderable, 85 const void* pixels, size_t rowBytes, 86 const SkColor4f* color, 87 GrProtected isProtected) override; 88 void deleteBackendTexture(const GrBackendTexture&) override; 89 #if GR_TEST_UTILS 90 bool isTestingOnlyBackendTexture(const GrBackendTexture&) const override; 91 92 GrBackendRenderTarget createTestingOnlyBackendRenderTarget(int w, int h, GrColorType) override; 93 void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override; 94 95 void testingOnly_flushGpuAndSync() override; 96 resetShaderCacheForTesting()97 void resetShaderCacheForTesting() const override { 98 fResourceProvider.resetShaderCacheForTesting(); 99 } 100 #endif 101 102 GrStencilAttachment* createStencilAttachmentForRenderTarget( 103 const GrRenderTarget*, int width, int height, int numStencilSamples) override; 104 105 GrGpuRTCommandBuffer* getCommandBuffer( 106 GrRenderTarget*, GrSurfaceOrigin, const SkRect&, 107 const GrGpuRTCommandBuffer::LoadAndStoreInfo&, 108 const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override; 109 110 GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override; 111 112 113 void addBufferMemoryBarrier(const GrVkResource*, 114 VkPipelineStageFlags srcStageMask, 115 VkPipelineStageFlags dstStageMask, 116 bool byRegion, 117 VkBufferMemoryBarrier* barrier) const; 118 void addImageMemoryBarrier(const GrVkResource*, 119 VkPipelineStageFlags srcStageMask, 120 VkPipelineStageFlags dstStageMask, 121 bool byRegion, 122 VkImageMemoryBarrier* barrier) const; 123 shaderCompiler()124 SkSL::Compiler* shaderCompiler() const { 125 return fCompiler; 126 } 127 128 bool onRegenerateMipMapLevels(GrTexture* tex) override; 129 resolveRenderTargetNoFlush(GrRenderTarget * target)130 void resolveRenderTargetNoFlush(GrRenderTarget* target) { 131 this->internalResolveRenderTarget(target, false); 132 } 133 onResolveRenderTarget(GrRenderTarget * target)134 void onResolveRenderTarget(GrRenderTarget* target) override { 135 // This resolve is called when we are preparing an msaa surface for external I/O. It is 136 // called after flushing, so we need to make sure we submit the command buffer after doing 137 // the resolve so that the resolve actually happens. 138 this->internalResolveRenderTarget(target, true); 139 } 140 141 void submitSecondaryCommandBuffer(std::unique_ptr<GrVkSecondaryCommandBuffer>, 142 const GrVkRenderPass*, 143 const VkClearValue* colorClear, 144 GrVkRenderTarget*, GrSurfaceOrigin, 145 const SkIRect& bounds); 146 147 void submit(GrGpuCommandBuffer*) override; 148 149 GrFence SK_WARN_UNUSED_RESULT insertFence() override; 150 bool waitFence(GrFence, uint64_t timeout) override; 151 void deleteFence(GrFence) const override; 152 153 sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override; 154 sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore, 155 GrResourceProvider::SemaphoreWrapType wrapType, 156 GrWrapOwnership ownership) override; 157 void insertSemaphore(sk_sp<GrSemaphore> semaphore) override; 158 void waitSemaphore(sk_sp<GrSemaphore> semaphore) override; 159 160 // These match the definitions in SkDrawable, from whence they came 161 typedef void* SubmitContext; 162 typedef void (*SubmitProc)(SubmitContext submitContext); 163 164 // Adds an SkDrawable::GpuDrawHandler that we will delete the next time we submit the primary 165 // command buffer to the gpu. 166 void addDrawable(std::unique_ptr<SkDrawable::GpuDrawHandler> drawable); 167 checkFinishProcs()168 void checkFinishProcs() override { fResourceProvider.checkCommandBuffers(); } 169 170 sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override; 171 172 void copyBuffer(GrVkBuffer* srcBuffer, GrVkBuffer* dstBuffer, VkDeviceSize srcOffset, 173 VkDeviceSize dstOffset, VkDeviceSize size); 174 bool updateBuffer(GrVkBuffer* buffer, const void* src, VkDeviceSize offset, VkDeviceSize size); 175 176 uint32_t getExtraSamplerKeyForProgram(const GrSamplerState&, 177 const GrBackendFormat& format) override; 178 179 enum PersistentCacheKeyType : uint32_t { 180 kShader_PersistentCacheKeyType = 0, 181 kPipelineCache_PersistentCacheKeyType = 1, 182 }; 183 184 void storeVkPipelineCacheData() override; 185 186 private: 187 GrVkGpu(GrContext*, const GrContextOptions&, const GrVkBackendContext&, 188 sk_sp<const GrVkInterface>, uint32_t instanceVersion, uint32_t physicalDeviceVersion); 189 onResetContext(uint32_t resetBits)190 void onResetContext(uint32_t resetBits) override {} 191 192 void destroyResources(); 193 194 sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, 195 const GrBackendFormat& format, 196 GrRenderable, 197 int renderTargetSampleCnt, 198 SkBudgeted, 199 GrProtected, 200 const GrMipLevel[], 201 int mipLevelCount) override; 202 sk_sp<GrTexture> onCreateCompressedTexture(int width, int height, const GrBackendFormat&, 203 SkImage::CompressionType, SkBudgeted, 204 const void* data) override; 205 206 sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrColorType, GrWrapOwnership, 207 GrWrapCacheable, GrIOType) override; 208 sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&, 209 int sampleCnt, 210 GrColorType colorType, 211 GrWrapOwnership, 212 GrWrapCacheable) override; 213 sk_sp<GrRenderTarget> onWrapBackendRenderTarget(const GrBackendRenderTarget&, 214 GrColorType) override; 215 216 sk_sp<GrRenderTarget> onWrapBackendTextureAsRenderTarget(const GrBackendTexture&, 217 int sampleCnt, GrColorType) override; 218 219 sk_sp<GrRenderTarget> onWrapVulkanSecondaryCBAsRenderTarget(const SkImageInfo&, 220 const GrVkDrawableInfo&) override; 221 222 sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType type, GrAccessPattern, 223 const void* data) override; 224 225 bool onReadPixels(GrSurface* surface, int left, int top, int width, int height, 226 GrColorType surfaceColorType, GrColorType dstColorType, void* buffer, 227 size_t rowBytes) override; 228 229 bool onWritePixels(GrSurface* surface, int left, int top, int width, int height, 230 GrColorType surfaceColorType, GrColorType srcColorType, 231 const GrMipLevel texels[], int mipLevelCount) override; 232 233 bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height, 234 GrColorType textureColorType, GrColorType bufferColorType, 235 GrGpuBuffer* transferBuffer, size_t offset, size_t rowBytes) override; 236 bool onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height, 237 GrColorType surfaceColorType, GrColorType bufferColorType, 238 GrGpuBuffer* transferBuffer, size_t offset) override; 239 240 bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 241 const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) override; 242 243 void onFinishFlush(GrSurfaceProxy*[], int, SkSurface::BackendSurfaceAccess access, 244 const GrFlushInfo&, const GrPrepareForExternalIORequests&) override; 245 246 // Ends and submits the current command buffer to the queue and then creates a new command 247 // buffer and begins it. If sync is set to kForce_SyncQueue, the function will wait for all 248 // work in the queue to finish before returning. If this GrVkGpu object has any semaphores in 249 // fSemaphoreToSignal, we will add those signal semaphores to the submission of this command 250 // buffer. If this GrVkGpu object has any semaphores in fSemaphoresToWaitOn, we will add those 251 // wait semaphores to the submission of this command buffer. 252 void submitCommandBuffer(SyncQueue sync, GrGpuFinishedProc finishedProc = nullptr, 253 GrGpuFinishedContext finishedContext = nullptr); 254 255 void internalResolveRenderTarget(GrRenderTarget*, bool requiresSubmit); 256 257 void copySurfaceAsCopyImage(GrSurface* dst, GrSurface* src, GrVkImage* dstImage, 258 GrVkImage* srcImage, const SkIRect& srcRect, 259 const SkIPoint& dstPoint); 260 261 void copySurfaceAsBlit(GrSurface* dst, GrSurface* src, GrVkImage* dstImage, GrVkImage* srcImage, 262 const SkIRect& srcRect, const SkIPoint& dstPoint); 263 264 void copySurfaceAsResolve(GrSurface* dst, GrSurface* src, const SkIRect& srcRect, 265 const SkIPoint& dstPoint); 266 267 // helpers for onCreateTexture and writeTexturePixels 268 bool uploadTexDataLinear(GrVkTexture* tex, int left, int top, int width, int height, 269 GrColorType colorType, const void* data, size_t rowBytes); 270 bool uploadTexDataOptimal(GrVkTexture* tex, int left, int top, int width, int height, 271 GrColorType colorType, const GrMipLevel texels[], int mipLevelCount); 272 bool uploadTexDataCompressed(GrVkTexture* tex, int left, int top, int width, int height, 273 SkImage::CompressionType, const void* data); 274 void resolveImage(GrSurface* dst, GrVkRenderTarget* src, const SkIRect& srcRect, 275 const SkIPoint& dstPoint); 276 277 bool createVkImageForBackendSurface(VkFormat vkFormat, int w, int h, bool texturable, 278 bool renderable, GrMipMapped mipMapped, const void* srcData, 279 size_t srcRowBytes, const SkColor4f* color, 280 GrVkImageInfo* info, GrProtected isProtected); 281 282 sk_sp<const GrVkInterface> fInterface; 283 sk_sp<GrVkMemoryAllocator> fMemoryAllocator; 284 sk_sp<GrVkCaps> fVkCaps; 285 286 VkInstance fInstance; 287 VkPhysicalDevice fPhysicalDevice; 288 VkDevice fDevice; 289 VkQueue fQueue; // Must be Graphics queue 290 uint32_t fQueueIndex; 291 292 // Created by GrVkGpu 293 GrVkResourceProvider fResourceProvider; 294 295 GrVkCommandPool* fCmdPool; 296 297 // just a raw pointer; object's lifespan is managed by fCmdPool 298 GrVkPrimaryCommandBuffer* fCurrentCmdBuffer; 299 300 SkSTArray<1, GrVkSemaphore::Resource*> fSemaphoresToWaitOn; 301 SkSTArray<1, GrVkSemaphore::Resource*> fSemaphoresToSignal; 302 303 SkTArray<std::unique_ptr<SkDrawable::GpuDrawHandler>> fDrawables; 304 305 VkPhysicalDeviceProperties fPhysDevProps; 306 VkPhysicalDeviceMemoryProperties fPhysDevMemProps; 307 308 // compiler used for compiling sksl into spirv. We only want to create the compiler once since 309 // there is significant overhead to the first compile of any compiler. 310 SkSL::Compiler* fCompiler; 311 312 // We need a bool to track whether or not we've already disconnected all the gpu resources from 313 // vulkan context. 314 bool fDisconnected; 315 316 GrProtected fProtectedContext; 317 318 std::unique_ptr<GrVkGpuRTCommandBuffer> fCachedRTCommandBuffer; 319 std::unique_ptr<GrVkGpuTextureCommandBuffer> fCachedTexCommandBuffer; 320 321 typedef GrGpu INHERITED; 322 }; 323 324 #endif 325