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