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 // RenderTargetVk:
7 // Wrapper around a Vulkan renderable resource, using an ImageView.
8 //
9
10 #include "libANGLE/renderer/vulkan/RenderTargetVk.h"
11
12 #include "libANGLE/renderer/vulkan/ContextVk.h"
13 #include "libANGLE/renderer/vulkan/ResourceVk.h"
14 #include "libANGLE/renderer/vulkan/TextureVk.h"
15 #include "libANGLE/renderer/vulkan/vk_format_utils.h"
16 #include "libANGLE/renderer/vulkan/vk_helpers.h"
17
18 namespace rx
19 {
20
RenderTargetVk()21 RenderTargetVk::RenderTargetVk()
22 {
23 reset();
24 }
25
~RenderTargetVk()26 RenderTargetVk::~RenderTargetVk() {}
27
RenderTargetVk(RenderTargetVk && other)28 RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
29 : mImage(other.mImage),
30 mImageViews(other.mImageViews),
31 mLevelIndex(other.mLevelIndex),
32 mLayerIndex(other.mLayerIndex),
33 mContentDefined(other.mContentDefined)
34 {
35 other.reset();
36 }
37
init(vk::ImageHelper * image,vk::ImageViewHelper * imageViews,uint32_t levelIndex,uint32_t layerIndex)38 void RenderTargetVk::init(vk::ImageHelper *image,
39 vk::ImageViewHelper *imageViews,
40 uint32_t levelIndex,
41 uint32_t layerIndex)
42 {
43 mImage = image;
44 mImageViews = imageViews;
45 mLevelIndex = levelIndex;
46 mLayerIndex = layerIndex;
47 // We are being conservative here since our targeted optimization is to skip surfaceVK's depth
48 // buffer load after swap call.
49 mContentDefined = true;
50 }
51
reset()52 void RenderTargetVk::reset()
53 {
54 mImage = nullptr;
55 mImageViews = nullptr;
56 mLevelIndex = 0;
57 mLayerIndex = 0;
58 mContentDefined = false;
59 }
60
getAssignSerial(ContextVk * contextVk)61 vk::AttachmentSerial RenderTargetVk::getAssignSerial(ContextVk *contextVk)
62 {
63 ASSERT(mImage && mImage->valid());
64 vk::AttachmentSerial attachmentSerial;
65 ASSERT(mLayerIndex < std::numeric_limits<uint16_t>::max());
66 ASSERT(mLevelIndex < std::numeric_limits<uint16_t>::max());
67 Serial imageSerial = mImage->getAssignSerial(contextVk);
68 ASSERT(imageSerial.getValue() < std::numeric_limits<uint32_t>::max());
69 SetBitField(attachmentSerial.layer, mLayerIndex);
70 SetBitField(attachmentSerial.level, mLevelIndex);
71 SetBitField(attachmentSerial.imageSerial, imageSerial.getValue());
72 return attachmentSerial;
73 }
74
onColorDraw(ContextVk * contextVk)75 angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk)
76 {
77 ASSERT(!mImage->getFormat().actualImageFormat().hasDepthOrStencilBits());
78
79 contextVk->onRenderPassImageWrite(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorAttachment,
80 mImage);
81 mContentDefined = true;
82 retainImageViews(contextVk);
83
84 return angle::Result::Continue;
85 }
86
onDepthStencilDraw(ContextVk * contextVk)87 angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk)
88 {
89 ASSERT(mImage->getFormat().actualImageFormat().hasDepthOrStencilBits());
90
91 const angle::Format &format = mImage->getFormat().actualImageFormat();
92 VkImageAspectFlags aspectFlags = vk::GetDepthStencilAspectFlags(format);
93
94 contextVk->onRenderPassImageWrite(aspectFlags, vk::ImageLayout::DepthStencilAttachment, mImage);
95 mContentDefined = true;
96 retainImageViews(contextVk);
97
98 return angle::Result::Continue;
99 }
100
getImage()101 vk::ImageHelper &RenderTargetVk::getImage()
102 {
103 ASSERT(mImage && mImage->valid());
104 return *mImage;
105 }
106
getImage() const107 const vk::ImageHelper &RenderTargetVk::getImage() const
108 {
109 ASSERT(mImage && mImage->valid());
110 return *mImage;
111 }
112
getImageView(ContextVk * contextVk,const vk::ImageView ** imageViewOut) const113 angle::Result RenderTargetVk::getImageView(ContextVk *contextVk,
114 const vk::ImageView **imageViewOut) const
115 {
116 ASSERT(mImage && mImage->valid() && mImageViews);
117 return mImageViews->getLevelLayerDrawImageView(contextVk, *mImage, mLevelIndex, mLayerIndex,
118 imageViewOut);
119 }
120
getImageFormat() const121 const vk::Format &RenderTargetVk::getImageFormat() const
122 {
123 ASSERT(mImage && mImage->valid());
124 return mImage->getFormat();
125 }
126
getExtents() const127 gl::Extents RenderTargetVk::getExtents() const
128 {
129 ASSERT(mImage && mImage->valid());
130 return mImage->getLevelExtents2D(static_cast<uint32_t>(mLevelIndex));
131 }
132
updateSwapchainImage(vk::ImageHelper * image,vk::ImageViewHelper * imageViews)133 void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image, vk::ImageViewHelper *imageViews)
134 {
135 ASSERT(image && image->valid() && imageViews);
136 mImage = image;
137 mImageViews = imageViews;
138 }
139
getImageForWrite(ContextVk * contextVk) const140 vk::ImageHelper *RenderTargetVk::getImageForWrite(ContextVk *contextVk) const
141 {
142 ASSERT(mImage && mImage->valid());
143 retainImageViews(contextVk);
144 return mImage;
145 }
146
flushStagedUpdates(ContextVk * contextVk)147 angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk)
148 {
149 ASSERT(mImage->valid());
150 if (!mImage->hasStagedUpdates())
151 return angle::Result::Continue;
152
153 vk::CommandBuffer *commandBuffer;
154 ANGLE_TRY(contextVk->endRenderPassAndGetCommandBuffer(&commandBuffer));
155 return mImage->flushStagedUpdates(contextVk, mLevelIndex, mLevelIndex + 1, mLayerIndex,
156 mLayerIndex + 1, commandBuffer);
157 }
158
retainImageViews(ContextVk * contextVk) const159 void RenderTargetVk::retainImageViews(ContextVk *contextVk) const
160 {
161 mImageViews->retain(&contextVk->getResourceUseList());
162 }
163 } // namespace rx
164