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 "common/vulkan/vk_headers.h"
17 #include "libANGLE/renderer/ContextImpl.h"
18 #include "libANGLE/renderer/renderer_utils.h"
19 #include "libANGLE/renderer/vulkan/DisplayVk.h"
20 #include "libANGLE/renderer/vulkan/OverlayVk.h"
21 #include "libANGLE/renderer/vulkan/PersistentCommandPool.h"
22 #include "libANGLE/renderer/vulkan/RendererVk.h"
23 #include "libANGLE/renderer/vulkan/vk_helpers.h"
24
25 namespace angle
26 {
27 struct FeaturesVk;
28 } // namespace angle
29
30 namespace rx
31 {
32 class ProgramExecutableVk;
33 class RendererVk;
34 class WindowSurfaceVk;
35 class ShareGroupVk;
36
37 static constexpr uint32_t kMaxGpuEventNameLen = 32;
38 using EventName = std::array<char, kMaxGpuEventNameLen>;
39
40 enum class PipelineType
41 {
42 Graphics = 0,
43 Compute = 1,
44
45 InvalidEnum = 2,
46 EnumCount = 2,
47 };
48
49 using ContextVkDescriptorSetList = angle::PackedEnumMap<PipelineType, uint32_t>;
50
51 struct ContextVkPerfCounters
52 {
53 ContextVkDescriptorSetList descriptorSetsAllocated;
54 };
55
56 enum class GraphicsEventCmdBuf
57 {
58 NotInQueryCmd = 0,
59 InOutsideCmdBufQueryCmd = 1,
60 InRenderPassCmdBufQueryCmd = 2,
61
62 InvalidEnum = 3,
63 EnumCount = 3,
64 };
65
66 enum class QueueSubmitType
67 {
68 PerformQueueSubmit,
69 SkipQueueSubmit,
70 };
71
72 class ContextVk : public ContextImpl, public vk::Context, public MultisampleTextureInitializer
73 {
74 public:
75 ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk *renderer);
76 ~ContextVk() override;
77
78 angle::Result initialize() override;
79
80 void onDestroy(const gl::Context *context) override;
81
82 // Flush and finish.
83 angle::Result flush(const gl::Context *context) override;
84 angle::Result finish(const gl::Context *context) override;
85
86 // Drawing methods.
87 angle::Result drawArrays(const gl::Context *context,
88 gl::PrimitiveMode mode,
89 GLint first,
90 GLsizei count) override;
91 angle::Result drawArraysInstanced(const gl::Context *context,
92 gl::PrimitiveMode mode,
93 GLint first,
94 GLsizei count,
95 GLsizei instanceCount) override;
96 angle::Result drawArraysInstancedBaseInstance(const gl::Context *context,
97 gl::PrimitiveMode mode,
98 GLint first,
99 GLsizei count,
100 GLsizei instanceCount,
101 GLuint baseInstance) override;
102
103 angle::Result drawElements(const gl::Context *context,
104 gl::PrimitiveMode mode,
105 GLsizei count,
106 gl::DrawElementsType type,
107 const void *indices) override;
108 angle::Result drawElementsBaseVertex(const gl::Context *context,
109 gl::PrimitiveMode mode,
110 GLsizei count,
111 gl::DrawElementsType type,
112 const void *indices,
113 GLint baseVertex) override;
114 angle::Result drawElementsInstanced(const gl::Context *context,
115 gl::PrimitiveMode mode,
116 GLsizei count,
117 gl::DrawElementsType type,
118 const void *indices,
119 GLsizei instanceCount) override;
120 angle::Result drawElementsInstancedBaseVertex(const gl::Context *context,
121 gl::PrimitiveMode mode,
122 GLsizei count,
123 gl::DrawElementsType type,
124 const void *indices,
125 GLsizei instanceCount,
126 GLint baseVertex) override;
127 angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
128 gl::PrimitiveMode mode,
129 GLsizei count,
130 gl::DrawElementsType type,
131 const void *indices,
132 GLsizei instances,
133 GLint baseVertex,
134 GLuint baseInstance) override;
135 angle::Result drawRangeElements(const gl::Context *context,
136 gl::PrimitiveMode mode,
137 GLuint start,
138 GLuint end,
139 GLsizei count,
140 gl::DrawElementsType type,
141 const void *indices) override;
142 angle::Result drawRangeElementsBaseVertex(const gl::Context *context,
143 gl::PrimitiveMode mode,
144 GLuint start,
145 GLuint end,
146 GLsizei count,
147 gl::DrawElementsType type,
148 const void *indices,
149 GLint baseVertex) override;
150 angle::Result drawArraysIndirect(const gl::Context *context,
151 gl::PrimitiveMode mode,
152 const void *indirect) override;
153 angle::Result drawElementsIndirect(const gl::Context *context,
154 gl::PrimitiveMode mode,
155 gl::DrawElementsType type,
156 const void *indirect) override;
157
158 angle::Result multiDrawArrays(const gl::Context *context,
159 gl::PrimitiveMode mode,
160 const GLint *firsts,
161 const GLsizei *counts,
162 GLsizei drawcount) override;
163 angle::Result multiDrawArraysInstanced(const gl::Context *context,
164 gl::PrimitiveMode mode,
165 const GLint *firsts,
166 const GLsizei *counts,
167 const GLsizei *instanceCounts,
168 GLsizei drawcount) override;
169 angle::Result multiDrawArraysIndirect(const gl::Context *context,
170 gl::PrimitiveMode mode,
171 const void *indirect,
172 GLsizei drawcount,
173 GLsizei stride) override;
174 angle::Result multiDrawElements(const gl::Context *context,
175 gl::PrimitiveMode mode,
176 const GLsizei *counts,
177 gl::DrawElementsType type,
178 const GLvoid *const *indices,
179 GLsizei drawcount) override;
180 angle::Result multiDrawElementsInstanced(const gl::Context *context,
181 gl::PrimitiveMode mode,
182 const GLsizei *counts,
183 gl::DrawElementsType type,
184 const GLvoid *const *indices,
185 const GLsizei *instanceCounts,
186 GLsizei drawcount) override;
187 angle::Result multiDrawElementsIndirect(const gl::Context *context,
188 gl::PrimitiveMode mode,
189 gl::DrawElementsType type,
190 const void *indirect,
191 GLsizei drawcount,
192 GLsizei stride) override;
193 angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
194 gl::PrimitiveMode mode,
195 const GLint *firsts,
196 const GLsizei *counts,
197 const GLsizei *instanceCounts,
198 const GLuint *baseInstances,
199 GLsizei drawcount) override;
200 angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
201 gl::PrimitiveMode mode,
202 const GLsizei *counts,
203 gl::DrawElementsType type,
204 const GLvoid *const *indices,
205 const GLsizei *instanceCounts,
206 const GLint *baseVertices,
207 const GLuint *baseInstances,
208 GLsizei drawcount) override;
209
210 // MultiDrawIndirect helper functions
211 angle::Result multiDrawElementsIndirectHelper(const gl::Context *context,
212 gl::PrimitiveMode mode,
213 gl::DrawElementsType type,
214 const void *indirect,
215 GLsizei drawcount,
216 GLsizei stride);
217 angle::Result multiDrawArraysIndirectHelper(const gl::Context *context,
218 gl::PrimitiveMode mode,
219 const void *indirect,
220 GLsizei drawcount,
221 GLsizei stride);
222
223 // ShareGroup
getShareGroupVk()224 ShareGroupVk *getShareGroupVk() { return mShareGroupVk; }
getPipelineLayoutCache()225 PipelineLayoutCache &getPipelineLayoutCache()
226 {
227 return mShareGroupVk->getPipelineLayoutCache();
228 }
getDescriptorSetLayoutCache()229 DescriptorSetLayoutCache &getDescriptorSetLayoutCache()
230 {
231 return mShareGroupVk->getDescriptorSetLayoutCache();
232 }
233
234 // Device loss
235 gl::GraphicsResetStatus getResetStatus() override;
236
237 // EXT_debug_marker
238 angle::Result insertEventMarker(GLsizei length, const char *marker) override;
239 angle::Result pushGroupMarker(GLsizei length, const char *marker) override;
240 angle::Result popGroupMarker() override;
241
242 void insertEventMarkerImpl(GLenum source, const char *marker);
243
244 // KHR_debug
245 angle::Result pushDebugGroup(const gl::Context *context,
246 GLenum source,
247 GLuint id,
248 const std::string &message) override;
249 angle::Result popDebugGroup(const gl::Context *context) override;
250
251 // Record GL API calls for debuggers
252 void logEvent(const char *eventString);
253 void endEventLog(angle::EntryPoint entryPoint, PipelineType pipelineType);
254 void endEventLogForClearOrQuery();
255
256 bool isViewportFlipEnabledForDrawFBO() const;
257 bool isViewportFlipEnabledForReadFBO() const;
258 // When the device/surface is rotated such that the surface's aspect ratio is different than
259 // the native device (e.g. 90 degrees), the width and height of the viewport, scissor, and
260 // render area must be swapped.
261 bool isRotatedAspectRatioForDrawFBO() const;
262 bool isRotatedAspectRatioForReadFBO() const;
263 SurfaceRotation getRotationDrawFramebuffer() const;
264 SurfaceRotation getRotationReadFramebuffer() const;
265
266 // View port (x, y, w, h) will be determined by a combination of -
267 // 1. clip space origin
268 // 2. isViewportFlipEnabledForDrawFBO
269 // For userdefined FBOs it will be based on the value of isViewportFlipEnabledForDrawFBO.
270 // For default FBOs it will be XOR of ClipOrigin and isViewportFlipEnabledForDrawFBO.
271 // isYFlipEnabledForDrawFBO indicates the rendered image is upside-down.
isYFlipEnabledForDrawFBO()272 ANGLE_INLINE bool isYFlipEnabledForDrawFBO() const
273 {
274 return mState.getClipSpaceOrigin() == gl::ClipSpaceOrigin::UpperLeft
275 ? !isViewportFlipEnabledForDrawFBO()
276 : isViewportFlipEnabledForDrawFBO();
277 }
278
279 void invalidateProgramBindingHelper(const gl::State &glState);
280
281 // State sync with dirty bits.
282 angle::Result syncState(const gl::Context *context,
283 const gl::State::DirtyBits &dirtyBits,
284 const gl::State::DirtyBits &bitMask,
285 gl::Command command) override;
286
287 // Disjoint timer queries
288 GLint getGPUDisjoint() override;
289 GLint64 getTimestamp() override;
290
291 // Context switching
292 angle::Result onMakeCurrent(const gl::Context *context) override;
293 angle::Result onUnMakeCurrent(const gl::Context *context) override;
294
295 // Native capabilities, unmodified by gl::Context.
296 gl::Caps getNativeCaps() const override;
297 const gl::TextureCapsMap &getNativeTextureCaps() const override;
298 const gl::Extensions &getNativeExtensions() const override;
299 const gl::Limitations &getNativeLimitations() const override;
300
301 // Shader creation
302 CompilerImpl *createCompiler() override;
303 ShaderImpl *createShader(const gl::ShaderState &state) override;
304 ProgramImpl *createProgram(const gl::ProgramState &state) override;
305
306 // Framebuffer creation
307 FramebufferImpl *createFramebuffer(const gl::FramebufferState &state) override;
308
309 // Texture creation
310 TextureImpl *createTexture(const gl::TextureState &state) override;
311
312 // Renderbuffer creation
313 RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override;
314
315 // Buffer creation
316 BufferImpl *createBuffer(const gl::BufferState &state) override;
317
318 // Vertex Array creation
319 VertexArrayImpl *createVertexArray(const gl::VertexArrayState &state) override;
320
321 // Query and Fence creation
322 QueryImpl *createQuery(gl::QueryType type) override;
323 FenceNVImpl *createFenceNV() override;
324 SyncImpl *createSync() override;
325
326 // Transform Feedback creation
327 TransformFeedbackImpl *createTransformFeedback(
328 const gl::TransformFeedbackState &state) override;
329
330 // Sampler object creation
331 SamplerImpl *createSampler(const gl::SamplerState &state) override;
332
333 // Program Pipeline object creation
334 ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
335
336 // Memory object creation.
337 MemoryObjectImpl *createMemoryObject() override;
338
339 // Semaphore creation.
340 SemaphoreImpl *createSemaphore() override;
341
342 // Overlay creation.
343 OverlayImpl *createOverlay(const gl::OverlayState &state) override;
344
345 angle::Result dispatchCompute(const gl::Context *context,
346 GLuint numGroupsX,
347 GLuint numGroupsY,
348 GLuint numGroupsZ) override;
349 angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override;
350
351 angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override;
352 angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override;
353
invalidateTexture(gl::TextureType target)354 ANGLE_INLINE void invalidateTexture(gl::TextureType target) override {}
355
356 // EXT_shader_framebuffer_fetch_non_coherent
357 void framebufferFetchBarrier() override;
358
359 // GL_ANGLE_vulkan_image
360 angle::Result acquireTextures(const gl::Context *context,
361 const gl::TextureBarrierVector &textureBarriers) override;
362 angle::Result releaseTextures(const gl::Context *context,
363 gl::TextureBarrierVector *textureBarriers) override;
364
365 VkDevice getDevice() const;
getPriority()366 egl::ContextPriority getPriority() const { return mContextPriority; }
hasProtectedContent()367 bool hasProtectedContent() const { return mState.hasProtectedContent(); }
368
getFeatures()369 ANGLE_INLINE const angle::FeaturesVk &getFeatures() const { return mRenderer->getFeatures(); }
370
invalidateVertexAndIndexBuffers()371 ANGLE_INLINE void invalidateVertexAndIndexBuffers()
372 {
373 mGraphicsDirtyBits |= kIndexAndVertexDirtyBits;
374 }
375
376 angle::Result onVertexBufferChange(const vk::BufferHelper *vertexBuffer);
377
378 angle::Result onVertexAttributeChange(size_t attribIndex,
379 GLuint stride,
380 GLuint divisor,
381 angle::FormatID format,
382 bool compressed,
383 GLuint relativeOffset,
384 const vk::BufferHelper *vertexBuffer);
385
386 void invalidateDefaultAttribute(size_t attribIndex);
387 void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
388 angle::Result onFramebufferChange(FramebufferVk *framebufferVk, gl::Command command);
389 void onDrawFramebufferRenderPassDescChange(FramebufferVk *framebufferVk,
390 bool *renderPassDescChangedOut);
onHostVisibleBufferWrite()391 void onHostVisibleBufferWrite() { mIsAnyHostVisibleBufferWritten = true; }
392
393 void invalidateCurrentTransformFeedbackBuffers();
394 void onTransformFeedbackStateChanged();
395 angle::Result onBeginTransformFeedback(
396 size_t bufferCount,
397 const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &buffers,
398 const gl::TransformFeedbackBuffersArray<vk::BufferHelper> &counterBuffers);
399 void onEndTransformFeedback();
400 angle::Result onPauseTransformFeedback();
401 void pauseTransformFeedbackIfActiveUnpaused();
402
403 // When UtilsVk issues draw or dispatch calls, it binds a new pipeline and descriptor sets that
404 // the context is not aware of. These functions are called to make sure the pipeline and
405 // affected descriptor set bindings are dirtied for the next application draw/dispatch call.
406 void invalidateGraphicsPipelineBinding();
407 void invalidateComputePipelineBinding();
408 void invalidateGraphicsDescriptorSet(DescriptorSetIndex usedDescriptorSet);
409 void invalidateComputeDescriptorSet(DescriptorSetIndex usedDescriptorSet);
410 void invalidateViewportAndScissor();
411
412 void optimizeRenderPassForPresent(VkFramebuffer framebufferHandle);
413
414 vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType);
415
416 const VkClearValue &getClearColorValue() const;
417 const VkClearValue &getClearDepthStencilValue() const;
418 gl::BlendStateExt::ColorMaskStorage::Type getClearColorMasks() const;
getScissor()419 const VkRect2D &getScissor() const { return mScissor; }
420 angle::Result getIncompleteTexture(const gl::Context *context,
421 gl::TextureType type,
422 gl::SamplerFormat format,
423 gl::Texture **textureOut);
424 void updateColorMasks();
425 void updateBlendFuncsAndEquations();
426 void updateSampleMaskWithRasterizationSamples(const uint32_t rasterizationSamples);
427
428 void handleError(VkResult errorCode,
429 const char *file,
430 const char *function,
431 unsigned int line) override;
getActiveTextures()432 const gl::ActiveTextureArray<vk::TextureUnit> &getActiveTextures() const
433 {
434 return mActiveTextures;
435 }
getActiveImages()436 const gl::ActiveTextureArray<TextureVk *> &getActiveImages() const { return mActiveImages; }
437
438 angle::Result onIndexBufferChange(const vk::BufferHelper *currentIndexBuffer);
439
440 angle::Result flushImpl(const vk::Semaphore *semaphore,
441 RenderPassClosureReason renderPassClosureReason);
442 angle::Result flushAndGetSerial(const vk::Semaphore *semaphore,
443 Serial *submitSerialOut,
444 RenderPassClosureReason renderPassClosureReason);
445 angle::Result finishImpl(RenderPassClosureReason renderPassClosureReason);
446
447 void addWaitSemaphore(VkSemaphore semaphore, VkPipelineStageFlags stageMask);
448
449 const vk::CommandPool &getCommandPool() const;
450
getLastCompletedQueueSerial()451 Serial getLastCompletedQueueSerial() const { return mRenderer->getLastCompletedQueueSerial(); }
452
453 bool isSerialInUse(Serial serial) const;
454
455 template <typename T>
addGarbage(T * object)456 void addGarbage(T *object)
457 {
458 if (object->valid())
459 {
460 mCurrentGarbage.emplace_back(vk::GetGarbage(object));
461 }
462 }
463
464 // It would be nice if we didn't have to expose this for QueryVk::getResult.
465 angle::Result checkCompletedCommands();
466
467 // Wait for completion of batches until (at least) batch with given serial is finished.
468 angle::Result finishToSerial(Serial serial);
469
470 angle::Result getCompatibleRenderPass(const vk::RenderPassDesc &desc,
471 vk::RenderPass **renderPassOut);
472 angle::Result getRenderPassWithOps(const vk::RenderPassDesc &desc,
473 const vk::AttachmentOpsArray &ops,
474 vk::RenderPass **renderPassOut);
475
getShaderLibrary()476 vk::ShaderLibrary &getShaderLibrary() { return mShaderLibrary; }
getUtils()477 UtilsVk &getUtils() { return mUtils; }
478
479 angle::Result getTimestamp(uint64_t *timestampOut);
480
481 // Create Begin/End/Instant GPU trace events, which take their timestamps from GPU queries.
482 // The events are queued until the query results are available. Possible values for `phase`
483 // are TRACE_EVENT_PHASE_*
traceGpuEvent(vk::CommandBuffer * commandBuffer,char phase,const EventName & name)484 ANGLE_INLINE angle::Result traceGpuEvent(vk::CommandBuffer *commandBuffer,
485 char phase,
486 const EventName &name)
487 {
488 if (mGpuEventsEnabled)
489 return traceGpuEventImpl(commandBuffer, phase, name);
490 return angle::Result::Continue;
491 }
492
getRenderPassCache()493 RenderPassCache &getRenderPassCache() { return mRenderPassCache; }
494
495 vk::DescriptorSetLayoutDesc getDriverUniformsDescriptorSetDesc() const;
496
497 void updateScissor(const gl::State &glState);
498
499 void updateDepthStencil(const gl::State &glState);
500
emulateSeamfulCubeMapSampling()501 bool emulateSeamfulCubeMapSampling() const { return mEmulateSeamfulCubeMapSampling; }
502
getDebug()503 const gl::Debug &getDebug() const { return mState.getDebug(); }
getOverlay()504 const gl::OverlayType *getOverlay() const { return mState.getOverlay(); }
505
getResourceUseList()506 vk::ResourceUseList &getResourceUseList() { return mResourceUseList; }
507
508 angle::Result onBufferReleaseToExternal(const vk::BufferHelper &buffer);
509 angle::Result onImageReleaseToExternal(const vk::ImageHelper &image);
510
onImageRenderPassRead(VkImageAspectFlags aspectFlags,vk::ImageLayout imageLayout,vk::ImageHelper * image)511 void onImageRenderPassRead(VkImageAspectFlags aspectFlags,
512 vk::ImageLayout imageLayout,
513 vk::ImageHelper *image)
514 {
515 ASSERT(mRenderPassCommands->started());
516 mRenderPassCommands->imageRead(this, aspectFlags, imageLayout, image);
517 }
518
onImageRenderPassWrite(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,VkImageAspectFlags aspectFlags,vk::ImageLayout imageLayout,vk::ImageHelper * image)519 void onImageRenderPassWrite(gl::LevelIndex level,
520 uint32_t layerStart,
521 uint32_t layerCount,
522 VkImageAspectFlags aspectFlags,
523 vk::ImageLayout imageLayout,
524 vk::ImageHelper *image)
525 {
526 ASSERT(mRenderPassCommands->started());
527 mRenderPassCommands->imageWrite(this, level, layerStart, layerCount, aspectFlags,
528 imageLayout, vk::AliasingMode::Allowed, image);
529 }
530
onColorDraw(vk::ImageHelper * image,vk::ImageHelper * resolveImage,vk::PackedAttachmentIndex packedAttachmentIndex)531 void onColorDraw(vk::ImageHelper *image,
532 vk::ImageHelper *resolveImage,
533 vk::PackedAttachmentIndex packedAttachmentIndex)
534 {
535 ASSERT(mRenderPassCommands->started());
536 mRenderPassCommands->colorImagesDraw(&mResourceUseList, image, resolveImage,
537 packedAttachmentIndex);
538 }
onDepthStencilDraw(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,vk::ImageHelper * image,vk::ImageHelper * resolveImage)539 void onDepthStencilDraw(gl::LevelIndex level,
540 uint32_t layerStart,
541 uint32_t layerCount,
542 vk::ImageHelper *image,
543 vk::ImageHelper *resolveImage)
544 {
545 ASSERT(mRenderPassCommands->started());
546 mRenderPassCommands->depthStencilImagesDraw(&mResourceUseList, level, layerStart,
547 layerCount, image, resolveImage);
548 }
549
finalizeImageLayout(const vk::ImageHelper * image)550 void finalizeImageLayout(const vk::ImageHelper *image)
551 {
552 if (mRenderPassCommands->started())
553 {
554 mRenderPassCommands->finalizeImageLayout(this, image);
555 }
556 }
557
getOutsideRenderPassCommandBuffer(const vk::CommandBufferAccess & access,vk::CommandBuffer ** commandBufferOut)558 angle::Result getOutsideRenderPassCommandBuffer(const vk::CommandBufferAccess &access,
559 vk::CommandBuffer **commandBufferOut)
560 {
561 ASSERT(!mOutsideRenderPassCommands->hasRenderPass());
562 ANGLE_TRY(onResourceAccess(access));
563 *commandBufferOut = &mOutsideRenderPassCommands->getCommandBuffer();
564 return angle::Result::Continue;
565 }
566
567 angle::Result beginNewRenderPass(const vk::Framebuffer &framebuffer,
568 const gl::Rectangle &renderArea,
569 const vk::RenderPassDesc &renderPassDesc,
570 const vk::AttachmentOpsArray &renderPassAttachmentOps,
571 const vk::PackedAttachmentCount colorAttachmentCount,
572 const vk::PackedAttachmentIndex depthStencilAttachmentIndex,
573 const vk::PackedClearValuesArray &clearValues,
574 vk::CommandBuffer **commandBufferOut);
575
576 // Only returns true if we have a started RP and we've run setupDraw.
hasStartedRenderPass()577 bool hasStartedRenderPass() const
578 {
579 // Checking mRenderPassCommandBuffer ensures we've called setupDraw.
580 return mRenderPassCommandBuffer && mRenderPassCommands->started();
581 }
582
hasStartedRenderPassWithFramebuffer(vk::Framebuffer * framebuffer)583 bool hasStartedRenderPassWithFramebuffer(vk::Framebuffer *framebuffer)
584 {
585 return hasStartedRenderPass() &&
586 mRenderPassCommands->getFramebufferHandle() == framebuffer->getHandle();
587 }
588
hasStartedRenderPassWithCommands()589 bool hasStartedRenderPassWithCommands() const
590 {
591 return hasStartedRenderPass() && !mRenderPassCommands->getCommandBuffer().empty();
592 }
593
getStartedRenderPassCommands()594 vk::CommandBufferHelper &getStartedRenderPassCommands()
595 {
596 ASSERT(mRenderPassCommands->started());
597 return *mRenderPassCommands;
598 }
599
600 // TODO(https://anglebug.com/4968): Support multiple open render passes.
601 void restoreFinishedRenderPass(vk::Framebuffer *framebuffer);
602
603 uint32_t getCurrentSubpassIndex() const;
604 uint32_t getCurrentViewCount() const;
605
getContextPriority()606 egl::ContextPriority getContextPriority() const override { return mContextPriority; }
607 angle::Result startRenderPass(gl::Rectangle renderArea,
608 vk::CommandBuffer **commandBufferOut,
609 bool *renderPassDescChangedOut);
610 void startNextSubpass();
611 angle::Result flushCommandsAndEndRenderPass(RenderPassClosureReason reason);
612 angle::Result flushCommandsAndEndRenderPassWithoutQueueSubmit(RenderPassClosureReason reason);
613
614 angle::Result syncExternalMemory();
615
616 void addCommandBufferDiagnostics(const std::string &commandBufferDiagnostics);
617
618 VkIndexType getVkIndexType(gl::DrawElementsType glIndexType) const;
619 size_t getVkIndexTypeSize(gl::DrawElementsType glIndexType) const;
620 bool shouldConvertUint8VkIndexType(gl::DrawElementsType glIndexType) const;
621
isBresenhamEmulationEnabled(const gl::PrimitiveMode mode)622 ANGLE_INLINE bool isBresenhamEmulationEnabled(const gl::PrimitiveMode mode)
623 {
624 return getFeatures().basicGLLineRasterization.enabled && gl::IsLineMode(mode);
625 }
626
getExecutable()627 const ProgramExecutableVk *getExecutable() const { return mExecutable; }
getExecutable()628 ProgramExecutableVk *getExecutable() { return mExecutable; }
629
630 bool isRobustResourceInitEnabled() const;
631
632 // Queries that begin and end automatically with render pass start and end
633 angle::Result beginRenderPassQuery(QueryVk *queryVk);
634 angle::Result endRenderPassQuery(QueryVk *queryVk);
635 void pauseRenderPassQueriesIfActive();
636 angle::Result resumeRenderPassQueriesIfActive();
637 angle::Result resumeXfbRenderPassQueriesIfActive();
638 bool doesPrimitivesGeneratedQuerySupportRasterizerDiscard() const;
639 bool isEmulatingRasterizerDiscardDuringPrimitivesGeneratedQuery(
640 bool isPrimitivesGeneratedQueryActive) const;
641
642 // Used by QueryVk to share query helpers between transform feedback queries.
643 QueryVk *getActiveRenderPassQuery(gl::QueryType queryType) const;
644
645 void syncObjectPerfCounters();
646 void updateOverlayOnPresent();
647 void addOverlayUsedBuffersCount(vk::CommandBufferHelper *commandBuffer);
648
649 // DescriptorSet writes
650 VkDescriptorBufferInfo *allocDescriptorBufferInfos(size_t count);
651 VkDescriptorImageInfo *allocDescriptorImageInfos(size_t count);
652 VkWriteDescriptorSet *allocWriteDescriptorSets(size_t count);
653
allocDescriptorBufferInfo()654 VkDescriptorBufferInfo &allocDescriptorBufferInfo() { return *allocDescriptorBufferInfos(1); }
allocDescriptorImageInfo()655 VkDescriptorImageInfo &allocDescriptorImageInfo() { return *allocDescriptorImageInfos(1); }
allocWriteDescriptorSet()656 VkWriteDescriptorSet &allocWriteDescriptorSet() { return *allocWriteDescriptorSets(1); }
657
getDefaultUniformStorage()658 vk::DynamicBuffer *getDefaultUniformStorage() { return &mDefaultUniformStorage; }
659 // For testing only.
660 void setDefaultUniformBlocksMinSizeForTesting(size_t minSize);
661
getEmptyBuffer()662 vk::BufferHelper &getEmptyBuffer() { return mEmptyBuffer; }
getStagingBuffer()663 vk::DynamicBuffer *getStagingBuffer() { return &mStagingBuffer; }
664
getPerfCounters()665 const vk::PerfCounters &getPerfCounters() const { return mPerfCounters; }
getPerfCounters()666 vk::PerfCounters &getPerfCounters() { return mPerfCounters; }
667
668 // Implementation of MultisampleTextureInitializer
669 angle::Result initializeMultisampleTextureToBlack(const gl::Context *context,
670 gl::Texture *glTexture) override;
671
672 // TODO(http://anglebug.com/5624): rework updateActiveTextures(), createPipelineLayout(),
673 // handleDirtyGraphicsPipeline(), and ProgramPipelineVk::link().
resetCurrentGraphicsPipeline()674 void resetCurrentGraphicsPipeline() { mCurrentGraphicsPipeline = nullptr; }
675
676 void onProgramExecutableReset(ProgramExecutableVk *executableVk);
677
678 angle::Result handleGraphicsEventLog(GraphicsEventCmdBuf queryEventType);
679
680 void flushDescriptorSetUpdates();
681
682 private:
683 // Dirty bits.
684 enum DirtyBitType : size_t
685 {
686 // A glMemoryBarrier has been called and command buffers may need flushing.
687 DIRTY_BIT_MEMORY_BARRIER,
688 // Dirty bits that must be processed before the render pass is started. The handlers for
689 // these dirty bits don't record any commands.
690 DIRTY_BIT_DEFAULT_ATTRIBS,
691 // The pipeline has changed and needs to be recreated. This dirty bit may close the render
692 // pass.
693 DIRTY_BIT_PIPELINE_DESC,
694
695 // Start the render pass.
696 DIRTY_BIT_RENDER_PASS,
697
698 // Dirty bits that must be processed after the render pass is started. Their handlers
699 // record commands.
700 DIRTY_BIT_EVENT_LOG,
701 // Pipeline needs to rebind because a new command buffer has been allocated, or UtilsVk has
702 // changed the binding. The pipeline itself doesn't need to be recreated.
703 DIRTY_BIT_PIPELINE_BINDING,
704 DIRTY_BIT_TEXTURES,
705 DIRTY_BIT_VERTEX_BUFFERS,
706 DIRTY_BIT_INDEX_BUFFER,
707 DIRTY_BIT_DRIVER_UNIFORMS,
708 DIRTY_BIT_DRIVER_UNIFORMS_BINDING,
709 // Shader resources excluding textures, which are handled separately.
710 DIRTY_BIT_SHADER_RESOURCES,
711 DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS,
712 DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME,
713 DIRTY_BIT_DESCRIPTOR_SETS,
714 DIRTY_BIT_FRAMEBUFFER_FETCH_BARRIER,
715 // Dynamic viewport/scissor
716 DIRTY_BIT_VIEWPORT,
717 DIRTY_BIT_SCISSOR,
718 DIRTY_BIT_MAX,
719 };
720
721 using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
722
723 using GraphicsDirtyBitHandler = angle::Result (
724 ContextVk::*)(DirtyBits::Iterator *dirtyBitsIterator, DirtyBits dirtyBitMask);
725 using ComputeDirtyBitHandler = angle::Result (ContextVk::*)();
726
727 struct DriverUniformsDescriptorSet
728 {
729 vk::DynamicBuffer dynamicBuffer;
730 VkDescriptorSet descriptorSet;
731 uint32_t dynamicOffset;
732 vk::BindingPointer<vk::DescriptorSetLayout> descriptorSetLayout;
733 vk::RefCountedDescriptorPoolBinding descriptorPoolBinding;
734 DriverUniformsDescriptorSetCache descriptorSetCache;
735
736 DriverUniformsDescriptorSet();
737 ~DriverUniformsDescriptorSet();
738
739 void init(RendererVk *rendererVk);
740 void destroy(RendererVk *rendererVk);
741 };
742
743 // The GpuEventQuery struct holds together a timestamp query and enough data to create a
744 // trace event based on that. Use traceGpuEvent to insert such queries. They will be readback
745 // when the results are available, without inserting a GPU bubble.
746 //
747 // - eventName will be the reported name of the event
748 // - phase is either 'B' (duration begin), 'E' (duration end) or 'i' (instant // event).
749 // See Google's "Trace Event Format":
750 // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
751 // - serial is the serial of the batch the query was submitted on. Until the batch is
752 // submitted, the query is not checked to avoid incuring a flush.
753 struct GpuEventQuery final
754 {
755 EventName name;
756 char phase;
757 vk::QueryHelper queryHelper;
758 };
759
760 // Once a query result is available, the timestamp is read and a GpuEvent object is kept until
761 // the next clock sync, at which point the clock drift is compensated in the results before
762 // handing them off to the application.
763 struct GpuEvent final
764 {
765 uint64_t gpuTimestampCycles;
766 std::array<char, kMaxGpuEventNameLen> name;
767 char phase;
768 };
769
770 struct GpuClockSyncInfo
771 {
772 double gpuTimestampS;
773 double cpuTimestampS;
774 };
775
776 class ScopedDescriptorSetUpdates;
777
778 angle::Result setupDraw(const gl::Context *context,
779 gl::PrimitiveMode mode,
780 GLint firstVertexOrInvalid,
781 GLsizei vertexOrIndexCount,
782 GLsizei instanceCount,
783 gl::DrawElementsType indexTypeOrInvalid,
784 const void *indices,
785 DirtyBits dirtyBitMask);
786
787 angle::Result setupIndexedDraw(const gl::Context *context,
788 gl::PrimitiveMode mode,
789 GLsizei indexCount,
790 GLsizei instanceCount,
791 gl::DrawElementsType indexType,
792 const void *indices);
793 angle::Result setupIndirectDraw(const gl::Context *context,
794 gl::PrimitiveMode mode,
795 DirtyBits dirtyBitMask,
796 vk::BufferHelper *indirectBuffer,
797 VkDeviceSize indirectBufferOffset);
798 angle::Result setupIndexedIndirectDraw(const gl::Context *context,
799 gl::PrimitiveMode mode,
800 gl::DrawElementsType indexType,
801 vk::BufferHelper *indirectBuffer,
802 VkDeviceSize indirectBufferOffset);
803
804 angle::Result setupLineLoopIndexedIndirectDraw(const gl::Context *context,
805 gl::PrimitiveMode mode,
806 gl::DrawElementsType indexType,
807 vk::BufferHelper *srcIndirectBuf,
808 VkDeviceSize indirectBufferOffset,
809 vk::BufferHelper **indirectBufferOut,
810 VkDeviceSize *indirectBufferOffsetOut);
811 angle::Result setupLineLoopIndirectDraw(const gl::Context *context,
812 gl::PrimitiveMode mode,
813 vk::BufferHelper *indirectBuffer,
814 VkDeviceSize indirectBufferOffset,
815 vk::BufferHelper **indirectBufferOut,
816 VkDeviceSize *indirectBufferOffsetOut);
817
818 angle::Result setupLineLoopDraw(const gl::Context *context,
819 gl::PrimitiveMode mode,
820 GLint firstVertex,
821 GLsizei vertexOrIndexCount,
822 gl::DrawElementsType indexTypeOrInvalid,
823 const void *indices,
824 uint32_t *numIndicesOut);
825 angle::Result setupDispatch(const gl::Context *context);
826
827 gl::Rectangle getCorrectedViewport(const gl::Rectangle &viewport) const;
828 void updateViewport(FramebufferVk *framebufferVk,
829 const gl::Rectangle &viewport,
830 float nearPlane,
831 float farPlane);
832 void updateDepthRange(float nearPlane, float farPlane);
833 void updateFlipViewportDrawFramebuffer(const gl::State &glState);
834 void updateFlipViewportReadFramebuffer(const gl::State &glState);
835 void updateSurfaceRotationDrawFramebuffer(const gl::State &glState);
836 void updateSurfaceRotationReadFramebuffer(const gl::State &glState);
837
838 angle::Result updateActiveTextures(const gl::Context *context, gl::Command command);
839 angle::Result updateActiveImages(vk::CommandBufferHelper *commandBufferHelper);
840 angle::Result updateDefaultAttribute(size_t attribIndex);
841
invalidateCurrentGraphicsPipeline()842 ANGLE_INLINE void invalidateCurrentGraphicsPipeline()
843 {
844 // Note: DIRTY_BIT_PIPELINE_BINDING will be automatically set if pipeline bind is necessary.
845 mGraphicsDirtyBits.set(DIRTY_BIT_PIPELINE_DESC);
846 }
847
invalidateCurrentComputePipeline()848 ANGLE_INLINE void invalidateCurrentComputePipeline()
849 {
850 mComputeDirtyBits |= kPipelineDescAndBindingDirtyBits;
851 mCurrentComputePipeline = nullptr;
852 }
853
854 angle::Result invalidateProgramExecutableHelper(const gl::Context *context);
855
856 void invalidateCurrentDefaultUniforms();
857 angle::Result invalidateCurrentTextures(const gl::Context *context, gl::Command command);
858 angle::Result invalidateCurrentShaderResources(gl::Command command);
859 void invalidateGraphicsDriverUniforms();
860 void invalidateDriverUniforms();
861
862 angle::Result handleNoopDrawEvent() override;
863
864 // Handlers for graphics pipeline dirty bits.
865 angle::Result handleDirtyGraphicsMemoryBarrier(DirtyBits::Iterator *dirtyBitsIterator,
866 DirtyBits dirtyBitMask);
867 angle::Result handleDirtyGraphicsEventLog(DirtyBits::Iterator *dirtyBitsIterator,
868 DirtyBits dirtyBitMask);
869 angle::Result handleDirtyGraphicsDefaultAttribs(DirtyBits::Iterator *dirtyBitsIterator,
870 DirtyBits dirtyBitMask);
871 angle::Result handleDirtyGraphicsPipelineDesc(DirtyBits::Iterator *dirtyBitsIterator,
872 DirtyBits dirtyBitMask);
873 angle::Result handleDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator,
874 DirtyBits dirtyBitMask);
875 angle::Result handleDirtyGraphicsPipelineBinding(DirtyBits::Iterator *dirtyBitsIterator,
876 DirtyBits dirtyBitMask);
877 angle::Result handleDirtyGraphicsTextures(DirtyBits::Iterator *dirtyBitsIterator,
878 DirtyBits dirtyBitMask);
879 angle::Result handleDirtyGraphicsVertexBuffers(DirtyBits::Iterator *dirtyBitsIterator,
880 DirtyBits dirtyBitMask);
881 angle::Result handleDirtyGraphicsIndexBuffer(DirtyBits::Iterator *dirtyBitsIterator,
882 DirtyBits dirtyBitMask);
883 angle::Result handleDirtyGraphicsDriverUniforms(DirtyBits::Iterator *dirtyBitsIterator,
884 DirtyBits dirtyBitMask);
885 angle::Result handleDirtyGraphicsDriverUniformsBinding(DirtyBits::Iterator *dirtyBitsIterator,
886 DirtyBits dirtyBitMask);
887 angle::Result handleDirtyGraphicsShaderResources(DirtyBits::Iterator *dirtyBitsIterator,
888 DirtyBits dirtyBitMask);
889 angle::Result handleDirtyGraphicsFramebufferFetchBarrier(DirtyBits::Iterator *dirtyBitsIterator,
890 DirtyBits dirtyBitMask);
891 angle::Result handleDirtyGraphicsTransformFeedbackBuffersEmulation(
892 DirtyBits::Iterator *dirtyBitsIterator,
893 DirtyBits dirtyBitMask);
894 angle::Result handleDirtyGraphicsTransformFeedbackBuffersExtension(
895 DirtyBits::Iterator *dirtyBitsIterator,
896 DirtyBits dirtyBitMask);
897 angle::Result handleDirtyGraphicsTransformFeedbackResume(DirtyBits::Iterator *dirtyBitsIterator,
898 DirtyBits dirtyBitMask);
899 angle::Result handleDirtyGraphicsDescriptorSets(DirtyBits::Iterator *dirtyBitsIterator,
900 DirtyBits dirtyBitMask);
901 angle::Result handleDirtyGraphicsViewport(DirtyBits::Iterator *dirtyBitsIterator,
902 DirtyBits dirtyBitMask);
903 angle::Result handleDirtyGraphicsScissor(DirtyBits::Iterator *dirtyBitsIterator,
904 DirtyBits dirtyBitMask);
905
906 // Handlers for compute pipeline dirty bits.
907 angle::Result handleDirtyComputeMemoryBarrier();
908 angle::Result handleDirtyComputeEventLog();
909 angle::Result handleDirtyComputePipelineDesc();
910 angle::Result handleDirtyComputePipelineBinding();
911 angle::Result handleDirtyComputeTextures();
912 angle::Result handleDirtyComputeDriverUniforms();
913 angle::Result handleDirtyComputeDriverUniformsBinding();
914 angle::Result handleDirtyComputeShaderResources();
915 angle::Result handleDirtyComputeDescriptorSets();
916
917 // Common parts of the common dirty bit handlers.
918 angle::Result handleDirtyMemoryBarrierImpl(DirtyBits::Iterator *dirtyBitsIterator,
919 DirtyBits dirtyBitMask);
920 angle::Result handleDirtyEventLogImpl(vk::CommandBuffer *commandBuffer);
921 angle::Result handleDirtyTexturesImpl(vk::CommandBufferHelper *commandBufferHelper,
922 PipelineType pipelineType);
923 angle::Result handleDirtyShaderResourcesImpl(vk::CommandBufferHelper *commandBufferHelper);
924 void handleDirtyDriverUniformsBindingImpl(vk::CommandBuffer *commandBuffer,
925 VkPipelineBindPoint bindPoint,
926 DriverUniformsDescriptorSet *driverUniforms);
927 angle::Result handleDirtyDescriptorSetsImpl(vk::CommandBuffer *commandBuffer,
928 PipelineType pipelineType);
929 void handleDirtyGraphicsScissorImpl(bool isPrimitivesGeneratedQueryActive);
930
931 angle::Result allocateDriverUniforms(size_t driverUniformsSize,
932 DriverUniformsDescriptorSet *driverUniforms,
933 uint8_t **ptrOut,
934 bool *newBufferOut);
935 angle::Result updateDriverUniformsDescriptorSet(bool newBuffer,
936 size_t driverUniformsSize,
937 PipelineType pipelineType);
938
939 void writeAtomicCounterBufferDriverUniformOffsets(uint32_t *offsetsOut, size_t offsetsSize);
940
941 angle::Result submitFrame(const vk::Semaphore *signalSemaphore, Serial *submitSerialOut);
942
943 angle::Result synchronizeCpuGpuTime();
944 angle::Result traceGpuEventImpl(vk::CommandBuffer *commandBuffer,
945 char phase,
946 const EventName &name);
947 angle::Result checkCompletedGpuEvents();
948 void flushGpuEvents(double nextSyncGpuTimestampS, double nextSyncCpuTimestampS);
949 void handleDeviceLost();
950 bool shouldEmulateSeamfulCubeMapSampling() const;
951 void clearAllGarbage();
952 bool hasRecordedCommands();
953 void dumpCommandStreamDiagnostics();
954 angle::Result flushOutsideRenderPassCommands();
955 // Flush commands and end render pass without setting any dirty bits.
956 // flushCommandsAndEndRenderPass() and flushDirtyGraphicsRenderPass() will set the dirty bits
957 // directly or through the iterator respectively. Outside those two functions, this shouldn't
958 // be called directly.
959 angle::Result flushCommandsAndEndRenderPassImpl(QueueSubmitType queueSubmit,
960 RenderPassClosureReason reason);
961 angle::Result flushDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator,
962 DirtyBits dirtyBitMask,
963 RenderPassClosureReason reason);
964
965 void onRenderPassFinished(RenderPassClosureReason reason);
966
967 void initIndexTypeMap();
968
969 // Read-after-write hazards are generally handled with |glMemoryBarrier| when the source of
970 // write is storage output. When the write is outside render pass, the natural placement of the
971 // render pass after the current outside render pass commands ensures that the memory barriers
972 // and image layout transitions automatically take care of such synchronizations.
973 //
974 // There are a number of read-after-write cases that require breaking the render pass however to
975 // preserve the order of operations:
976 //
977 // - Transform feedback write (in render pass), then vertex/index read (in render pass)
978 // - Transform feedback write (in render pass), then ubo read (outside render pass)
979 // - Framebuffer attachment write (in render pass), then texture sample (outside render pass)
980 // * Note that texture sampling inside render pass would cause a feedback loop
981 //
982 angle::Result endRenderPassIfTransformFeedbackBuffer(const vk::BufferHelper *buffer);
983 angle::Result endRenderPassIfComputeReadAfterTransformFeedbackWrite();
984 angle::Result endRenderPassIfComputeReadAfterAttachmentWrite();
985
986 void populateTransformFeedbackBufferSet(
987 size_t bufferCount,
988 const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &buffers);
989
990 // DescriptorSet writes
991 template <typename T, const T *VkWriteDescriptorSet::*pInfo>
992 T *allocDescriptorInfos(std::vector<T> *descriptorVector, size_t count);
993 template <typename T, const T *VkWriteDescriptorSet::*pInfo>
994 void growDesciptorCapacity(std::vector<T> *descriptorVector, size_t newSize);
995
996 angle::Result updateRenderPassDepthStencilAccess();
997 bool shouldSwitchToReadOnlyDepthFeedbackLoopMode(gl::Texture *texture,
998 gl::Command command) const;
999
1000 angle::Result onResourceAccess(const vk::CommandBufferAccess &access);
1001 angle::Result flushCommandBuffersIfNecessary(const vk::CommandBufferAccess &access);
1002 bool renderPassUsesStorageResources() const;
1003
1004 angle::Result pushDebugGroupImpl(GLenum source, GLuint id, const char *message);
1005 angle::Result popDebugGroupImpl();
1006
1007 void outputCumulativePerfCounters();
1008
1009 void updateSampleShadingWithRasterizationSamples(const uint32_t rasterizationSamples);
1010 void updateRasterizationSamples(const uint32_t rasterizationSamples);
1011 void updateRasterizerDiscardEnabled(bool isPrimitivesGeneratedQueryActive);
1012
1013 SpecConstUsageBits getCurrentProgramSpecConstUsageBits() const;
1014 void updateGraphicsPipelineDescWithSpecConstUsageBits(SpecConstUsageBits usageBits);
1015
1016 ContextVkPerfCounters getAndResetObjectPerfCounters();
1017
1018 std::array<GraphicsDirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers;
1019 std::array<ComputeDirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers;
1020
1021 vk::CommandBuffer *mRenderPassCommandBuffer;
1022
1023 vk::PipelineHelper *mCurrentGraphicsPipeline;
1024 vk::PipelineHelper *mCurrentComputePipeline;
1025 gl::PrimitiveMode mCurrentDrawMode;
1026
1027 WindowSurfaceVk *mCurrentWindowSurface;
1028 // Records the current rotation of the surface (draw/read) framebuffer, derived from
1029 // mCurrentWindowSurface->getPreTransform().
1030 SurfaceRotation mCurrentRotationDrawFramebuffer;
1031 SurfaceRotation mCurrentRotationReadFramebuffer;
1032
1033 // Keep a cached pipeline description structure that can be used to query the pipeline cache.
1034 // Kept in a pointer so allocations can be aligned, and structs can be portably packed.
1035 std::unique_ptr<vk::GraphicsPipelineDesc> mGraphicsPipelineDesc;
1036 vk::GraphicsPipelineTransitionBits mGraphicsPipelineTransition;
1037
1038 // These pools are externally synchronized, so cannot be accessed from different
1039 // threads simultaneously. Hence, we keep them in the ContextVk instead of the RendererVk.
1040 // Note that this implementation would need to change in shared resource scenarios. Likely
1041 // we'd instead share a single set of pools between the share groups.
1042 angle::PackedEnumMap<PipelineType, vk::DynamicDescriptorPool> mDriverUniformsDescriptorPools;
1043 gl::QueryTypeMap<vk::DynamicQueryPool> mQueryPools;
1044
1045 // Queries that need to be closed and reopened with the render pass:
1046 //
1047 // - Occlusion queries
1048 // - Transform feedback queries, if not emulated
1049 gl::QueryTypeMap<QueryVk *> mActiveRenderPassQueries;
1050
1051 // Dirty bits.
1052 DirtyBits mGraphicsDirtyBits;
1053 DirtyBits mComputeDirtyBits;
1054 DirtyBits mNonIndexedDirtyBitsMask;
1055 DirtyBits mIndexedDirtyBitsMask;
1056 DirtyBits mNewGraphicsCommandBufferDirtyBits;
1057 DirtyBits mNewComputeCommandBufferDirtyBits;
1058 static constexpr DirtyBits kIndexAndVertexDirtyBits{DIRTY_BIT_VERTEX_BUFFERS,
1059 DIRTY_BIT_INDEX_BUFFER};
1060 static constexpr DirtyBits kPipelineDescAndBindingDirtyBits{DIRTY_BIT_PIPELINE_DESC,
1061 DIRTY_BIT_PIPELINE_BINDING};
1062 static constexpr DirtyBits kTexturesAndDescSetDirtyBits{DIRTY_BIT_TEXTURES,
1063 DIRTY_BIT_DESCRIPTOR_SETS};
1064 static constexpr DirtyBits kResourcesAndDescSetDirtyBits{DIRTY_BIT_SHADER_RESOURCES,
1065 DIRTY_BIT_DESCRIPTOR_SETS};
1066 static constexpr DirtyBits kXfbBuffersAndDescSetDirtyBits{DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS,
1067 DIRTY_BIT_DESCRIPTOR_SETS};
1068 static constexpr DirtyBits kDriverUniformsAndBindingDirtyBits{
1069 DIRTY_BIT_DRIVER_UNIFORMS, DIRTY_BIT_DRIVER_UNIFORMS_BINDING};
1070
1071 // Cached back-end objects.
1072 VertexArrayVk *mVertexArray;
1073 FramebufferVk *mDrawFramebuffer;
1074 ProgramVk *mProgram;
1075 ProgramPipelineVk *mProgramPipeline;
1076 ProgramExecutableVk *mExecutable;
1077
1078 // The offset we had the last time we bound the index buffer.
1079 const GLvoid *mLastIndexBufferOffset;
1080 VkDeviceSize mCurrentIndexBufferOffset;
1081 gl::DrawElementsType mCurrentDrawElementsType;
1082 angle::PackedEnumMap<gl::DrawElementsType, VkIndexType> mIndexTypeMap;
1083
1084 // Cache the current draw call's firstVertex to be passed to
1085 // TransformFeedbackVk::getBufferOffsets. Unfortunately, gl_BaseVertex support in Vulkan is
1086 // not yet ubiquitous, which would have otherwise removed the need for this value to be passed
1087 // as a uniform.
1088 GLint mXfbBaseVertex;
1089 // Cache the current draw call's vertex count as well to support instanced draw calls
1090 GLuint mXfbVertexCountPerInstance;
1091
1092 // Cached clear value/mask for color and depth/stencil.
1093 VkClearValue mClearColorValue;
1094 VkClearValue mClearDepthStencilValue;
1095 gl::BlendStateExt::ColorMaskStorage::Type mClearColorMasks;
1096
1097 IncompleteTextureSet mIncompleteTextures;
1098
1099 // If the current surface bound to this context wants to have all rendering flipped vertically.
1100 // Updated on calls to onMakeCurrent.
1101 bool mFlipYForCurrentSurface;
1102 bool mFlipViewportForDrawFramebuffer;
1103 bool mFlipViewportForReadFramebuffer;
1104
1105 // If any host-visible buffer is written by the GPU since last submission, a barrier is inserted
1106 // at the end of the command buffer to make that write available to the host.
1107 bool mIsAnyHostVisibleBufferWritten;
1108
1109 // Whether this context should do seamful cube map sampling emulation.
1110 bool mEmulateSeamfulCubeMapSampling;
1111
1112 angle::PackedEnumMap<PipelineType, DriverUniformsDescriptorSet> mDriverUniforms;
1113
1114 // This cache should also probably include the texture index (shader location) and array
1115 // index (also in the shader). This info is used in the descriptor update step.
1116 gl::ActiveTextureArray<vk::TextureUnit> mActiveTextures;
1117
1118 // We use textureSerial to optimize texture binding updates. Each permutation of a
1119 // {VkImage/VkSampler} generates a unique serial. These object ids are combined to form a unique
1120 // signature for each descriptor set. This allows us to keep a cache of descriptor sets and
1121 // avoid calling vkAllocateDesctiporSets each texture update.
1122 vk::TextureDescriptorDesc mActiveTexturesDesc;
1123
1124 vk::ShaderBuffersDescriptorDesc mShaderBuffersDescriptorDesc;
1125
1126 gl::ActiveTextureArray<TextureVk *> mActiveImages;
1127
1128 // "Current Value" aka default vertex attribute state.
1129 gl::AttributesMask mDirtyDefaultAttribsMask;
1130 gl::AttribArray<vk::DynamicBuffer> mDefaultAttribBuffers;
1131
1132 // We use a single pool for recording commands. We also keep a free list for pool recycling.
1133 vk::CommandPool mCommandPool;
1134
1135 vk::GarbageList mCurrentGarbage;
1136
1137 RenderPassCache mRenderPassCache;
1138
1139 vk::CommandBufferHelper *mOutsideRenderPassCommands;
1140 vk::CommandBufferHelper *mRenderPassCommands;
1141
1142 // The following is used when creating debug-util markers for graphics debuggers (e.g. AGI). A
1143 // given gl{Begin|End}Query command may result in commands being submitted to the outside or
1144 // render-pass command buffer. The ContextVk::handleGraphicsEventLog() method records the
1145 // appropriate command buffer for use by ContextVk::endEventLogForQuery(). The knowledge of
1146 // which command buffer to use depends on the particular type of query (e.g. samples
1147 // vs. timestamp), and is only known by the query code, which is what calls
1148 // ContextVk::handleGraphicsEventLog(). After all back-end processing of the gl*Query command
1149 // is complete, the front-end calls ContextVk::endEventLogForQuery(), which needs to know which
1150 // command buffer to call endDebugUtilsLabelEXT() for.
1151 GraphicsEventCmdBuf mQueryEventType;
1152
1153 // Transform feedback buffers.
1154 angle::FastUnorderedSet<const vk::BufferHelper *,
1155 gl::IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS>
1156 mCurrentTransformFeedbackBuffers;
1157
1158 // Internal shader library.
1159 vk::ShaderLibrary mShaderLibrary;
1160 UtilsVk mUtils;
1161
1162 bool mGpuEventsEnabled;
1163 vk::DynamicQueryPool mGpuEventQueryPool;
1164 // A list of queries that have yet to be turned into an event (their result is not yet
1165 // available).
1166 std::vector<GpuEventQuery> mInFlightGpuEventQueries;
1167 // A list of gpu events since the last clock sync.
1168 std::vector<GpuEvent> mGpuEvents;
1169
1170 // Cached value of the color attachment mask of the current draw framebuffer. This is used to
1171 // know which attachment indices have their blend state set in |mGraphicsPipelineDesc|, and
1172 // subsequently is used to clear the blend state for attachments that no longer exist when a new
1173 // framebuffer is bound.
1174 gl::DrawBufferMask mCachedDrawFramebufferColorAttachmentMask;
1175
1176 bool mHasDeferredFlush;
1177
1178 // GL_EXT_shader_framebuffer_fetch_non_coherent
1179 bool mLastProgramUsesFramebufferFetch;
1180
1181 // Semaphores that must be waited on in the next submission.
1182 std::vector<VkSemaphore> mWaitSemaphores;
1183 std::vector<VkPipelineStageFlags> mWaitSemaphoreStageMasks;
1184
1185 // Hold information from the last gpu clock sync for future gpu-to-cpu timestamp conversions.
1186 GpuClockSyncInfo mGpuClockSync;
1187
1188 // The very first timestamp queried for a GPU event is used as origin, so event timestamps would
1189 // have a value close to zero, to avoid losing 12 bits when converting these 64 bit values to
1190 // double.
1191 uint64_t mGpuEventTimestampOrigin;
1192
1193 // A mix of per-frame and per-run counters.
1194 vk::PerfCounters mPerfCounters;
1195 ContextVkPerfCounters mContextPerfCounters;
1196 ContextVkPerfCounters mCumulativeContextPerfCounters;
1197
1198 gl::State::DirtyBits mPipelineDirtyBitsMask;
1199
1200 // List of all resources currently being used by this ContextVk's recorded commands.
1201 vk::ResourceUseList mResourceUseList;
1202
1203 egl::ContextPriority mContextPriority;
1204
1205 // Storage for vkUpdateDescriptorSets
1206 std::vector<VkDescriptorBufferInfo> mDescriptorBufferInfos;
1207 std::vector<VkDescriptorImageInfo> mDescriptorImageInfos;
1208 std::vector<VkWriteDescriptorSet> mWriteDescriptorSets;
1209
1210 ShareGroupVk *mShareGroupVk;
1211
1212 // This is a special "empty" placeholder buffer for use when we just need a placeholder buffer
1213 // but not the data. Examples are shader that has no uniform or doesn't use all slots in the
1214 // atomic counter buffer array, or places where there is no vertex buffer since Vulkan does not
1215 // allow binding a null vertex buffer.
1216 vk::BufferHelper mEmptyBuffer;
1217
1218 // Storage for default uniforms of ProgramVks and ProgramPipelineVks.
1219 vk::DynamicBuffer mDefaultUniformStorage;
1220
1221 // All staging buffer support is provided by a DynamicBuffer.
1222 vk::DynamicBuffer mStagingBuffer;
1223
1224 std::vector<std::string> mCommandBufferDiagnostics;
1225
1226 // Record GL API calls for debuggers
1227 std::vector<std::string> mEventLog;
1228
1229 // Viewport and scissor are handled as dynamic state.
1230 VkViewport mViewport;
1231 VkRect2D mScissor;
1232 };
1233
endRenderPassIfTransformFeedbackBuffer(const vk::BufferHelper * buffer)1234 ANGLE_INLINE angle::Result ContextVk::endRenderPassIfTransformFeedbackBuffer(
1235 const vk::BufferHelper *buffer)
1236 {
1237 if (!buffer || !mCurrentTransformFeedbackBuffers.contains(buffer))
1238 {
1239 return angle::Result::Continue;
1240 }
1241
1242 return flushCommandsAndEndRenderPass(RenderPassClosureReason::XfbWriteThenVertexIndexBuffer);
1243 }
1244
onIndexBufferChange(const vk::BufferHelper * currentIndexBuffer)1245 ANGLE_INLINE angle::Result ContextVk::onIndexBufferChange(
1246 const vk::BufferHelper *currentIndexBuffer)
1247 {
1248 mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
1249 mLastIndexBufferOffset = reinterpret_cast<const void *>(angle::DirtyPointer);
1250 return endRenderPassIfTransformFeedbackBuffer(currentIndexBuffer);
1251 }
1252
onVertexBufferChange(const vk::BufferHelper * vertexBuffer)1253 ANGLE_INLINE angle::Result ContextVk::onVertexBufferChange(const vk::BufferHelper *vertexBuffer)
1254 {
1255 mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
1256 return endRenderPassIfTransformFeedbackBuffer(vertexBuffer);
1257 }
1258
onVertexAttributeChange(size_t attribIndex,GLuint stride,GLuint divisor,angle::FormatID format,bool compressed,GLuint relativeOffset,const vk::BufferHelper * vertexBuffer)1259 ANGLE_INLINE angle::Result ContextVk::onVertexAttributeChange(size_t attribIndex,
1260 GLuint stride,
1261 GLuint divisor,
1262 angle::FormatID format,
1263 bool compressed,
1264 GLuint relativeOffset,
1265 const vk::BufferHelper *vertexBuffer)
1266 {
1267 invalidateCurrentGraphicsPipeline();
1268 // Set divisor to 1 for attribs with emulated divisor
1269 mGraphicsPipelineDesc->updateVertexInput(
1270 &mGraphicsPipelineTransition, static_cast<uint32_t>(attribIndex), stride,
1271 divisor > mRenderer->getMaxVertexAttribDivisor() ? 1 : divisor, format, compressed,
1272 relativeOffset);
1273 return onVertexBufferChange(vertexBuffer);
1274 }
1275 } // namespace rx
1276
1277 // Generate a perf warning, and insert an event marker in the command buffer.
1278 #define ANGLE_VK_PERF_WARNING(contextVk, severity, ...) \
1279 do \
1280 { \
1281 char ANGLE_MESSAGE[100]; \
1282 snprintf(ANGLE_MESSAGE, sizeof(ANGLE_MESSAGE), __VA_ARGS__); \
1283 ANGLE_PERF_WARNING(contextVk->getDebug(), severity, ANGLE_MESSAGE); \
1284 \
1285 contextVk->insertEventMarkerImpl(GL_DEBUG_SOURCE_OTHER, ANGLE_MESSAGE); \
1286 } while (0)
1287
1288 // Generate a trace event for graphics profiler, and insert an event marker in the command buffer.
1289 #define ANGLE_VK_TRACE_EVENT_AND_MARKER(contextVk, ...) \
1290 do \
1291 { \
1292 char ANGLE_MESSAGE[100]; \
1293 snprintf(ANGLE_MESSAGE, sizeof(ANGLE_MESSAGE), __VA_ARGS__); \
1294 ANGLE_TRACE_EVENT0("gpu.angle", ANGLE_MESSAGE); \
1295 \
1296 contextVk->insertEventMarkerImpl(GL_DEBUG_SOURCE_OTHER, ANGLE_MESSAGE); \
1297 } while (0)
1298
1299 #endif // LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_
1300