blob: 1b52f64e96cf84c8284139195f5a8e4ac4dc22f1 [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"
Jamie Madillec1fe5b2018-08-10 10:05:52 -040011
12#include "libANGLE/Context.h"
13#include "libANGLE/renderer/d3d/ContextD3D.h"
daniel@transgaming.com955377e2012-12-20 21:09:15 +000014
daniel@transgaming.com955377e2012-12-20 21:09:15 +000015namespace rx
16{
17
daniel@transgaming.com2befccd2012-12-20 21:09:31 +000018unsigned int IndexBuffer::mNextSerial = 1;
19
20IndexBuffer::IndexBuffer()
21{
22 updateSerial();
23}
24
25IndexBuffer::~IndexBuffer()
26{
27}
28
29unsigned int IndexBuffer::getSerial() const
30{
31 return mSerial;
32}
33
34void IndexBuffer::updateSerial()
35{
36 mSerial = mNextSerial++;
37}
38
39
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040040IndexBufferInterface::IndexBufferInterface(BufferFactoryD3D *factory, bool dynamic)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000041{
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040042 mIndexBuffer = factory->createIndexBuffer();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000043
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000044 mDynamic = dynamic;
45 mWritePosition = 0;
daniel@transgaming.com955377e2012-12-20 21:09:15 +000046}
47
daniel@transgaming.com50cc7252012-12-20 21:09:23 +000048IndexBufferInterface::~IndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +000049{
50 if (mIndexBuffer)
51 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000052 delete mIndexBuffer;
daniel@transgaming.com955377e2012-12-20 21:09:15 +000053 }
54}
55
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000056GLenum IndexBufferInterface::getIndexType() const
daniel@transgaming.com955377e2012-12-20 21:09:15 +000057{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000058 return mIndexBuffer->getIndexType();
59}
60
61unsigned int IndexBufferInterface::getBufferSize() const
62{
63 return mIndexBuffer->getBufferSize();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000064}
65
daniel@transgaming.com50cc7252012-12-20 21:09:23 +000066unsigned int IndexBufferInterface::getSerial() const
daniel@transgaming.com955377e2012-12-20 21:09:15 +000067{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000068 return mIndexBuffer->getSerial();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000069}
70
Jamie Madillec1fe5b2018-08-10 10:05:52 -040071angle::Result IndexBufferInterface::mapBuffer(const gl::Context *context,
72 unsigned int size,
73 void **outMappedMemory,
74 unsigned int *streamOffset)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000075{
Geoff Langa36ead42013-08-02 11:54:08 -040076 // Protect against integer overflow
Jamie Madillec1fe5b2018-08-10 10:05:52 -040077 bool check = (mWritePosition + size < mWritePosition);
Jamie Madille39e8f42018-10-05 08:17:38 -040078 ANGLE_CHECK(GetImplAs<ContextD3D>(context), !check,
79 "Mapping of internal index buffer would cause an integer overflow.", E_OUTOFMEMORY);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000080
Jamie Madillec1fe5b2018-08-10 10:05:52 -040081 angle::Result error = mIndexBuffer->mapBuffer(context, mWritePosition, size, outMappedMemory);
82 if (error == angle::Result::Stop())
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;
Jamie Madillec1fe5b2018-08-10 10:05:52 -040097 return angle::Result::Continue();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000098}
99
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400100angle::Result 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 Madillec1fe5b2018-08-10 10:05:52 -0400120angle::Result 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 Madillec1fe5b2018-08-10 10:05:52 -0400125angle::Result 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 Madillec1fe5b2018-08-10 10:05:52 -0400148angle::Result 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
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400165 return angle::Result::Continue();
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 Madillec1fe5b2018-08-10 10:05:52 -0400178angle::Result 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 }
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400187
188 ASSERT(curSize >= size && indexType == getIndexType());
189 return angle::Result::Continue();
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000190}
191
Jamie Madill87718a82017-11-13 15:01:19 -0500192} // namespace rx