blob: 937512a96aa3cccb171af21b130115b2b30b6ec9 [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 Madillfd1bf4e2015-03-31 09:46:02 -040069gl::Error IndexBufferInterface::mapBuffer(unsigned int size, void **outMappedMemory, unsigned int *streamOffset)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000070{
Geoff Langa36ead42013-08-02 11:54:08 -040071 // Protect against integer overflow
72 if (mWritePosition + size < mWritePosition)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000073 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050074 return gl::OutOfMemory()
75 << "Mapping of internal index buffer would cause an integer overflow.";
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000076 }
77
Geoff Langc9e69b12014-09-08 16:06:25 -040078 gl::Error error = mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory);
79 if (error.isError())
Geoff Langa36ead42013-08-02 11:54:08 -040080 {
81 if (outMappedMemory)
82 {
Yunchao Hed7297bf2017-04-19 15:27:10 +080083 *outMappedMemory = nullptr;
Geoff Langa36ead42013-08-02 11:54:08 -040084 }
Geoff Langc9e69b12014-09-08 16:06:25 -040085 return error;
Geoff Langa36ead42013-08-02 11:54:08 -040086 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000087
Geoff Langa36ead42013-08-02 11:54:08 -040088 if (streamOffset)
89 {
90 *streamOffset = mWritePosition;
91 }
92
93 mWritePosition += size;
He Yunchaoacd18982017-01-04 10:46:42 +080094 return gl::NoError();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000095}
96
Geoff Langc9e69b12014-09-08 16:06:25 -040097gl::Error IndexBufferInterface::unmapBuffer()
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000098{
99 return mIndexBuffer->unmapBuffer();
100}
101
102IndexBuffer * IndexBufferInterface::getIndexBuffer() const
103{
104 return mIndexBuffer;
105}
106
107unsigned int IndexBufferInterface::getWritePosition() const
108{
109 return mWritePosition;
110}
111
112void IndexBufferInterface::setWritePosition(unsigned int writePosition)
113{
114 mWritePosition = writePosition;
115}
116
Geoff Langc9e69b12014-09-08 16:06:25 -0400117gl::Error IndexBufferInterface::discard()
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000118{
119 return mIndexBuffer->discard();
120}
121
Geoff Langc9e69b12014-09-08 16:06:25 -0400122gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000123{
124 if (mIndexBuffer->getBufferSize() == 0)
125 {
126 return mIndexBuffer->initialize(bufferSize, indexType, mDynamic);
127 }
128 else
129 {
130 return mIndexBuffer->setSize(bufferSize, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000131 }
132}
133
Jamie Madillfd1bf4e2015-03-31 09:46:02 -0400134StreamingIndexBufferInterface::StreamingIndexBufferInterface(BufferFactoryD3D *factory)
135 : IndexBufferInterface(factory, true)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000136{
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000137}
138
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000139StreamingIndexBufferInterface::~StreamingIndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000140{
141}
142
Geoff Langc9e69b12014-09-08 16:06:25 -0400143gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000144{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000145 unsigned int curBufferSize = getBufferSize();
Geoff Langd81cf642013-07-09 16:02:30 -0400146 unsigned int writePos = getWritePosition();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000147 if (size > curBufferSize)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000148 {
Jamie Madill87718a82017-11-13 15:01:19 -0500149 ANGLE_TRY(setBufferSize(std::max(size, 2 * curBufferSize), indexType));
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000150 setWritePosition(0);
151 }
Geoff Langd81cf642013-07-09 16:02:30 -0400152 else if (writePos + size > curBufferSize || writePos + size < writePos)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000153 {
Jamie Madill87718a82017-11-13 15:01:19 -0500154 ANGLE_TRY(discard());
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000155 setWritePosition(0);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000156 }
157
He Yunchaoacd18982017-01-04 10:46:42 +0800158 return gl::NoError();
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000159}
160
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000161
Jamie Madillfd1bf4e2015-03-31 09:46:02 -0400162StaticIndexBufferInterface::StaticIndexBufferInterface(BufferFactoryD3D *factory)
163 : IndexBufferInterface(factory, false)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000164{
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000165}
166
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000167StaticIndexBufferInterface::~StaticIndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000168{
169}
170
Geoff Langc9e69b12014-09-08 16:06:25 -0400171gl::Error StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000172{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000173 unsigned int curSize = getBufferSize();
174 if (curSize == 0)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000175 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000176 return setBufferSize(size, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000177 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000178 else if (curSize >= size && indexType == getIndexType())
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000179 {
He Yunchaoacd18982017-01-04 10:46:42 +0800180 return gl::NoError();
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000181 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000182 else
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000183 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000184 UNREACHABLE();
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500185 return gl::InternalError() << "Internal static index buffers can't be resized";
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000186 }
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000187}
188
Jamie Madill87718a82017-11-13 15:01:19 -0500189} // namespace rx