• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/CommandGraph.h"
13 #include "libANGLE/renderer/vulkan/ContextVk.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 {
RenderTargetVk()20 RenderTargetVk::RenderTargetVk()
21     : mImage(nullptr),
22       mImageView(nullptr),
23       mCubeImageFetchView(nullptr),
24       mLevelIndex(0),
25       mLayerIndex(0)
26 {}
27 
~RenderTargetVk()28 RenderTargetVk::~RenderTargetVk() {}
29 
RenderTargetVk(RenderTargetVk && other)30 RenderTargetVk::RenderTargetVk(RenderTargetVk &&other)
31     : mImage(other.mImage),
32       mImageView(other.mImageView),
33       mCubeImageFetchView(other.mCubeImageFetchView),
34       mLevelIndex(other.mLevelIndex),
35       mLayerIndex(other.mLayerIndex)
36 {}
37 
init(vk::ImageHelper * image,vk::ImageView * imageView,vk::ImageView * cubeImageFetchView,uint32_t levelIndex,uint32_t layerIndex)38 void RenderTargetVk::init(vk::ImageHelper *image,
39                           vk::ImageView *imageView,
40                           vk::ImageView *cubeImageFetchView,
41                           uint32_t levelIndex,
42                           uint32_t layerIndex)
43 {
44     mImage              = image;
45     mImageView          = imageView;
46     mCubeImageFetchView = cubeImageFetchView;
47     mLevelIndex         = levelIndex;
48     mLayerIndex         = layerIndex;
49 }
50 
reset()51 void RenderTargetVk::reset()
52 {
53     mImage              = nullptr;
54     mImageView          = nullptr;
55     mCubeImageFetchView = nullptr;
56     mLevelIndex         = 0;
57     mLayerIndex         = 0;
58 }
59 
onColorDraw(ContextVk * contextVk,vk::FramebufferHelper * framebufferVk,vk::CommandBuffer * commandBuffer)60 angle::Result RenderTargetVk::onColorDraw(ContextVk *contextVk,
61                                           vk::FramebufferHelper *framebufferVk,
62                                           vk::CommandBuffer *commandBuffer)
63 {
64     ASSERT(commandBuffer->valid());
65     ASSERT(!mImage->getFormat().imageFormat().hasDepthOrStencilBits());
66 
67     // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
68     mImage->changeLayout(VK_IMAGE_ASPECT_COLOR_BIT, vk::ImageLayout::ColorAttachment,
69                          commandBuffer);
70 
71     // Set up dependencies between the RT resource and the Framebuffer.
72     mImage->addWriteDependency(framebufferVk);
73 
74     return angle::Result::Continue;
75 }
76 
onDepthStencilDraw(ContextVk * contextVk,vk::FramebufferHelper * framebufferVk,vk::CommandBuffer * commandBuffer)77 angle::Result RenderTargetVk::onDepthStencilDraw(ContextVk *contextVk,
78                                                  vk::FramebufferHelper *framebufferVk,
79                                                  vk::CommandBuffer *commandBuffer)
80 {
81     ASSERT(commandBuffer->valid());
82     ASSERT(mImage->getFormat().imageFormat().hasDepthOrStencilBits());
83 
84     // TODO(jmadill): Use automatic layout transition. http://anglebug.com/2361
85     const angle::Format &format    = mImage->getFormat().imageFormat();
86     VkImageAspectFlags aspectFlags = vk::GetDepthStencilAspectFlags(format);
87 
88     mImage->changeLayout(aspectFlags, vk::ImageLayout::DepthStencilAttachment, commandBuffer);
89 
90     // Set up dependencies between the RT resource and the Framebuffer.
91     mImage->addWriteDependency(framebufferVk);
92 
93     return angle::Result::Continue;
94 }
95 
getImage()96 vk::ImageHelper &RenderTargetVk::getImage()
97 {
98     ASSERT(mImage && mImage->valid());
99     return *mImage;
100 }
101 
getImage() const102 const vk::ImageHelper &RenderTargetVk::getImage() const
103 {
104     ASSERT(mImage && mImage->valid());
105     return *mImage;
106 }
107 
getDrawImageView() const108 vk::ImageView *RenderTargetVk::getDrawImageView() const
109 {
110     ASSERT(mImageView && mImageView->valid());
111     return mImageView;
112 }
113 
getReadImageView() const114 vk::ImageView *RenderTargetVk::getReadImageView() const
115 {
116     return getDrawImageView();
117 }
118 
getFetchImageView() const119 vk::ImageView *RenderTargetVk::getFetchImageView() const
120 {
121     return mCubeImageFetchView && mCubeImageFetchView->valid() ? mCubeImageFetchView
122                                                                : getReadImageView();
123 }
124 
getImageFormat() const125 const vk::Format &RenderTargetVk::getImageFormat() const
126 {
127     ASSERT(mImage && mImage->valid());
128     return mImage->getFormat();
129 }
130 
getExtents() const131 gl::Extents RenderTargetVk::getExtents() const
132 {
133     ASSERT(mImage && mImage->valid());
134     return mImage->getLevelExtents2D(static_cast<uint32_t>(mLevelIndex));
135 }
136 
updateSwapchainImage(vk::ImageHelper * image,vk::ImageView * imageView)137 void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image, vk::ImageView *imageView)
138 {
139     ASSERT(image && image->valid() && imageView && imageView->valid());
140     mImage              = image;
141     mImageView          = imageView;
142     mCubeImageFetchView = nullptr;
143 }
144 
getImageForRead(vk::CommandGraphResource * readingResource,vk::ImageLayout layout,vk::CommandBuffer * commandBuffer)145 vk::ImageHelper *RenderTargetVk::getImageForRead(vk::CommandGraphResource *readingResource,
146                                                  vk::ImageLayout layout,
147                                                  vk::CommandBuffer *commandBuffer)
148 {
149     ASSERT(mImage && mImage->valid());
150 
151     // TODO(jmadill): Better simultaneous resource access. http://anglebug.com/2679
152     //
153     // A better alternative would be:
154     //
155     // if (mImage->isLayoutChangeNecessary(layout)
156     // {
157     //     vk::CommandBuffer *srcLayoutChange;
158     //     ANGLE_TRY(mImage->recordCommands(contextVk, &srcLayoutChange));
159     //     mImage->changeLayout(mImage->getAspectFlags(), layout, srcLayoutChange);
160     // }
161     // mImage->addReadDependency(readingResource);
162     //
163     // I.e. the transition should happen on a node generated from mImage itself.
164     // However, this needs context to be available here, or all call sites changed
165     // to perform the layout transition and set the dependency.
166     mImage->addWriteDependency(readingResource);
167 
168     mImage->changeLayout(mImage->getAspectFlags(), layout, commandBuffer);
169 
170     return mImage;
171 }
172 
getImageForWrite(vk::CommandGraphResource * writingResource) const173 vk::ImageHelper *RenderTargetVk::getImageForWrite(vk::CommandGraphResource *writingResource) const
174 {
175     ASSERT(mImage && mImage->valid());
176     mImage->addWriteDependency(writingResource);
177     return mImage;
178 }
179 
flushStagedUpdates(ContextVk * contextVk)180 angle::Result RenderTargetVk::flushStagedUpdates(ContextVk *contextVk)
181 {
182     ASSERT(mImage->valid());
183     if (!mImage->hasStagedUpdates())
184         return angle::Result::Continue;
185 
186     vk::CommandBuffer *commandBuffer;
187     ANGLE_TRY(mImage->recordCommands(contextVk, &commandBuffer));
188     return mImage->flushStagedUpdates(contextVk, mLevelIndex, mLevelIndex + 1, mLayerIndex,
189                                       mLayerIndex + 1, commandBuffer);
190 }
191 
192 }  // namespace rx
193