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 | #include "RenderAPI/BsIndexBuffer.h" |
4 | #include "Managers/BsHardwareBufferManager.h" |
5 | #include "RenderAPI/BsRenderAPI.h" |
6 | #include "RenderAPI/BsGpuBuffer.h" |
7 | #include "Profiling/BsRenderStats.h" |
8 | |
9 | namespace bs |
10 | { |
11 | UINT32 calcIndexSize(IndexType type) |
12 | { |
13 | switch (type) |
14 | { |
15 | case IT_16BIT: |
16 | return sizeof(unsigned short); |
17 | default: |
18 | case IT_32BIT: |
19 | return sizeof(unsigned int); |
20 | } |
21 | } |
22 | |
23 | void checkValidDesc(const INDEX_BUFFER_DESC& desc) |
24 | { |
25 | if(desc.numIndices == 0) |
26 | BS_EXCEPT(InvalidParametersException, "Index buffer index count is not allowed to be zero." ); |
27 | } |
28 | |
29 | IndexBufferProperties::IndexBufferProperties(IndexType idxType, UINT32 numIndices) |
30 | :mIndexType(idxType), mNumIndices(numIndices), mIndexSize(calcIndexSize(idxType)) |
31 | { } |
32 | |
33 | IndexBuffer::IndexBuffer(const INDEX_BUFFER_DESC& desc) |
34 | :mProperties(desc.indexType, desc.numIndices), mUsage(desc.usage) |
35 | { |
36 | #if BS_DEBUG_MODE |
37 | checkValidDesc(desc); |
38 | #endif |
39 | } |
40 | |
41 | SPtr<ct::IndexBuffer> IndexBuffer::getCore() const |
42 | { |
43 | return std::static_pointer_cast<ct::IndexBuffer>(mCoreSpecific); |
44 | } |
45 | |
46 | SPtr<ct::CoreObject> IndexBuffer::createCore() const |
47 | { |
48 | INDEX_BUFFER_DESC desc; |
49 | desc.indexType = mProperties.mIndexType; |
50 | desc.numIndices = mProperties.mNumIndices; |
51 | desc.usage = mUsage; |
52 | |
53 | return ct::HardwareBufferManager::instance().createIndexBufferInternal(desc); |
54 | } |
55 | |
56 | SPtr<IndexBuffer> IndexBuffer::create(const INDEX_BUFFER_DESC& desc) |
57 | { |
58 | return HardwareBufferManager::instance().createIndexBuffer(desc); |
59 | } |
60 | |
61 | namespace ct |
62 | { |
63 | IndexBuffer::IndexBuffer(const INDEX_BUFFER_DESC& desc, GpuDeviceFlags deviceMask) |
64 | : HardwareBuffer(calcIndexSize(desc.indexType) * desc.numIndices, desc.usage, deviceMask) |
65 | , mProperties(desc.indexType, desc.numIndices) |
66 | { |
67 | #if BS_DEBUG_MODE |
68 | checkValidDesc(desc); |
69 | #endif |
70 | } |
71 | |
72 | IndexBuffer::~IndexBuffer() |
73 | { |
74 | if(mBuffer && !mSharedBuffer) |
75 | mBufferDeleter(mBuffer); |
76 | |
77 | BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_IndexBuffer); |
78 | } |
79 | |
80 | void IndexBuffer::initialize() |
81 | { |
82 | BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_IndexBuffer); |
83 | CoreObject::initialize(); |
84 | } |
85 | |
86 | void* IndexBuffer::map(UINT32 offset, UINT32 length, GpuLockOptions options, UINT32 deviceIdx, UINT32 queueIdx) |
87 | { |
88 | #if BS_PROFILING_ENABLED |
89 | if (options == GBL_READ_ONLY || options == GBL_READ_WRITE) |
90 | { |
91 | BS_INC_RENDER_STAT_CAT(ResRead, RenderStatObject_IndexBuffer); |
92 | } |
93 | |
94 | if (options == GBL_READ_WRITE || options == GBL_WRITE_ONLY || options == GBL_WRITE_ONLY_DISCARD || options == GBL_WRITE_ONLY_NO_OVERWRITE) |
95 | { |
96 | BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_IndexBuffer); |
97 | } |
98 | #endif |
99 | |
100 | return mBuffer->lock(offset, length, options, deviceIdx, queueIdx); |
101 | } |
102 | |
103 | void IndexBuffer::unmap() |
104 | { |
105 | mBuffer->unlock(); |
106 | } |
107 | |
108 | void IndexBuffer::readData(UINT32 offset, UINT32 length, void* dest, UINT32 deviceIdx, UINT32 queueIdx) |
109 | { |
110 | mBuffer->readData(offset, length, dest, deviceIdx, queueIdx); |
111 | |
112 | BS_INC_RENDER_STAT_CAT(ResRead, RenderStatObject_IndexBuffer); |
113 | } |
114 | |
115 | void IndexBuffer::writeData(UINT32 offset, UINT32 length, const void* source, BufferWriteType writeFlags, |
116 | UINT32 queueIdx) |
117 | { |
118 | mBuffer->writeData(offset, length, source, writeFlags, queueIdx); |
119 | |
120 | BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_IndexBuffer); |
121 | } |
122 | |
123 | void IndexBuffer::copyData(HardwareBuffer& srcBuffer, UINT32 srcOffset, UINT32 dstOffset, UINT32 length, |
124 | bool discardWholeBuffer, const SPtr<CommandBuffer>& commandBuffer) |
125 | { |
126 | auto& srcIndexBuffer = static_cast<IndexBuffer&>(srcBuffer); |
127 | mBuffer->copyData(*srcIndexBuffer.mBuffer, srcOffset, dstOffset, length, discardWholeBuffer, commandBuffer); |
128 | } |
129 | |
130 | SPtr<GpuBuffer> IndexBuffer::getLoadStore(GpuBufferType type, GpuBufferFormat format, UINT32 elementSize) |
131 | { |
132 | if((mUsage & GBU_LOADSTORE) != GBU_LOADSTORE) |
133 | return nullptr; |
134 | |
135 | for(const auto& entry : mLoadStoreViews) |
136 | { |
137 | const GpuBufferProperties& props = entry->getProperties(); |
138 | if(props.getType() == type) |
139 | { |
140 | if(type == GBT_STANDARD && props.getFormat() == format) |
141 | return entry; |
142 | |
143 | if(type == GBT_STRUCTURED && props.getElementSize() == elementSize) |
144 | return entry; |
145 | } |
146 | } |
147 | |
148 | UINT32 elemSize = type == GBT_STANDARD ? bs::GpuBuffer::getFormatSize(format) : elementSize; |
149 | if((mBuffer->getSize() % elemSize) != 0) |
150 | { |
151 | LOGERR("Size of the buffer isn't divisible by individual element size provided for the buffer view." ); |
152 | return nullptr; |
153 | } |
154 | |
155 | GPU_BUFFER_DESC desc; |
156 | desc.type = type; |
157 | desc.format = format; |
158 | desc.usage = mUsage; |
159 | desc.elementSize = elementSize; |
160 | desc.elementCount = mBuffer->getSize() / elemSize; |
161 | |
162 | if(!mSharedBuffer) |
163 | mSharedBuffer = bs_shared_ptr(mBuffer, mBufferDeleter); |
164 | |
165 | SPtr<GpuBuffer> newView = GpuBuffer::create(desc, mSharedBuffer); |
166 | mLoadStoreViews.push_back(newView); |
167 | |
168 | return newView; |
169 | } |
170 | |
171 | SPtr<IndexBuffer> IndexBuffer::create(const INDEX_BUFFER_DESC& desc, GpuDeviceFlags deviceMask) |
172 | { |
173 | return HardwareBufferManager::instance().createIndexBuffer(desc, deviceMask); |
174 | } |
175 | } |
176 | } |
177 | |