xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/OverlayVk.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2019 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 // OverlayVk.cpp:
7 //    Implements the OverlayVk class.
8 //
9 
10 #include "libANGLE/renderer/vulkan/OverlayVk.h"
11 
12 #include "common/system_utils.h"
13 #include "libANGLE/Context.h"
14 #include "libANGLE/Overlay_font_autogen.h"
15 #include "libANGLE/renderer/vulkan/ContextVk.h"
16 
17 #include <numeric>
18 
19 namespace rx
20 {
OverlayVk(const gl::OverlayState & state)21 OverlayVk::OverlayVk(const gl::OverlayState &state) : OverlayImpl(state) {}
22 OverlayVk::~OverlayVk() = default;
23 
onDestroy(const gl::Context * context)24 void OverlayVk::onDestroy(const gl::Context *context)
25 {
26     vk::Renderer *renderer = vk::GetImpl(context)->getRenderer();
27     VkDevice device        = renderer->getDevice();
28 
29     mFontImage.destroy(renderer);
30     mFontImageView.destroy(device);
31 }
32 
createFont(ContextVk * contextVk)33 angle::Result OverlayVk::createFont(ContextVk *contextVk)
34 {
35     vk::Renderer *renderer = contextVk->getRenderer();
36 
37     // Create a buffer to stage font data upload.
38     VkBufferCreateInfo bufferCreateInfo = {};
39     bufferCreateInfo.sType              = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
40     bufferCreateInfo.size               = gl::overlay::kFontTotalDataSize;
41     bufferCreateInfo.usage              = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
42     bufferCreateInfo.sharingMode        = VK_SHARING_MODE_EXCLUSIVE;
43 
44     vk::RendererScoped<vk::BufferHelper> fontDataBuffer(renderer);
45 
46     ANGLE_TRY(fontDataBuffer.get().init(contextVk, bufferCreateInfo,
47                                         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
48 
49     uint8_t *mappedFontData;
50     ANGLE_TRY(fontDataBuffer.get().map(contextVk, &mappedFontData));
51 
52     const uint8_t *fontData = mState.getFontData();
53     memcpy(mappedFontData, fontData, gl::overlay::kFontTotalDataSize * sizeof(*fontData));
54 
55     ANGLE_TRY(fontDataBuffer.get().flush(renderer, 0, fontDataBuffer.get().getSize()));
56     fontDataBuffer.get().unmap(renderer);
57 
58     // Don't use robust resource init for overlay widgets.
59     constexpr bool kNoRobustInit = false;
60 
61     // Create the font image.
62     ANGLE_TRY(mFontImage.init(
63         contextVk, gl::TextureType::_2D,
64         VkExtent3D{gl::overlay::kFontGlyphWidth, gl::overlay::kFontGlyphHeight, 1},
65         renderer->getFormat(angle::FormatID::R8_UNORM), 1,
66         VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, gl::LevelIndex(0),
67         gl::overlay::kFontMipCount, gl::overlay::kFontCharacters, kNoRobustInit, false));
68 
69     ANGLE_TRY(contextVk->initImageAllocation(&mFontImage, false, renderer->getMemoryProperties(),
70                                              VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
71                                              vk::MemoryAllocationType::FontImage));
72 
73     ANGLE_TRY(mFontImage.initLayerImageView(
74         contextVk, gl::TextureType::_2DArray, VK_IMAGE_ASPECT_COLOR_BIT, gl::SwizzleState(),
75         &mFontImageView, vk::LevelIndex(0), gl::overlay::kFontMipCount, 0,
76         mFontImage.getLayerCount()));
77 
78     // Copy font data from staging buffer.
79     vk::CommandBufferAccess access;
80     access.onBufferTransferRead(&fontDataBuffer.get());
81     access.onImageTransferWrite(gl::LevelIndex(0), gl::overlay::kFontMipCount, 0,
82                                 gl::overlay::kFontCharacters, VK_IMAGE_ASPECT_COLOR_BIT,
83                                 &mFontImage);
84     vk::OutsideRenderPassCommandBuffer *fontDataUpload;
85     ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &fontDataUpload));
86 
87     VkBufferImageCopy copy           = {};
88     copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
89     copy.imageSubresource.layerCount = gl::overlay::kFontCharacters;
90     copy.imageExtent.depth           = 1;
91 
92     for (uint32_t mip = 0; mip < gl::overlay::kFontMipCount; ++mip)
93     {
94         copy.bufferOffset              = gl::overlay::kFontMipDataOffset[mip];
95         copy.bufferRowLength           = gl::overlay::kFontGlyphWidth >> mip;
96         copy.bufferImageHeight         = gl::overlay::kFontGlyphHeight >> mip;
97         copy.imageSubresource.mipLevel = mip;
98         copy.imageExtent.width         = gl::overlay::kFontGlyphWidth >> mip;
99         copy.imageExtent.height        = gl::overlay::kFontGlyphHeight >> mip;
100 
101         fontDataUpload->copyBufferToImage(fontDataBuffer.get().getBuffer().getHandle(),
102                                           mFontImage.getImage(),
103                                           VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy);
104     }
105 
106     return angle::Result::Continue;
107 }
108 
onPresent(ContextVk * contextVk,vk::ImageHelper * imageToPresent,const vk::ImageView * imageToPresentView,bool is90DegreeRotation)109 angle::Result OverlayVk::onPresent(ContextVk *contextVk,
110                                    vk::ImageHelper *imageToPresent,
111                                    const vk::ImageView *imageToPresentView,
112                                    bool is90DegreeRotation)
113 {
114     if (mState.getEnabledWidgetCount() == 0)
115     {
116         return angle::Result::Continue;
117     }
118 
119     // Lazily initialize the font on first use
120     if (!mFontImage.valid())
121     {
122         ANGLE_TRY(createFont(contextVk));
123     }
124 
125     vk::Renderer *renderer = contextVk->getRenderer();
126 
127     vk::RendererScoped<vk::BufferHelper> textDataBuffer(renderer);
128     vk::RendererScoped<vk::BufferHelper> graphDataBuffer(renderer);
129 
130     VkBufferCreateInfo textBufferCreateInfo = {};
131     textBufferCreateInfo.sType              = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
132     textBufferCreateInfo.size               = mState.getTextWidgetsBufferSize();
133     textBufferCreateInfo.usage              = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
134     textBufferCreateInfo.sharingMode        = VK_SHARING_MODE_EXCLUSIVE;
135 
136     VkBufferCreateInfo graphBufferCreateInfo = textBufferCreateInfo;
137     graphBufferCreateInfo.size               = mState.getGraphWidgetsBufferSize();
138 
139     ANGLE_TRY(textDataBuffer.get().init(contextVk, textBufferCreateInfo,
140                                         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
141     ANGLE_TRY(graphDataBuffer.get().init(contextVk, graphBufferCreateInfo,
142                                          VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
143 
144     uint8_t *textData;
145     uint8_t *graphData;
146     ANGLE_TRY(textDataBuffer.get().map(contextVk, &textData));
147     ANGLE_TRY(graphDataBuffer.get().map(contextVk, &graphData));
148 
149     uint32_t textWidgetCount  = 0;
150     uint32_t graphWidgetCount = 0;
151 
152     gl::Extents presentImageExtents(imageToPresent->getExtents().width,
153                                     imageToPresent->getExtents().height, 1);
154     mState.fillWidgetData(presentImageExtents, textData, graphData, &textWidgetCount,
155                           &graphWidgetCount);
156 
157     ANGLE_TRY(textDataBuffer.get().flush(renderer, 0, textDataBuffer.get().getSize()));
158     ANGLE_TRY(graphDataBuffer.get().flush(renderer, 0, graphDataBuffer.get().getSize()));
159     textDataBuffer.get().unmap(renderer);
160     graphDataBuffer.get().unmap(renderer);
161 
162     UtilsVk::OverlayDrawParameters params;
163     params.textWidgetCount  = textWidgetCount;
164     params.graphWidgetCount = graphWidgetCount;
165     params.rotateXY         = is90DegreeRotation;
166 
167     return contextVk->getUtils().drawOverlay(contextVk, &textDataBuffer.get(),
168                                              &graphDataBuffer.get(), &mFontImage, &mFontImageView,
169                                              imageToPresent, imageToPresentView, params);
170 }
171 
172 }  // namespace rx
173