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#include "RenderAPI/BsHardwareBuffer.h"
7#include "CoreThread/BsCoreObject.h"
8
9namespace bs
10{
11 /** @addtogroup RenderAPI
12 * @{
13 */
14
15 /** Descriptor structure used for initialization of an IndexBuffer. */
16 struct INDEX_BUFFER_DESC
17 {
18 IndexType indexType; /**< Index type, determines the size of a single index. */
19 UINT32 numIndices; /**< Number of indices can buffer can hold. */
20 GpuBufferUsage usage = GBU_STATIC; /**< Usage that tells the hardware how will be buffer be used. */
21 };
22
23 /** Contains information about an index buffer. */
24 class BS_CORE_EXPORT IndexBufferProperties
25 {
26 public:
27 IndexBufferProperties(IndexType idxType, UINT32 numIndexes);
28
29 /** Returns the type of indices stored. */
30 IndexType getType() const { return mIndexType; }
31
32 /** Returns the number of indices this buffer can hold. */
33 UINT32 getNumIndices() const { return mNumIndices; }
34
35 /** Returns the size of a single index in bytes. */
36 UINT32 getIndexSize() const { return mIndexSize; }
37
38 protected:
39 friend class IndexBuffer;
40 friend class ct::IndexBuffer;
41
42 IndexType mIndexType;
43 UINT32 mNumIndices;
44 UINT32 mIndexSize;
45 };
46
47 /** Hardware buffer that hold indices that reference vertices in a vertex buffer. */
48 class BS_CORE_EXPORT IndexBuffer : public CoreObject
49 {
50 public:
51 virtual ~IndexBuffer() { }
52
53 /** Returns information about the index buffer. */
54 const IndexBufferProperties& getProperties() const { return mProperties; }
55
56 /**
57 * Retrieves a core implementation of an index buffer usable only from the core thread.
58 *
59 * @note Core thread only.
60 */
61 SPtr<ct::IndexBuffer> getCore() const;
62
63 /** @copydoc HardwareBufferManager::createIndexBuffer */
64 static SPtr<IndexBuffer> create(const INDEX_BUFFER_DESC& desc);
65
66 protected:
67 friend class HardwareBufferManager;
68
69 IndexBuffer(const INDEX_BUFFER_DESC& desc);
70
71 /** @copydoc CoreObject::createCore */
72 virtual SPtr<ct::CoreObject> createCore() const;
73
74 IndexBufferProperties mProperties;
75 GpuBufferUsage mUsage;
76 };
77
78 /** @} */
79
80 namespace ct
81 {
82 /** @addtogroup RenderAPI-Internal
83 * @{
84 */
85
86 /** Core thread specific implementation of an bs::IndexBuffer. */
87 class BS_CORE_EXPORT IndexBuffer : public CoreObject, public HardwareBuffer
88 {
89 public:
90 IndexBuffer(const INDEX_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
91 virtual ~IndexBuffer();
92
93 /** Returns information about the index buffer. */
94 const IndexBufferProperties& getProperties() const { return mProperties; }
95
96 /** @copydoc HardwareBuffer::readData */
97 void readData(UINT32 offset, UINT32 length, void* dest, UINT32 deviceIdx = 0, UINT32 queueIdx = 0) override;
98
99 /** @copydoc HardwareBuffer::writeData */
100 void writeData(UINT32 offset, UINT32 length, const void* source,
101 BufferWriteType writeFlags = BWT_NORMAL, UINT32 queueIdx = 0) override;
102
103 /** @copydoc HardwareBuffer::copyData */
104 void copyData(HardwareBuffer& srcBuffer, UINT32 srcOffset, UINT32 dstOffset, UINT32 length,
105 bool discardWholeBuffer = false, const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
106
107 /**
108 * Returns a view of this buffer that can be used for load-store operations. Buffer must have been created with
109 * the GBU_LOADSTORE usage flag.
110 *
111 * @param[in] type Type of buffer to view the contents as. Only supported values are GBT_STANDARD and
112 * GBT_STRUCTURED.
113 * @param[in] format Format of the data in the buffer. Size of the underlying buffer must be divisible by
114 * the size of an individual element of this format. Must be BF_UNKNOWN if buffer type
115 * is GBT_STRUCTURED.
116 * @param[in] elementSize Size of the individual element in the buffer. Size of the underlying buffer must be
117 * divisible by this size. Must be 0 if buffer type is GBT_STANDARD (element size gets
118 * deduced from format).
119 * @return Buffer usable for load store operations or null if the operation fails. Failure
120 * can happen if the buffer hasn't been created with GBU_LOADSTORE usage or if the
121 * element size doesn't divide the current buffer size.
122 */
123 SPtr<GpuBuffer> getLoadStore(GpuBufferType type, GpuBufferFormat format, UINT32 elementSize = 0);
124
125 /** @copydoc HardwareBufferManager::createIndexBuffer */
126 static SPtr<IndexBuffer> create(const INDEX_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
127
128 protected:
129 friend class HardwareBufferManager;
130
131 /** @copydoc HardwareBuffer::map */
132 void* map(UINT32 offset, UINT32 length, GpuLockOptions options, UINT32 deviceIdx, UINT32 queueIdx) override;
133
134 /** @copydoc HardwareBuffer::unmap */
135 void unmap() override;
136
137 /** @copydoc CoreObject::initialize */
138 void initialize() override;
139
140 IndexBufferProperties mProperties;
141
142 HardwareBuffer* mBuffer = nullptr;
143 SPtr<HardwareBuffer> mSharedBuffer;
144 Vector<SPtr<GpuBuffer>> mLoadStoreViews;
145
146 typedef void(*Deleter)(HardwareBuffer*);
147 Deleter mBufferDeleter = nullptr;
148 };
149
150 /** @} */
151 }
152}