blob: 5ff4b90cea5fb79c1df5d11ff86987bd0ccd05a7 [file] [log] [blame]
daniel@transgaming.com29787c32012-12-20 20:55:48 +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
daniel@transgaming.comdcfb1f72012-12-20 20:57:03 +00007// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface
8// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
daniel@transgaming.com29787c32012-12-20 20:55:48 +00009
10#include "libGLESv2/renderer/VertexBuffer.h"
11
12#include "libGLESv2/renderer/Renderer9.h"
13
14namespace rx
15{
16
daniel@transgaming.comdcfb1f72012-12-20 20:57:03 +000017unsigned int VertexBuffer::mNextSerial = 1;
18
19VertexBuffer::VertexBuffer()
20{
21 updateSerial();
22}
23
24VertexBuffer::~VertexBuffer()
25{
26}
27
28void VertexBuffer::updateSerial()
29{
30 mSerial = mNextSerial++;
31}
32
33unsigned int VertexBuffer::getSerial() const
34{
35 return mSerial;
36}
37
38
daniel@transgaming.come4e45062012-12-20 20:56:53 +000039unsigned int VertexBufferInterface::mCurrentSerial = 1;
daniel@transgaming.com29787c32012-12-20 20:55:48 +000040
daniel@transgaming.come4e45062012-12-20 20:56:53 +000041VertexBufferInterface::VertexBufferInterface(rx::Renderer9 *renderer, std::size_t size, DWORD usageFlags) : mRenderer(renderer), mVertexBuffer(NULL)
daniel@transgaming.com29787c32012-12-20 20:55:48 +000042{
43 if (size > 0)
44 {
45 // D3D9_REPLACE
46 HRESULT result = mRenderer->createVertexBuffer(size, usageFlags,&mVertexBuffer);
47 mSerial = issueSerial();
48
49 if (FAILED(result))
50 {
51 ERR("Out of memory allocating a vertex buffer of size %lu.", size);
52 }
53 }
daniel@transgaming.coma41d07f2012-12-20 20:55:57 +000054
55 mBufferSize = size;
56 mWritePosition = 0;
57 mRequiredSpace = 0;
daniel@transgaming.com29787c32012-12-20 20:55:48 +000058}
59
daniel@transgaming.come4e45062012-12-20 20:56:53 +000060VertexBufferInterface::~VertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +000061{
62 if (mVertexBuffer)
63 {
64 mVertexBuffer->Release();
65 }
66}
67
daniel@transgaming.come4e45062012-12-20 20:56:53 +000068void VertexBufferInterface::unmap()
daniel@transgaming.com29787c32012-12-20 20:55:48 +000069{
70 if (mVertexBuffer)
71 {
72 mVertexBuffer->Unlock();
73 }
74}
75
daniel@transgaming.come4e45062012-12-20 20:56:53 +000076IDirect3DVertexBuffer9 *VertexBufferInterface::getBuffer() const
daniel@transgaming.com29787c32012-12-20 20:55:48 +000077{
78 return mVertexBuffer;
79}
80
daniel@transgaming.come4e45062012-12-20 20:56:53 +000081unsigned int VertexBufferInterface::getSerial() const
daniel@transgaming.com29787c32012-12-20 20:55:48 +000082{
83 return mSerial;
84}
85
daniel@transgaming.come4e45062012-12-20 20:56:53 +000086unsigned int VertexBufferInterface::issueSerial()
daniel@transgaming.com29787c32012-12-20 20:55:48 +000087{
88 return mCurrentSerial++;
89}
90
daniel@transgaming.come4e45062012-12-20 20:56:53 +000091void VertexBufferInterface::addRequiredSpace(UINT requiredSpace)
daniel@transgaming.com29787c32012-12-20 20:55:48 +000092{
93 mRequiredSpace += requiredSpace;
94}
95
daniel@transgaming.come4e45062012-12-20 20:56:53 +000096StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer9 *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, initialSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY)
daniel@transgaming.com29787c32012-12-20 20:55:48 +000097{
98}
99
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000100StreamingVertexBufferInterface::~StreamingVertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000101{
102}
103
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000104void *StreamingVertexBufferInterface::map(const gl::VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *offset)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000105{
106 void *mapPtr = NULL;
107
108 if (mVertexBuffer)
109 {
110 HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
111
112 if (FAILED(result))
113 {
114 ERR("Lock failed with error 0x%08x", result);
115 return NULL;
116 }
117
118 *offset = mWritePosition;
119 mWritePosition += requiredSpace;
120 }
121
122 return mapPtr;
123}
124
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000125void StreamingVertexBufferInterface::reserveRequiredSpace()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000126{
127 if (mRequiredSpace > mBufferSize)
128 {
129 if (mVertexBuffer)
130 {
131 mVertexBuffer->Release();
132 mVertexBuffer = NULL;
133 }
134
135 mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2); // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.
136
137 // D3D9_REPLACE
138 HRESULT result = mRenderer->createVertexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, &mVertexBuffer);
139 mSerial = issueSerial();
140
141 if (FAILED(result))
142 {
143 ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
144 }
145
146 mWritePosition = 0;
147 }
148 else if (mWritePosition + mRequiredSpace > mBufferSize) // Recycle
149 {
150 if (mVertexBuffer)
151 {
152 void *dummy;
153 mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
154 mVertexBuffer->Unlock();
155 }
156
157 mWritePosition = 0;
158 }
159
160 mRequiredSpace = 0;
161}
162
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000163StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer9 *renderer) : VertexBufferInterface(renderer, 0, D3DUSAGE_WRITEONLY)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000164{
165}
166
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000167StaticVertexBufferInterface::~StaticVertexBufferInterface()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000168{
169}
170
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000171void *StaticVertexBufferInterface::map(const gl::VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000172{
173 void *mapPtr = NULL;
174
175 if (mVertexBuffer)
176 {
177 HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, 0);
178
179 if (FAILED(result))
180 {
181 ERR("Lock failed with error 0x%08x", result);
182 return NULL;
183 }
184
185 int attributeOffset = attribute.mOffset % attribute.stride();
186 VertexElement element = {attribute.mType, attribute.mSize, attribute.stride(), attribute.mNormalized, attributeOffset, mWritePosition};
187 mCache.push_back(element);
188
189 *streamOffset = mWritePosition;
190 mWritePosition += requiredSpace;
191 }
192
193 return mapPtr;
194}
195
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000196void StaticVertexBufferInterface::reserveRequiredSpace()
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000197{
198 if (!mVertexBuffer && mBufferSize == 0)
199 {
200 // D3D9_REPLACE
201 HRESULT result = mRenderer->createVertexBuffer(mRequiredSpace, D3DUSAGE_WRITEONLY, &mVertexBuffer);
202 mSerial = issueSerial();
203
204 if (FAILED(result))
205 {
206 ERR("Out of memory allocating a vertex buffer of size %lu.", mRequiredSpace);
207 }
208
209 mBufferSize = mRequiredSpace;
210 }
211 else if (mVertexBuffer && mBufferSize >= mRequiredSpace)
212 {
213 // Already allocated
214 }
215 else UNREACHABLE(); // Static vertex buffers can't be resized
216
217 mRequiredSpace = 0;
218}
219
daniel@transgaming.come4e45062012-12-20 20:56:53 +0000220std::size_t StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute)
daniel@transgaming.com29787c32012-12-20 20:55:48 +0000221{
222 for (unsigned int element = 0; element < mCache.size(); element++)
223 {
224 if (mCache[element].type == attribute.mType &&
225 mCache[element].size == attribute.mSize &&
226 mCache[element].stride == attribute.stride() &&
227 mCache[element].normalized == attribute.mNormalized)
228 {
229 if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
230 {
231 return mCache[element].streamOffset;
232 }
233 }
234 }
235
236 return -1;
237}
238
239}