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 <vulkan/vulkan.h> 14 15 #include "common/PackedEnums.h" 16 #include "libANGLE/renderer/ContextImpl.h" 17 #include "libANGLE/renderer/vulkan/PersistentCommandPool.h" 18 #include "libANGLE/renderer/vulkan/RendererVk.h" 19 #include "libANGLE/renderer/vulkan/vk_helpers.h" 20 21 namespace angle 22 { 23 struct FeaturesVk; 24 } 25 26 namespace rx 27 { 28 class RendererVk; 29 class WindowSurfaceVk; 30 31 class ContextVk : public ContextImpl, public vk::Context, public vk::RenderPassOwner 32 { 33 public: 34 ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk *renderer); 35 ~ContextVk() override; 36 37 angle::Result initialize() override; 38 39 void onDestroy(const gl::Context *context) override; 40 41 // Flush and finish. 42 angle::Result flush(const gl::Context *context) override; 43 angle::Result finish(const gl::Context *context) override; 44 45 // Drawing methods. 46 angle::Result drawArrays(const gl::Context *context, 47 gl::PrimitiveMode mode, 48 GLint first, 49 GLsizei count) override; 50 angle::Result drawArraysInstanced(const gl::Context *context, 51 gl::PrimitiveMode mode, 52 GLint first, 53 GLsizei count, 54 GLsizei instanceCount) override; 55 angle::Result drawArraysInstancedBaseInstance(const gl::Context *context, 56 gl::PrimitiveMode mode, 57 GLint first, 58 GLsizei count, 59 GLsizei instanceCount, 60 GLuint baseInstance) override; 61 62 angle::Result drawElements(const gl::Context *context, 63 gl::PrimitiveMode mode, 64 GLsizei count, 65 gl::DrawElementsType type, 66 const void *indices) override; 67 angle::Result drawElementsInstanced(const gl::Context *context, 68 gl::PrimitiveMode mode, 69 GLsizei count, 70 gl::DrawElementsType type, 71 const void *indices, 72 GLsizei instanceCount) override; 73 angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context, 74 gl::PrimitiveMode mode, 75 GLsizei count, 76 gl::DrawElementsType type, 77 const void *indices, 78 GLsizei instances, 79 GLint baseVertex, 80 GLuint baseInstance) override; 81 angle::Result drawRangeElements(const gl::Context *context, 82 gl::PrimitiveMode mode, 83 GLuint start, 84 GLuint end, 85 GLsizei count, 86 gl::DrawElementsType type, 87 const void *indices) override; 88 angle::Result drawArraysIndirect(const gl::Context *context, 89 gl::PrimitiveMode mode, 90 const void *indirect) override; 91 angle::Result drawElementsIndirect(const gl::Context *context, 92 gl::PrimitiveMode mode, 93 gl::DrawElementsType type, 94 const void *indirect) override; 95 96 // Device loss 97 gl::GraphicsResetStatus getResetStatus() override; 98 99 // Vendor and description strings. 100 std::string getVendorString() const override; 101 std::string getRendererDescription() const override; 102 103 // EXT_debug_marker 104 void insertEventMarker(GLsizei length, const char *marker) override; 105 void pushGroupMarker(GLsizei length, const char *marker) override; 106 void popGroupMarker() override; 107 108 // KHR_debug 109 void pushDebugGroup(GLenum source, GLuint id, const std::string &message) override; 110 void popDebugGroup() override; 111 112 bool isViewportFlipEnabledForDrawFBO() const; 113 bool isViewportFlipEnabledForReadFBO() const; 114 115 // State sync with dirty bits. 116 angle::Result syncState(const gl::Context *context, 117 const gl::State::DirtyBits &dirtyBits, 118 const gl::State::DirtyBits &bitMask) override; 119 120 // Disjoint timer queries 121 GLint getGPUDisjoint() override; 122 GLint64 getTimestamp() override; 123 124 // Context switching 125 angle::Result onMakeCurrent(const gl::Context *context) override; 126 angle::Result onUnMakeCurrent(const gl::Context *context) override; 127 128 // Native capabilities, unmodified by gl::Context. 129 gl::Caps getNativeCaps() const override; 130 const gl::TextureCapsMap &getNativeTextureCaps() const override; 131 const gl::Extensions &getNativeExtensions() const override; 132 const gl::Limitations &getNativeLimitations() const override; 133 134 // Shader creation 135 CompilerImpl *createCompiler() override; 136 ShaderImpl *createShader(const gl::ShaderState &state) override; 137 ProgramImpl *createProgram(const gl::ProgramState &state) override; 138 139 // Framebuffer creation 140 FramebufferImpl *createFramebuffer(const gl::FramebufferState &state) override; 141 142 // Texture creation 143 TextureImpl *createTexture(const gl::TextureState &state) override; 144 145 // Renderbuffer creation 146 RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override; 147 148 // Buffer creation 149 BufferImpl *createBuffer(const gl::BufferState &state) override; 150 151 // Vertex Array creation 152 VertexArrayImpl *createVertexArray(const gl::VertexArrayState &state) override; 153 154 // Query and Fence creation 155 QueryImpl *createQuery(gl::QueryType type) override; 156 FenceNVImpl *createFenceNV() override; 157 SyncImpl *createSync() override; 158 159 // Transform Feedback creation 160 TransformFeedbackImpl *createTransformFeedback( 161 const gl::TransformFeedbackState &state) override; 162 163 // Sampler object creation 164 SamplerImpl *createSampler(const gl::SamplerState &state) override; 165 166 // Program Pipeline object creation 167 ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override; 168 169 // Path object creation 170 std::vector<PathImpl *> createPaths(GLsizei) override; 171 172 // Memory object creation. 173 MemoryObjectImpl *createMemoryObject() override; 174 175 // Semaphore creation. 176 SemaphoreImpl *createSemaphore() override; 177 178 angle::Result dispatchCompute(const gl::Context *context, 179 GLuint numGroupsX, 180 GLuint numGroupsY, 181 GLuint numGroupsZ) override; 182 angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override; 183 184 angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override; 185 angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override; 186 187 VkDevice getDevice() const; 188 getFeatures()189 ANGLE_INLINE const angle::FeaturesVk &getFeatures() const { return mRenderer->getFeatures(); } 190 invalidateVertexAndIndexBuffers()191 ANGLE_INLINE void invalidateVertexAndIndexBuffers() 192 { 193 // TODO: Make the pipeline invalidate more fine-grained. Only need to dirty here if PSO 194 // VtxInput state (stride, fmt, inputRate...) has changed. http://anglebug.com/3256 195 invalidateCurrentGraphicsPipeline(); 196 mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS); 197 mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER); 198 } 199 invalidateVertexBuffers()200 ANGLE_INLINE void invalidateVertexBuffers() 201 { 202 mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS); 203 } 204 onVertexAttributeChange(size_t attribIndex,GLuint stride,GLuint divisor,angle::FormatID format,GLuint relativeOffset)205 ANGLE_INLINE void onVertexAttributeChange(size_t attribIndex, 206 GLuint stride, 207 GLuint divisor, 208 angle::FormatID format, 209 GLuint relativeOffset) 210 { 211 invalidateVertexAndIndexBuffers(); 212 mGraphicsPipelineDesc->updateVertexInput(&mGraphicsPipelineTransition, 213 static_cast<uint32_t>(attribIndex), stride, 214 divisor, format, relativeOffset); 215 } 216 217 void invalidateDefaultAttribute(size_t attribIndex); 218 void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask); 219 void onDrawFramebufferChange(FramebufferVk *framebufferVk); onHostVisibleBufferWrite()220 void onHostVisibleBufferWrite() { mIsAnyHostVisibleBufferWritten = true; } 221 222 void invalidateCurrentTransformFeedbackBuffers(); 223 void onTransformFeedbackPauseResume(); 224 225 vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType); 226 227 const VkClearValue &getClearColorValue() const; 228 const VkClearValue &getClearDepthStencilValue() const; 229 VkColorComponentFlags getClearColorMask() const; 230 angle::Result getIncompleteTexture(const gl::Context *context, 231 gl::TextureType type, 232 gl::Texture **textureOut); 233 void updateColorMask(const gl::BlendState &blendState); 234 void updateSampleMask(const gl::State &glState); 235 236 void handleError(VkResult errorCode, 237 const char *file, 238 const char *function, 239 unsigned int line) override; 240 const gl::ActiveTextureArray<vk::TextureUnit> &getActiveTextures() const; 241 setIndexBufferDirty()242 void setIndexBufferDirty() 243 { 244 mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER); 245 mLastIndexBufferOffset = reinterpret_cast<const void *>(angle::DirtyPointer); 246 } 247 248 void insertWaitSemaphore(const vk::Semaphore *waitSemaphore); 249 250 angle::Result flushImpl(const vk::Semaphore *semaphore); 251 angle::Result finishImpl(); 252 253 void addWaitSemaphore(VkSemaphore semaphore); 254 255 const vk::CommandPool &getCommandPool() const; 256 getCurrentQueueSerial()257 Serial getCurrentQueueSerial() const { return mCurrentQueueSerial; } getLastSubmittedQueueSerial()258 Serial getLastSubmittedQueueSerial() const { return mLastSubmittedQueueSerial; } getLastCompletedQueueSerial()259 Serial getLastCompletedQueueSerial() const { return mLastCompletedQueueSerial; } 260 261 bool isSerialInUse(Serial serial) const; 262 263 template <typename T> releaseObject(Serial resourceSerial,T * object)264 void releaseObject(Serial resourceSerial, T *object) 265 { 266 if (!isSerialInUse(resourceSerial)) 267 { 268 object->destroy(getDevice()); 269 } 270 else 271 { 272 object->dumpResources(resourceSerial, &mGarbage); 273 } 274 } 275 276 // Check to see which batches have finished completion (forward progress for 277 // mLastCompletedQueueSerial, for example for when the application busy waits on a query 278 // result). 279 angle::Result checkCompletedCommands(); 280 281 // Wait for completion of batches until (at least) batch with given serial is finished. 282 angle::Result finishToSerial(Serial serial); 283 // A variant of finishToSerial that can time out. Timeout status returned in outTimedOut. 284 angle::Result finishToSerialOrTimeout(Serial serial, uint64_t timeout, bool *outTimedOut); 285 286 angle::Result getCompatibleRenderPass(const vk::RenderPassDesc &desc, 287 vk::RenderPass **renderPassOut); 288 angle::Result getRenderPassWithOps(const vk::RenderPassDesc &desc, 289 const vk::AttachmentOpsArray &ops, 290 vk::RenderPass **renderPassOut); 291 292 // Get (or allocate) the fence that will be signaled on next submission. 293 angle::Result getNextSubmitFence(vk::Shared<vk::Fence> *sharedFenceOut); 294 vk::Shared<vk::Fence> getLastSubmittedFence() const; 295 296 // This should only be called from ResourceVk. 297 vk::CommandGraph *getCommandGraph(); 298 getShaderLibrary()299 vk::ShaderLibrary &getShaderLibrary() { return mShaderLibrary; } getUtils()300 UtilsVk &getUtils() { return mUtils; } 301 302 angle::Result getTimestamp(uint64_t *timestampOut); 303 304 // Create Begin/End/Instant GPU trace events, which take their timestamps from GPU queries. 305 // The events are queued until the query results are available. Possible values for `phase` 306 // are TRACE_EVENT_PHASE_* traceGpuEvent(vk::PrimaryCommandBuffer * commandBuffer,char phase,const char * name)307 ANGLE_INLINE angle::Result traceGpuEvent(vk::PrimaryCommandBuffer *commandBuffer, 308 char phase, 309 const char *name) 310 { 311 if (mGpuEventsEnabled) 312 return traceGpuEventImpl(commandBuffer, phase, name); 313 return angle::Result::Continue; 314 } 315 getRenderPassCache()316 RenderPassCache &getRenderPassCache() { return mRenderPassCache; } 317 318 vk::DescriptorSetLayoutDesc getDriverUniformsDescriptorSetDesc( 319 VkShaderStageFlags shaderStages) const; 320 321 // We use texture serials to optimize texture binding updates. Each permutation of a 322 // {VkImage/VkSampler} generates a unique serial. These serials are combined to form a unique 323 // signature for each descriptor set. This allows us to keep a cache of descriptor sets and 324 // avoid calling vkAllocateDesctiporSets each texture update. generateTextureSerial()325 Serial generateTextureSerial() { return mTextureSerialFactory.generate(); } getActiveTexturesDesc()326 const vk::TextureDescriptorDesc &getActiveTexturesDesc() const { return mActiveTexturesDesc; } 327 328 void updateScissor(const gl::State &glState); 329 emulateSeamfulCubeMapSampling(bool * useSubgroupOpsOut)330 bool emulateSeamfulCubeMapSampling(bool *useSubgroupOpsOut) const 331 { 332 *useSubgroupOpsOut = mEmulateSeamfulCubeMapSamplingWithSubgroupOps; 333 return mEmulateSeamfulCubeMapSampling; 334 } 335 336 private: 337 // Dirty bits. 338 enum DirtyBitType : size_t 339 { 340 DIRTY_BIT_DEFAULT_ATTRIBS, 341 DIRTY_BIT_PIPELINE, 342 DIRTY_BIT_TEXTURES, 343 DIRTY_BIT_VERTEX_BUFFERS, 344 DIRTY_BIT_INDEX_BUFFER, 345 DIRTY_BIT_DRIVER_UNIFORMS, 346 DIRTY_BIT_SHADER_RESOURCES, // excluding textures, which are handled separately. 347 DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS, 348 DIRTY_BIT_DESCRIPTOR_SETS, 349 DIRTY_BIT_MAX, 350 }; 351 352 using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>; 353 354 using DirtyBitHandler = angle::Result (ContextVk::*)(const gl::Context *, 355 vk::CommandBuffer *commandBuffer); 356 357 std::array<DirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers; 358 std::array<DirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers; 359 360 enum class PipelineType 361 { 362 Graphics = 0, 363 Compute = 1, 364 365 InvalidEnum = 2, 366 EnumCount = 2, 367 }; 368 369 angle::Result setupDraw(const gl::Context *context, 370 gl::PrimitiveMode mode, 371 GLint firstVertex, 372 GLsizei vertexOrIndexCount, 373 GLsizei instanceCount, 374 gl::DrawElementsType indexTypeOrInvalid, 375 const void *indices, 376 DirtyBits dirtyBitMask, 377 vk::CommandBuffer **commandBufferOut); 378 angle::Result setupIndexedDraw(const gl::Context *context, 379 gl::PrimitiveMode mode, 380 GLsizei indexCount, 381 GLsizei instanceCount, 382 gl::DrawElementsType indexType, 383 const void *indices, 384 vk::CommandBuffer **commandBufferOut); 385 angle::Result setupLineLoopDraw(const gl::Context *context, 386 gl::PrimitiveMode mode, 387 GLint firstVertex, 388 GLsizei vertexOrIndexCount, 389 gl::DrawElementsType indexTypeOrInvalid, 390 const void *indices, 391 vk::CommandBuffer **commandBufferOut, 392 uint32_t *numIndicesOut); 393 angle::Result setupDispatch(const gl::Context *context, vk::CommandBuffer **commandBufferOut); 394 395 void updateViewport(FramebufferVk *framebufferVk, 396 const gl::Rectangle &viewport, 397 float nearPlane, 398 float farPlane, 399 bool invertViewport); 400 void updateDepthRange(float nearPlane, float farPlane); 401 void updateFlipViewportDrawFramebuffer(const gl::State &glState); 402 void updateFlipViewportReadFramebuffer(const gl::State &glState); 403 404 angle::Result updateActiveTextures(const gl::Context *context, 405 vk::CommandGraphResource *recorder); 406 angle::Result updateDefaultAttribute(size_t attribIndex); 407 invalidateCurrentGraphicsPipeline()408 ANGLE_INLINE void invalidateCurrentGraphicsPipeline() 409 { 410 mGraphicsDirtyBits.set(DIRTY_BIT_PIPELINE); 411 } invalidateCurrentComputePipeline()412 ANGLE_INLINE void invalidateCurrentComputePipeline() 413 { 414 mComputeDirtyBits.set(DIRTY_BIT_PIPELINE); 415 mCurrentComputePipeline = nullptr; 416 } 417 418 void invalidateCurrentTextures(); 419 void invalidateCurrentShaderResources(); 420 void invalidateGraphicsDriverUniforms(); 421 void invalidateDriverUniforms(); 422 423 // Handlers for graphics pipeline dirty bits. 424 angle::Result handleDirtyGraphicsDefaultAttribs(const gl::Context *context, 425 vk::CommandBuffer *commandBuffer); 426 angle::Result handleDirtyGraphicsPipeline(const gl::Context *context, 427 vk::CommandBuffer *commandBuffer); 428 angle::Result handleDirtyGraphicsTextures(const gl::Context *context, 429 vk::CommandBuffer *commandBuffer); 430 angle::Result handleDirtyGraphicsVertexBuffers(const gl::Context *context, 431 vk::CommandBuffer *commandBuffer); 432 angle::Result handleDirtyGraphicsIndexBuffer(const gl::Context *context, 433 vk::CommandBuffer *commandBuffer); 434 angle::Result handleDirtyGraphicsDriverUniforms(const gl::Context *context, 435 vk::CommandBuffer *commandBuffer); 436 angle::Result handleDirtyGraphicsShaderResources(const gl::Context *context, 437 vk::CommandBuffer *commandBuffer); 438 angle::Result handleDirtyGraphicsTransformFeedbackBuffers(const gl::Context *context, 439 vk::CommandBuffer *commandBuffer); 440 angle::Result handleDirtyGraphicsDescriptorSets(const gl::Context *context, 441 vk::CommandBuffer *commandBuffer); 442 443 // Handlers for compute pipeline dirty bits. 444 angle::Result handleDirtyComputePipeline(const gl::Context *context, 445 vk::CommandBuffer *commandBuffer); 446 angle::Result handleDirtyComputeTextures(const gl::Context *context, 447 vk::CommandBuffer *commandBuffer); 448 angle::Result handleDirtyComputeDriverUniforms(const gl::Context *context, 449 vk::CommandBuffer *commandBuffer); 450 angle::Result handleDirtyComputeShaderResources(const gl::Context *context, 451 vk::CommandBuffer *commandBuffer); 452 angle::Result handleDirtyComputeDescriptorSets(const gl::Context *context, 453 vk::CommandBuffer *commandBuffer); 454 455 // Common parts of the common dirty bit handlers. 456 angle::Result handleDirtyTexturesImpl(const gl::Context *context, 457 vk::CommandBuffer *commandBuffer, 458 vk::CommandGraphResource *recorder); 459 angle::Result handleDirtyShaderResourcesImpl(const gl::Context *context, 460 vk::CommandBuffer *commandBuffer, 461 vk::CommandGraphResource *recorder); 462 struct DriverUniformsDescriptorSet; 463 angle::Result handleDirtyDescriptorSetsImpl(vk::CommandBuffer *commandBuffer, 464 VkPipelineBindPoint bindPoint, 465 const DriverUniformsDescriptorSet &driverUniforms); 466 angle::Result allocateDriverUniforms(size_t driverUniformsSize, 467 DriverUniformsDescriptorSet *driverUniforms, 468 VkBuffer *bufferOut, 469 uint8_t **ptrOut, 470 bool *newBufferOut); 471 angle::Result updateDriverUniformsDescriptorSet(VkBuffer buffer, 472 bool newBuffer, 473 size_t driverUniformsSize, 474 DriverUniformsDescriptorSet *driverUniforms); 475 476 void writeAtomicCounterBufferDriverUniformOffsets(uint32_t *offsetsOut, size_t offsetsSize); 477 478 angle::Result submitFrame(const VkSubmitInfo &submitInfo, 479 vk::PrimaryCommandBuffer &&commandBuffer); 480 angle::Result flushCommandGraph(vk::PrimaryCommandBuffer *commandBatch); 481 482 angle::Result synchronizeCpuGpuTime(); 483 angle::Result traceGpuEventImpl(vk::PrimaryCommandBuffer *commandBuffer, 484 char phase, 485 const char *name); 486 angle::Result checkCompletedGpuEvents(); 487 void flushGpuEvents(double nextSyncGpuTimestampS, double nextSyncCpuTimestampS); 488 489 void handleDeviceLost(); 490 491 void waitForSwapchainImageIfNecessary(); 492 493 bool shouldEmulateSeamfulCubeMapSampling(bool *useSubgroupOpsOut) const; 494 495 vk::PipelineHelper *mCurrentGraphicsPipeline; 496 vk::PipelineAndSerial *mCurrentComputePipeline; 497 gl::PrimitiveMode mCurrentDrawMode; 498 499 WindowSurfaceVk *mCurrentWindowSurface; 500 501 // Keep a cached pipeline description structure that can be used to query the pipeline cache. 502 // Kept in a pointer so allocations can be aligned, and structs can be portably packed. 503 std::unique_ptr<vk::GraphicsPipelineDesc> mGraphicsPipelineDesc; 504 vk::GraphicsPipelineTransitionBits mGraphicsPipelineTransition; 505 506 // These pools are externally sychronized, so cannot be accessed from different 507 // threads simultaneously. Hence, we keep them in the ContextVk instead of the RendererVk. 508 // Note that this implementation would need to change in shared resource scenarios. Likely 509 // we'd instead share a single set of pools between the share groups. 510 vk::DynamicDescriptorPool mDriverUniformsDescriptorPool; 511 angle::PackedEnumMap<gl::QueryType, vk::DynamicQueryPool> mQueryPools; 512 513 // Dirty bits. 514 DirtyBits mGraphicsDirtyBits; 515 DirtyBits mComputeDirtyBits; 516 DirtyBits mNonIndexedDirtyBitsMask; 517 DirtyBits mIndexedDirtyBitsMask; 518 DirtyBits mNewGraphicsCommandBufferDirtyBits; 519 DirtyBits mNewComputeCommandBufferDirtyBits; 520 521 // Cached back-end objects. 522 VertexArrayVk *mVertexArray; 523 FramebufferVk *mDrawFramebuffer; 524 ProgramVk *mProgram; 525 526 // Graph resource used to record dispatch commands and hold resource dependencies. 527 vk::DispatchHelper mDispatcher; 528 529 // The offset we had the last time we bound the index buffer. 530 const GLvoid *mLastIndexBufferOffset; 531 gl::DrawElementsType mCurrentDrawElementsType; 532 533 // Cache the current draw call's firstVertex to be passed to 534 // TransformFeedbackVk::getBufferOffsets. Unfortunately, gl_BaseVertex support in Vulkan is 535 // not yet ubiquitous, which would have otherwise removed the need for this value to be passed 536 // as a uniform. 537 GLint mXfbBaseVertex; 538 539 // Cached clear value/mask for color and depth/stencil. 540 VkClearValue mClearColorValue; 541 VkClearValue mClearDepthStencilValue; 542 VkColorComponentFlags mClearColorMask; 543 544 IncompleteTextureSet mIncompleteTextures; 545 546 // If the current surface bound to this context wants to have all rendering flipped vertically. 547 // Updated on calls to onMakeCurrent. 548 bool mFlipYForCurrentSurface; 549 bool mFlipViewportForDrawFramebuffer; 550 bool mFlipViewportForReadFramebuffer; 551 552 // If any host-visible buffer is written by the GPU since last submission, a barrier is inserted 553 // at the end of the command buffer to make that write available to the host. 554 bool mIsAnyHostVisibleBufferWritten; 555 556 // Whether this context should do seamful cube map sampling emulation, and whether subgroup 557 // operations should be used. 558 bool mEmulateSeamfulCubeMapSampling; 559 bool mEmulateSeamfulCubeMapSamplingWithSubgroupOps; 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(VkDevice device); 574 }; 575 576 angle::PackedEnumMap<PipelineType, DriverUniformsDescriptorSet> mDriverUniforms; 577 578 // This cache should also probably include the texture index (shader location) and array 579 // index (also in the shader). This info is used in the descriptor update step. 580 gl::ActiveTextureArray<vk::TextureUnit> mActiveTextures; 581 vk::TextureDescriptorDesc mActiveTexturesDesc; 582 583 // "Current Value" aka default vertex attribute state. 584 gl::AttributesMask mDirtyDefaultAttribsMask; 585 gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers; 586 587 // We use a single pool for recording commands. We also keep a free list for pool recycling. 588 vk::CommandPool mCommandPool; 589 std::vector<vk::CommandPool> mCommandPoolFreeList; 590 591 // We use a Persistent CommandPool with pre-allocated buffers for primary CommandBuffer 592 vk::PersistentCommandPool mPrimaryCommandPool; 593 594 Serial mLastCompletedQueueSerial; 595 Serial mLastSubmittedQueueSerial; 596 Serial mCurrentQueueSerial; 597 598 struct CommandBatch final : angle::NonCopyable 599 { 600 CommandBatch(); 601 ~CommandBatch(); 602 CommandBatch(CommandBatch &&other); 603 CommandBatch &operator=(CommandBatch &&other); 604 605 void destroy(VkDevice device); 606 607 vk::PrimaryCommandBuffer primaryCommands; 608 // commandPool is for secondary CommandBuffer allocation 609 vk::CommandPool commandPool; 610 vk::Shared<vk::Fence> fence; 611 Serial serial; 612 }; 613 614 angle::Result releaseToCommandBatch(vk::PrimaryCommandBuffer &&commandBuffer, 615 CommandBatch *batch); 616 angle::Result recycleCommandBatch(CommandBatch *batch); 617 618 std::vector<CommandBatch> mInFlightCommands; 619 std::vector<vk::GarbageObject> mGarbage; 620 621 RenderPassCache mRenderPassCache; 622 623 // mSubmitFence is the fence that's going to be signaled at the next submission. This is used 624 // to support SyncVk objects, which may outlive the context (as EGLSync objects). 625 // 626 // TODO(geofflang): this is in preparation for moving RendererVk functionality to ContextVk, and 627 // is otherwise unnecessary as the SyncVk objects don't actually outlive the renderer currently. 628 // http://anglebug.com/2701 629 vk::Shared<vk::Fence> mSubmitFence; 630 631 // Pool allocator used for command graph but may be expanded to other allocations 632 angle::PoolAllocator mPoolAllocator; 633 634 // See CommandGraph.h for a desription of the Command Graph. 635 vk::CommandGraph mCommandGraph; 636 637 // Internal shader library. 638 vk::ShaderLibrary mShaderLibrary; 639 UtilsVk mUtils; 640 641 // The GpuEventQuery struct holds together a timestamp query and enough data to create a 642 // trace event based on that. Use traceGpuEvent to insert such queries. They will be readback 643 // when the results are available, without inserting a GPU bubble. 644 // 645 // - eventName will be the reported name of the event 646 // - phase is either 'B' (duration begin), 'E' (duration end) or 'i' (instant // event). 647 // See Google's "Trace Event Format": 648 // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU 649 // - serial is the serial of the batch the query was submitted on. Until the batch is 650 // submitted, the query is not checked to avoid incuring a flush. 651 struct GpuEventQuery final 652 { 653 const char *name; 654 char phase; 655 656 uint32_t queryIndex; 657 size_t queryPoolIndex; 658 659 Serial serial; 660 }; 661 662 // Once a query result is available, the timestamp is read and a GpuEvent object is kept until 663 // the next clock sync, at which point the clock drift is compensated in the results before 664 // handing them off to the application. 665 struct GpuEvent final 666 { 667 uint64_t gpuTimestampCycles; 668 const char *name; 669 char phase; 670 }; 671 672 bool mGpuEventsEnabled; 673 vk::DynamicQueryPool mGpuEventQueryPool; 674 // A list of queries that have yet to be turned into an event (their result is not yet 675 // available). 676 std::vector<GpuEventQuery> mInFlightGpuEventQueries; 677 // A list of gpu events since the last clock sync. 678 std::vector<GpuEvent> mGpuEvents; 679 680 // Semaphores that must be waited on in the next submission. 681 std::vector<VkSemaphore> mWaitSemaphores; 682 std::vector<VkPipelineStageFlags> mWaitSemaphoreStageMasks; 683 684 // Hold information from the last gpu clock sync for future gpu-to-cpu timestamp conversions. 685 struct GpuClockSyncInfo 686 { 687 double gpuTimestampS; 688 double cpuTimestampS; 689 }; 690 GpuClockSyncInfo mGpuClockSync; 691 692 // The very first timestamp queried for a GPU event is used as origin, so event timestamps would 693 // have a value close to zero, to avoid losing 12 bits when converting these 64 bit values to 694 // double. 695 uint64_t mGpuEventTimestampOrigin; 696 697 // Generator for texure serials. 698 SerialFactory mTextureSerialFactory; 699 700 gl::State::DirtyBits mPipelineDirtyBitsMask; 701 }; 702 } // namespace rx 703 704 #endif // LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_ 705