blob: 1b04193f381ee8c791d5e0f704f5a1b4f31094d2 [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
Jamie Madillb980c562018-11-27 11:34:27 -050025IndexBuffer::~IndexBuffer() {}
daniel@transgaming.com2befccd2012-12-20 21:09:31 +000026
27unsigned int IndexBuffer::getSerial() const
28{
29 return mSerial;
30}
31
32void IndexBuffer::updateSerial()
33{
34 mSerial = mNextSerial++;
35}
36
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040037IndexBufferInterface::IndexBufferInterface(BufferFactoryD3D *factory, bool dynamic)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000038{
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040039 mIndexBuffer = factory->createIndexBuffer();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000040
Jamie Madillb980c562018-11-27 11:34:27 -050041 mDynamic = dynamic;
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000042 mWritePosition = 0;
daniel@transgaming.com955377e2012-12-20 21:09:15 +000043}
44
daniel@transgaming.com50cc7252012-12-20 21:09:23 +000045IndexBufferInterface::~IndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +000046{
47 if (mIndexBuffer)
48 {
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000049 delete mIndexBuffer;
daniel@transgaming.com955377e2012-12-20 21:09:15 +000050 }
51}
52
Jamie Madill8dc27f92018-11-29 11:45:44 -050053gl::DrawElementsType IndexBufferInterface::getIndexType() const
daniel@transgaming.com955377e2012-12-20 21:09:15 +000054{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000055 return mIndexBuffer->getIndexType();
56}
57
58unsigned int IndexBufferInterface::getBufferSize() const
59{
60 return mIndexBuffer->getBufferSize();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000061}
62
daniel@transgaming.com50cc7252012-12-20 21:09:23 +000063unsigned int IndexBufferInterface::getSerial() const
daniel@transgaming.com955377e2012-12-20 21:09:15 +000064{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000065 return mIndexBuffer->getSerial();
daniel@transgaming.com955377e2012-12-20 21:09:15 +000066}
67
Jamie Madillec1fe5b2018-08-10 10:05:52 -040068angle::Result IndexBufferInterface::mapBuffer(const gl::Context *context,
69 unsigned int size,
70 void **outMappedMemory,
71 unsigned int *streamOffset)
daniel@transgaming.com955377e2012-12-20 21:09:15 +000072{
Geoff Langa36ead42013-08-02 11:54:08 -040073 // Protect against integer overflow
Jamie Madillec1fe5b2018-08-10 10:05:52 -040074 bool check = (mWritePosition + size < mWritePosition);
Jamie Madille39e8f42018-10-05 08:17:38 -040075 ANGLE_CHECK(GetImplAs<ContextD3D>(context), !check,
Jamie Madillc1fd7372018-10-26 22:48:39 -040076 "Mapping of internal index buffer would cause an integer overflow.",
77 GL_OUT_OF_MEMORY);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000078
Jamie Madillec1fe5b2018-08-10 10:05:52 -040079 angle::Result error = mIndexBuffer->mapBuffer(context, mWritePosition, size, outMappedMemory);
80 if (error == angle::Result::Stop())
Geoff Langa36ead42013-08-02 11:54:08 -040081 {
82 if (outMappedMemory)
83 {
Yunchao Hed7297bf2017-04-19 15:27:10 +080084 *outMappedMemory = nullptr;
Geoff Langa36ead42013-08-02 11:54:08 -040085 }
Geoff Langc9e69b12014-09-08 16:06:25 -040086 return error;
Geoff Langa36ead42013-08-02 11:54:08 -040087 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000088
Geoff Langa36ead42013-08-02 11:54:08 -040089 if (streamOffset)
90 {
91 *streamOffset = mWritePosition;
92 }
93
94 mWritePosition += size;
Jamie Madillec1fe5b2018-08-10 10:05:52 -040095 return angle::Result::Continue();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000096}
97
Jamie Madillec1fe5b2018-08-10 10:05:52 -040098angle::Result IndexBufferInterface::unmapBuffer(const gl::Context *context)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000099{
Jamie Madillb1565902018-07-27 08:12:48 -0400100 return mIndexBuffer->unmapBuffer(context);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000101}
102
Jamie Madillb980c562018-11-27 11:34:27 -0500103IndexBuffer *IndexBufferInterface::getIndexBuffer() const
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000104{
105 return mIndexBuffer;
106}
107
108unsigned int IndexBufferInterface::getWritePosition() const
109{
110 return mWritePosition;
111}
112
113void IndexBufferInterface::setWritePosition(unsigned int writePosition)
114{
115 mWritePosition = writePosition;
116}
117
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400118angle::Result IndexBufferInterface::discard(const gl::Context *context)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000119{
Jamie Madillb1565902018-07-27 08:12:48 -0400120 return mIndexBuffer->discard(context);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000121}
122
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400123angle::Result IndexBufferInterface::setBufferSize(const gl::Context *context,
124 unsigned int bufferSize,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500125 gl::DrawElementsType indexType)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000126{
127 if (mIndexBuffer->getBufferSize() == 0)
128 {
Jamie Madillb1565902018-07-27 08:12:48 -0400129 return mIndexBuffer->initialize(context, bufferSize, indexType, mDynamic);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000130 }
131 else
132 {
Jamie Madillb1565902018-07-27 08:12:48 -0400133 return mIndexBuffer->setSize(context, bufferSize, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000134 }
135}
136
Jamie Madillfd1bf4e2015-03-31 09:46:02 -0400137StreamingIndexBufferInterface::StreamingIndexBufferInterface(BufferFactoryD3D *factory)
138 : IndexBufferInterface(factory, true)
Jamie Madillb980c562018-11-27 11:34:27 -0500139{}
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000140
Jamie Madillb980c562018-11-27 11:34:27 -0500141StreamingIndexBufferInterface::~StreamingIndexBufferInterface() {}
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000142
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400143angle::Result StreamingIndexBufferInterface::reserveBufferSpace(const gl::Context *context,
144 unsigned int size,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500145 gl::DrawElementsType indexType)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000146{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000147 unsigned int curBufferSize = getBufferSize();
Jamie Madillb980c562018-11-27 11:34:27 -0500148 unsigned int writePos = getWritePosition();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000149 if (size > curBufferSize)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000150 {
Jamie Madillb1565902018-07-27 08:12:48 -0400151 ANGLE_TRY(setBufferSize(context, std::max(size, 2 * curBufferSize), indexType));
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000152 setWritePosition(0);
153 }
Geoff Langd81cf642013-07-09 16:02:30 -0400154 else if (writePos + size > curBufferSize || writePos + size < writePos)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000155 {
Jamie Madillb1565902018-07-27 08:12:48 -0400156 ANGLE_TRY(discard(context));
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000157 setWritePosition(0);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000158 }
159
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400160 return angle::Result::Continue();
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000161}
162
Jamie Madillfd1bf4e2015-03-31 09:46:02 -0400163StaticIndexBufferInterface::StaticIndexBufferInterface(BufferFactoryD3D *factory)
164 : IndexBufferInterface(factory, false)
Jamie Madillb980c562018-11-27 11:34:27 -0500165{}
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000166
Jamie Madillb980c562018-11-27 11:34:27 -0500167StaticIndexBufferInterface::~StaticIndexBufferInterface() {}
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000168
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400169angle::Result StaticIndexBufferInterface::reserveBufferSpace(const gl::Context *context,
170 unsigned int size,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500171 gl::DrawElementsType 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 {
Jamie Madillb1565902018-07-27 08:12:48 -0400176 return setBufferSize(context, size, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000177 }
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400178
179 ASSERT(curSize >= size && indexType == getIndexType());
180 return angle::Result::Continue();
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000181}
182
Jamie Madill87718a82017-11-13 15:01:19 -0500183} // namespace rx