blob: 68e926e16742a7bca543c3d13bb9d1d344938655 [file] [log] [blame]
daniel@transgaming.com955377e2012-12-20 21:09:15 +00001//
2// Copyright (c) 2002-2012 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
7// IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface
8// class with derivations, classes that perform graphics API agnostic index buffer operations.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/renderer/d3d/IndexBuffer.h"
11#include "libANGLE/renderer/d3d/RendererD3D.h"
daniel@transgaming.com955377e2012-12-20 21:09:15 +000012
daniel@transgaming.com955377e2012-12-20 21:09:15 +000013namespace rx
14{
15
daniel@transgaming.com2befccd2012-12-20 21:09:31 +000016unsigned int IndexBuffer::mNextSerial = 1;
17
18IndexBuffer::IndexBuffer()
19{
20 updateSerial();
21}
22
23IndexBuffer::~IndexBuffer()
24{
25}
26
27unsigned int IndexBuffer::getSerial() const
28{
29 return mSerial;
30}
31
32void IndexBuffer::updateSerial()
33{
34 mSerial = mNextSerial++;
35}
36
37
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040038IndexBufferInterface::IndexBufferInterface(BufferFactoryD3D *factory, bool dynamic)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000039{
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040040 mIndexBuffer = factory->createIndexBuffer();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000041
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000042 mDynamic = dynamic;
43 mWritePosition = 0;
daniel@transgaming.com955377e2012-12-20 21:09:15 +000044}
45
daniel@transgaming.com50cc7252012-12-20 21:09:23 +000046IndexBufferInterface::~IndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +000047{
48 if (mIndexBuffer)
49 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000050 delete mIndexBuffer;
daniel@transgaming.com955377e2012-12-20 21:09:15 +000051 }
52}
53
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000054GLenum IndexBufferInterface::getIndexType() const
daniel@transgaming.com955377e2012-12-20 21:09:15 +000055{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000056 return mIndexBuffer->getIndexType();
57}
58
59unsigned int IndexBufferInterface::getBufferSize() const
60{
61 return mIndexBuffer->getBufferSize();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000062}
63
daniel@transgaming.com50cc7252012-12-20 21:09:23 +000064unsigned int IndexBufferInterface::getSerial() const
daniel@transgaming.com955377e2012-12-20 21:09:15 +000065{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000066 return mIndexBuffer->getSerial();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000067}
68
Jamie Madillb1565902018-07-27 08:12:48 -040069gl::Error IndexBufferInterface::mapBuffer(const gl::Context *context,
70 unsigned int size,
71 void **outMappedMemory,
72 unsigned int *streamOffset)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000073{
Geoff Langa36ead42013-08-02 11:54:08 -040074 // Protect against integer overflow
75 if (mWritePosition + size < mWritePosition)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000076 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050077 return gl::OutOfMemory()
78 << "Mapping of internal index buffer would cause an integer overflow.";
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000079 }
80
Jamie Madillb1565902018-07-27 08:12:48 -040081 gl::Error error = mIndexBuffer->mapBuffer(context, mWritePosition, size, outMappedMemory);
Geoff Langc9e69b12014-09-08 16:06:25 -040082 if (error.isError())
Geoff Langa36ead42013-08-02 11:54:08 -040083 {
84 if (outMappedMemory)
85 {
Yunchao Hed7297bf2017-04-19 15:27:10 +080086 *outMappedMemory = nullptr;
Geoff Langa36ead42013-08-02 11:54:08 -040087 }
Geoff Langc9e69b12014-09-08 16:06:25 -040088 return error;
Geoff Langa36ead42013-08-02 11:54:08 -040089 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000090
Geoff Langa36ead42013-08-02 11:54:08 -040091 if (streamOffset)
92 {
93 *streamOffset = mWritePosition;
94 }
95
96 mWritePosition += size;
He Yunchaoacd18982017-01-04 10:46:42 +080097 return gl::NoError();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000098}
99
Jamie Madillb1565902018-07-27 08:12:48 -0400100gl::Error IndexBufferInterface::unmapBuffer(const gl::Context *context)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000101{
Jamie Madillb1565902018-07-27 08:12:48 -0400102 return mIndexBuffer->unmapBuffer(context);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000103}
104
105IndexBuffer * IndexBufferInterface::getIndexBuffer() const
106{
107 return mIndexBuffer;
108}
109
110unsigned int IndexBufferInterface::getWritePosition() const
111{
112 return mWritePosition;
113}
114
115void IndexBufferInterface::setWritePosition(unsigned int writePosition)
116{
117 mWritePosition = writePosition;
118}
119
Jamie Madillb1565902018-07-27 08:12:48 -0400120gl::Error IndexBufferInterface::discard(const gl::Context *context)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000121{
Jamie Madillb1565902018-07-27 08:12:48 -0400122 return mIndexBuffer->discard(context);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000123}
124
Jamie Madillb1565902018-07-27 08:12:48 -0400125gl::Error IndexBufferInterface::setBufferSize(const gl::Context *context,
126 unsigned int bufferSize,
127 GLenum indexType)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000128{
129 if (mIndexBuffer->getBufferSize() == 0)
130 {
Jamie Madillb1565902018-07-27 08:12:48 -0400131 return mIndexBuffer->initialize(context, bufferSize, indexType, mDynamic);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000132 }
133 else
134 {
Jamie Madillb1565902018-07-27 08:12:48 -0400135 return mIndexBuffer->setSize(context, bufferSize, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000136 }
137}
138
Jamie Madillfd1bf4e2015-03-31 09:46:02 -0400139StreamingIndexBufferInterface::StreamingIndexBufferInterface(BufferFactoryD3D *factory)
140 : IndexBufferInterface(factory, true)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000141{
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000142}
143
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000144StreamingIndexBufferInterface::~StreamingIndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000145{
146}
147
Jamie Madillb1565902018-07-27 08:12:48 -0400148gl::Error StreamingIndexBufferInterface::reserveBufferSpace(const gl::Context *context,
149 unsigned int size,
150 GLenum indexType)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000151{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000152 unsigned int curBufferSize = getBufferSize();
Geoff Langd81cf642013-07-09 16:02:30 -0400153 unsigned int writePos = getWritePosition();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000154 if (size > curBufferSize)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000155 {
Jamie Madillb1565902018-07-27 08:12:48 -0400156 ANGLE_TRY(setBufferSize(context, std::max(size, 2 * curBufferSize), indexType));
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000157 setWritePosition(0);
158 }
Geoff Langd81cf642013-07-09 16:02:30 -0400159 else if (writePos + size > curBufferSize || writePos + size < writePos)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000160 {
Jamie Madillb1565902018-07-27 08:12:48 -0400161 ANGLE_TRY(discard(context));
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000162 setWritePosition(0);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000163 }
164
He Yunchaoacd18982017-01-04 10:46:42 +0800165 return gl::NoError();
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000166}
167
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000168
Jamie Madillfd1bf4e2015-03-31 09:46:02 -0400169StaticIndexBufferInterface::StaticIndexBufferInterface(BufferFactoryD3D *factory)
170 : IndexBufferInterface(factory, false)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000171{
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000172}
173
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000174StaticIndexBufferInterface::~StaticIndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000175{
176}
177
Jamie Madillb1565902018-07-27 08:12:48 -0400178gl::Error StaticIndexBufferInterface::reserveBufferSpace(const gl::Context *context,
179 unsigned int size,
180 GLenum indexType)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000181{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000182 unsigned int curSize = getBufferSize();
183 if (curSize == 0)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000184 {
Jamie Madillb1565902018-07-27 08:12:48 -0400185 return setBufferSize(context, size, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000186 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000187 else if (curSize >= size && indexType == getIndexType())
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000188 {
He Yunchaoacd18982017-01-04 10:46:42 +0800189 return gl::NoError();
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000190 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000191 else
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000192 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000193 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 return gl::InternalError() << "Internal static index buffers can't be resized";
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000195 }
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000196}
197
Jamie Madill87718a82017-11-13 15:01:19 -0500198} // namespace rx