• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2017 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 // Resource:
7 //    Resource lifetime tracking in the Vulkan back-end.
8 //
9 
10 #include "libANGLE/renderer/vulkan/ResourceVk.h"
11 
12 #include "libANGLE/renderer/vulkan/ContextVk.h"
13 
14 namespace rx
15 {
16 namespace vk
17 {
18 namespace
19 {
FinishRunningCommands(ContextVk * contextVk,Serial serial)20 angle::Result FinishRunningCommands(ContextVk *contextVk, Serial serial)
21 {
22     return contextVk->finishToSerial(serial);
23 }
24 
25 template <typename T>
WaitForIdle(ContextVk * contextVk,T * resource,const char * debugMessage,RenderPassClosureReason reason)26 angle::Result WaitForIdle(ContextVk *contextVk,
27                           T *resource,
28                           const char *debugMessage,
29                           RenderPassClosureReason reason)
30 {
31     // If there are pending commands for the resource, flush them.
32     if (resource->usedInRecordedCommands())
33     {
34         ANGLE_TRY(contextVk->flushImpl(nullptr, reason));
35     }
36 
37     // Make sure the driver is done with the resource.
38     if (resource->usedInRunningCommands(contextVk->getLastCompletedQueueSerial()))
39     {
40         if (debugMessage)
41         {
42             ANGLE_VK_PERF_WARNING(contextVk, GL_DEBUG_SEVERITY_HIGH, "%s", debugMessage);
43         }
44         ANGLE_TRY(resource->finishRunningCommands(contextVk));
45     }
46 
47     ASSERT(!resource->isCurrentlyInUse(contextVk->getLastCompletedQueueSerial()));
48 
49     return angle::Result::Continue;
50 }
51 }  // namespace
52 
53 // Resource implementation.
Resource()54 Resource::Resource()
55 {
56     mUse.init();
57 }
58 
Resource(Resource && other)59 Resource::Resource(Resource &&other) : Resource()
60 {
61     mUse = std::move(other.mUse);
62 }
63 
operator =(Resource && rhs)64 Resource &Resource::operator=(Resource &&rhs)
65 {
66     std::swap(mUse, rhs.mUse);
67     return *this;
68 }
69 
~Resource()70 Resource::~Resource()
71 {
72     mUse.release();
73 }
74 
finishRunningCommands(ContextVk * contextVk)75 angle::Result Resource::finishRunningCommands(ContextVk *contextVk)
76 {
77     return FinishRunningCommands(contextVk, mUse.getSerial());
78 }
79 
waitForIdle(ContextVk * contextVk,const char * debugMessage,RenderPassClosureReason reason)80 angle::Result Resource::waitForIdle(ContextVk *contextVk,
81                                     const char *debugMessage,
82                                     RenderPassClosureReason reason)
83 {
84     return WaitForIdle(contextVk, this, debugMessage, reason);
85 }
86 
87 // Resource implementation.
ReadWriteResource()88 ReadWriteResource::ReadWriteResource()
89 {
90     mReadOnlyUse.init();
91     mReadWriteUse.init();
92 }
93 
ReadWriteResource(ReadWriteResource && other)94 ReadWriteResource::ReadWriteResource(ReadWriteResource &&other) : ReadWriteResource()
95 {
96     mReadOnlyUse  = std::move(other.mReadOnlyUse);
97     mReadWriteUse = std::move(other.mReadWriteUse);
98 }
99 
~ReadWriteResource()100 ReadWriteResource::~ReadWriteResource()
101 {
102     mReadOnlyUse.release();
103     mReadWriteUse.release();
104 }
105 
finishRunningCommands(ContextVk * contextVk)106 angle::Result ReadWriteResource::finishRunningCommands(ContextVk *contextVk)
107 {
108     ASSERT(!mReadOnlyUse.usedInRecordedCommands());
109     return FinishRunningCommands(contextVk, mReadOnlyUse.getSerial());
110 }
111 
finishGPUWriteCommands(ContextVk * contextVk)112 angle::Result ReadWriteResource::finishGPUWriteCommands(ContextVk *contextVk)
113 {
114     ASSERT(!mReadWriteUse.usedInRecordedCommands());
115     return FinishRunningCommands(contextVk, mReadWriteUse.getSerial());
116 }
117 
waitForIdle(ContextVk * contextVk,const char * debugMessage,RenderPassClosureReason reason)118 angle::Result ReadWriteResource::waitForIdle(ContextVk *contextVk,
119                                              const char *debugMessage,
120                                              RenderPassClosureReason reason)
121 {
122     return WaitForIdle(contextVk, this, debugMessage, reason);
123 }
124 
125 // SharedGarbage implementation.
126 SharedGarbage::SharedGarbage() = default;
127 
SharedGarbage(SharedGarbage && other)128 SharedGarbage::SharedGarbage(SharedGarbage &&other)
129 {
130     *this = std::move(other);
131 }
132 
SharedGarbage(SharedResourceUse && use,std::vector<GarbageObject> && garbage)133 SharedGarbage::SharedGarbage(SharedResourceUse &&use, std::vector<GarbageObject> &&garbage)
134     : mLifetime(std::move(use)), mGarbage(std::move(garbage))
135 {}
136 
137 SharedGarbage::~SharedGarbage() = default;
138 
operator =(SharedGarbage && rhs)139 SharedGarbage &SharedGarbage::operator=(SharedGarbage &&rhs)
140 {
141     std::swap(mLifetime, rhs.mLifetime);
142     std::swap(mGarbage, rhs.mGarbage);
143     return *this;
144 }
145 
destroyIfComplete(RendererVk * renderer,Serial completedSerial)146 bool SharedGarbage::destroyIfComplete(RendererVk *renderer, Serial completedSerial)
147 {
148     if (mLifetime.isCurrentlyInUse(completedSerial))
149     {
150         return false;
151     }
152 
153     for (GarbageObject &object : mGarbage)
154     {
155         object.destroy(renderer);
156     }
157 
158     mLifetime.release();
159 
160     return true;
161 }
162 
163 // ResourceUseList implementation.
ResourceUseList()164 ResourceUseList::ResourceUseList()
165 {
166     constexpr size_t kDefaultResourceUseCount = 4096;
167     mResourceUses.reserve(kDefaultResourceUseCount);
168 }
169 
ResourceUseList(ResourceUseList && other)170 ResourceUseList::ResourceUseList(ResourceUseList &&other)
171 {
172     *this = std::move(other);
173 }
174 
~ResourceUseList()175 ResourceUseList::~ResourceUseList()
176 {
177     ASSERT(mResourceUses.empty());
178 }
179 
operator =(ResourceUseList && rhs)180 ResourceUseList &ResourceUseList::operator=(ResourceUseList &&rhs)
181 {
182     std::swap(mResourceUses, rhs.mResourceUses);
183     return *this;
184 }
185 
releaseResourceUses()186 void ResourceUseList::releaseResourceUses()
187 {
188     for (SharedResourceUse &use : mResourceUses)
189     {
190         use.release();
191     }
192 
193     mResourceUses.clear();
194 }
195 
releaseResourceUsesAndUpdateSerials(Serial serial)196 void ResourceUseList::releaseResourceUsesAndUpdateSerials(Serial serial)
197 {
198     for (SharedResourceUse &use : mResourceUses)
199     {
200         use.releaseAndUpdateSerial(serial);
201     }
202 
203     mResourceUses.clear();
204 }
205 }  // namespace vk
206 }  // namespace rx
207