1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6
7namespace bs { namespace ct
8{
9 /** @addtogroup RenderAPI
10 * @{
11 */
12
13 /** Mask that determines synchronization between command buffers executing on different hardware queues. */
14 class BS_CORE_EXPORT CommandSyncMask
15 {
16 public:
17 /**
18 * Registers a dependency on a command buffer. Use getMask() to get the new mask value after registering all
19 * dependencies.
20 */
21 void addDependency(const SPtr<CommandBuffer>& buffer);
22
23 /** Returns a combined mask that contains all the required dependencies. */
24 UINT32 getMask() const { return mMask; }
25
26 /** Uses the queue type and index to generate a mask with a bit set for that queue's global index. */
27 static UINT32 getGlobalQueueMask(GpuQueueType type, UINT32 queueIdx);
28
29 /** Uses the queue type and index to generate a global queue index. */
30 static UINT32 getGlobalQueueIdx(GpuQueueType type, UINT32 queueIdx);
31
32 /** Uses the global queue index to retrieve local queue index and queue type. */
33 static UINT32 getQueueIdxAndType(UINT32 globalQueueIdx, GpuQueueType& type);
34
35 private:
36 UINT32 mMask = 0;
37 };
38
39 /**
40 * Contains a list of render API commands that can be queued for execution on the GPU. User is allowed to populate the
41 * command buffer from any thread, ensuring render API command generation can be multi-threaded. Command buffers
42 * must always be created on the core thread. Same command buffer cannot be used on multiple threads simulateously
43 * without external synchronization.
44 */
45 class BS_CORE_EXPORT CommandBuffer
46 {
47 public:
48 virtual ~CommandBuffer() = default;
49
50 /**
51 * Creates a new CommandBuffer.
52 *
53 * @param[in] type Determines what type of commands can be added to the command buffer.
54 * @param[in] deviceIdx Index of the GPU the command buffer will be used to queue commands on. 0 is always
55 * the primary available GPU.
56 * @param[in] queueIdx Index of the GPU queue the command buffer will be used on. Command buffers with
57 * the same index will execute sequentially, but command buffers with different queue
58 * indices may execute in parallel, for a potential performance improvement.
59 *
60 * Caller must ensure to synchronize operations executing on different queues via
61 * sync masks. Command buffer dependant on another command buffer should provide a sync
62 * mask when being submitted (see RenderAPI::executeCommands).
63 *
64 * Queue indices are unique per buffer type (e.g. upload index 0 and graphics index 0 may
65 * map to different queues internally). Must be in range [0, 7].
66 * @param[in] secondary If true the command buffer will not be allowed to execute on its own, but it can
67 * be appended to a primary command buffer.
68 * @return New CommandBuffer instance.
69 */
70 static SPtr<CommandBuffer> create(GpuQueueType type, UINT32 deviceIdx = 0, UINT32 queueIdx = 0,
71 bool secondary = false);
72
73 /** Returns the type of queue the command buffer will execute on. */
74 GpuQueueType getType() const { return mType; }
75
76 /** Returns the index of the queue the command buffer will execute on. */
77 UINT32 getQueueIdx() const { return mQueueIdx; }
78
79 /** Returns the device index this buffer will execute on. */
80 UINT32 getDeviceIdx() const { return mDeviceIdx; }
81
82 protected:
83 CommandBuffer(GpuQueueType type, UINT32 deviceIdx, UINT32 queueIdx, bool secondary);
84
85 GpuQueueType mType;
86 UINT32 mDeviceIdx;
87 UINT32 mQueueIdx;
88 bool mIsSecondary;
89 };
90
91 /** @} */
92}}