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 "image_util/loadimage.h"
18 #include "libANGLE/renderer/ContextImpl.h"
19 #include "libANGLE/renderer/renderer_utils.h"
20 #include "libANGLE/renderer/vulkan/DisplayVk.h"
21 #include "libANGLE/renderer/vulkan/OverlayVk.h"
22 #include "libANGLE/renderer/vulkan/PersistentCommandPool.h"
23 #include "libANGLE/renderer/vulkan/ShareGroupVk.h"
24 #include "libANGLE/renderer/vulkan/vk_helpers.h"
25 #include "libANGLE/renderer/vulkan/vk_renderer.h"
26
27 namespace angle
28 {
29 struct FeaturesVk;
30 } // namespace angle
31
32 namespace rx
33 {
34 namespace vk
35 {
36 class SyncHelper;
37 } // namespace vk
38
39 class ConversionBuffer;
40 class ProgramExecutableVk;
41 class WindowSurfaceVk;
42 class OffscreenSurfaceVk;
43 class ShareGroupVk;
44
45 static constexpr uint32_t kMaxGpuEventNameLen = 32;
46 using EventName = std::array<char, kMaxGpuEventNameLen>;
47
48 using ContextVkDescriptorSetList = angle::PackedEnumMap<PipelineType, uint32_t>;
49 using CounterPipelineTypeMap = angle::PackedEnumMap<PipelineType, uint32_t>;
50
51 enum class GraphicsEventCmdBuf
52 {
53 NotInQueryCmd = 0,
54 InOutsideCmdBufQueryCmd = 1,
55 InRenderPassCmdBufQueryCmd = 2,
56
57 InvalidEnum = 3,
58 EnumCount = 3,
59 };
60
61 // Why depth/stencil feedback loop is being updated. Based on whether it's due to a draw or clear,
62 // different GL state affect depth/stencil write.
63 enum class UpdateDepthFeedbackLoopReason
64 {
65 None,
66 Draw,
67 Clear,
68 };
69
70 static constexpr GLbitfield kBufferMemoryBarrierBits =
71 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
72 GL_COMMAND_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
73 GL_TRANSFORM_FEEDBACK_BARRIER_BIT | GL_ATOMIC_COUNTER_BARRIER_BIT |
74 GL_SHADER_STORAGE_BARRIER_BIT | GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT;
75 static constexpr GLbitfield kImageMemoryBarrierBits =
76 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
77 GL_TEXTURE_UPDATE_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT;
78
79 class ContextVk : public ContextImpl, public vk::Context, public MultisampleTextureInitializer
80 {
81 public:
82 ContextVk(const gl::State &state, gl::ErrorSet *errorSet, vk::Renderer *renderer);
83 ~ContextVk() override;
84
85 angle::Result initialize(const angle::ImageLoadContext &imageLoadContext) override;
86
87 void onDestroy(const gl::Context *context) override;
88
89 // Flush and finish.
90 angle::Result flush(const gl::Context *context) override;
91 angle::Result finish(const gl::Context *context) override;
92
93 // Drawing methods.
94 angle::Result drawArrays(const gl::Context *context,
95 gl::PrimitiveMode mode,
96 GLint first,
97 GLsizei count) override;
98 angle::Result drawArraysInstanced(const gl::Context *context,
99 gl::PrimitiveMode mode,
100 GLint first,
101 GLsizei count,
102 GLsizei instanceCount) override;
103 angle::Result drawArraysInstancedBaseInstance(const gl::Context *context,
104 gl::PrimitiveMode mode,
105 GLint first,
106 GLsizei count,
107 GLsizei instanceCount,
108 GLuint baseInstance) override;
109
110 angle::Result drawElements(const gl::Context *context,
111 gl::PrimitiveMode mode,
112 GLsizei count,
113 gl::DrawElementsType type,
114 const void *indices) override;
115 angle::Result drawElementsBaseVertex(const gl::Context *context,
116 gl::PrimitiveMode mode,
117 GLsizei count,
118 gl::DrawElementsType type,
119 const void *indices,
120 GLint baseVertex) override;
121 angle::Result drawElementsInstanced(const gl::Context *context,
122 gl::PrimitiveMode mode,
123 GLsizei count,
124 gl::DrawElementsType type,
125 const void *indices,
126 GLsizei instanceCount) override;
127 angle::Result drawElementsInstancedBaseVertex(const gl::Context *context,
128 gl::PrimitiveMode mode,
129 GLsizei count,
130 gl::DrawElementsType type,
131 const void *indices,
132 GLsizei instanceCount,
133 GLint baseVertex) override;
134 angle::Result drawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
135 gl::PrimitiveMode mode,
136 GLsizei count,
137 gl::DrawElementsType type,
138 const void *indices,
139 GLsizei instances,
140 GLint baseVertex,
141 GLuint baseInstance) override;
142 angle::Result drawRangeElements(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) override;
149 angle::Result drawRangeElementsBaseVertex(const gl::Context *context,
150 gl::PrimitiveMode mode,
151 GLuint start,
152 GLuint end,
153 GLsizei count,
154 gl::DrawElementsType type,
155 const void *indices,
156 GLint baseVertex) override;
157 angle::Result drawArraysIndirect(const gl::Context *context,
158 gl::PrimitiveMode mode,
159 const void *indirect) override;
160 angle::Result drawElementsIndirect(const gl::Context *context,
161 gl::PrimitiveMode mode,
162 gl::DrawElementsType type,
163 const void *indirect) override;
164
165 angle::Result multiDrawArrays(const gl::Context *context,
166 gl::PrimitiveMode mode,
167 const GLint *firsts,
168 const GLsizei *counts,
169 GLsizei drawcount) override;
170 angle::Result multiDrawArraysInstanced(const gl::Context *context,
171 gl::PrimitiveMode mode,
172 const GLint *firsts,
173 const GLsizei *counts,
174 const GLsizei *instanceCounts,
175 GLsizei drawcount) override;
176 angle::Result multiDrawArraysIndirect(const gl::Context *context,
177 gl::PrimitiveMode mode,
178 const void *indirect,
179 GLsizei drawcount,
180 GLsizei stride) override;
181 angle::Result multiDrawElements(const gl::Context *context,
182 gl::PrimitiveMode mode,
183 const GLsizei *counts,
184 gl::DrawElementsType type,
185 const GLvoid *const *indices,
186 GLsizei drawcount) override;
187 angle::Result multiDrawElementsInstanced(const gl::Context *context,
188 gl::PrimitiveMode mode,
189 const GLsizei *counts,
190 gl::DrawElementsType type,
191 const GLvoid *const *indices,
192 const GLsizei *instanceCounts,
193 GLsizei drawcount) override;
194 angle::Result multiDrawElementsIndirect(const gl::Context *context,
195 gl::PrimitiveMode mode,
196 gl::DrawElementsType type,
197 const void *indirect,
198 GLsizei drawcount,
199 GLsizei stride) override;
200 angle::Result multiDrawArraysInstancedBaseInstance(const gl::Context *context,
201 gl::PrimitiveMode mode,
202 const GLint *firsts,
203 const GLsizei *counts,
204 const GLsizei *instanceCounts,
205 const GLuint *baseInstances,
206 GLsizei drawcount) override;
207 angle::Result multiDrawElementsInstancedBaseVertexBaseInstance(const gl::Context *context,
208 gl::PrimitiveMode mode,
209 const GLsizei *counts,
210 gl::DrawElementsType type,
211 const GLvoid *const *indices,
212 const GLsizei *instanceCounts,
213 const GLint *baseVertices,
214 const GLuint *baseInstances,
215 GLsizei drawcount) override;
216
217 // MultiDrawIndirect helper functions
218 angle::Result multiDrawElementsIndirectHelper(const gl::Context *context,
219 gl::PrimitiveMode mode,
220 gl::DrawElementsType type,
221 const void *indirect,
222 GLsizei drawcount,
223 GLsizei stride);
224 angle::Result multiDrawArraysIndirectHelper(const gl::Context *context,
225 gl::PrimitiveMode mode,
226 const void *indirect,
227 GLsizei drawcount,
228 GLsizei stride);
229
230 // ShareGroup
getShareGroup()231 ShareGroupVk *getShareGroup() { return mShareGroupVk; }
getPipelineLayoutCache()232 PipelineLayoutCache &getPipelineLayoutCache()
233 {
234 return mShareGroupVk->getPipelineLayoutCache();
235 }
getDescriptorSetLayoutCache()236 DescriptorSetLayoutCache &getDescriptorSetLayoutCache()
237 {
238 return mShareGroupVk->getDescriptorSetLayoutCache();
239 }
getMetaDescriptorPools()240 vk::DescriptorSetArray<vk::MetaDescriptorPool> &getMetaDescriptorPools()
241 {
242 return mShareGroupVk->getMetaDescriptorPools();
243 }
244
245 // Device loss
246 gl::GraphicsResetStatus getResetStatus() override;
247
isDebugEnabled()248 bool isDebugEnabled()
249 {
250 return mRenderer->enableDebugUtils() || mRenderer->angleDebuggerMode();
251 }
252
253 // EXT_debug_marker
254 angle::Result insertEventMarker(GLsizei length, const char *marker) override;
255 angle::Result pushGroupMarker(GLsizei length, const char *marker) override;
256 angle::Result popGroupMarker() override;
257
258 void insertEventMarkerImpl(GLenum source, const char *marker);
259
260 // KHR_debug
261 angle::Result pushDebugGroup(const gl::Context *context,
262 GLenum source,
263 GLuint id,
264 const std::string &message) override;
265 angle::Result popDebugGroup(const gl::Context *context) override;
266
267 // Record GL API calls for debuggers
268 void logEvent(const char *eventString);
269 void endEventLog(angle::EntryPoint entryPoint, PipelineType pipelineType);
270 void endEventLogForClearOrQuery();
271
272 bool isViewportFlipEnabledForDrawFBO() const;
273 bool isViewportFlipEnabledForReadFBO() const;
274 // When the device/surface is rotated such that the surface's aspect ratio is different than
275 // the native device (e.g. 90 degrees), the width and height of the viewport, scissor, and
276 // render area must be swapped.
277 bool isRotatedAspectRatioForDrawFBO() const;
278 bool isRotatedAspectRatioForReadFBO() const;
279 SurfaceRotation getRotationDrawFramebuffer() const;
280 SurfaceRotation getRotationReadFramebuffer() const;
281 SurfaceRotation getSurfaceRotationImpl(const gl::Framebuffer *framebuffer,
282 const egl::Surface *surface);
283
284 // View port (x, y, w, h) will be determined by a combination of -
285 // 1. clip space origin
286 // 2. isViewportFlipEnabledForDrawFBO
287 // For userdefined FBOs it will be based on the value of isViewportFlipEnabledForDrawFBO.
288 // For default FBOs it will be XOR of ClipOrigin and isViewportFlipEnabledForDrawFBO.
289 // isYFlipEnabledForDrawFBO indicates the rendered image is upside-down.
isYFlipEnabledForDrawFBO()290 ANGLE_INLINE bool isYFlipEnabledForDrawFBO() const
291 {
292 return mState.getClipOrigin() == gl::ClipOrigin::UpperLeft
293 ? !isViewportFlipEnabledForDrawFBO()
294 : isViewportFlipEnabledForDrawFBO();
295 }
296
297 // State sync with dirty bits.
298 angle::Result syncState(const gl::Context *context,
299 const gl::state::DirtyBits dirtyBits,
300 const gl::state::DirtyBits bitMask,
301 const gl::state::ExtendedDirtyBits extendedDirtyBits,
302 const gl::state::ExtendedDirtyBits extendedBitMask,
303 gl::Command command) override;
304
305 // Disjoint timer queries
306 GLint getGPUDisjoint() override;
307 GLint64 getTimestamp() override;
308
309 // Context switching
310 angle::Result onMakeCurrent(const gl::Context *context) override;
311 angle::Result onUnMakeCurrent(const gl::Context *context) override;
312 angle::Result onSurfaceUnMakeCurrent(WindowSurfaceVk *surface);
313 angle::Result onSurfaceUnMakeCurrent(OffscreenSurfaceVk *surface);
314
315 // Native capabilities, unmodified by gl::Context.
316 gl::Caps getNativeCaps() const override;
317 const gl::TextureCapsMap &getNativeTextureCaps() const override;
318 const gl::Extensions &getNativeExtensions() const override;
319 const gl::Limitations &getNativeLimitations() const override;
320 const ShPixelLocalStorageOptions &getNativePixelLocalStorageOptions() const override;
321
322 // Shader creation
323 CompilerImpl *createCompiler() override;
324 ShaderImpl *createShader(const gl::ShaderState &state) override;
325 ProgramImpl *createProgram(const gl::ProgramState &state) override;
326 ProgramExecutableImpl *createProgramExecutable(
327 const gl::ProgramExecutable *executable) override;
328
329 // Framebuffer creation
330 FramebufferImpl *createFramebuffer(const gl::FramebufferState &state) override;
331
332 // Texture creation
333 TextureImpl *createTexture(const gl::TextureState &state) override;
334
335 // Renderbuffer creation
336 RenderbufferImpl *createRenderbuffer(const gl::RenderbufferState &state) override;
337
338 // Buffer creation
339 BufferImpl *createBuffer(const gl::BufferState &state) override;
340
341 // Vertex Array creation
342 VertexArrayImpl *createVertexArray(const gl::VertexArrayState &state) override;
343
344 // Query and Fence creation
345 QueryImpl *createQuery(gl::QueryType type) override;
346 FenceNVImpl *createFenceNV() override;
347 SyncImpl *createSync() override;
348
349 // Transform Feedback creation
350 TransformFeedbackImpl *createTransformFeedback(
351 const gl::TransformFeedbackState &state) override;
352
353 // Sampler object creation
354 SamplerImpl *createSampler(const gl::SamplerState &state) override;
355
356 // Program Pipeline object creation
357 ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override;
358
359 // Memory object creation.
360 MemoryObjectImpl *createMemoryObject() override;
361
362 // Semaphore creation.
363 SemaphoreImpl *createSemaphore() override;
364
365 // Overlay creation.
366 OverlayImpl *createOverlay(const gl::OverlayState &state) override;
367
368 angle::Result dispatchCompute(const gl::Context *context,
369 GLuint numGroupsX,
370 GLuint numGroupsY,
371 GLuint numGroupsZ) override;
372 angle::Result dispatchComputeIndirect(const gl::Context *context, GLintptr indirect) override;
373
374 angle::Result memoryBarrier(const gl::Context *context, GLbitfield barriers) override;
375 angle::Result memoryBarrierByRegion(const gl::Context *context, GLbitfield barriers) override;
376
invalidateTexture(gl::TextureType target)377 ANGLE_INLINE void invalidateTexture(gl::TextureType target) override {}
378
hasDisplayTextureShareGroup()379 bool hasDisplayTextureShareGroup() const { return mState.hasDisplayTextureShareGroup(); }
380
381 // EXT_shader_framebuffer_fetch_non_coherent
382 void framebufferFetchBarrier() override;
383
384 // KHR_blend_equation_advanced
385 void blendBarrier() override;
386
387 // GL_ANGLE_vulkan_image
388 angle::Result acquireTextures(const gl::Context *context,
389 const gl::TextureBarrierVector &textureBarriers) override;
390 angle::Result releaseTextures(const gl::Context *context,
391 gl::TextureBarrierVector *textureBarriers) override;
392
393 // Sets effective Context Priority. Changed by ShareGroupVk.
setPriority(egl::ContextPriority newPriority)394 void setPriority(egl::ContextPriority newPriority)
395 {
396 mContextPriority = newPriority;
397 mDeviceQueueIndex = mRenderer->getDeviceQueueIndex(mContextPriority);
398 }
399
400 VkDevice getDevice() const;
401 // Effective Context Priority
getPriority()402 egl::ContextPriority getPriority() const { return mContextPriority; }
getProtectionType()403 vk::ProtectionType getProtectionType() const { return mProtectionType; }
404
getFeatures()405 ANGLE_INLINE const angle::FeaturesVk &getFeatures() const { return mRenderer->getFeatures(); }
406
invalidateVertexAndIndexBuffers()407 ANGLE_INLINE void invalidateVertexAndIndexBuffers()
408 {
409 mGraphicsDirtyBits |= kIndexAndVertexDirtyBits;
410 }
411
412 angle::Result onVertexBufferChange(const vk::BufferHelper *vertexBuffer);
413
414 angle::Result onVertexAttributeChange(size_t attribIndex,
415 GLuint stride,
416 GLuint divisor,
417 angle::FormatID format,
418 bool compressed,
419 GLuint relativeOffset,
420 const vk::BufferHelper *vertexBuffer);
421
422 void invalidateDefaultAttribute(size_t attribIndex);
423 void invalidateDefaultAttributes(const gl::AttributesMask &dirtyMask);
424 angle::Result onFramebufferChange(FramebufferVk *framebufferVk, gl::Command command);
425 void onDrawFramebufferRenderPassDescChange(FramebufferVk *framebufferVk,
426 bool *renderPassDescChangedOut);
onHostVisibleBufferWrite()427 void onHostVisibleBufferWrite() { mIsAnyHostVisibleBufferWritten = true; }
428
429 void invalidateCurrentTransformFeedbackBuffers();
430 void onTransformFeedbackStateChanged();
431 angle::Result onBeginTransformFeedback(
432 size_t bufferCount,
433 const gl::TransformFeedbackBuffersArray<vk::BufferHelper *> &buffers,
434 const gl::TransformFeedbackBuffersArray<vk::BufferHelper> &counterBuffers);
435 void onEndTransformFeedback();
436 angle::Result onPauseTransformFeedback();
437 void pauseTransformFeedbackIfActiveUnpaused();
438
onColorAccessChange()439 void onColorAccessChange() { mGraphicsDirtyBits |= kColorAccessChangeDirtyBits; }
onDepthStencilAccessChange()440 void onDepthStencilAccessChange() { mGraphicsDirtyBits |= kDepthStencilAccessChangeDirtyBits; }
441
442 // When UtilsVk issues draw or dispatch calls, it binds a new pipeline and descriptor sets that
443 // the context is not aware of. These functions are called to make sure the pipeline and
444 // affected descriptor set bindings are dirtied for the next application draw/dispatch call.
445 void invalidateGraphicsPipelineBinding();
446 void invalidateComputePipelineBinding();
447 void invalidateGraphicsDescriptorSet(DescriptorSetIndex usedDescriptorSet);
448 void invalidateComputeDescriptorSet(DescriptorSetIndex usedDescriptorSet);
449 void invalidateAllDynamicState();
450 angle::Result updateRenderPassDepthFeedbackLoopMode(
451 UpdateDepthFeedbackLoopReason depthReason,
452 UpdateDepthFeedbackLoopReason stencilReason);
453
454 angle::Result optimizeRenderPassForPresent(vk::ImageViewHelper *colorImageView,
455 vk::ImageHelper *colorImage,
456 vk::ImageHelper *colorImageMS,
457 vk::PresentMode presentMode,
458 bool *imageResolved);
459
460 vk::DynamicQueryPool *getQueryPool(gl::QueryType queryType);
461
462 const VkClearValue &getClearColorValue() const;
463 const VkClearValue &getClearDepthStencilValue() const;
464 gl::BlendStateExt::ColorMaskStorage::Type getClearColorMasks() const;
getScissor()465 const VkRect2D &getScissor() const { return mScissor; }
466 angle::Result getIncompleteTexture(const gl::Context *context,
467 gl::TextureType type,
468 gl::SamplerFormat format,
469 gl::Texture **textureOut);
470 void updateColorMasks();
471 void updateBlendFuncsAndEquations();
472
473 void handleError(VkResult errorCode,
474 const char *file,
475 const char *function,
476 unsigned int line) override;
477
478 angle::Result onIndexBufferChange(const vk::BufferHelper *currentIndexBuffer);
479
480 angle::Result flushAndSubmitCommands(const vk::Semaphore *semaphore,
481 const vk::SharedExternalFence *externalFence,
482 RenderPassClosureReason renderPassClosureReason);
483
484 angle::Result finishImpl(RenderPassClosureReason renderPassClosureReason);
485
486 void addWaitSemaphore(VkSemaphore semaphore, VkPipelineStageFlags stageMask);
487
488 template <typename T>
addGarbage(T * object)489 void addGarbage(T *object)
490 {
491 if (object->valid())
492 {
493 mCurrentGarbage.emplace_back(vk::GetGarbage(object));
494 }
495 }
496
497 angle::Result getCompatibleRenderPass(const vk::RenderPassDesc &desc,
498 const vk::RenderPass **renderPassOut);
499 angle::Result getRenderPassWithOps(const vk::RenderPassDesc &desc,
500 const vk::AttachmentOpsArray &ops,
501 const vk::RenderPass **renderPassOut);
502
getShaderLibrary()503 vk::ShaderLibrary &getShaderLibrary() { return mShaderLibrary; }
getUtils()504 UtilsVk &getUtils() { return mUtils; }
505
506 angle::Result getTimestamp(uint64_t *timestampOut);
507
508 // Create Begin/End/Instant GPU trace events, which take their timestamps from GPU queries.
509 // The events are queued until the query results are available. Possible values for `phase`
510 // are TRACE_EVENT_PHASE_*
traceGpuEvent(vk::OutsideRenderPassCommandBuffer * commandBuffer,char phase,const EventName & name)511 ANGLE_INLINE angle::Result traceGpuEvent(vk::OutsideRenderPassCommandBuffer *commandBuffer,
512 char phase,
513 const EventName &name)
514 {
515 if (mGpuEventsEnabled)
516 return traceGpuEventImpl(commandBuffer, phase, name);
517 return angle::Result::Continue;
518 }
519
getDebug()520 const gl::Debug &getDebug() const { return mState.getDebug(); }
getOverlay()521 const gl::OverlayType *getOverlay() const { return mState.getOverlay(); }
522
523 angle::Result onBufferReleaseToExternal(const vk::BufferHelper &buffer);
524 angle::Result onImageReleaseToExternal(const vk::ImageHelper &image);
525
onImageRenderPassRead(VkImageAspectFlags aspectFlags,vk::ImageLayout imageLayout,vk::ImageHelper * image)526 void onImageRenderPassRead(VkImageAspectFlags aspectFlags,
527 vk::ImageLayout imageLayout,
528 vk::ImageHelper *image)
529 {
530 ASSERT(mRenderPassCommands->started());
531 mRenderPassCommands->imageRead(this, aspectFlags, imageLayout, image);
532 }
533
onImageRenderPassWrite(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,VkImageAspectFlags aspectFlags,vk::ImageLayout imageLayout,vk::ImageHelper * image)534 void onImageRenderPassWrite(gl::LevelIndex level,
535 uint32_t layerStart,
536 uint32_t layerCount,
537 VkImageAspectFlags aspectFlags,
538 vk::ImageLayout imageLayout,
539 vk::ImageHelper *image)
540 {
541 ASSERT(mRenderPassCommands->started());
542 mRenderPassCommands->imageWrite(this, level, layerStart, layerCount, aspectFlags,
543 imageLayout, image);
544 }
545
onColorDraw(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,vk::ImageHelper * image,vk::ImageHelper * resolveImage,UniqueSerial imageSiblingSerial,vk::PackedAttachmentIndex packedAttachmentIndex)546 void onColorDraw(gl::LevelIndex level,
547 uint32_t layerStart,
548 uint32_t layerCount,
549 vk::ImageHelper *image,
550 vk::ImageHelper *resolveImage,
551 UniqueSerial imageSiblingSerial,
552 vk::PackedAttachmentIndex packedAttachmentIndex)
553 {
554 ASSERT(mRenderPassCommands->started());
555 mRenderPassCommands->colorImagesDraw(level, layerStart, layerCount, image, resolveImage,
556 imageSiblingSerial, packedAttachmentIndex);
557 }
onColorResolve(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,vk::ImageHelper * image,VkImageView view,UniqueSerial imageSiblingSerial,size_t colorIndexGL)558 void onColorResolve(gl::LevelIndex level,
559 uint32_t layerStart,
560 uint32_t layerCount,
561 vk::ImageHelper *image,
562 VkImageView view,
563 UniqueSerial imageSiblingSerial,
564 size_t colorIndexGL)
565 {
566 ASSERT(mRenderPassCommands->started());
567 mRenderPassCommands->addColorResolveAttachment(colorIndexGL, image, view, level, layerStart,
568 layerCount, imageSiblingSerial);
569 }
onDepthStencilDraw(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,vk::ImageHelper * image,vk::ImageHelper * resolveImage,UniqueSerial imageSiblingSerial)570 void onDepthStencilDraw(gl::LevelIndex level,
571 uint32_t layerStart,
572 uint32_t layerCount,
573 vk::ImageHelper *image,
574 vk::ImageHelper *resolveImage,
575 UniqueSerial imageSiblingSerial)
576 {
577 ASSERT(mRenderPassCommands->started());
578 mRenderPassCommands->depthStencilImagesDraw(level, layerStart, layerCount, image,
579 resolveImage, imageSiblingSerial);
580 }
onDepthStencilResolve(gl::LevelIndex level,uint32_t layerStart,uint32_t layerCount,VkImageAspectFlags aspects,vk::ImageHelper * image,VkImageView view,UniqueSerial imageSiblingSerial)581 void onDepthStencilResolve(gl::LevelIndex level,
582 uint32_t layerStart,
583 uint32_t layerCount,
584 VkImageAspectFlags aspects,
585 vk::ImageHelper *image,
586 VkImageView view,
587 UniqueSerial imageSiblingSerial)
588 {
589 ASSERT(mRenderPassCommands->started());
590 mRenderPassCommands->addDepthStencilResolveAttachment(
591 image, view, aspects, level, layerStart, layerCount, imageSiblingSerial);
592 }
593
onFragmentShadingRateRead(vk::ImageHelper * image)594 void onFragmentShadingRateRead(vk::ImageHelper *image)
595 {
596 ASSERT(mRenderPassCommands->started());
597 mRenderPassCommands->fragmentShadingRateImageRead(image);
598 }
599
finalizeImageLayout(const vk::ImageHelper * image,UniqueSerial imageSiblingSerial)600 void finalizeImageLayout(const vk::ImageHelper *image, UniqueSerial imageSiblingSerial)
601 {
602 if (mRenderPassCommands->started())
603 {
604 mRenderPassCommands->finalizeImageLayout(this, image, imageSiblingSerial);
605 }
606 }
607
getOutsideRenderPassCommandBuffer(const vk::CommandBufferAccess & access,vk::OutsideRenderPassCommandBuffer ** commandBufferOut)608 angle::Result getOutsideRenderPassCommandBuffer(
609 const vk::CommandBufferAccess &access,
610 vk::OutsideRenderPassCommandBuffer **commandBufferOut)
611 {
612 ANGLE_TRY(onResourceAccess(access));
613 *commandBufferOut = &mOutsideRenderPassCommands->getCommandBuffer();
614 return angle::Result::Continue;
615 }
616
getOutsideRenderPassCommandBufferHelper(const vk::CommandBufferAccess & access,vk::OutsideRenderPassCommandBufferHelper ** commandBufferHelperOut)617 angle::Result getOutsideRenderPassCommandBufferHelper(
618 const vk::CommandBufferAccess &access,
619 vk::OutsideRenderPassCommandBufferHelper **commandBufferHelperOut)
620 {
621 ANGLE_TRY(onResourceAccess(access));
622 *commandBufferHelperOut = mOutsideRenderPassCommands;
623 return angle::Result::Continue;
624 }
625
trackImageWithOutsideRenderPassEvent(vk::ImageHelper * image)626 void trackImageWithOutsideRenderPassEvent(vk::ImageHelper *image)
627 {
628 if (mRenderer->getFeatures().useVkEventForImageBarrier.enabled)
629 {
630 mOutsideRenderPassCommands->trackImageWithEvent(this, image);
631 }
632 }
submitStagedTextureUpdates()633 angle::Result submitStagedTextureUpdates()
634 {
635 // Staged updates are recorded in outside RP cammand buffer, submit them.
636 return flushOutsideRenderPassCommands();
637 }
638
onEGLImageQueueChange()639 angle::Result onEGLImageQueueChange()
640 {
641 // Flush the barrier inserted to change the queue and layout of an EGL image. Another
642 // thread may start using this image without issuing a sync object.
643 return flushOutsideRenderPassCommands();
644 }
645
646 angle::Result beginNewRenderPass(vk::RenderPassFramebuffer &&framebuffer,
647 const gl::Rectangle &renderArea,
648 const vk::RenderPassDesc &renderPassDesc,
649 const vk::AttachmentOpsArray &renderPassAttachmentOps,
650 const vk::PackedAttachmentCount colorAttachmentCount,
651 const vk::PackedAttachmentIndex depthStencilAttachmentIndex,
652 const vk::PackedClearValuesArray &clearValues,
653 vk::RenderPassCommandBuffer **commandBufferOut);
654
disableRenderPassReactivation()655 void disableRenderPassReactivation() { mAllowRenderPassToReactivate = false; }
656
657 // Only returns true if we have a started RP and we've run setupDraw.
hasActiveRenderPass()658 bool hasActiveRenderPass() const
659 {
660 // If mRenderPassCommandBuffer is not null, mRenderPassCommands must already started, we
661 // call this active render pass. A started render pass will have null
662 // mRenderPassCommandBuffer after onRenderPassFinished call, we call this state started but
663 // inactive.
664 ASSERT(mRenderPassCommandBuffer == nullptr || mRenderPassCommands->started());
665 // Checking mRenderPassCommandBuffer ensures we've called setupDraw.
666 return mRenderPassCommandBuffer != nullptr;
667 }
668
hasStartedRenderPassWithQueueSerial(const QueueSerial & queueSerial)669 bool hasStartedRenderPassWithQueueSerial(const QueueSerial &queueSerial) const
670 {
671 return mRenderPassCommands->started() &&
672 mRenderPassCommands->getQueueSerial() == queueSerial;
673 }
hasStartedRenderPassWithDefaultFramebuffer()674 bool hasStartedRenderPassWithDefaultFramebuffer() const
675 {
676 // WindowSurfaceVk caches its own framebuffers and guarantees that render passes are not
677 // kept open between frames (including when a swapchain is recreated and framebuffer handles
678 // change). It is therefore safe to verify an open render pass just by checking if it
679 // originated from the default framebuffer.
680 return mRenderPassCommands->started() && mRenderPassCommands->isDefault();
681 }
682
isRenderPassStartedAndUsesBuffer(const vk::BufferHelper & buffer)683 bool isRenderPassStartedAndUsesBuffer(const vk::BufferHelper &buffer) const
684 {
685 return mRenderPassCommands->started() && mRenderPassCommands->usesBuffer(buffer);
686 }
687
isRenderPassStartedAndUsesBufferForWrite(const vk::BufferHelper & buffer)688 bool isRenderPassStartedAndUsesBufferForWrite(const vk::BufferHelper &buffer) const
689 {
690 return mRenderPassCommands->started() && mRenderPassCommands->usesBufferForWrite(buffer);
691 }
692
isRenderPassStartedAndUsesImage(const vk::ImageHelper & image)693 bool isRenderPassStartedAndUsesImage(const vk::ImageHelper &image) const
694 {
695 return mRenderPassCommands->started() && mRenderPassCommands->usesImage(image);
696 }
697
getStartedRenderPassCommands()698 vk::RenderPassCommandBufferHelper &getStartedRenderPassCommands()
699 {
700 ASSERT(mRenderPassCommands->started());
701 return *mRenderPassCommands;
702 }
703
704 uint32_t getCurrentSubpassIndex() const;
705 uint32_t getCurrentViewCount() const;
706
707 // Initial Context Priority. Used for EGL_CONTEXT_PRIORITY_LEVEL_IMG attribute.
getContextPriority()708 egl::ContextPriority getContextPriority() const override { return mInitialContextPriority; }
709 angle::Result startRenderPass(gl::Rectangle renderArea,
710 vk::RenderPassCommandBuffer **commandBufferOut,
711 bool *renderPassDescChangedOut);
712 angle::Result startNextSubpass();
713 angle::Result flushCommandsAndEndRenderPass(RenderPassClosureReason reason);
714 angle::Result flushCommandsAndEndRenderPassWithoutSubmit(RenderPassClosureReason reason);
715 angle::Result flushAndSubmitOutsideRenderPassCommands();
716
717 angle::Result syncExternalMemory();
718
719 // Either issue a submission or defer it when a sync object is initialized. If deferred, a
720 // submission will have to be incurred during client wait.
721 angle::Result onSyncObjectInit(vk::SyncHelper *syncHelper, SyncFenceScope scope);
722 // Called when a sync object is waited on while its submission was deffered in onSyncObjectInit.
723 // It's a no-op if this context doesn't have a pending submission. Note that due to
724 // mHasDeferredFlush being set, flushing the render pass leads to a submission automatically.
725 angle::Result flushCommandsAndEndRenderPassIfDeferredSyncInit(RenderPassClosureReason reason);
726
727 void addCommandBufferDiagnostics(const std::string &commandBufferDiagnostics);
728
729 VkIndexType getVkIndexType(gl::DrawElementsType glIndexType) const;
730 size_t getVkIndexTypeSize(gl::DrawElementsType glIndexType) const;
731 bool shouldConvertUint8VkIndexType(gl::DrawElementsType glIndexType) const;
732
733 bool isRobustResourceInitEnabled() const;
hasRobustAccess()734 bool hasRobustAccess() const { return mState.hasRobustAccess(); }
735
736 // Queries that begin and end automatically with render pass start and end
737 angle::Result beginRenderPassQuery(QueryVk *queryVk);
738 angle::Result endRenderPassQuery(QueryVk *queryVk);
739 void pauseRenderPassQueriesIfActive();
740 angle::Result resumeRenderPassQueriesIfActive();
741 angle::Result resumeXfbRenderPassQueriesIfActive();
742 bool doesPrimitivesGeneratedQuerySupportRasterizerDiscard() const;
743 bool isEmulatingRasterizerDiscardDuringPrimitivesGeneratedQuery(
744 bool isPrimitivesGeneratedQueryActive) const;
745
746 // Used by QueryVk to share query helpers between transform feedback queries.
747 QueryVk *getActiveRenderPassQuery(gl::QueryType queryType) const;
748
749 void syncObjectPerfCounters(const angle::VulkanPerfCounters &commandQueuePerfCounters);
750 void updateOverlayOnPresent();
751 void addOverlayUsedBuffersCount(vk::CommandBufferHelperCommon *commandBuffer);
752
753 // For testing only.
754 void setDefaultUniformBlocksMinSizeForTesting(size_t minSize);
755
getEmptyBuffer()756 vk::BufferHelper &getEmptyBuffer() { return mEmptyBuffer; }
757
758 // Keeping track of the buffer copy size. Used to determine when to submit the outside command
759 // buffer.
760 angle::Result onCopyUpdate(VkDeviceSize size, bool *commandBufferWasFlushedOut);
761
762 // Implementation of MultisampleTextureInitializer
763 angle::Result initializeMultisampleTextureToBlack(const gl::Context *context,
764 gl::Texture *glTexture) override;
765
766 // TODO(http://anglebug.com/42264159): rework updateActiveTextures(), createPipelineLayout(),
767 // handleDirtyGraphicsPipeline(), and ProgramPipelineVk::link().
resetCurrentGraphicsPipeline()768 void resetCurrentGraphicsPipeline()
769 {
770 mCurrentGraphicsPipeline = nullptr;
771 mCurrentGraphicsPipelineShaders = nullptr;
772 }
773
774 void onProgramExecutableReset(ProgramExecutableVk *executableVk);
775
776 angle::Result handleGraphicsEventLog(GraphicsEventCmdBuf queryEventType);
777
778 void flushDescriptorSetUpdates();
779
getDefaultBufferPool(VkDeviceSize size,uint32_t memoryTypeIndex,BufferUsageType usageType)780 vk::BufferPool *getDefaultBufferPool(VkDeviceSize size,
781 uint32_t memoryTypeIndex,
782 BufferUsageType usageType)
783 {
784 return mShareGroupVk->getDefaultBufferPool(size, memoryTypeIndex, usageType);
785 }
786
allocateStreamedVertexBuffer(size_t attribIndex,size_t bytesToAllocate,vk::BufferHelper ** vertexBufferOut)787 angle::Result allocateStreamedVertexBuffer(size_t attribIndex,
788 size_t bytesToAllocate,
789 vk::BufferHelper **vertexBufferOut)
790 {
791 bool newBufferOut;
792 ANGLE_TRY(mStreamedVertexBuffers[attribIndex].allocate(this, bytesToAllocate,
793 vertexBufferOut, &newBufferOut));
794 if (newBufferOut)
795 {
796 mHasInFlightStreamedVertexBuffers.set(attribIndex);
797 }
798 return angle::Result::Continue;
799 }
800
801 // Put the context in framebuffer fetch mode. If the permanentlySwitchToFramebufferFetchMode
802 // feature is enabled, this is done on first encounter of framebuffer fetch, and makes the
803 // context use framebuffer-fetch-enabled render passes from here on.
804 angle::Result switchToColorFramebufferFetchMode(bool hasColorFramebufferFetch);
isInColorFramebufferFetchMode()805 bool isInColorFramebufferFetchMode() const
806 {
807 ASSERT(!getFeatures().preferDynamicRendering.enabled);
808 return mIsInColorFramebufferFetchMode;
809 }
810
811 const angle::PerfMonitorCounterGroups &getPerfMonitorCounters() override;
812
813 void resetPerFramePerfCounters();
814
815 // Accumulate cache stats for a specific cache
accumulateCacheStats(VulkanCacheType cache,const CacheStats & stats)816 void accumulateCacheStats(VulkanCacheType cache, const CacheStats &stats)
817 {
818 mVulkanCacheStats[cache].accumulate(stats);
819 }
820
821 // Whether VK_EXT_pipeline_robustness should be used to enable robust buffer access in the
822 // pipeline.
pipelineRobustness()823 vk::PipelineRobustness pipelineRobustness() const
824 {
825 return getFeatures().supportsPipelineRobustness.enabled && mState.hasRobustAccess()
826 ? vk::PipelineRobustness::Robust
827 : vk::PipelineRobustness::NonRobust;
828 }
829 // Whether VK_EXT_pipeline_protected_access should be used to restrict the pipeline to protected
830 // command buffers. Note that when false, if the extension is supported, the pipeline can be
831 // restricted to unprotected command buffers.
pipelineProtectedAccess()832 vk::PipelineProtectedAccess pipelineProtectedAccess() const
833 {
834 return getFeatures().supportsPipelineProtectedAccess.enabled && mState.hasProtectedContent()
835 ? vk::PipelineProtectedAccess::Protected
836 : vk::PipelineProtectedAccess::Unprotected;
837 }
838
getImageLoadContext()839 const angle::ImageLoadContext &getImageLoadContext() const { return mImageLoadContext; }
840
841 bool hasUnsubmittedUse(const vk::ResourceUse &use) const;
hasUnsubmittedUse(const vk::Resource & resource)842 bool hasUnsubmittedUse(const vk::Resource &resource) const
843 {
844 return hasUnsubmittedUse(resource.getResourceUse());
845 }
hasUnsubmittedUse(const vk::ReadWriteResource & resource)846 bool hasUnsubmittedUse(const vk::ReadWriteResource &resource) const
847 {
848 return hasUnsubmittedUse(resource.getResourceUse());
849 }
850
getLastSubmittedQueueSerial()851 const QueueSerial &getLastSubmittedQueueSerial() const { return mLastSubmittedQueueSerial; }
getSubmittedResourceUse()852 const vk::ResourceUse &getSubmittedResourceUse() const { return mSubmittedResourceUse; }
853
854 // Uploading mutable mipmap textures is currently restricted to single-context applications.
isEligibleForMutableTextureFlush()855 bool isEligibleForMutableTextureFlush() const
856 {
857 return getFeatures().mutableMipmapTextureUpload.enabled && !hasDisplayTextureShareGroup() &&
858 mShareGroupVk->getContexts().size() == 1;
859 }
860
getDepthStencilAttachmentFlags()861 vk::RenderPassUsageFlags getDepthStencilAttachmentFlags() const
862 {
863 return mDepthStencilAttachmentFlags;
864 }
865
isDitherEnabled()866 bool isDitherEnabled() { return mState.isDitherEnabled(); }
867
868 // The following functions try to allocate memory for buffers and images. If they fail due to
869 // OOM errors, they will try other options for memory allocation.
870 angle::Result initBufferAllocation(vk::BufferHelper *bufferHelper,
871 uint32_t memoryTypeIndex,
872 size_t allocationSize,
873 size_t alignment,
874 BufferUsageType bufferUsageType);
875 angle::Result initImageAllocation(vk::ImageHelper *imageHelper,
876 bool hasProtectedContent,
877 const vk::MemoryProperties &memoryProperties,
878 VkMemoryPropertyFlags flags,
879 vk::MemoryAllocationType allocationType);
880
881 angle::Result releaseBufferAllocation(vk::BufferHelper *bufferHelper);
882
883 // Helper functions to initialize a buffer for a specific usage
884 // Suballocate a host visible buffer with alignment good for copyBuffer.
885 angle::Result initBufferForBufferCopy(vk::BufferHelper *bufferHelper,
886 size_t size,
887 vk::MemoryCoherency coherency);
888 // Suballocate a host visible buffer with alignment good for copyImage.
889 angle::Result initBufferForImageCopy(vk::BufferHelper *bufferHelper,
890 size_t size,
891 vk::MemoryCoherency coherency,
892 angle::FormatID formatId,
893 VkDeviceSize *offset,
894 uint8_t **dataPtr);
895 // Suballocate a buffer with alignment good for shader storage or copyBuffer.
896 angle::Result initBufferForVertexConversion(ConversionBuffer *conversionBuffer,
897 size_t size,
898 vk::MemoryHostVisibility hostVisibility);
899
900 // In the event of collecting too much garbage, we should flush the garbage so it can be freed.
901 void addToPendingImageGarbage(vk::ResourceUse use, VkDeviceSize size);
902
903 bool hasExcessPendingGarbage() const;
904
905 angle::Result onFramebufferBoundary(const gl::Context *contextGL);
906
getCurrentFrameCount()907 uint32_t getCurrentFrameCount() const { return mShareGroupVk->getCurrentFrameCount(); }
908
909 private:
910 // Dirty bits.
911 enum DirtyBitType : size_t
912 {
913 // Dirty bits that must be processed before the render pass is started. The handlers for
914 // these dirty bits don't record any commands.
915
916 // the AnySamplePassed render pass query has been ended.
917 DIRTY_BIT_ANY_SAMPLE_PASSED_QUERY_END,
918 // A glMemoryBarrier has been called and command buffers may need flushing.
919 DIRTY_BIT_MEMORY_BARRIER,
920 // Update default attribute buffers.
921 DIRTY_BIT_DEFAULT_ATTRIBS,
922 // The pipeline has changed and needs to be recreated. This dirty bit may close the render
923 // pass.
924 DIRTY_BIT_PIPELINE_DESC,
925 // Support for depth/stencil read-only feedback loop. When depth/stencil access changes,
926 // the render pass may need closing.
927 DIRTY_BIT_READ_ONLY_DEPTH_FEEDBACK_LOOP_MODE,
928
929 // Start the render pass.
930 DIRTY_BIT_RENDER_PASS,
931
932 // Dirty bits that must be processed after the render pass is started. Their handlers
933 // record commands.
934 DIRTY_BIT_EVENT_LOG,
935 // Update color and depth/stencil accesses in the render pass.
936 DIRTY_BIT_COLOR_ACCESS,
937 DIRTY_BIT_DEPTH_STENCIL_ACCESS,
938 // Pipeline needs to rebind because a new command buffer has been allocated, or UtilsVk has
939 // changed the binding. The pipeline itself doesn't need to be recreated.
940 DIRTY_BIT_PIPELINE_BINDING,
941 DIRTY_BIT_TEXTURES,
942 DIRTY_BIT_VERTEX_BUFFERS,
943 DIRTY_BIT_INDEX_BUFFER,
944 DIRTY_BIT_UNIFORMS,
945 DIRTY_BIT_DRIVER_UNIFORMS,
946 // Shader resources excluding textures, which are handled separately.
947 DIRTY_BIT_SHADER_RESOURCES,
948 DIRTY_BIT_UNIFORM_BUFFERS,
949 DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS,
950 DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME,
951 DIRTY_BIT_DESCRIPTOR_SETS,
952 DIRTY_BIT_FRAMEBUFFER_FETCH_BARRIER,
953 DIRTY_BIT_BLEND_BARRIER,
954
955 // Dynamic state
956 // - In core Vulkan 1.0
957 DIRTY_BIT_DYNAMIC_VIEWPORT,
958 DIRTY_BIT_DYNAMIC_SCISSOR,
959 DIRTY_BIT_DYNAMIC_LINE_WIDTH,
960 DIRTY_BIT_DYNAMIC_DEPTH_BIAS,
961 DIRTY_BIT_DYNAMIC_BLEND_CONSTANTS,
962 DIRTY_BIT_DYNAMIC_STENCIL_COMPARE_MASK,
963 DIRTY_BIT_DYNAMIC_STENCIL_WRITE_MASK,
964 DIRTY_BIT_DYNAMIC_STENCIL_REFERENCE,
965 // - In VK_EXT_extended_dynamic_state
966 DIRTY_BIT_DYNAMIC_CULL_MODE,
967 DIRTY_BIT_DYNAMIC_FRONT_FACE,
968 DIRTY_BIT_DYNAMIC_DEPTH_TEST_ENABLE,
969 DIRTY_BIT_DYNAMIC_DEPTH_WRITE_ENABLE,
970 DIRTY_BIT_DYNAMIC_DEPTH_COMPARE_OP,
971 DIRTY_BIT_DYNAMIC_STENCIL_TEST_ENABLE,
972 DIRTY_BIT_DYNAMIC_STENCIL_OP,
973 // - In VK_EXT_extended_dynamic_state2
974 DIRTY_BIT_DYNAMIC_RASTERIZER_DISCARD_ENABLE,
975 DIRTY_BIT_DYNAMIC_DEPTH_BIAS_ENABLE,
976 DIRTY_BIT_DYNAMIC_LOGIC_OP,
977 DIRTY_BIT_DYNAMIC_PRIMITIVE_RESTART_ENABLE,
978 // - In VK_KHR_fragment_shading_rate
979 DIRTY_BIT_DYNAMIC_FRAGMENT_SHADING_RATE,
980
981 DIRTY_BIT_MAX,
982 };
983
984 // Dirty bit handlers that can break the render pass must always be specified before
985 // DIRTY_BIT_RENDER_PASS.
986 static_assert(
987 DIRTY_BIT_ANY_SAMPLE_PASSED_QUERY_END < DIRTY_BIT_RENDER_PASS,
988 "Render pass breaking dirty bit must be handled before the render pass dirty bit");
989 static_assert(
990 DIRTY_BIT_MEMORY_BARRIER < DIRTY_BIT_RENDER_PASS,
991 "Render pass breaking dirty bit must be handled before the render pass dirty bit");
992 static_assert(
993 DIRTY_BIT_DEFAULT_ATTRIBS < DIRTY_BIT_RENDER_PASS,
994 "Render pass breaking dirty bit must be handled before the render pass dirty bit");
995 static_assert(
996 DIRTY_BIT_PIPELINE_DESC < DIRTY_BIT_RENDER_PASS,
997 "Render pass breaking dirty bit must be handled before the render pass dirty bit");
998 static_assert(
999 DIRTY_BIT_READ_ONLY_DEPTH_FEEDBACK_LOOP_MODE < DIRTY_BIT_RENDER_PASS,
1000 "Render pass breaking dirty bit must be handled before the render pass dirty bit");
1001
1002 // Dirty bit handlers that record commands or otherwise expect to manipulate the render pass
1003 // that will be used for the draw call must be specified after DIRTY_BIT_RENDER_PASS.
1004 static_assert(DIRTY_BIT_EVENT_LOG > DIRTY_BIT_RENDER_PASS,
1005 "Render pass using dirty bit must be handled after the render pass dirty bit");
1006 static_assert(DIRTY_BIT_COLOR_ACCESS > DIRTY_BIT_RENDER_PASS,
1007 "Render pass using dirty bit must be handled after the render pass dirty bit");
1008 static_assert(DIRTY_BIT_DEPTH_STENCIL_ACCESS > DIRTY_BIT_RENDER_PASS,
1009 "Render pass using dirty bit must be handled after the render pass dirty bit");
1010 static_assert(DIRTY_BIT_PIPELINE_BINDING > DIRTY_BIT_RENDER_PASS,
1011 "Render pass using dirty bit must be handled after the render pass dirty bit");
1012 static_assert(DIRTY_BIT_TEXTURES > DIRTY_BIT_RENDER_PASS,
1013 "Render pass using dirty bit must be handled after the render pass dirty bit");
1014 static_assert(DIRTY_BIT_VERTEX_BUFFERS > DIRTY_BIT_RENDER_PASS,
1015 "Render pass using dirty bit must be handled after the render pass dirty bit");
1016 static_assert(DIRTY_BIT_INDEX_BUFFER > DIRTY_BIT_RENDER_PASS,
1017 "Render pass using dirty bit must be handled after the render pass dirty bit");
1018 static_assert(DIRTY_BIT_DRIVER_UNIFORMS > DIRTY_BIT_RENDER_PASS,
1019 "Render pass using dirty bit must be handled after the render pass dirty bit");
1020 static_assert(DIRTY_BIT_SHADER_RESOURCES > DIRTY_BIT_RENDER_PASS,
1021 "Render pass using dirty bit must be handled after the render pass dirty bit");
1022 static_assert(
1023 DIRTY_BIT_UNIFORM_BUFFERS > DIRTY_BIT_SHADER_RESOURCES,
1024 "Uniform buffer using dirty bit must be handled after the shader resource dirty bit");
1025 static_assert(DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS > DIRTY_BIT_RENDER_PASS,
1026 "Render pass using dirty bit must be handled after the render pass dirty bit");
1027 static_assert(DIRTY_BIT_TRANSFORM_FEEDBACK_RESUME > DIRTY_BIT_RENDER_PASS,
1028 "Render pass using dirty bit must be handled after the render pass dirty bit");
1029 static_assert(DIRTY_BIT_DESCRIPTOR_SETS > DIRTY_BIT_RENDER_PASS,
1030 "Render pass using dirty bit must be handled after the render pass dirty bit");
1031 static_assert(DIRTY_BIT_UNIFORMS > DIRTY_BIT_RENDER_PASS,
1032 "Render pass using dirty bit must be handled after the render pass dirty bit");
1033 static_assert(DIRTY_BIT_FRAMEBUFFER_FETCH_BARRIER > DIRTY_BIT_RENDER_PASS,
1034 "Render pass using dirty bit must be handled after the render pass dirty bit");
1035 static_assert(DIRTY_BIT_BLEND_BARRIER > DIRTY_BIT_RENDER_PASS,
1036 "Render pass using dirty bit must be handled after the render pass dirty bit");
1037 static_assert(DIRTY_BIT_DYNAMIC_VIEWPORT > DIRTY_BIT_RENDER_PASS,
1038 "Render pass using dirty bit must be handled after the render pass dirty bit");
1039 static_assert(DIRTY_BIT_DYNAMIC_SCISSOR > DIRTY_BIT_RENDER_PASS,
1040 "Render pass using dirty bit must be handled after the render pass dirty bit");
1041 static_assert(DIRTY_BIT_DYNAMIC_LINE_WIDTH > DIRTY_BIT_RENDER_PASS,
1042 "Render pass using dirty bit must be handled after the render pass dirty bit");
1043 static_assert(DIRTY_BIT_DYNAMIC_DEPTH_BIAS > DIRTY_BIT_RENDER_PASS,
1044 "Render pass using dirty bit must be handled after the render pass dirty bit");
1045 static_assert(DIRTY_BIT_DYNAMIC_BLEND_CONSTANTS > DIRTY_BIT_RENDER_PASS,
1046 "Render pass using dirty bit must be handled after the render pass dirty bit");
1047 static_assert(DIRTY_BIT_DYNAMIC_STENCIL_COMPARE_MASK > DIRTY_BIT_RENDER_PASS,
1048 "Render pass using dirty bit must be handled after the render pass dirty bit");
1049 static_assert(DIRTY_BIT_DYNAMIC_STENCIL_WRITE_MASK > DIRTY_BIT_RENDER_PASS,
1050 "Render pass using dirty bit must be handled after the render pass dirty bit");
1051 static_assert(DIRTY_BIT_DYNAMIC_STENCIL_REFERENCE > DIRTY_BIT_RENDER_PASS,
1052 "Render pass using dirty bit must be handled after the render pass dirty bit");
1053 static_assert(DIRTY_BIT_DYNAMIC_CULL_MODE > DIRTY_BIT_RENDER_PASS,
1054 "Render pass using dirty bit must be handled after the render pass dirty bit");
1055 static_assert(DIRTY_BIT_DYNAMIC_FRONT_FACE > DIRTY_BIT_RENDER_PASS,
1056 "Render pass using dirty bit must be handled after the render pass dirty bit");
1057 static_assert(DIRTY_BIT_DYNAMIC_DEPTH_TEST_ENABLE > DIRTY_BIT_RENDER_PASS,
1058 "Render pass using dirty bit must be handled after the render pass dirty bit");
1059 static_assert(DIRTY_BIT_DYNAMIC_DEPTH_WRITE_ENABLE > DIRTY_BIT_RENDER_PASS,
1060 "Render pass using dirty bit must be handled after the render pass dirty bit");
1061 static_assert(DIRTY_BIT_DYNAMIC_DEPTH_COMPARE_OP > DIRTY_BIT_RENDER_PASS,
1062 "Render pass using dirty bit must be handled after the render pass dirty bit");
1063 static_assert(DIRTY_BIT_DYNAMIC_STENCIL_TEST_ENABLE > DIRTY_BIT_RENDER_PASS,
1064 "Render pass using dirty bit must be handled after the render pass dirty bit");
1065 static_assert(DIRTY_BIT_DYNAMIC_STENCIL_OP > DIRTY_BIT_RENDER_PASS,
1066 "Render pass using dirty bit must be handled after the render pass dirty bit");
1067 static_assert(DIRTY_BIT_DYNAMIC_RASTERIZER_DISCARD_ENABLE > DIRTY_BIT_RENDER_PASS,
1068 "Render pass using dirty bit must be handled after the render pass dirty bit");
1069 static_assert(DIRTY_BIT_DYNAMIC_DEPTH_BIAS_ENABLE > DIRTY_BIT_RENDER_PASS,
1070 "Render pass using dirty bit must be handled after the render pass dirty bit");
1071 static_assert(DIRTY_BIT_DYNAMIC_LOGIC_OP > DIRTY_BIT_RENDER_PASS,
1072 "Render pass using dirty bit must be handled after the render pass dirty bit");
1073 static_assert(DIRTY_BIT_DYNAMIC_PRIMITIVE_RESTART_ENABLE > DIRTY_BIT_RENDER_PASS,
1074 "Render pass using dirty bit must be handled after the render pass dirty bit");
1075 static_assert(DIRTY_BIT_DYNAMIC_FRAGMENT_SHADING_RATE > DIRTY_BIT_RENDER_PASS,
1076 "Render pass using dirty bit must be handled after the render pass dirty bit");
1077
1078 using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
1079
1080 using GraphicsDirtyBitHandler = angle::Result (
1081 ContextVk::*)(DirtyBits::Iterator *dirtyBitsIterator, DirtyBits dirtyBitMask);
1082 using ComputeDirtyBitHandler =
1083 angle::Result (ContextVk::*)(DirtyBits::Iterator *dirtyBitsIterator);
1084
1085 // The GpuEventQuery struct holds together a timestamp query and enough data to create a
1086 // trace event based on that. Use traceGpuEvent to insert such queries. They will be readback
1087 // when the results are available, without inserting a GPU bubble.
1088 //
1089 // - eventName will be the reported name of the event
1090 // - phase is either 'B' (duration begin), 'E' (duration end) or 'i' (instant // event).
1091 // See Google's "Trace Event Format":
1092 // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU
1093 // - serial is the serial of the batch the query was submitted on. Until the batch is
1094 // submitted, the query is not checked to avoid incuring a flush.
1095 struct GpuEventQuery final
1096 {
1097 EventName name;
1098 char phase;
1099 vk::QueryHelper queryHelper;
1100 };
1101
1102 // Once a query result is available, the timestamp is read and a GpuEvent object is kept until
1103 // the next clock sync, at which point the clock drift is compensated in the results before
1104 // handing them off to the application.
1105 struct GpuEvent final
1106 {
1107 uint64_t gpuTimestampCycles;
1108 std::array<char, kMaxGpuEventNameLen> name;
1109 char phase;
1110 };
1111
1112 struct GpuClockSyncInfo
1113 {
1114 double gpuTimestampS;
1115 double cpuTimestampS;
1116 };
1117
1118 class ScopedDescriptorSetUpdates;
1119
1120 bool isSingleBufferedWindowCurrent() const;
1121 bool hasSomethingToFlush() const;
1122
1123 angle::Result setupDraw(const gl::Context *context,
1124 gl::PrimitiveMode mode,
1125 GLint firstVertexOrInvalid,
1126 GLsizei vertexOrIndexCount,
1127 GLsizei instanceCount,
1128 gl::DrawElementsType indexTypeOrInvalid,
1129 const void *indices,
1130 DirtyBits dirtyBitMask);
1131
1132 angle::Result setupIndexedDraw(const gl::Context *context,
1133 gl::PrimitiveMode mode,
1134 GLsizei indexCount,
1135 GLsizei instanceCount,
1136 gl::DrawElementsType indexType,
1137 const void *indices);
1138 angle::Result setupIndirectDraw(const gl::Context *context,
1139 gl::PrimitiveMode mode,
1140 DirtyBits dirtyBitMask,
1141 vk::BufferHelper *indirectBuffer);
1142 angle::Result setupIndexedIndirectDraw(const gl::Context *context,
1143 gl::PrimitiveMode mode,
1144 gl::DrawElementsType indexType,
1145 vk::BufferHelper *indirectBuffer);
1146
1147 angle::Result setupLineLoopIndexedIndirectDraw(const gl::Context *context,
1148 gl::PrimitiveMode mode,
1149 gl::DrawElementsType indexType,
1150 vk::BufferHelper *srcIndexBuffer,
1151 vk::BufferHelper *srcIndirectBuffer,
1152 VkDeviceSize indirectBufferOffset,
1153 vk::BufferHelper **indirectBufferOut);
1154 angle::Result setupLineLoopIndirectDraw(const gl::Context *context,
1155 gl::PrimitiveMode mode,
1156 vk::BufferHelper *indirectBuffer,
1157 VkDeviceSize indirectBufferOffset,
1158 vk::BufferHelper **indirectBufferOut);
1159
1160 angle::Result setupLineLoopDraw(const gl::Context *context,
1161 gl::PrimitiveMode mode,
1162 GLint firstVertex,
1163 GLsizei vertexOrIndexCount,
1164 gl::DrawElementsType indexTypeOrInvalid,
1165 const void *indices,
1166 uint32_t *numIndicesOut);
1167
1168 angle::Result setupDispatch(const gl::Context *context);
1169
1170 gl::Rectangle getCorrectedViewport(const gl::Rectangle &viewport) const;
1171 void updateViewport(FramebufferVk *framebufferVk,
1172 const gl::Rectangle &viewport,
1173 float nearPlane,
1174 float farPlane);
1175 void updateFrontFace();
1176 void updateDepthRange(float nearPlane, float farPlane);
1177 void updateMissingOutputsMask();
1178 void updateSampleMaskWithRasterizationSamples(const uint32_t rasterizationSamples);
1179 void updateAlphaToCoverageWithRasterizationSamples(const uint32_t rasterizationSamples);
1180 void updateFrameBufferFetchSamples(const uint32_t prevSamples, const uint32_t curSamples);
1181 void updateFlipViewportDrawFramebuffer(const gl::State &glState);
1182 void updateFlipViewportReadFramebuffer(const gl::State &glState);
1183 void updateSurfaceRotationDrawFramebuffer(const gl::State &glState,
1184 const egl::Surface *currentDrawSurface);
1185 void updateSurfaceRotationReadFramebuffer(const gl::State &glState,
1186 const egl::Surface *currentReadSurface);
1187
1188 angle::Result updateActiveTextures(const gl::Context *context, gl::Command command);
1189 template <typename CommandBufferHelperT>
1190 angle::Result updateActiveImages(CommandBufferHelperT *commandBufferHelper);
1191
invalidateCurrentGraphicsPipeline()1192 ANGLE_INLINE void invalidateCurrentGraphicsPipeline()
1193 {
1194 // Note: DIRTY_BIT_PIPELINE_BINDING will be automatically set if pipeline bind is necessary.
1195 mGraphicsDirtyBits.set(DIRTY_BIT_PIPELINE_DESC);
1196 }
1197
invalidateCurrentComputePipeline()1198 ANGLE_INLINE void invalidateCurrentComputePipeline()
1199 {
1200 mComputeDirtyBits |= kPipelineDescAndBindingDirtyBits;
1201 mCurrentComputePipeline = nullptr;
1202 }
1203
1204 angle::Result invalidateProgramExecutableHelper(const gl::Context *context);
1205
1206 void invalidateCurrentDefaultUniforms();
1207 angle::Result invalidateCurrentTextures(const gl::Context *context, gl::Command command);
1208 angle::Result invalidateCurrentShaderResources(gl::Command command);
1209 angle::Result invalidateCurrentShaderUniformBuffers(gl::Command command);
1210 void invalidateGraphicsDriverUniforms();
1211 void invalidateDriverUniforms();
1212
1213 angle::Result handleNoopDrawEvent() override;
1214
1215 // Handlers for graphics pipeline dirty bits.
1216 angle::Result handleDirtyGraphicsMemoryBarrier(DirtyBits::Iterator *dirtyBitsIterator,
1217 DirtyBits dirtyBitMask);
1218 angle::Result handleDirtyGraphicsDefaultAttribs(DirtyBits::Iterator *dirtyBitsIterator,
1219 DirtyBits dirtyBitMask);
1220 angle::Result handleDirtyGraphicsPipelineDesc(DirtyBits::Iterator *dirtyBitsIterator,
1221 DirtyBits dirtyBitMask);
1222 angle::Result handleDirtyGraphicsReadOnlyDepthFeedbackLoopMode(
1223 DirtyBits::Iterator *dirtyBitsIterator,
1224 DirtyBits dirtyBitMask);
1225 angle::Result handleDirtyAnySamplePassedQueryEnd(DirtyBits::Iterator *dirtyBitsIterator,
1226 DirtyBits dirtyBitMask);
1227 angle::Result handleDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator,
1228 DirtyBits dirtyBitMask);
1229 angle::Result handleDirtyGraphicsEventLog(DirtyBits::Iterator *dirtyBitsIterator,
1230 DirtyBits dirtyBitMask);
1231 angle::Result handleDirtyGraphicsColorAccess(DirtyBits::Iterator *dirtyBitsIterator,
1232 DirtyBits dirtyBitMask);
1233 angle::Result handleDirtyGraphicsDepthStencilAccess(DirtyBits::Iterator *dirtyBitsIterator,
1234 DirtyBits dirtyBitMask);
1235 angle::Result handleDirtyGraphicsPipelineBinding(DirtyBits::Iterator *dirtyBitsIterator,
1236 DirtyBits dirtyBitMask);
1237 angle::Result handleDirtyGraphicsTextures(DirtyBits::Iterator *dirtyBitsIterator,
1238 DirtyBits dirtyBitMask);
1239 angle::Result handleDirtyGraphicsVertexBuffers(DirtyBits::Iterator *dirtyBitsIterator,
1240 DirtyBits dirtyBitMask);
1241 angle::Result handleDirtyGraphicsIndexBuffer(DirtyBits::Iterator *dirtyBitsIterator,
1242 DirtyBits dirtyBitMask);
1243 angle::Result handleDirtyGraphicsDriverUniforms(DirtyBits::Iterator *dirtyBitsIterator,
1244 DirtyBits dirtyBitMask);
1245 angle::Result handleDirtyGraphicsShaderResources(DirtyBits::Iterator *dirtyBitsIterator,
1246 DirtyBits dirtyBitMask);
1247 angle::Result handleDirtyGraphicsUniformBuffers(DirtyBits::Iterator *dirtyBitsIterator,
1248 DirtyBits dirtyBitMask);
1249 angle::Result handleDirtyGraphicsFramebufferFetchBarrier(DirtyBits::Iterator *dirtyBitsIterator,
1250 DirtyBits dirtyBitMask);
1251 angle::Result handleDirtyGraphicsBlendBarrier(DirtyBits::Iterator *dirtyBitsIterator,
1252 DirtyBits dirtyBitMask);
1253 angle::Result handleDirtyGraphicsTransformFeedbackBuffersEmulation(
1254 DirtyBits::Iterator *dirtyBitsIterator,
1255 DirtyBits dirtyBitMask);
1256 angle::Result handleDirtyGraphicsTransformFeedbackBuffersExtension(
1257 DirtyBits::Iterator *dirtyBitsIterator,
1258 DirtyBits dirtyBitMask);
1259 angle::Result handleDirtyGraphicsTransformFeedbackResume(DirtyBits::Iterator *dirtyBitsIterator,
1260 DirtyBits dirtyBitMask);
1261 angle::Result handleDirtyGraphicsDescriptorSets(DirtyBits::Iterator *dirtyBitsIterator,
1262 DirtyBits dirtyBitMask);
1263 angle::Result handleDirtyGraphicsUniforms(DirtyBits::Iterator *dirtyBitsIterator,
1264 DirtyBits dirtyBitMask);
1265 angle::Result handleDirtyGraphicsDynamicViewport(DirtyBits::Iterator *dirtyBitsIterator,
1266 DirtyBits dirtyBitMask);
1267 angle::Result handleDirtyGraphicsDynamicScissor(DirtyBits::Iterator *dirtyBitsIterator,
1268 DirtyBits dirtyBitMask);
1269 angle::Result handleDirtyGraphicsDynamicLineWidth(DirtyBits::Iterator *dirtyBitsIterator,
1270 DirtyBits dirtyBitMask);
1271 angle::Result handleDirtyGraphicsDynamicDepthBias(DirtyBits::Iterator *dirtyBitsIterator,
1272 DirtyBits dirtyBitMask);
1273 angle::Result handleDirtyGraphicsDynamicBlendConstants(DirtyBits::Iterator *dirtyBitsIterator,
1274 DirtyBits dirtyBitMask);
1275 angle::Result handleDirtyGraphicsDynamicStencilCompareMask(
1276 DirtyBits::Iterator *dirtyBitsIterator,
1277 DirtyBits dirtyBitMask);
1278 angle::Result handleDirtyGraphicsDynamicStencilWriteMask(DirtyBits::Iterator *dirtyBitsIterator,
1279 DirtyBits dirtyBitMask);
1280 angle::Result handleDirtyGraphicsDynamicStencilReference(DirtyBits::Iterator *dirtyBitsIterator,
1281 DirtyBits dirtyBitMask);
1282 angle::Result handleDirtyGraphicsDynamicCullMode(DirtyBits::Iterator *dirtyBitsIterator,
1283 DirtyBits dirtyBitMask);
1284 angle::Result handleDirtyGraphicsDynamicFrontFace(DirtyBits::Iterator *dirtyBitsIterator,
1285 DirtyBits dirtyBitMask);
1286 angle::Result handleDirtyGraphicsDynamicDepthTestEnable(DirtyBits::Iterator *dirtyBitsIterator,
1287 DirtyBits dirtyBitMask);
1288 angle::Result handleDirtyGraphicsDynamicDepthWriteEnable(DirtyBits::Iterator *dirtyBitsIterator,
1289 DirtyBits dirtyBitMask);
1290 angle::Result handleDirtyGraphicsDynamicDepthCompareOp(DirtyBits::Iterator *dirtyBitsIterator,
1291 DirtyBits dirtyBitMask);
1292 angle::Result handleDirtyGraphicsDynamicStencilTestEnable(
1293 DirtyBits::Iterator *dirtyBitsIterator,
1294 DirtyBits dirtyBitMask);
1295 angle::Result handleDirtyGraphicsDynamicStencilOp(DirtyBits::Iterator *dirtyBitsIterator,
1296 DirtyBits dirtyBitMask);
1297 angle::Result handleDirtyGraphicsDynamicRasterizerDiscardEnable(
1298 DirtyBits::Iterator *dirtyBitsIterator,
1299 DirtyBits dirtyBitMask);
1300 angle::Result handleDirtyGraphicsDynamicDepthBiasEnable(DirtyBits::Iterator *dirtyBitsIterator,
1301 DirtyBits dirtyBitMask);
1302 angle::Result handleDirtyGraphicsDynamicLogicOp(DirtyBits::Iterator *dirtyBitsIterator,
1303 DirtyBits dirtyBitMask);
1304 angle::Result handleDirtyGraphicsDynamicPrimitiveRestartEnable(
1305 DirtyBits::Iterator *dirtyBitsIterator,
1306 DirtyBits dirtyBitMask);
1307 angle::Result handleDirtyGraphicsDynamicFragmentShadingRate(
1308 DirtyBits::Iterator *dirtyBitsIterator,
1309 DirtyBits dirtyBitMask);
1310
1311 // Handlers for compute pipeline dirty bits.
1312 angle::Result handleDirtyComputeMemoryBarrier(DirtyBits::Iterator *dirtyBitsIterator);
1313 angle::Result handleDirtyComputeEventLog(DirtyBits::Iterator *dirtyBitsIterator);
1314 angle::Result handleDirtyComputePipelineDesc(DirtyBits::Iterator *dirtyBitsIterator);
1315 angle::Result handleDirtyComputePipelineBinding(DirtyBits::Iterator *dirtyBitsIterator);
1316 angle::Result handleDirtyComputeTextures(DirtyBits::Iterator *dirtyBitsIterator);
1317 angle::Result handleDirtyComputeDriverUniforms(DirtyBits::Iterator *dirtyBitsIterator);
1318 angle::Result handleDirtyComputeShaderResources(DirtyBits::Iterator *dirtyBitsIterator);
1319 angle::Result handleDirtyComputeUniformBuffers(DirtyBits::Iterator *dirtyBitsIterator);
1320 angle::Result handleDirtyComputeDescriptorSets(DirtyBits::Iterator *dirtyBitsIterator);
1321 angle::Result handleDirtyComputeUniforms(DirtyBits::Iterator *dirtyBitsIterator);
1322
1323 // Common parts of the common dirty bit handlers.
1324 angle::Result handleDirtyUniformsImpl(DirtyBits::Iterator *dirtyBitsIterator);
1325 angle::Result handleDirtyMemoryBarrierImpl(DirtyBits::Iterator *dirtyBitsIterator,
1326 DirtyBits dirtyBitMask);
1327 template <typename CommandBufferT>
1328 angle::Result handleDirtyEventLogImpl(CommandBufferT *commandBuffer);
1329 template <typename CommandBufferHelperT>
1330 angle::Result handleDirtyTexturesImpl(CommandBufferHelperT *commandBufferHelper,
1331 PipelineType pipelineType);
1332 template <typename CommandBufferHelperT>
1333 angle::Result handleDirtyShaderResourcesImpl(CommandBufferHelperT *commandBufferHelper,
1334 PipelineType pipelineType,
1335 DirtyBits::Iterator *dirtyBitsIterator);
1336 template <typename CommandBufferHelperT>
1337 angle::Result handleDirtyUniformBuffersImpl(CommandBufferHelperT *commandBufferHelper);
1338 template <typename CommandBufferHelperT>
1339 angle::Result handleDirtyDescriptorSetsImpl(CommandBufferHelperT *commandBufferHelper,
1340 PipelineType pipelineType);
1341 void handleDirtyGraphicsDynamicScissorImpl(bool isPrimitivesGeneratedQueryActive);
1342
1343 void writeAtomicCounterBufferDriverUniformOffsets(uint32_t *offsetsOut, size_t offsetsSize);
1344
1345 enum class Submit
1346 {
1347 OutsideRenderPassCommandsOnly,
1348 AllCommands,
1349 };
1350
1351 angle::Result submitCommands(const vk::Semaphore *signalSemaphore,
1352 const vk::SharedExternalFence *externalFence,
1353 Submit submission);
1354 angle::Result flushImpl(const gl::Context *context);
1355
1356 angle::Result synchronizeCpuGpuTime();
1357 angle::Result traceGpuEventImpl(vk::OutsideRenderPassCommandBuffer *commandBuffer,
1358 char phase,
1359 const EventName &name);
1360 angle::Result checkCompletedGpuEvents();
1361 void flushGpuEvents(double nextSyncGpuTimestampS, double nextSyncCpuTimestampS);
1362 void handleDeviceLost();
1363 bool shouldEmulateSeamfulCubeMapSampling() const;
1364 void clearAllGarbage();
1365 void dumpCommandStreamDiagnostics();
1366 angle::Result flushOutsideRenderPassCommands();
1367 // Flush commands and end render pass without setting any dirty bits.
1368 // flushCommandsAndEndRenderPass() and flushDirtyGraphicsRenderPass() will set the dirty bits
1369 // directly or through the iterator respectively. Outside those two functions, this shouldn't
1370 // be called directly.
1371 angle::Result flushDirtyGraphicsRenderPass(DirtyBits::Iterator *dirtyBitsIterator,
1372 DirtyBits dirtyBitMask,
1373 RenderPassClosureReason reason);
1374
1375 // Mark the render pass to be closed on the next draw call. The render pass is not actually
1376 // closed and can be restored with restoreFinishedRenderPass if necessary, for example to append
1377 // a resolve attachment.
1378 void onRenderPassFinished(RenderPassClosureReason reason);
1379
1380 void initIndexTypeMap();
1381
1382 VertexArrayVk *getVertexArray() const;
1383 FramebufferVk *getDrawFramebuffer() const;
1384
1385 // Read-after-write hazards are generally handled with |glMemoryBarrier| when the source of
1386 // write is storage output. When the write is outside render pass, the natural placement of the
1387 // render pass after the current outside render pass commands ensures that the memory barriers
1388 // and image layout transitions automatically take care of such synchronizations.
1389 //
1390 // There are a number of read-after-write cases that require breaking the render pass however to
1391 // preserve the order of operations:
1392 //
1393 // - Transform feedback write (in render pass), then vertex/index read (in render pass)
1394 // - Transform feedback write (in render pass), then ubo read (outside render pass)
1395 // - Framebuffer attachment write (in render pass), then texture sample (outside render pass)
1396 // * Note that texture sampling inside render pass would cause a feedback loop
1397 //
1398 angle::Result endRenderPassIfTransformFeedbackBuffer(const vk::BufferHelper *buffer);
1399 angle::Result endRenderPassIfComputeReadAfterTransformFeedbackWrite();
1400 angle::Result endRenderPassIfComputeAccessAfterGraphicsImageAccess();
1401
1402 // Update read-only depth feedback loop mode. Typically called from
1403 // handleDirtyGraphicsReadOnlyDepthFeedbackLoopMode, but can be called from UtilsVk in functions
1404 // that don't necessarily break the render pass.
1405 angle::Result switchOutReadOnlyDepthStencilMode(DirtyBits::Iterator *dirtyBitsIterator,
1406 DirtyBits dirtyBitMask,
1407 UpdateDepthFeedbackLoopReason depthReason,
1408 UpdateDepthFeedbackLoopReason stencilReason);
1409 angle::Result switchToReadOnlyDepthStencilMode(gl::Texture *texture,
1410 gl::Command command,
1411 FramebufferVk *drawFramebuffer,
1412 bool isStencilTexture);
1413
1414 angle::Result onResourceAccess(const vk::CommandBufferAccess &access);
1415 angle::Result flushCommandBuffersIfNecessary(const vk::CommandBufferAccess &access);
1416 bool renderPassUsesStorageResources() const;
1417
1418 angle::Result pushDebugGroupImpl(GLenum source, GLuint id, const char *message);
1419 angle::Result popDebugGroupImpl();
1420
1421 void updateScissor(const gl::State &glState);
1422
1423 void updateDepthStencil(const gl::State &glState);
1424 void updateDepthTestEnabled(const gl::State &glState);
1425 void updateDepthWriteEnabled(const gl::State &glState);
1426 void updateDepthFunc(const gl::State &glState);
1427 void updateStencilTestEnabled(const gl::State &glState);
1428
1429 void updateSampleShadingWithRasterizationSamples(const uint32_t rasterizationSamples);
1430 void updateRasterizationSamples(const uint32_t rasterizationSamples);
1431 void updateRasterizerDiscardEnabled(bool isPrimitivesGeneratedQueryActive);
1432
1433 void updateAdvancedBlendEquations(const gl::ProgramExecutable *executable);
1434
1435 void updateDither();
1436
1437 // For dynamic rendering only, mark the current render pass as being in framebuffer fetch mode.
1438 // In this mode, the FramebufferVk object and its render pass description are unaffected by
1439 // framebuffer fetch use, and the context needs to just configure the command buffer for
1440 // framebuffer fetch.
1441 void onFramebufferFetchUse(vk::FramebufferFetchMode framebufferFetchMode);
1442
1443 // When the useNonZeroStencilWriteMaskStaticState workaround is enabled, the static state for
1444 // stencil should be non-zero despite the state being dynamic. This is done when:
1445 //
1446 // - The shader includes discard, or
1447 // - Alpha-to-coverage is enabled.
1448 //
1449 // An alternative could have been to set the static state unconditionally to non-zero. This is
1450 // avoided however, as on the affected driver that would disable certain optimizations.
1451 void updateStencilWriteWorkaround();
1452
1453 void updateShaderResourcesWithSharedCacheKey(
1454 const vk::SharedDescriptorSetCacheKey &sharedCacheKey);
1455
1456 angle::Result createGraphicsPipeline();
1457
1458 angle::Result allocateQueueSerialIndex();
1459 void releaseQueueSerialIndex();
1460
1461 void generateOutsideRenderPassCommandsQueueSerial();
1462 void generateRenderPassCommandsQueueSerial(QueueSerial *queueSerialOut);
1463
1464 angle::Result ensureInterfacePipelineCache();
1465
1466 angle::ImageLoadContext mImageLoadContext;
1467
1468 std::array<GraphicsDirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers;
1469 std::array<ComputeDirtyBitHandler, DIRTY_BIT_MAX> mComputeDirtyBitHandlers;
1470
1471 vk::RenderPassCommandBuffer *mRenderPassCommandBuffer;
1472
1473 vk::PipelineHelper *mCurrentGraphicsPipeline;
1474 vk::PipelineHelper *mCurrentGraphicsPipelineShaders;
1475 vk::PipelineHelper *mCurrentGraphicsPipelineVertexInput;
1476 vk::PipelineHelper *mCurrentGraphicsPipelineFragmentOutput;
1477 vk::PipelineHelper *mCurrentComputePipeline;
1478 gl::PrimitiveMode mCurrentDrawMode;
1479
1480 WindowSurfaceVk *mCurrentWindowSurface;
1481 // Records the current rotation of the surface (draw/read) framebuffer, derived from
1482 // mCurrentWindowSurface->getPreTransform().
1483 SurfaceRotation mCurrentRotationDrawFramebuffer;
1484 SurfaceRotation mCurrentRotationReadFramebuffer;
1485
1486 // Tracks if we are in depth/stencil *read-only* or feedback loop mode. The read only is
1487 // specially allowed as both usages attachment and texture are read-only. When switching away
1488 // from read-only mode, the render pass is broken is to accommodate the new writable layout.
1489 vk::RenderPassUsageFlags mDepthStencilAttachmentFlags;
1490
1491 // Keep a cached pipeline description structure that can be used to query the pipeline cache.
1492 // Kept in a pointer so allocations can be aligned, and structs can be portably packed.
1493 std::unique_ptr<vk::GraphicsPipelineDesc> mGraphicsPipelineDesc;
1494 // Transition bits indicating which state has changed since last pipeline recreation. It is
1495 // used to look up pipelines in the cache without iterating over the entire key as a performance
1496 // optimization.
1497 //
1498 // |mGraphicsPipelineTransition| tracks transition bits since the last complete pipeline
1499 // creation/retrieval. |mGraphicsPipelineLibraryTransition| tracks the same but for the case
1500 // where the pipeline is created through libraries. The latter accumulates
1501 // |mGraphicsPipelineTransition| while the caches are hit, so that the bits are not lost if a
1502 // partial library needs to be created in the future.
1503 vk::GraphicsPipelineTransitionBits mGraphicsPipelineTransition;
1504 vk::GraphicsPipelineTransitionBits mGraphicsPipelineLibraryTransition;
1505
1506 // A pipeline cache specifically used for vertex input and fragment output pipelines, when there
1507 // is no blob reuse between libraries and monolithic pipelines. In that case, there's no point
1508 // in making monolithic pipelines be stored in the same cache as these partial pipelines.
1509 //
1510 // Note additionally that applications only create a handful of vertex input and fragment output
1511 // pipelines, which is also s fast operation, so this cache is both small and ephemeral (i.e.
1512 // not cached to disk).
1513 vk::PipelineCache mInterfacePipelinesCache;
1514
1515 // These pools are externally synchronized, so cannot be accessed from different
1516 // threads simultaneously. Hence, we keep them in the ContextVk instead of the vk::Renderer.
1517 // Note that this implementation would need to change in shared resource scenarios. Likely
1518 // we'd instead share a single set of pools between the share groups.
1519 gl::QueryTypeMap<vk::DynamicQueryPool> mQueryPools;
1520
1521 // Queries that need to be closed and reopened with the render pass:
1522 //
1523 // - Occlusion queries
1524 // - Transform feedback queries, if not emulated
1525 gl::QueryTypeMap<QueryVk *> mActiveRenderPassQueries;
1526
1527 // Dirty bits.
1528 DirtyBits mGraphicsDirtyBits;
1529 DirtyBits mComputeDirtyBits;
1530 DirtyBits mNonIndexedDirtyBitsMask;
1531 DirtyBits mIndexedDirtyBitsMask;
1532 DirtyBits mNewGraphicsCommandBufferDirtyBits;
1533 DirtyBits mNewComputeCommandBufferDirtyBits;
1534 DirtyBits mDynamicStateDirtyBits;
1535 DirtyBits mPersistentGraphicsDirtyBits;
1536 static constexpr DirtyBits kColorAccessChangeDirtyBits{DIRTY_BIT_COLOR_ACCESS};
1537 static constexpr DirtyBits kDepthStencilAccessChangeDirtyBits{
1538 DIRTY_BIT_READ_ONLY_DEPTH_FEEDBACK_LOOP_MODE, DIRTY_BIT_DEPTH_STENCIL_ACCESS};
1539 static constexpr DirtyBits kIndexAndVertexDirtyBits{DIRTY_BIT_VERTEX_BUFFERS,
1540 DIRTY_BIT_INDEX_BUFFER};
1541 static constexpr DirtyBits kPipelineDescAndBindingDirtyBits{DIRTY_BIT_PIPELINE_DESC,
1542 DIRTY_BIT_PIPELINE_BINDING};
1543 static constexpr DirtyBits kTexturesAndDescSetDirtyBits{DIRTY_BIT_TEXTURES,
1544 DIRTY_BIT_DESCRIPTOR_SETS};
1545 static constexpr DirtyBits kResourcesAndDescSetDirtyBits{DIRTY_BIT_SHADER_RESOURCES,
1546 DIRTY_BIT_DESCRIPTOR_SETS};
1547 static constexpr DirtyBits kUniformBuffersAndDescSetDirtyBits{DIRTY_BIT_UNIFORM_BUFFERS,
1548 DIRTY_BIT_DESCRIPTOR_SETS};
1549 static constexpr DirtyBits kXfbBuffersAndDescSetDirtyBits{DIRTY_BIT_TRANSFORM_FEEDBACK_BUFFERS,
1550 DIRTY_BIT_DESCRIPTOR_SETS};
1551
1552 // The offset we had the last time we bound the index buffer.
1553 const GLvoid *mLastIndexBufferOffset;
1554 vk::BufferHelper *mCurrentIndexBuffer;
1555 VkDeviceSize mCurrentIndexBufferOffset;
1556 gl::DrawElementsType mCurrentDrawElementsType;
1557 angle::PackedEnumMap<gl::DrawElementsType, VkIndexType> mIndexTypeMap;
1558
1559 // Cache the current draw call's firstVertex to be passed to
1560 // TransformFeedbackVk::getBufferOffsets. Unfortunately, gl_BaseVertex support in Vulkan is
1561 // not yet ubiquitous, which would have otherwise removed the need for this value to be passed
1562 // as a uniform.
1563 GLint mXfbBaseVertex;
1564 // Cache the current draw call's vertex count as well to support instanced draw calls
1565 GLuint mXfbVertexCountPerInstance;
1566
1567 // Cached clear value/mask for color and depth/stencil.
1568 VkClearValue mClearColorValue;
1569 VkClearValue mClearDepthStencilValue;
1570 gl::BlendStateExt::ColorMaskStorage::Type mClearColorMasks;
1571
1572 // The unprocessed bits passed in from the previous glMemoryBarrier call
1573 GLbitfield mDeferredMemoryBarriers;
1574
1575 IncompleteTextureSet mIncompleteTextures;
1576
1577 // If the current surface bound to this context wants to have all rendering flipped vertically.
1578 // Updated on calls to onMakeCurrent.
1579 bool mFlipYForCurrentSurface;
1580 bool mFlipViewportForDrawFramebuffer;
1581 bool mFlipViewportForReadFramebuffer;
1582
1583 // If any host-visible buffer is written by the GPU since last submission, a barrier is inserted
1584 // at the end of the command buffer to make that write available to the host.
1585 bool mIsAnyHostVisibleBufferWritten;
1586
1587 // This info is used in the descriptor update step.
1588 gl::ActiveTextureArray<TextureVk *> mActiveTextures;
1589
1590 vk::DescriptorSetDescBuilder mShaderBuffersDescriptorDesc;
1591 // The WriteDescriptorDescs from ProgramExecutableVk with InputAttachment update.
1592 vk::WriteDescriptorDescs mShaderBufferWriteDescriptorDescs;
1593
1594 gl::ActiveTextureArray<TextureVk *> mActiveImages;
1595
1596 // "Current Value" aka default vertex attribute state.
1597 gl::AttributesMask mDirtyDefaultAttribsMask;
1598
1599 // DynamicBuffers for streaming vertex data from client memory pointer as well as for default
1600 // attributes. mHasInFlightStreamedVertexBuffers indicates if the dynamic buffer has any
1601 // in-flight buffer or not that we need to release at submission time.
1602 gl::AttribArray<vk::DynamicBuffer> mStreamedVertexBuffers;
1603 gl::AttributesMask mHasInFlightStreamedVertexBuffers;
1604
1605 // We use a single pool for recording commands. We also keep a free list for pool recycling.
1606 vk::SecondaryCommandPools mCommandPools;
1607
1608 // Per context queue serial
1609 SerialIndex mCurrentQueueSerialIndex;
1610 QueueSerial mLastFlushedQueueSerial;
1611 QueueSerial mLastSubmittedQueueSerial;
1612 // All submitted queue serials over the life time of this context.
1613 vk::ResourceUse mSubmittedResourceUse;
1614 // Current active transform feedback buffer queue serial. Invalid if TF not active.
1615 QueueSerial mCurrentTransformFeedbackQueueSerial;
1616
1617 // The garbage list for single context use objects. The list will be GPU tracked by next
1618 // submission queueSerial. Note: Resource based shared object should always be added to
1619 // renderer's mSharedGarbageList.
1620 vk::GarbageObjects mCurrentGarbage;
1621
1622 RenderPassCache mRenderPassCache;
1623 // Used with dynamic rendering as it doesn't use render passes.
1624 vk::RenderPass mNullRenderPass;
1625
1626 vk::OutsideRenderPassCommandBufferHelper *mOutsideRenderPassCommands;
1627 vk::RenderPassCommandBufferHelper *mRenderPassCommands;
1628
1629 // Allocators for the render pass command buffers. They are utilized only when shared ring
1630 // buffer allocators are being used.
1631 vk::SecondaryCommandMemoryAllocator mOutsideRenderPassCommandsAllocator;
1632 vk::SecondaryCommandMemoryAllocator mRenderPassCommandsAllocator;
1633
1634 // The following is used when creating debug-util markers for graphics debuggers (e.g. AGI). A
1635 // given gl{Begin|End}Query command may result in commands being submitted to the outside or
1636 // render-pass command buffer. The ContextVk::handleGraphicsEventLog() method records the
1637 // appropriate command buffer for use by ContextVk::endEventLogForQuery(). The knowledge of
1638 // which command buffer to use depends on the particular type of query (e.g. samples
1639 // vs. timestamp), and is only known by the query code, which is what calls
1640 // ContextVk::handleGraphicsEventLog(). After all back-end processing of the gl*Query command
1641 // is complete, the front-end calls ContextVk::endEventLogForQuery(), which needs to know which
1642 // command buffer to call endDebugUtilsLabelEXT() for.
1643 GraphicsEventCmdBuf mQueryEventType;
1644
1645 // Internal shader library.
1646 vk::ShaderLibrary mShaderLibrary;
1647 UtilsVk mUtils;
1648
1649 bool mGpuEventsEnabled;
1650 vk::DynamicQueryPool mGpuEventQueryPool;
1651 // A list of queries that have yet to be turned into an event (their result is not yet
1652 // available).
1653 std::vector<GpuEventQuery> mInFlightGpuEventQueries;
1654 // A list of gpu events since the last clock sync.
1655 std::vector<GpuEvent> mGpuEvents;
1656 // The current frame index, used to generate a submission-encompassing event tagged with it.
1657 uint32_t mPrimaryBufferEventCounter;
1658
1659 // Cached value of the color attachment mask of the current draw framebuffer. This is used to
1660 // know which attachment indices have their blend state set in |mGraphicsPipelineDesc|, and
1661 // subsequently is used to clear the blend state for attachments that no longer exist when a new
1662 // framebuffer is bound.
1663 gl::DrawBufferMask mCachedDrawFramebufferColorAttachmentMask;
1664
1665 // Whether a flush was requested, but is deferred as an optimization to avoid breaking the
1666 // render pass.
1667 bool mHasDeferredFlush;
1668
1669 // Whether this context has produced any commands so far. While the renderer already skips
1670 // vkQueueSubmit when there is no command recorded, this variable allows glFlush itself to be
1671 // entirely skipped. This is particularly needed for an optimization where the Surface is in
1672 // shared-present mode, and the app is unnecessarily calling eglSwapBuffers (which equates
1673 // glFlush in that mode).
1674 bool mHasAnyCommandsPendingSubmission;
1675
1676 // Whether color framebuffer fetch is active. When the permanentlySwitchToFramebufferFetchMode
1677 // feature is enabled, if any program uses framebuffer fetch, rendering switches to assuming
1678 // framebuffer fetch could happen in any render pass. This incurs a potential cost due to usage
1679 // of the GENERAL layout instead of COLOR_ATTACHMENT_OPTIMAL, but has definite benefits of
1680 // avoiding render pass breaks when a framebuffer fetch program is used mid render pass.
1681 //
1682 // This only applies to legacy render passes (i.e. when dynamic rendering is NOT used). In the
1683 // case of dynamic rendering, every render pass starts with the assumption of not needing input
1684 // attachments and switches later if it needs to with no penalty.
1685 //
1686 // Note that depth/stencil framebuffer fetch does not need this sort of tracking because it is
1687 // only enabled with dynamic rendering.
1688 bool mIsInColorFramebufferFetchMode;
1689
1690 // True if current started render pass is allowed to reactivate.
1691 bool mAllowRenderPassToReactivate;
1692
1693 // The size of copy commands issued between buffers and images. Used to submit the command
1694 // buffer for the outside render pass.
1695 VkDeviceSize mTotalBufferToImageCopySize;
1696 VkDeviceSize mEstimatedPendingImageGarbageSize;
1697
1698 // Semaphores that must be flushed before the current commands. Flushed semaphores will be
1699 // waited on in the next submission.
1700 std::vector<VkSemaphore> mWaitSemaphores;
1701 std::vector<VkPipelineStageFlags> mWaitSemaphoreStageMasks;
1702 // Whether this context has wait semaphores (flushed and unflushed) that must be submitted.
1703 bool mHasWaitSemaphoresPendingSubmission;
1704
1705 // Hold information from the last gpu clock sync for future gpu-to-cpu timestamp conversions.
1706 GpuClockSyncInfo mGpuClockSync;
1707
1708 // The very first timestamp queried for a GPU event is used as origin, so event timestamps would
1709 // have a value close to zero, to avoid losing 12 bits when converting these 64 bit values to
1710 // double.
1711 uint64_t mGpuEventTimestampOrigin;
1712
1713 // A mix of per-frame and per-run counters.
1714 angle::PerfMonitorCounterGroups mPerfMonitorCounters;
1715
1716 gl::state::DirtyBits mPipelineDirtyBitsMask;
1717
1718 egl::ContextPriority mInitialContextPriority;
1719 egl::ContextPriority mContextPriority;
1720 vk::ProtectionType mProtectionType;
1721
1722 ShareGroupVk *mShareGroupVk;
1723
1724 // This is a special "empty" placeholder buffer for use when we just need a placeholder buffer
1725 // but not the data. Examples are shader that has no uniform or doesn't use all slots in the
1726 // atomic counter buffer array, or places where there is no vertex buffer since Vulkan does not
1727 // allow binding a null vertex buffer.
1728 vk::BufferHelper mEmptyBuffer;
1729
1730 // Storage for default uniforms of ProgramVks and ProgramPipelineVks.
1731 vk::DynamicBuffer mDefaultUniformStorage;
1732
1733 std::vector<std::string> mCommandBufferDiagnostics;
1734
1735 // Record GL API calls for debuggers
1736 std::vector<std::string> mEventLog;
1737
1738 // Viewport and scissor are handled as dynamic state.
1739 VkViewport mViewport;
1740 VkRect2D mScissor;
1741
1742 VulkanCacheStats mVulkanCacheStats;
1743
1744 RangedSerialFactory mOutsideRenderPassSerialFactory;
1745 };
1746
endRenderPassIfTransformFeedbackBuffer(const vk::BufferHelper * buffer)1747 ANGLE_INLINE angle::Result ContextVk::endRenderPassIfTransformFeedbackBuffer(
1748 const vk::BufferHelper *buffer)
1749 {
1750 if (!mCurrentTransformFeedbackQueueSerial.valid() || !buffer ||
1751 !buffer->writtenByCommandBuffer(mCurrentTransformFeedbackQueueSerial))
1752 {
1753 return angle::Result::Continue;
1754 }
1755
1756 return flushCommandsAndEndRenderPass(RenderPassClosureReason::XfbWriteThenVertexIndexBuffer);
1757 }
1758
onIndexBufferChange(const vk::BufferHelper * currentIndexBuffer)1759 ANGLE_INLINE angle::Result ContextVk::onIndexBufferChange(
1760 const vk::BufferHelper *currentIndexBuffer)
1761 {
1762 mGraphicsDirtyBits.set(DIRTY_BIT_INDEX_BUFFER);
1763 mLastIndexBufferOffset = reinterpret_cast<const void *>(angle::DirtyPointer);
1764 return endRenderPassIfTransformFeedbackBuffer(currentIndexBuffer);
1765 }
1766
onVertexBufferChange(const vk::BufferHelper * vertexBuffer)1767 ANGLE_INLINE angle::Result ContextVk::onVertexBufferChange(const vk::BufferHelper *vertexBuffer)
1768 {
1769 mGraphicsDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS);
1770 return endRenderPassIfTransformFeedbackBuffer(vertexBuffer);
1771 }
1772
onVertexAttributeChange(size_t attribIndex,GLuint stride,GLuint divisor,angle::FormatID format,bool compressed,GLuint relativeOffset,const vk::BufferHelper * vertexBuffer)1773 ANGLE_INLINE angle::Result ContextVk::onVertexAttributeChange(size_t attribIndex,
1774 GLuint stride,
1775 GLuint divisor,
1776 angle::FormatID format,
1777 bool compressed,
1778 GLuint relativeOffset,
1779 const vk::BufferHelper *vertexBuffer)
1780 {
1781 const GLuint staticStride =
1782 mRenderer->getFeatures().useVertexInputBindingStrideDynamicState.enabled ? 0 : stride;
1783
1784 if (!getFeatures().supportsVertexInputDynamicState.enabled)
1785 {
1786 invalidateCurrentGraphicsPipeline();
1787
1788 // Set divisor to 1 for attribs with emulated divisor
1789 mGraphicsPipelineDesc->updateVertexInput(
1790 this, &mGraphicsPipelineTransition, static_cast<uint32_t>(attribIndex), staticStride,
1791 divisor > mRenderer->getMaxVertexAttribDivisor() ? 1 : divisor, format, compressed,
1792 relativeOffset);
1793 }
1794 return onVertexBufferChange(vertexBuffer);
1795 }
1796
hasUnsubmittedUse(const vk::ResourceUse & use)1797 ANGLE_INLINE bool ContextVk::hasUnsubmittedUse(const vk::ResourceUse &use) const
1798 {
1799 return mCurrentQueueSerialIndex != kInvalidQueueSerialIndex &&
1800 use > QueueSerial(mCurrentQueueSerialIndex,
1801 mRenderer->getLastSubmittedSerial(mCurrentQueueSerialIndex));
1802 }
1803
UseLineRaster(const ContextVk * contextVk,gl::PrimitiveMode mode)1804 ANGLE_INLINE bool UseLineRaster(const ContextVk *contextVk, gl::PrimitiveMode mode)
1805 {
1806 return gl::IsLineMode(mode);
1807 }
1808
1809 uint32_t GetDriverUniformSize(vk::Context *context, PipelineType pipelineType);
1810 } // namespace rx
1811
1812 // Generate a perf warning, and insert an event marker in the command buffer.
1813 #define ANGLE_VK_PERF_WARNING(contextVk, severity, ...) \
1814 do \
1815 { \
1816 ANGLE_PERF_WARNING(contextVk->getDebug(), severity, __VA_ARGS__); \
1817 if (contextVk->isDebugEnabled()) \
1818 { \
1819 char ANGLE_MESSAGE[200]; \
1820 snprintf(ANGLE_MESSAGE, sizeof(ANGLE_MESSAGE), __VA_ARGS__); \
1821 contextVk->insertEventMarkerImpl(GL_DEBUG_SOURCE_OTHER, ANGLE_MESSAGE); \
1822 } \
1823 } while (0)
1824
1825 // Generate a trace event for graphics profiler, and insert an event marker in the command buffer.
1826 #define ANGLE_VK_TRACE_EVENT_AND_MARKER(contextVk, ...) \
1827 do \
1828 { \
1829 char ANGLE_MESSAGE[200]; \
1830 snprintf(ANGLE_MESSAGE, sizeof(ANGLE_MESSAGE), __VA_ARGS__); \
1831 ANGLE_TRACE_EVENT0("gpu.angle", ANGLE_MESSAGE); \
1832 \
1833 contextVk->insertEventMarkerImpl(GL_DEBUG_SOURCE_OTHER, ANGLE_MESSAGE); \
1834 } while (0)
1835
1836 #endif // LIBANGLE_RENDERER_VULKAN_CONTEXTVK_H_
1837