blob: df3fa691744b03908eb6a660c847487f742958e8 [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 {
Geoff Langc9e69b12014-09-08 16:06:25 -040074 return gl::Error(GL_OUT_OF_MEMORY, "Mapping of internal index buffer would cause an integer overflow.");
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000075 }
76
Geoff Langc9e69b12014-09-08 16:06:25 -040077 gl::Error error = mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory);
78 if (error.isError())
Geoff Langa36ead42013-08-02 11:54:08 -040079 {
80 if (outMappedMemory)
81 {
82 *outMappedMemory = NULL;
83 }
Geoff Langc9e69b12014-09-08 16:06:25 -040084 return error;
Geoff Langa36ead42013-08-02 11:54:08 -040085 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000086
Geoff Langa36ead42013-08-02 11:54:08 -040087 if (streamOffset)
88 {
89 *streamOffset = mWritePosition;
90 }
91
92 mWritePosition += size;
He Yunchaoacd18982017-01-04 10:46:42 +080093 return gl::NoError();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000094}
95
Geoff Langc9e69b12014-09-08 16:06:25 -040096gl::Error IndexBufferInterface::unmapBuffer()
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000097{
98 return mIndexBuffer->unmapBuffer();
99}
100
101IndexBuffer * IndexBufferInterface::getIndexBuffer() const
102{
103 return mIndexBuffer;
104}
105
106unsigned int IndexBufferInterface::getWritePosition() const
107{
108 return mWritePosition;
109}
110
111void IndexBufferInterface::setWritePosition(unsigned int writePosition)
112{
113 mWritePosition = writePosition;
114}
115
Geoff Langc9e69b12014-09-08 16:06:25 -0400116gl::Error IndexBufferInterface::discard()
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000117{
118 return mIndexBuffer->discard();
119}
120
Geoff Langc9e69b12014-09-08 16:06:25 -0400121gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000122{
123 if (mIndexBuffer->getBufferSize() == 0)
124 {
125 return mIndexBuffer->initialize(bufferSize, indexType, mDynamic);
126 }
127 else
128 {
129 return mIndexBuffer->setSize(bufferSize, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000130 }
131}
132
Jamie Madillfd1bf4e2015-03-31 09:46:02 -0400133StreamingIndexBufferInterface::StreamingIndexBufferInterface(BufferFactoryD3D *factory)
134 : IndexBufferInterface(factory, true)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000135{
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000136}
137
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000138StreamingIndexBufferInterface::~StreamingIndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000139{
140}
141
Geoff Langc9e69b12014-09-08 16:06:25 -0400142gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000143{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000144 unsigned int curBufferSize = getBufferSize();
Geoff Langd81cf642013-07-09 16:02:30 -0400145 unsigned int writePos = getWritePosition();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000146 if (size > curBufferSize)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000147 {
Geoff Langc9e69b12014-09-08 16:06:25 -0400148 gl::Error error = setBufferSize(std::max(size, 2 * curBufferSize), indexType);
149 if (error.isError())
150 {
151 return error;
152 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000153 setWritePosition(0);
154 }
Geoff Langd81cf642013-07-09 16:02:30 -0400155 else if (writePos + size > curBufferSize || writePos + size < writePos)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000156 {
Geoff Langc9e69b12014-09-08 16:06:25 -0400157 gl::Error error = discard();
158 if (error.isError())
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000159 {
Geoff Langc9e69b12014-09-08 16:06:25 -0400160 return error;
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000161 }
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
Geoff Langc9e69b12014-09-08 16:06:25 -0400178gl::Error StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000179{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000180 unsigned int curSize = getBufferSize();
181 if (curSize == 0)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000182 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000183 return setBufferSize(size, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000184 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000185 else if (curSize >= size && indexType == getIndexType())
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000186 {
He Yunchaoacd18982017-01-04 10:46:42 +0800187 return gl::NoError();
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000188 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000189 else
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000190 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000191 UNREACHABLE();
Geoff Langc9e69b12014-09-08 16:06:25 -0400192 return gl::Error(GL_INVALID_OPERATION, "Internal static index buffers can't be resized");
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000193 }
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000194}
195
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000196}