• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     RendererVk *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     RendererVk *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     ANGLE_TRY(mFontImage.initMemory(contextVk, false, renderer->getMemoryProperties(),
69                                     VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
70     ANGLE_TRY(mFontImage.initImageView(
71         contextVk, gl::TextureType::_2DArray, VK_IMAGE_ASPECT_COLOR_BIT, gl::SwizzleState(),
72         &mFontImageView, vk::LevelIndex(0), gl::overlay::kFontMipCount));
73 
74     // Copy font data from staging buffer.
75     vk::CommandBufferAccess access;
76     access.onBufferTransferRead(&fontDataBuffer.get());
77     access.onImageTransferWrite(gl::LevelIndex(0), gl::overlay::kFontMipCount, 0,
78                                 gl::overlay::kFontCharacters, VK_IMAGE_ASPECT_COLOR_BIT,
79                                 &mFontImage);
80     vk::OutsideRenderPassCommandBuffer *fontDataUpload;
81     ANGLE_TRY(contextVk->getOutsideRenderPassCommandBuffer(access, &fontDataUpload));
82 
83     VkBufferImageCopy copy           = {};
84     copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
85     copy.imageSubresource.layerCount = gl::overlay::kFontCharacters;
86     copy.imageExtent.depth           = 1;
87 
88     for (uint32_t mip = 0; mip < gl::overlay::kFontMipCount; ++mip)
89     {
90         copy.bufferOffset              = gl::overlay::kFontMipDataOffset[mip];
91         copy.bufferRowLength           = gl::overlay::kFontGlyphWidth >> mip;
92         copy.bufferImageHeight         = gl::overlay::kFontGlyphHeight >> mip;
93         copy.imageSubresource.mipLevel = mip;
94         copy.imageExtent.width         = gl::overlay::kFontGlyphWidth >> mip;
95         copy.imageExtent.height        = gl::overlay::kFontGlyphHeight >> mip;
96 
97         fontDataUpload->copyBufferToImage(fontDataBuffer.get().getBuffer().getHandle(),
98                                           mFontImage.getImage(),
99                                           VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy);
100     }
101 
102     return angle::Result::Continue;
103 }
104 
onPresent(ContextVk * contextVk,vk::ImageHelper * imageToPresent,const vk::ImageView * imageToPresentView,bool is90DegreeRotation)105 angle::Result OverlayVk::onPresent(ContextVk *contextVk,
106                                    vk::ImageHelper *imageToPresent,
107                                    const vk::ImageView *imageToPresentView,
108                                    bool is90DegreeRotation)
109 {
110     if (mState.getEnabledWidgetCount() == 0)
111     {
112         return angle::Result::Continue;
113     }
114 
115     // Lazily initialize the font on first use
116     if (!mFontImage.valid())
117     {
118         ANGLE_TRY(createFont(contextVk));
119     }
120 
121     RendererVk *renderer = contextVk->getRenderer();
122 
123     vk::RendererScoped<vk::BufferHelper> textDataBuffer(renderer);
124     vk::RendererScoped<vk::BufferHelper> graphDataBuffer(renderer);
125 
126     VkBufferCreateInfo textBufferCreateInfo = {};
127     textBufferCreateInfo.sType              = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
128     textBufferCreateInfo.size               = mState.getTextWidgetsBufferSize();
129     textBufferCreateInfo.usage              = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
130     textBufferCreateInfo.sharingMode        = VK_SHARING_MODE_EXCLUSIVE;
131 
132     VkBufferCreateInfo graphBufferCreateInfo = textBufferCreateInfo;
133     graphBufferCreateInfo.size               = mState.getGraphWidgetsBufferSize();
134 
135     ANGLE_TRY(textDataBuffer.get().init(contextVk, textBufferCreateInfo,
136                                         VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
137     ANGLE_TRY(graphDataBuffer.get().init(contextVk, graphBufferCreateInfo,
138                                          VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
139 
140     uint8_t *textData;
141     uint8_t *graphData;
142     ANGLE_TRY(textDataBuffer.get().map(contextVk, &textData));
143     ANGLE_TRY(graphDataBuffer.get().map(contextVk, &graphData));
144 
145     uint32_t textWidgetCount  = 0;
146     uint32_t graphWidgetCount = 0;
147 
148     gl::Extents presentImageExtents(imageToPresent->getExtents().width,
149                                     imageToPresent->getExtents().height, 1);
150     mState.fillWidgetData(presentImageExtents, textData, graphData, &textWidgetCount,
151                           &graphWidgetCount);
152 
153     ANGLE_TRY(textDataBuffer.get().flush(renderer, 0, textDataBuffer.get().getSize()));
154     ANGLE_TRY(graphDataBuffer.get().flush(renderer, 0, graphDataBuffer.get().getSize()));
155     textDataBuffer.get().unmap(renderer);
156     graphDataBuffer.get().unmap(renderer);
157 
158     UtilsVk::OverlayDrawParameters params;
159     params.textWidgetCount  = textWidgetCount;
160     params.graphWidgetCount = graphWidgetCount;
161     params.rotateXY         = is90DegreeRotation;
162 
163     return contextVk->getUtils().drawOverlay(contextVk, &textDataBuffer.get(),
164                                              &graphDataBuffer.get(), &mFontImage, &mFontImageView,
165                                              imageToPresent, imageToPresentView, params);
166 }
167 
168 }  // namespace rx
169