1 // 2 // Copyright 2016 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // ContextVk.h: 7 // Defines the class interface for ContextVk, implementing ContextImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_ 11 #define LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_ 12 13 #include <condition_variable> 14 15 #include "common/PackedEnums.h" 16 #include "libANGLE/renderer/ContextImpl.h" 17 #include "libANGLE/renderer/renderer_utils.h" 18 #include "libANGLE/renderer/vulkan/OverlayVk.h" 19 #include "libANGLE/renderer/vulkan/PersistentCommandPool.h" 20 #include "libANGLE/renderer/vulkan/RendererVk.h" 21 #include "libANGLE/renderer/vulkan/vk_headers.h" 22 #include "libANGLE/renderer/vulkan/vk_helpers.h" 23 24 namespace angle 25 { 26 struct FeaturesVk; 27 } // namespace angle 28 29 namespace rx 30 { 31 class ProgramExecutableVk; 32 class RendererVk; 33 class WindowSurfaceVk; 34 35 struct CommandBatch final : angle::NonCopyable 36 { 37 CommandBatch(); 38 ~CommandBatch(); 39 CommandBatch(CommandBatch &&other); 40 CommandBatch &operator=(CommandBatch &&other); 41 42 void destroy(VkDevice device); 43 44 vk::PrimaryCommandBuffer primaryCommands; 45 // commandPool is for secondary CommandBuffer allocation 46 vk::CommandPool commandPool; 47 vk::Shared<vk::Fence> fence; 48 Serial serial; 49 }; 50 51 class CommandQueue final : angle::NonCopyable 52 { 53 public: 54 CommandQueue(); 55 ~CommandQueue(); 56 57 angle::Result init(vk::Context *context); 58 void destroy(VkDevice device); 59 void handleDeviceLost(RendererVk *renderer); 60 61 bool hasInFlightCommands() const; 62 63 angle::Result allocatePrimaryCommandBuffer(vk::Context *context, 64 const vk::CommandPool &commandPool, 65 vk::PrimaryCommandBuffer *commandBufferOut); 66 angle::Result releasePrimaryCommandBuffer(vk::Context *context, 67 vk::PrimaryCommandBuffer &&commandBuffer); 68 69 void clearAllGarbage(RendererVk *renderer); 70 71 angle::Result finishToSerial(vk::Context *context, Serial serial, uint64_t timeout); 72 73 angle::Result submitFrame(vk::Context *context, 74 egl::ContextPriority priority, 75 const VkSubmitInfo &submitInfo, 76 const vk::Shared<vk::Fence> &sharedFence, 77 vk::GarbageList *currentGarbage, 78 vk::CommandPool *commandPool, 79 vk::PrimaryCommandBuffer &&commandBuffer); 80 81 vk::Shared<vk::Fence> getLastSubmittedFence(const vk::Context *context) const; 82 83 // Check to see which batches have finished completion (forward progress for 84 // mLastCompletedQueueSerial, for example for when the application busy waits on a query 85 // result). It would be nice if we didn't have to expose this for QueryVk::getResult. 86 angle::Result checkCompletedCommands(vk::Context *context); 87 88 private: 89 angle::Result releaseToCommandBatch(vk::Context *context, 90 vk::PrimaryCommandBuffer &&commandBuffer, 91 vk::CommandPool *commandPool, 92 CommandBatch *batch); 93 94 vk::GarbageQueue mGarbageQueue; 95 std::vector<CommandBatch> mInFlightCommands; 96 97 // Keeps a free list of reusable primary command buffers. 98 vk::PersistentCommandPool mPrimaryCommandPool; 99 }; 100 101 static constexpr uint32_t kMaxGpuEventNameLen = 32; 102 using EventName = std::array<char, kMaxGpuEventNameLen>; 103 104 class ContextVk : public ContextImpl, public vk::Context 105 { 106 public: 107 ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk *renderer); 108 ~ContextVk() override; 109 110 angle::Result initialize() override; 111 112 void onDestroy(const gl::Context *context) override; 113 114 // Flush and finish. 115 angle::Result flush(const gl::Context *context) override; 116 angle::Result finish(const gl::Context *context) override; 117 118 // Drawing methods. 119 angle::Result drawArrays(const gl::Context *context, 120 gl::PrimitiveMode mode, 121 GLint first, 122 GLsizei count) override; 123 angle::Result drawArraysInstanced(const gl::Context *context, 124 gl::PrimitiveMode mode, 125 GLint first, 126 GLsizei count, 127 GLsizei instanceCount) override; 128 angle::Result drawArraysInstancedBaseInstance(const gl::Context *context, 129 gl::PrimitiveMode mode, 130 GLint first, 131 GLsizei count, 132 GLsizei instanceCount, 133 GLuint baseInstance) override; 134 135 angle::Result drawElements(const gl::Context *context, 136 gl::PrimitiveMode mode, 137 GLsizei count, 138 gl::DrawElementsType type, 139 const void *indices) override; 140 angle::Result drawElementsBaseVertex(const gl::Context *context, 141 gl::PrimitiveMode mode, 142 GLsizei count, 143 gl::DrawElementsType type, 144 const void *indices, 145 GLint baseVertex) override; 146 angle::Result drawElementsInstanced(const gl::Context *context, 147 gl::PrimitiveMode mode, 148 GLsizei count, 149 gl::DrawElementsType type, 150 const void *indices, 151 GLsizei instanceCount) override; 152 angle::Result drawElementsInstancedBaseVertex(const gl::Context *context, 153 gl::PrimitiveMode mode, 154 GLsizei count, 155 gl::DrawElementsType type, 156 const void *indices, 157 GLsizei instanceCount, 158 GLint baseVertex) override; 159 angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, 160 gl::PrimitiveMode mode, 161 GLsizei count, 162 gl::DrawElementsType type, 163 const void *indices, 164 GLsizei instances, 165 GLint baseVertex, 166 GLuint baseInstance) override; 167 angle::Result drawRangeElements(const gl::Context *context, 168 gl::PrimitiveMode mode, 169 GLuint start, 170 GLuint end, 171 GLsizei count, 172 gl::DrawElementsType type, 173 const void *indices) override; 174 angle::Result drawRangeElementsBaseVertex(const gl::Context *context, 175 gl::PrimitiveMode mode, 176 GLuint start, 177 GLuint end, 178 GLsizei count, 179 gl::DrawElementsType type, 180 const void *indices, 181 GLint baseVertex) override; 182 angle::Result drawArraysIndirect(const gl::Context *context, 183 gl::PrimitiveMode mode, 184 const void *indirect) override; 185 angle::Result drawElementsIndirect(const gl::Context *context, 186 gl::PrimitiveMode mode, 187 gl::DrawElementsType type, 188 const void *indirect) override; 189 190 // Device loss 191 gl::GraphicsResetStatus getResetStatus() override; 192 193 // Vendor and description strings. 194 std::string getVendorString() const override; 195 std::string getRendererDescription() const override; 196 197 // EXT_debug_marker 198 angle::Result insertEventMarker(GLsizei length, const char *marker) override; 199 angle::Result pushGroupMarker(GLsizei length, const char *marker) override; 200 angle::Result popGroupMarker() override; 201 202 // KHR_debug 203 angle::Result pushDebugGroup(const gl::Context *context, 204 GLenum source, 205 GLuint id, 206 const std::string &message) override; 207 angle::Result popDebugGroup(const gl::Context *context) override; 208 209 bool isViewportFlipEnabledForDrawFBO() const; 210 bool isViewportFlipEnabledForReadFBO() const; 211 // When the device/surface is rotated such that the surface's aspect ratio is different than 212 // the native device (e.g. 90 degrees), the width and height of the viewport, scissor, and 213 // render area must be swapped. 214 bool isRotatedAspectRatioForDrawFBO() const; 215 bool isRotatedAspectRatioForReadFBO() const; 216 SurfaceRotation getRotationDrawFramebuffer() const; 217 SurfaceRotation getRotationReadFramebuffer() const; 218 219 void invalidateProgramBindingHelper(const gl::State &glState); 220 angle::Result invalidateProgramExecutableHelper(const gl::Context *context); 221 222 // State sync with dirty bits. 223 angle::Result syncState(const gl::Context *context, 224 const gl::State::DirtyBits &dirtyBits, 225 const gl::State::DirtyBits &bitMask) override; 226 227 // Disjoint timer queries 228 GLint getGPUDisjoint() override; 229 GLint64 getTimestamp() override; 230 231 // Context switching 232 angle::Result onMakeCurrent(const gl::Context *context) override; 233 angle::Result onUnMakeCurrent(const gl::Context *context) override; 234 235 // Native capabilities, unmodified by gl::Context. 236 gl::Caps getNativeCaps() const override; 237 const gl::TextureCapsMap &getNativeTextureCaps() const override; 238 const gl::Extensions &getNativeExtensions() const override; 239 const gl::Limitations &getNativeLimitations() const override; 240 241 // Shader creation 242 CompilerImpl *createCompiler() override; 243 ShaderImpl *createShader(const gl::ShaderState &state) override; 244 ProgramImpl *createProgram(const gl::ProgramState &state) override; 245 246 // Framebuffer creation 247 FramebufferImpl *createFramebuffer(const gl::FramebufferState &state) override; 248 249 // Texture creation 250 TextureImpl *createTexture(const gl::TextureState &state) override; 251 252 // Renderbuffer creation 253 RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override; 254 255 // Buffer creation 256 BufferImpl *createBuffer(const gl::BufferState &state) override; 257 258 // Vertex Array creation 259 VertexArrayImpl *createVertexArray(const gl::VertexArrayState &state) override; 260 261 // Query and Fence creation 262 QueryImpl *createQuery(gl::QueryType type) override; 263 FenceNVImpl *createFenceNV() override; 264 SyncImpl *createSync() override; 265 266 // Transform Feedback creation 267 TransformFeedbackImpl *createTransformFeedback( 268 const gl::TransformFeedbackState &state) override; 269 270 // Sampler object creation 271 SamplerImpl *createSampler(const gl::SamplerState &state) override; 272 273 // Program Pipeline object creation 274 ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override; 275 276 // Memory object creation. 277 MemoryObjectImpl *createMemoryObject() override; 278 279 // Semaphore creation. 280 SemaphoreImpl *createSemaphore() override; 281 282 // Overlay creation. 283 OverlayImpl *createOverlay(const gl::OverlayState &state) override; 284 285 angle::Result dispatchCompute(const gl::Context *context, 286 GLuint numGroupsX, 287 GLuint numGroupsY, 288 GLuint numGroupsZ) override; 289 angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override; 290 291 angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override; 292 angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override; 293 294 VkDevice getDevice() const; getPriority()295 egl::ContextPriority getPriority() const { return mContextPriority; } 296 getFeatures()297 ANGLE_INLINE const angle::FeaturesVk &getFeatures() const { return mRenderer->getFeatures(); } 298 invalidateVertexAndIndexBuffers()299 ANGLE_INLINE void invalidateVertexAndIndexBuffers() 300 { 301 // TODO: Make the pipeline invalidate more fine-grained. Only need to dirty here if PSO 302 // VtxInput state (stride, fmt, inputRate...) has changed. http://anglebug.com/3256 303 invalidateCurrentGraphicsPipeline(); 304 mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS); 305 mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER); 306 } 307 invalidateVertexBuffers()308 ANGLE_INLINE void invalidateVertexBuffers() 309 { 310 mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS); 311 } 312 onVertexAttributeChange(size_t attribIndex,GLuint stride,GLuint divisor,angle::FormatID format,GLuint relativeOffset)313 ANGLE_INLINE void onVertexAttributeChange(size_t attribIndex, 314 GLuint stride, 315 GLuint divisor, 316 angle::FormatID format, 317 GLuint relativeOffset) 318 { 319 invalidateCurrentGraphicsPipeline(); 320 mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS); 321 // Set divisor to 1 for attribs with emulated divisor 322 mGraphicsPipelineDesc->updateVertexInput( 323 &mGraphicsPipelineTransition, static_cast<uint32_t>(attribIndex), stride, 324 divisor > mRenderer->getMaxVertexAttribDivisor() ? 1 : divisor, format, relativeOffset); 325 } 326 327 void invalidateDefaultAttribute(size_t attribIndex); 328 void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask); 329 void onDrawFramebufferChange(FramebufferVk *framebufferVk); onHostVisibleBufferWrite()330 void onHostVisibleBufferWrite() { mIsAnyHostVisibleBufferWritten = true; } 331 332 void invalidateCurrentTransformFeedbackBuffers(); 333 void onTransformFeedbackStateChanged(); 334 335 // When UtilsVk issues draw or dispatch calls, it binds descriptor sets that the context is not 336 // aware of. This function is called to make sure affected descriptor set bindings are dirtied 337 // for the next application draw/dispatch call. 338 void invalidateGraphicsDescriptorSet(uint32_t usedDescriptorSet); 339 void invalidateComputeDescriptorSet(uint32_t usedDescriptorSet); 340 341 void optimizeRenderPassForPresent(VkFramebuffer framebufferHandle); 342 343 vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType); 344 345 const VkClearValue &getClearColorValue() const; 346 const VkClearValue &getClearDepthStencilValue() const; 347 VkColorComponentFlags getClearColorMask() const; 348 angle::Result getIncompleteTexture(const gl::Context *context, 349 gl::TextureType type, 350 gl::Texture **textureOut); 351 void updateColorMask(const gl::BlendState &blendState); 352 void updateSampleMask(const gl::State &glState); 353 354 void handleError(VkResult errorCode, 355 const char *file, 356 const char *function, 357 unsigned int line) override; getActiveTextures()358 const gl::ActiveTextureArray<vk::TextureUnit> &getActiveTextures() const 359 { 360 return mActiveTextures; 361 } getActiveImages()362 const gl::ActiveTextureArray<TextureVk *> &getActiveImages() const { return mActiveImages; } 363 setIndexBufferDirty()364 void setIndexBufferDirty() 365 { 366 mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER); 367 mLastIndexBufferOffset = reinterpret_cast<const void *>(angle::DirtyPointer); 368 } 369 370 angle::Result flushImpl(const vk::Semaphore *semaphore); 371 angle::Result finishImpl(); 372 373 void addWaitSemaphore(VkSemaphore semaphore, VkPipelineStageFlags stageMask); 374 375 const vk::CommandPool &getCommandPool() const; 376 getCurrentQueueSerial()377 Serial getCurrentQueueSerial() const { return mRenderer->getCurrentQueueSerial(); } getLastSubmittedQueueSerial()378 Serial getLastSubmittedQueueSerial() const { return mRenderer->getLastSubmittedQueueSerial(); } getLastCompletedQueueSerial()379 Serial getLastCompletedQueueSerial() const { return mRenderer->getLastCompletedQueueSerial(); } 380 381 bool isSerialInUse(Serial serial) const; 382 383 template <typename T> addGarbage(T * object)384 void addGarbage(T *object) 385 { 386 if (object->valid()) 387 { 388 mCurrentGarbage.emplace_back(vk::GetGarbage(object)); 389 } 390 } 391 392 // It would be nice if we didn't have to expose this for QueryVk::getResult. 393 angle::Result checkCompletedCommands(); 394 395 // Wait for completion of batches until (at least) batch with given serial is finished. 396 angle::Result finishToSerial(Serial serial); 397 398 angle::Result getCompatibleRenderPass(const vk::RenderPassDesc &desc, 399 vk::RenderPass **renderPassOut); 400 angle::Result getRenderPassWithOps(const vk::RenderPassDesc &desc, 401 const vk::AttachmentOpsArray &ops, 402 vk::RenderPass **renderPassOut); 403 404 // Get (or allocate) the fence that will be signaled on next submission. 405 angle::Result getNextSubmitFence(vk::Shared<vk::Fence> *sharedFenceOut); 406 vk::Shared<vk::Fence> getLastSubmittedFence() const; 407 getShaderLibrary()408 vk::ShaderLibrary &getShaderLibrary() { return mShaderLibrary; } getUtils()409 UtilsVk &getUtils() { return mUtils; } 410 411 angle::Result getTimestamp(uint64_t *timestampOut); 412 413 // Create Begin/End/Instant GPU trace events, which take their timestamps from GPU queries. 414 // The events are queued until the query results are available. Possible values for `phase` 415 // are TRACE_EVENT_PHASE_* traceGpuEvent(vk::CommandBuffer * commandBuffer,char phase,const EventName & name)416 ANGLE_INLINE angle::Result traceGpuEvent(vk::CommandBuffer *commandBuffer, 417 char phase, 418 const EventName &name) 419 { 420 if (mGpuEventsEnabled) 421 return traceGpuEventImpl(commandBuffer, phase, name); 422 return angle::Result::Continue; 423 } 424 getRenderPassCache()425 RenderPassCache &getRenderPassCache() { return mRenderPassCache; } 426 427 vk::DescriptorSetLayoutDesc getDriverUniformsDescriptorSetDesc( 428 VkShaderStageFlags shaderStages) const; 429 430 // We use texture serials to optimize texture binding updates. Each permutation of a 431 // {VkImage/VkSampler} generates a unique serial. These serials are combined to form a unique 432 // signature for each descriptor set. This allows us to keep a cache of descriptor sets and 433 // avoid calling vkAllocateDesctiporSets each texture update. generateTextureSerial()434 Serial generateTextureSerial() { return mTextureSerialFactory.generate(); } getActiveTexturesDesc()435 const vk::TextureDescriptorDesc &getActiveTexturesDesc() const { return mActiveTexturesDesc; } generateAttachmentImageSerial()436 Serial generateAttachmentImageSerial() { return mAttachmentImageSerialFactory.generate(); } 437 438 angle::Result updateScissor(const gl::State &glState); 439 emulateSeamfulCubeMapSampling()440 bool emulateSeamfulCubeMapSampling() const { return mEmulateSeamfulCubeMapSampling; } 441 useOldRewriteStructSamplers()442 bool useOldRewriteStructSamplers() const { return mUseOldRewriteStructSamplers; } 443 getOverlay()444 const gl::OverlayType *getOverlay() const { return mState.getOverlay(); } 445 getResourceUseList()446 vk::ResourceUseList &getResourceUseList() { return mResourceUseList; } 447 onBufferTransferRead(vk::BufferHelper * buffer)448 angle::Result onBufferTransferRead(vk::BufferHelper *buffer) 449 { 450 return onBufferRead(VK_ACCESS_TRANSFER_READ_BIT, vk::PipelineStage::Transfer, buffer); 451 } onBufferTransferWrite(vk::BufferHelper * buffer)452 angle::Result onBufferTransferWrite(vk::BufferHelper *buffer) 453 { 454 return onBufferWrite(VK_ACCESS_TRANSFER_WRITE_BIT, vk::PipelineStage::Transfer, buffer); 455 } onBufferComputeShaderRead(vk::BufferHelper * buffer)456 angle::Result onBufferComputeShaderRead(vk::BufferHelper *buffer) 457 { 458 return onBufferRead(VK_ACCESS_SHADER_READ_BIT, vk::PipelineStage::ComputeShader, buffer); 459 } onBufferComputeShaderWrite(vk::BufferHelper * buffer)460 angle::Result onBufferComputeShaderWrite(vk::BufferHelper *buffer) 461 { 462 return onBufferWrite(VK_ACCESS_SHADER_WRITE_BIT, vk::PipelineStage::ComputeShader, buffer); 463 } 464 465 angle::Result onImageRead(VkImageAspectFlags aspectFlags, 466 vk::ImageLayout imageLayout, 467 vk::ImageHelper *image); 468 469 angle::Result onImageWrite(VkImageAspectFlags aspectFlags, 470 vk::ImageLayout imageLayout, 471 vk::ImageHelper *image); 472 473 void onRenderPassImageWrite(VkImageAspectFlags aspectFlags, 474 vk::ImageLayout imageLayout, 475 vk::ImageHelper *image); 476 endRenderPassAndGetCommandBuffer(vk::CommandBuffer ** commandBufferOut)477 angle::Result endRenderPassAndGetCommandBuffer(vk::CommandBuffer **commandBufferOut) 478 { 479 // Only one command buffer should be active at a time 480 ASSERT(mOutsideRenderPassCommands->empty() || mRenderPassCommands->empty()); 481 ANGLE_TRY(endRenderPass()); 482 *commandBufferOut = &mOutsideRenderPassCommands->getCommandBuffer(); 483 return angle::Result::Continue; 484 } 485 486 angle::Result flushAndBeginRenderPass(const vk::Framebuffer &framebuffer, 487 const gl::Rectangle &renderArea, 488 const vk::RenderPassDesc &renderPassDesc, 489 const vk::AttachmentOpsArray &renderPassAttachmentOps, 490 const vk::ClearValuesArray &clearValues, 491 vk::CommandBuffer **commandBufferOut); 492 hasStartedRenderPass()493 bool hasStartedRenderPass() const { return !mRenderPassCommands->empty(); } 494 getStartedRenderPassCommands()495 vk::CommandBufferHelper &getStartedRenderPassCommands() 496 { 497 ASSERT(hasStartedRenderPass()); 498 return *mRenderPassCommands; 499 } 500 getContextPriority()501 egl::ContextPriority getContextPriority() const override { return mContextPriority; } 502 angle::Result startRenderPass(gl::Rectangle renderArea, vk::CommandBuffer **commandBufferOut); 503 angle::Result endRenderPass(); 504 505 angle::Result syncExternalMemory(); 506 507 void addCommandBufferDiagnostics(const std::string &commandBufferDiagnostics); 508 509 VkIndexType getVkIndexType(gl::DrawElementsType glIndexType) const; 510 size_t getVkIndexTypeSize(gl::DrawElementsType glIndexType) const; 511 bool shouldConvertUint8VkIndexType(gl::DrawElementsType glIndexType) const; 512 isBresenhamEmulationEnabled(const gl::PrimitiveMode mode)513 ANGLE_INLINE bool isBresenhamEmulationEnabled(const gl::PrimitiveMode mode) 514 { 515 return getFeatures().basicGLLineRasterization.enabled && gl::IsLineMode(mode); 516 } 517 getExecutable()518 const ProgramExecutableVk *getExecutable() const { return mExecutable; } getExecutable()519 ProgramExecutableVk *getExecutable() { return mExecutable; } 520 521 bool isRobustResourceInitEnabled() const override; 522 523 // occlusion query 524 void beginOcclusionQuery(QueryVk *queryVk); 525 void endOcclusionQuery(QueryVk *queryVk); 526 527 void updateOverlayOnPresent(); 528 529 // Submit commands to worker thread for processing queueCommandsToWorker(const vk::CommandProcessorTask & commands)530 ANGLE_INLINE void queueCommandsToWorker(const vk::CommandProcessorTask &commands) 531 { 532 mRenderer->queueCommands(commands); 533 } 534 // When worker thread completes, it releases command buffers back to context queue 535 void recycleCommandBuffer(vk::CommandBufferHelper *commandBuffer); 536 537 private: 538 // Dirty bits. 539 enum DirtyBitType : size_t 540 { 541 DIRTY_BIT_DEFAULT_ATTRIBS, 542 DIRTY_BIT_PIPELINE, 543 DIRTY_BIT_TEXTURES, 544 DIRTY_BIT_VERTEX_BUFFERS, 545 DIRTY_BIT_INDEX_BUFFER, 546 DIRTY_BIT_DRIVER_UNIFORMS, 547 DIRTY_BIT_DRIVER_UNIFORMS_BINDING, 548 DIRTY_BIT_SHADER_RESOURCES, // excluding textures, which are handled separately. 549 DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS, 550 DIRTY_BIT_TRANSFORM_FEEDBACK_STATE, 551 DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME, 552 DIRTY_BIT_DESCRIPTOR_SETS, 553 DIRTY_BIT_MAX, 554 }; 555 556 using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>; 557 558 using DirtyBitHandler = angle::Result (ContextVk::*)(const gl::Context *, 559 vk::CommandBuffer *commandBuffer); 560 561 struct DriverUniformsDescriptorSet 562 { 563 vk::DynamicBuffer dynamicBuffer; 564 VkDescriptorSet descriptorSet; 565 uint32_t dynamicOffset; 566 vk::BindingPointer<vk::DescriptorSetLayout> descriptorSetLayout; 567 vk::RefCountedDescriptorPoolBinding descriptorPoolBinding; 568 569 DriverUniformsDescriptorSet(); 570 ~DriverUniformsDescriptorSet(); 571 572 void init(RendererVk *rendererVk); 573 void destroy(RendererVk *rendererVk); 574 }; 575 576 enum class PipelineType 577 { 578 Graphics = 0, 579 Compute = 1, 580 581 InvalidEnum = 2, 582 EnumCount = 2, 583 }; 584 585 // The GpuEventQuery struct holds together a timestamp query and enough data to create a 586 // trace event based on that. Use traceGpuEvent to insert such queries. They will be readback 587 // when the results are available, without inserting a GPU bubble. 588 // 589 // - eventName will be the reported name of the event 590 // - phase is either 'B' (duration begin), 'E' (duration end) or 'i' (instant // event). 591 // See Google's "Trace Event Format": 592 // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU 593 // - serial is the serial of the batch the query was submitted on. Until the batch is 594 // submitted, the query is not checked to avoid incuring a flush. 595 struct GpuEventQuery final 596 { 597 EventName name; 598 char phase; 599 vk::QueryHelper queryHelper; 600 }; 601 602 // Once a query result is available, the timestamp is read and a GpuEvent object is kept until 603 // the next clock sync, at which point the clock drift is compensated in the results before 604 // handing them off to the application. 605 struct GpuEvent final 606 { 607 uint64_t gpuTimestampCycles; 608 std::array<char, kMaxGpuEventNameLen> name; 609 char phase; 610 }; 611 612 struct GpuClockSyncInfo 613 { 614 double gpuTimestampS; 615 double cpuTimestampS; 616 }; 617 618 angle::Result setupDraw(const gl::Context *context, 619 gl::PrimitiveMode mode, 620 GLint firstVertexOrInvalid, 621 GLsizei vertexOrIndexCount, 622 GLsizei instanceCount, 623 gl::DrawElementsType indexTypeOrInvalid, 624 const void *indices, 625 DirtyBits dirtyBitMask, 626 vk::CommandBuffer **commandBufferOut); 627 angle::Result setupIndexedDraw(const gl::Context *context, 628 gl::PrimitiveMode mode, 629 GLsizei indexCount, 630 GLsizei instanceCount, 631 gl::DrawElementsType indexType, 632 const void *indices, 633 vk::CommandBuffer **commandBufferOut); 634 angle::Result setupIndirectDraw(const gl::Context *context, 635 gl::PrimitiveMode mode, 636 DirtyBits dirtyBitMask, 637 vk::BufferHelper *indirectBuffer, 638 VkDeviceSize indirectBufferOffset, 639 vk::CommandBuffer **commandBufferOut); 640 angle::Result setupIndexedIndirectDraw(const gl::Context *context, 641 gl::PrimitiveMode mode, 642 gl::DrawElementsType indexType, 643 vk::BufferHelper *indirectBuffer, 644 VkDeviceSize indirectBufferOffset, 645 vk::CommandBuffer **commandBufferOut); 646 647 angle::Result setupLineLoopIndexedIndirectDraw(const gl::Context *context, 648 gl::PrimitiveMode mode, 649 gl::DrawElementsType indexType, 650 vk::BufferHelper *srcIndirectBuf, 651 VkDeviceSize indirectBufferOffset, 652 vk::CommandBuffer **commandBufferOut, 653 vk::BufferHelper **indirectBufferOut, 654 VkDeviceSize *indirectBufferOffsetOut); 655 angle::Result setupLineLoopIndirectDraw(const gl::Context *context, 656 gl::PrimitiveMode mode, 657 vk::BufferHelper *indirectBuffer, 658 VkDeviceSize indirectBufferOffset, 659 vk::CommandBuffer **commandBufferOut, 660 vk::BufferHelper **indirectBufferOut, 661 VkDeviceSize *indirectBufferOffsetOut); 662 663 angle::Result setupLineLoopDraw(const gl::Context *context, 664 gl::PrimitiveMode mode, 665 GLint firstVertex, 666 GLsizei vertexOrIndexCount, 667 gl::DrawElementsType indexTypeOrInvalid, 668 const void *indices, 669 vk::CommandBuffer **commandBufferOut, 670 uint32_t *numIndicesOut); 671 angle::Result setupDispatch(const gl::Context *context, vk::CommandBuffer **commandBufferOut); 672 673 gl::Rectangle getCorrectedViewport(const gl::Rectangle &viewport) const; 674 void updateViewport(FramebufferVk *framebufferVk, 675 const gl::Rectangle &viewport, 676 float nearPlane, 677 float farPlane, 678 bool invertViewport); 679 void updateDepthRange(float nearPlane, float farPlane); 680 void updateFlipViewportDrawFramebuffer(const gl::State &glState); 681 void updateFlipViewportReadFramebuffer(const gl::State &glState); 682 void updateSurfaceRotationDrawFramebuffer(const gl::State &glState); 683 void updateSurfaceRotationReadFramebuffer(const gl::State &glState); 684 685 angle::Result updateActiveTextures(const gl::Context *context); 686 angle::Result updateActiveImages(const gl::Context *context, 687 vk::CommandBufferHelper *commandBufferHelper); 688 angle::Result updateDefaultAttribute(size_t attribIndex); 689 invalidateCurrentGraphicsPipeline()690 ANGLE_INLINE void invalidateCurrentGraphicsPipeline() 691 { 692 mGraphicsDirtyBits |= mNewGraphicsPipelineDirtyBits; 693 // The draw mode may have changed, toggling whether line rasterization is 694 // enabled or not, which means we need to recreate the graphics pipeline. 695 mCurrentGraphicsPipeline = nullptr; 696 } invalidateCurrentComputePipeline()697 ANGLE_INLINE void invalidateCurrentComputePipeline() 698 { 699 mComputeDirtyBits.set(DIRTY_BIT_PIPELINE); 700 mCurrentComputePipeline = nullptr; 701 } 702 703 void invalidateCurrentDefaultUniforms(); 704 angle::Result invalidateCurrentTextures(const gl::Context *context); 705 void invalidateCurrentShaderResources(); 706 void invalidateGraphicsDriverUniforms(); 707 void invalidateDriverUniforms(); 708 709 // Handlers for graphics pipeline dirty bits. 710 angle::Result handleDirtyGraphicsDefaultAttribs(const gl::Context *context, 711 vk::CommandBuffer *commandBuffer); 712 angle::Result handleDirtyGraphicsPipeline(const gl::Context *context, 713 vk::CommandBuffer *commandBuffer); 714 angle::Result handleDirtyGraphicsTextures(const gl::Context *context, 715 vk::CommandBuffer *commandBuffer); 716 angle::Result handleDirtyGraphicsVertexBuffers(const gl::Context *context, 717 vk::CommandBuffer *commandBuffer); 718 angle::Result handleDirtyGraphicsIndexBuffer(const gl::Context *context, 719 vk::CommandBuffer *commandBuffer); 720 angle::Result handleDirtyGraphicsDriverUniforms(const gl::Context *context, 721 vk::CommandBuffer *commandBuffer); 722 angle::Result handleDirtyGraphicsDriverUniformsBinding(const gl::Context *context, 723 vk::CommandBuffer *commandBuffer); 724 angle::Result handleDirtyGraphicsShaderResources(const gl::Context *context, 725 vk::CommandBuffer *commandBuffer); 726 angle::Result handleDirtyGraphicsTransformFeedbackBuffersEmulation( 727 const gl::Context *context, 728 vk::CommandBuffer *commandBuffer); 729 angle::Result handleDirtyGraphicsTransformFeedbackBuffersExtension( 730 const gl::Context *context, 731 vk::CommandBuffer *commandBuffer); 732 angle::Result handleDirtyGraphicsTransformFeedbackState(const gl::Context *context, 733 vk::CommandBuffer *commandBuffer); 734 angle::Result handleDirtyGraphicsTransformFeedbackResume(const gl::Context *context, 735 vk::CommandBuffer *commandBuffer); 736 737 // Handlers for compute pipeline dirty bits. 738 angle::Result handleDirtyComputePipeline(const gl::Context *context, 739 vk::CommandBuffer *commandBuffer); 740 angle::Result handleDirtyComputeTextures(const gl::Context *context, 741 vk::CommandBuffer *commandBuffer); 742 angle::Result handleDirtyComputeDriverUniforms(const gl::Context *context, 743 vk::CommandBuffer *commandBuffer); 744 angle::Result handleDirtyComputeDriverUniformsBinding(const gl::Context *context, 745 vk::CommandBuffer *commandBuffer); 746 angle::Result handleDirtyComputeShaderResources(const gl::Context *context, 747 vk::CommandBuffer *commandBuffer); 748 749 // Common parts of the common dirty bit handlers. 750 angle::Result handleDirtyTexturesImpl(vk::CommandBufferHelper *commandBufferHelper); 751 angle::Result handleDirtyShaderResourcesImpl(const gl::Context *context, 752 vk::CommandBufferHelper *commandBufferHelper); 753 void handleDirtyDriverUniformsBindingImpl(vk::CommandBuffer *commandBuffer, 754 VkPipelineBindPoint bindPoint, 755 const DriverUniformsDescriptorSet &driverUniforms); 756 angle::Result handleDirtyDescriptorSets(const gl::Context *context, 757 vk::CommandBuffer *commandBuffer); 758 angle::Result allocateDriverUniforms(size_t driverUniformsSize, 759 DriverUniformsDescriptorSet *driverUniforms, 760 VkBuffer *bufferOut, 761 uint8_t **ptrOut, 762 bool *newBufferOut); 763 angle::Result updateDriverUniformsDescriptorSet(VkBuffer buffer, 764 bool newBuffer, 765 size_t driverUniformsSize, 766 DriverUniformsDescriptorSet *driverUniforms); 767 768 void writeAtomicCounterBufferDriverUniformOffsets(uint32_t *offsetsOut, size_t offsetsSize); 769 770 angle::Result submitFrame(const VkSubmitInfo &submitInfo, 771 vk::PrimaryCommandBuffer &&commandBuffer); 772 angle::Result memoryBarrierImpl(GLbitfield barriers, VkPipelineStageFlags stageMask); 773 774 angle::Result synchronizeCpuGpuTime(); 775 angle::Result traceGpuEventImpl(vk::CommandBuffer *commandBuffer, 776 char phase, 777 const EventName &name); 778 angle::Result checkCompletedGpuEvents(); 779 void flushGpuEvents(double nextSyncGpuTimestampS, double nextSyncCpuTimestampS); 780 void handleDeviceLost(); 781 void waitForSwapchainImageIfNecessary(); 782 bool shouldEmulateSeamfulCubeMapSampling() const; 783 bool shouldUseOldRewriteStructSamplers() const; 784 void clearAllGarbage(); 785 angle::Result ensureSubmitFenceInitialized(); 786 angle::Result startPrimaryCommandBuffer(); 787 bool hasRecordedCommands(); 788 void dumpCommandStreamDiagnostics(); 789 angle::Result flushOutsideRenderPassCommands(); 790 onRenderPassFinished()791 ANGLE_INLINE void onRenderPassFinished() { mRenderPassCommandBuffer = nullptr; } 792 793 angle::Result onBufferRead(VkAccessFlags readAccessType, 794 vk::PipelineStage readStage, 795 vk::BufferHelper *buffer); 796 angle::Result onBufferWrite(VkAccessFlags writeAccessType, 797 vk::PipelineStage writeStage, 798 vk::BufferHelper *buffer); 799 800 void initIndexTypeMap(); 801 802 // Pull an available CBH ptr from the CBH queue and set to specified hasRenderPass state 803 void getNextAvailableCommandBuffer(vk::CommandBufferHelper **commandBuffer, bool hasRenderPass); 804 805 std::array<DirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers; 806 std::array<DirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers; 807 808 vk::CommandBuffer *mRenderPassCommandBuffer; 809 810 vk::PipelineHelper *mCurrentGraphicsPipeline; 811 vk::PipelineAndSerial *mCurrentComputePipeline; 812 gl::PrimitiveMode mCurrentDrawMode; 813 814 WindowSurfaceVk *mCurrentWindowSurface; 815 // Records the current rotation of the surface (draw/read) framebuffer, derived from 816 // mCurrentWindowSurface->getPreTransform(). 817 SurfaceRotation mCurrentRotationDrawFramebuffer; 818 SurfaceRotation mCurrentRotationReadFramebuffer; 819 820 // Keep a cached pipeline description structure that can be used to query the pipeline cache. 821 // Kept in a pointer so allocations can be aligned, and structs can be portably packed. 822 std::unique_ptr<vk::GraphicsPipelineDesc> mGraphicsPipelineDesc; 823 vk::GraphicsPipelineTransitionBits mGraphicsPipelineTransition; 824 825 // These pools are externally sychronized, so cannot be accessed from different 826 // threads simultaneously. Hence, we keep them in the ContextVk instead of the RendererVk. 827 // Note that this implementation would need to change in shared resource scenarios. Likely 828 // we'd instead share a single set of pools between the share groups. 829 vk::DynamicDescriptorPool mDriverUniformsDescriptorPool; 830 angle::PackedEnumMap<gl::QueryType, vk::DynamicQueryPool> mQueryPools; 831 832 // Dirty bits. 833 DirtyBits mGraphicsDirtyBits; 834 DirtyBits mComputeDirtyBits; 835 DirtyBits mNonIndexedDirtyBitsMask; 836 DirtyBits mIndexedDirtyBitsMask; 837 DirtyBits mNewGraphicsCommandBufferDirtyBits; 838 DirtyBits mNewComputeCommandBufferDirtyBits; 839 DirtyBits mNewGraphicsPipelineDirtyBits; 840 841 // Cached back-end objects. 842 VertexArrayVk *mVertexArray; 843 FramebufferVk *mDrawFramebuffer; 844 ProgramVk *mProgram; 845 ProgramPipelineVk *mProgramPipeline; 846 ProgramExecutableVk *mExecutable; 847 848 // occlusion query 849 QueryVk *mActiveQueryAnySamples; 850 QueryVk *mActiveQueryAnySamplesConservative; 851 852 // Graph resource used to record dispatch commands and hold resource dependencies. 853 vk::DispatchHelper mDispatcher; 854 855 // The offset we had the last time we bound the index buffer. 856 const GLvoid *mLastIndexBufferOffset; 857 gl::DrawElementsType mCurrentDrawElementsType; 858 angle::PackedEnumMap<gl::DrawElementsType, VkIndexType> mIndexTypeMap; 859 860 // Cache the current draw call's firstVertex to be passed to 861 // TransformFeedbackVk::getBufferOffsets. Unfortunately, gl_BaseVertex support in Vulkan is 862 // not yet ubiquitous, which would have otherwise removed the need for this value to be passed 863 // as a uniform. 864 GLint mXfbBaseVertex; 865 // Cache the current draw call's vertex count as well to support instanced draw calls 866 GLuint mXfbVertexCountPerInstance; 867 868 // Cached clear value/mask for color and depth/stencil. 869 VkClearValue mClearColorValue; 870 VkClearValue mClearDepthStencilValue; 871 VkColorComponentFlags mClearColorMask; 872 873 IncompleteTextureSet mIncompleteTextures; 874 875 // If the current surface bound to this context wants to have all rendering flipped vertically. 876 // Updated on calls to onMakeCurrent. 877 bool mFlipYForCurrentSurface; 878 bool mFlipViewportForDrawFramebuffer; 879 bool mFlipViewportForReadFramebuffer; 880 881 // If any host-visible buffer is written by the GPU since last submission, a barrier is inserted 882 // at the end of the command buffer to make that write available to the host. 883 bool mIsAnyHostVisibleBufferWritten; 884 885 // Whether this context should do seamful cube map sampling emulation. 886 bool mEmulateSeamfulCubeMapSampling; 887 888 // Whether this context should use the old version of the 889 // RewriteStructSamplers pass. 890 bool mUseOldRewriteStructSamplers; 891 892 angle::PackedEnumMap<PipelineType, DriverUniformsDescriptorSet> mDriverUniforms; 893 894 // This cache should also probably include the texture index (shader location) and array 895 // index (also in the shader). This info is used in the descriptor update step. 896 gl::ActiveTextureArray<vk::TextureUnit> mActiveTextures; 897 vk::TextureDescriptorDesc mActiveTexturesDesc; 898 899 gl::ActiveTextureArray<TextureVk *> mActiveImages; 900 901 // "Current Value" aka default vertex attribute state. 902 gl::AttributesMask mDirtyDefaultAttribsMask; 903 gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers; 904 905 // We use a single pool for recording commands. We also keep a free list for pool recycling. 906 vk::CommandPool mCommandPool; 907 908 CommandQueue mCommandQueue; 909 vk::GarbageList mCurrentGarbage; 910 911 RenderPassCache mRenderPassCache; 912 913 // mSubmitFence is the fence that's going to be signaled at the next submission. This is used 914 // to support SyncVk objects, which may outlive the context (as EGLSync objects). 915 // 916 // TODO(geofflang): this is in preparation for moving RendererVk functionality to ContextVk, and 917 // is otherwise unnecessary as the SyncVk objects don't actually outlive the renderer currently. 918 // http://anglebug.com/2701 919 vk::Shared<vk::Fence> mSubmitFence; 920 921 // When the command graph is disabled we record commands completely linearly. We have plans to 922 // reorder independent draws so that we can create fewer RenderPasses in some scenarios. 923 // We have a queue of CommandBufferHelpers (CBHs) that is drawn from for the two active command 924 // buffers in the main thread. The two active command buffers are the inside and outside 925 // RenderPass command buffers. 926 constexpr static size_t kNumCommandBuffers = 2; 927 std::array<vk::CommandBufferHelper, kNumCommandBuffers> mCommandBuffers; 928 929 // Lock access to the command buffer queue 930 std::mutex mCommandBufferQueueMutex; 931 std::queue<vk::CommandBufferHelper *> mAvailableCommandBuffers; 932 std::condition_variable mAvailableCommandBufferCondition; 933 934 vk::CommandBufferHelper *mOutsideRenderPassCommands; 935 vk::CommandBufferHelper *mRenderPassCommands; 936 vk::PrimaryCommandBuffer mPrimaryCommands; 937 // Function recycleCommandBuffer() is public above 938 bool mHasPrimaryCommands; 939 940 // Internal shader library. 941 vk::ShaderLibrary mShaderLibrary; 942 UtilsVk mUtils; 943 944 bool mGpuEventsEnabled; 945 vk::DynamicQueryPool mGpuEventQueryPool; 946 // A list of queries that have yet to be turned into an event (their result is not yet 947 // available). 948 std::vector<GpuEventQuery> mInFlightGpuEventQueries; 949 // A list of gpu events since the last clock sync. 950 std::vector<GpuEvent> mGpuEvents; 951 952 // Semaphores that must be waited on in the next submission. 953 std::vector<VkSemaphore> mWaitSemaphores; 954 std::vector<VkPipelineStageFlags> mWaitSemaphoreStageMasks; 955 956 // Hold information from the last gpu clock sync for future gpu-to-cpu timestamp conversions. 957 GpuClockSyncInfo mGpuClockSync; 958 959 // The very first timestamp queried for a GPU event is used as origin, so event timestamps would 960 // have a value close to zero, to avoid losing 12 bits when converting these 64 bit values to 961 // double. 962 uint64_t mGpuEventTimestampOrigin; 963 964 // Used to count events for tracing. 965 uint32_t mPrimaryBufferCounter; 966 uint32_t mRenderPassCounter; 967 968 // Generators for texture & framebuffer serials. 969 SerialFactory mTextureSerialFactory; 970 SerialFactory mAttachmentImageSerialFactory; 971 972 gl::State::DirtyBits mPipelineDirtyBitsMask; 973 974 // List of all resources currently being used by this ContextVk's recorded commands. 975 vk::ResourceUseList mResourceUseList; 976 977 egl::ContextPriority mContextPriority; 978 979 std::vector<std::string> mCommandBufferDiagnostics; 980 }; 981 } // namespace rx 982 983 #endif // LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_ 984