1 // Copyright 2019 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SRC_VULKAN_COMMAND_BUFFER_H_
16 #define SRC_VULKAN_COMMAND_BUFFER_H_
17 
18 #include "amber/result.h"
19 #include "amber/vulkan_header.h"
20 
21 namespace amber {
22 namespace vulkan {
23 
24 /// Command buffer states.
25 enum class CommandBufferState : uint8_t {
26   kInitial = 0,
27   kRecording,
28   kExecutable,
29   kPending,
30   kInvalid,
31 };
32 
33 class CommandBufferGuard;
34 class CommandPool;
35 class Device;
36 
37 /// Wrapper around a Vulkan command buffer. This is designed to not be used
38 /// directly, but should always be used through the `CommandBufferGuard` class.
39 class CommandBuffer {
40  public:
41   CommandBuffer(Device* device, CommandPool* pool);
42   ~CommandBuffer();
43 
44   Result Initialize();
GetVkCommandBuffer()45   VkCommandBuffer GetVkCommandBuffer() const { return command_; }
46 
47  private:
48   friend CommandBufferGuard;
49 
50   Result BeginRecording();
51   Result SubmitAndReset(uint32_t timeout_ms,
52                         bool pipeline_runtime_layer_enabled);
53   void Reset();
54 
55   bool guarded_ = false;
56 
57   Device* device_ = nullptr;
58   CommandPool* pool_ = nullptr;
59   VkCommandBuffer command_ = VK_NULL_HANDLE;
60   VkFence fence_ = VK_NULL_HANDLE;
61 };
62 
63 /// Wrapper around a `CommandBuffer`.
64 ///
65 /// Usage follows the pattern:
66 /// ```
67 /// CommandBufferGuard guard(cb);
68 /// if (!guard.IsRecording())
69 ///   return guard.GetResult();
70 /// ...
71 /// Result r = guard.Submit(timeout);
72 /// if (!r.IsSuccess())
73 ///   return r;
74 /// ```
75 class CommandBufferGuard {
76  public:
77   /// Creates a command buffer guard and sets the command buffer to recording.
78   explicit CommandBufferGuard(CommandBuffer* buffer);
79   ~CommandBufferGuard();
80 
81   /// Returns true if the command buffer was successfully set to recording.
IsRecording()82   bool IsRecording() const { return result_.IsSuccess(); }
83   /// Returns the result object if the command buffer recording failed.
GetResult()84   Result GetResult() { return result_; }
85 
86   /// Submits and resets the internal command buffer.
87   Result Submit(uint32_t timeout_ms,
88                 bool pipeline_runtime_layer_enabled);
89 
90  private:
91   Result result_;
92   CommandBuffer* buffer_;
93 };
94 
95 }  // namespace vulkan
96 }  // namespace amber
97 
98 #endif  // SRC_VULKAN_COMMAND_BUFFER_H_
99