blob: 565f730dcdd15d8c3e9efc7735adde7fae9087c7 [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);
78 ANGLE_CHECK_HR(GetImplAs<ContextD3D>(context), !check,
79 "Mapping of internal index buffer would cause an integer overflow.",
80 E_OUTOFMEMORY);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000081
Jamie Madillec1fe5b2018-08-10 10:05:52 -040082 angle::Result error = mIndexBuffer->mapBuffer(context, mWritePosition, size, outMappedMemory);
83 if (error == angle::Result::Stop())
Geoff Langa36ead42013-08-02 11:54:08 -040084 {
85 if (outMappedMemory)
86 {
Yunchao Hed7297bf2017-04-19 15:27:10 +080087 *outMappedMemory = nullptr;
Geoff Langa36ead42013-08-02 11:54:08 -040088 }
Geoff Langc9e69b12014-09-08 16:06:25 -040089 return error;
Geoff Langa36ead42013-08-02 11:54:08 -040090 }
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000091
Geoff Langa36ead42013-08-02 11:54:08 -040092 if (streamOffset)
93 {
94 *streamOffset = mWritePosition;
95 }
96
97 mWritePosition += size;
Jamie Madillec1fe5b2018-08-10 10:05:52 -040098 return angle::Result::Continue();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +000099}
100
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400101angle::Result IndexBufferInterface::unmapBuffer(const gl::Context *context)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000102{
Jamie Madillb1565902018-07-27 08:12:48 -0400103 return mIndexBuffer->unmapBuffer(context);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000104}
105
106IndexBuffer * IndexBufferInterface::getIndexBuffer() const
107{
108 return mIndexBuffer;
109}
110
111unsigned int IndexBufferInterface::getWritePosition() const
112{
113 return mWritePosition;
114}
115
116void IndexBufferInterface::setWritePosition(unsigned int writePosition)
117{
118 mWritePosition = writePosition;
119}
120
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400121angle::Result IndexBufferInterface::discard(const gl::Context *context)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000122{
Jamie Madillb1565902018-07-27 08:12:48 -0400123 return mIndexBuffer->discard(context);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000124}
125
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400126angle::Result IndexBufferInterface::setBufferSize(const gl::Context *context,
127 unsigned int bufferSize,
128 GLenum indexType)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000129{
130 if (mIndexBuffer->getBufferSize() == 0)
131 {
Jamie Madillb1565902018-07-27 08:12:48 -0400132 return mIndexBuffer->initialize(context, bufferSize, indexType, mDynamic);
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000133 }
134 else
135 {
Jamie Madillb1565902018-07-27 08:12:48 -0400136 return mIndexBuffer->setSize(context, bufferSize, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000137 }
138}
139
Jamie Madillfd1bf4e2015-03-31 09:46:02 -0400140StreamingIndexBufferInterface::StreamingIndexBufferInterface(BufferFactoryD3D *factory)
141 : IndexBufferInterface(factory, true)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000142{
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000143}
144
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000145StreamingIndexBufferInterface::~StreamingIndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000146{
147}
148
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400149angle::Result StreamingIndexBufferInterface::reserveBufferSpace(const gl::Context *context,
150 unsigned int size,
151 GLenum indexType)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000152{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000153 unsigned int curBufferSize = getBufferSize();
Geoff Langd81cf642013-07-09 16:02:30 -0400154 unsigned int writePos = getWritePosition();
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000155 if (size > curBufferSize)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000156 {
Jamie Madillb1565902018-07-27 08:12:48 -0400157 ANGLE_TRY(setBufferSize(context, std::max(size, 2 * curBufferSize), indexType));
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000158 setWritePosition(0);
159 }
Geoff Langd81cf642013-07-09 16:02:30 -0400160 else if (writePos + size > curBufferSize || writePos + size < writePos)
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000161 {
Jamie Madillb1565902018-07-27 08:12:48 -0400162 ANGLE_TRY(discard(context));
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000163 setWritePosition(0);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000164 }
165
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400166 return angle::Result::Continue();
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000167}
168
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000169
Jamie Madillfd1bf4e2015-03-31 09:46:02 -0400170StaticIndexBufferInterface::StaticIndexBufferInterface(BufferFactoryD3D *factory)
171 : IndexBufferInterface(factory, false)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000172{
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000173}
174
daniel@transgaming.com50cc7252012-12-20 21:09:23 +0000175StaticIndexBufferInterface::~StaticIndexBufferInterface()
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000176{
177}
178
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400179angle::Result StaticIndexBufferInterface::reserveBufferSpace(const gl::Context *context,
180 unsigned int size,
181 GLenum indexType)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000182{
daniel@transgaming.com1e3a8042012-12-20 21:09:55 +0000183 unsigned int curSize = getBufferSize();
184 if (curSize == 0)
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000185 {
Jamie Madillb1565902018-07-27 08:12:48 -0400186 return setBufferSize(context, size, indexType);
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000187 }
Jamie Madillec1fe5b2018-08-10 10:05:52 -0400188
189 ASSERT(curSize >= size && indexType == getIndexType());
190 return angle::Result::Continue();
daniel@transgaming.com955377e2012-12-20 21:09:15 +0000191}
192
Jamie Madill87718a82017-11-13 15:01:19 -0500193} // namespace rx