blob: 5376e6c40c77f6165134a0afedcb7089ecce1f3e [file] [log] [blame]
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00001//
daniel@transgaming.com8ca9c6e2012-01-27 15:38:54 +00002// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00003// 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.com8fd34bd2011-02-18 02:52:14 +00007// VertexDataManager.h: Defines the VertexDataManager, a class that
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +00008// runs the Buffer translation process.
9
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/renderer/d3d/VertexDataManager.h"
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040011
Geoff Lang2b5420c2014-11-19 14:20:15 -050012#include "libANGLE/Buffer.h"
Geoff Lang7dd2e102014-11-10 15:19:26 -050013#include "libANGLE/Program.h"
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040014#include "libANGLE/State.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050015#include "libANGLE/VertexAttribute.h"
Geoff Lang5ead9272015-03-25 12:27:43 -040016#include "libANGLE/VertexArray.h"
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040017#include "libANGLE/renderer/d3d/BufferD3D.h"
18#include "libANGLE/renderer/d3d/VertexBuffer.h"
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +000019
20namespace
21{
22 enum { INITIAL_STREAM_BUFFER_SIZE = 1024*1024 };
jbauman@chromium.org83b61bc2011-09-02 18:59:24 +000023 // This has to be at least 4k or else it fails on ATI cards.
24 enum { CONSTANT_VERTEX_BUFFER_SIZE = 4096 };
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +000025}
26
daniel@transgaming.com31240482012-11-28 21:06:41 +000027namespace rx
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +000028{
29
Brandon Jones5bf98292014-06-06 17:19:38 -070030static int ElementsInBuffer(const gl::VertexAttribute &attrib, unsigned int size)
jbauman@chromium.org059fc152011-11-18 19:26:17 +000031{
Geoff Langa36ead42013-08-02 11:54:08 -040032 // Size cannot be larger than a GLsizei
33 if (size > static_cast<unsigned int>(std::numeric_limits<int>::max()))
34 {
35 size = static_cast<unsigned int>(std::numeric_limits<int>::max());
36 }
37
Cooper Partin4d61f7e2015-08-12 10:56:50 -070038 GLsizei stride = static_cast<GLsizei>(ComputeVertexAttributeStride(attrib));
39 return (size - attrib.offset % stride +
40 (stride - static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib)))) /
41 stride;
jbauman@chromium.org059fc152011-11-18 19:26:17 +000042}
43
Jamie Madillb3f4e8d2015-06-22 13:57:17 -040044VertexDataManager::CurrentValueState::CurrentValueState()
45 : buffer(nullptr),
46 offset(0)
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +000047{
Jamie Madillb3f4e8d2015-06-22 13:57:17 -040048 data.FloatValues[0] = std::numeric_limits<float>::quiet_NaN();
49 data.FloatValues[1] = std::numeric_limits<float>::quiet_NaN();
50 data.FloatValues[2] = std::numeric_limits<float>::quiet_NaN();
51 data.FloatValues[3] = std::numeric_limits<float>::quiet_NaN();
52 data.Type = GL_FLOAT;
53}
daniel@transgaming.com83921382011-01-08 05:46:00 +000054
Jamie Madillb3f4e8d2015-06-22 13:57:17 -040055VertexDataManager::CurrentValueState::~CurrentValueState()
56{
57 SafeDelete(buffer);
58}
59
60VertexDataManager::VertexDataManager(BufferFactoryD3D *factory)
61 : mFactory(factory),
62 mStreamingBuffer(nullptr),
63 // TODO(jmadill): use context caps
64 mCurrentValueCache(gl::MAX_VERTEX_ATTRIBS)
65{
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040066 mStreamingBuffer = new StreamingVertexBufferInterface(factory, INITIAL_STREAM_BUFFER_SIZE);
daniel@transgaming.com72b9e182011-04-13 14:58:33 +000067
68 if (!mStreamingBuffer)
69 {
70 ERR("Failed to allocate the streaming vertex buffer.");
71 }
Jamie Madill27c08912015-06-22 13:57:20 -040072
73 // TODO(jmadill): use context caps
74 mActiveEnabledAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
75 mActiveDisabledAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +000076}
77
78VertexDataManager::~VertexDataManager()
79{
Jamie Madillb3f4e8d2015-06-22 13:57:17 -040080 SafeDelete(mStreamingBuffer);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +000081}
82
Geoff Lang5ead9272015-03-25 12:27:43 -040083void VertexDataManager::hintUnmapAllResources(const std::vector<gl::VertexAttribute> &vertexAttributes)
Austin Kinrossbe0facc2015-01-07 16:22:29 -080084{
85 mStreamingBuffer->getVertexBuffer()->hintUnmapResource();
86
Jamie Madill27c08912015-06-22 13:57:20 -040087 for (const TranslatedAttribute *translated : mActiveEnabledAttributes)
Austin Kinrossbe0facc2015-01-07 16:22:29 -080088 {
Jamie Madill27c08912015-06-22 13:57:20 -040089 gl::Buffer *buffer = translated->attribute->buffer.get();
90 BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr;
Austin Kinross84b0c3b2015-11-05 15:15:28 -080091 StaticVertexBufferInterface *staticBuffer =
92 storage
93 ? storage->getStaticVertexBuffer(*translated->attribute, D3D_BUFFER_DO_NOT_CREATE)
94 : nullptr;
Austin Kinrossbe0facc2015-01-07 16:22:29 -080095
Jamie Madill27c08912015-06-22 13:57:20 -040096 if (staticBuffer)
97 {
Austin Kinross84b0c3b2015-11-05 15:15:28 -080098 // Commit all the static vertex buffers. This fixes them in size/contents, and forces
99 // ANGLE to use a new static buffer (or recreate the static buffers) next time
100 staticBuffer->commit();
101
Jamie Madill27c08912015-06-22 13:57:20 -0400102 staticBuffer->getVertexBuffer()->hintUnmapResource();
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800103 }
104 }
105
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400106 for (auto &currentValue : mCurrentValueCache)
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800107 {
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400108 if (currentValue.buffer != nullptr)
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800109 {
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400110 currentValue.buffer->getVertexBuffer()->hintUnmapResource();
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800111 }
112 }
113}
114
Jamie Madill476682e2015-06-30 10:04:29 -0400115gl::Error VertexDataManager::prepareVertexData(const gl::State &state,
116 GLint start,
117 GLsizei count,
118 std::vector<TranslatedAttribute> *translatedAttribs,
119 GLsizei instances)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000120{
daniel@transgaming.com72b9e182011-04-13 14:58:33 +0000121 if (!mStreamingBuffer)
122 {
Geoff Langf7100b92014-09-08 16:17:08 -0400123 return gl::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL.");
daniel@transgaming.com72b9e182011-04-13 14:58:33 +0000124 }
125
Jamie Madill27c08912015-06-22 13:57:20 -0400126 // Compute active enabled and active disable attributes, for speed.
127 // TODO(jmadill): don't recompute if there was no state change
Geoff Lang5ead9272015-03-25 12:27:43 -0400128 const gl::VertexArray *vertexArray = state.getVertexArray();
Jamie Madill63805b42015-08-25 13:17:39 -0400129 const gl::Program *program = state.getProgram();
130 const auto &vertexAttributes = vertexArray->getVertexAttributes();
Geoff Lang5ead9272015-03-25 12:27:43 -0400131
Jamie Madill27c08912015-06-22 13:57:20 -0400132 mActiveEnabledAttributes.clear();
133 mActiveDisabledAttributes.clear();
Jamie Madill476682e2015-06-30 10:04:29 -0400134 translatedAttribs->clear();
Jamie Madill27c08912015-06-22 13:57:20 -0400135
Jamie Madill9c385802015-06-22 13:57:18 -0400136 for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex)
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000137 {
Jamie Madill63805b42015-08-25 13:17:39 -0400138 if (program->isAttribLocationActive(attribIndex))
daniel@transgaming.comc828b142010-05-12 03:42:04 +0000139 {
Jamie Madill476682e2015-06-30 10:04:29 -0400140 // Resize automatically puts in empty attribs
141 translatedAttribs->resize(attribIndex + 1);
142
143 TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex];
144
Jamie Madill9c385802015-06-22 13:57:18 -0400145 // Record the attribute now
Jamie Madill476682e2015-06-30 10:04:29 -0400146 translated->active = true;
147 translated->attribute = &vertexAttributes[attribIndex];
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700148 translated->currentValueType =
149 state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex)).Type;
Jamie Madill476682e2015-06-30 10:04:29 -0400150 translated->divisor = vertexAttributes[attribIndex].divisor;
Jamie Madill9c385802015-06-22 13:57:18 -0400151
152 if (vertexAttributes[attribIndex].enabled)
153 {
Jamie Madill476682e2015-06-30 10:04:29 -0400154 mActiveEnabledAttributes.push_back(translated);
Jamie Madill27c08912015-06-22 13:57:20 -0400155
Austin Kinross84b0c3b2015-11-05 15:15:28 -0800156 gl::Buffer *buffer = vertexAttributes[attribIndex].buffer.get();
157 if (buffer)
158 {
159 // Also reinitialize static buffers which didn't contain matching data
160 // last time they were used
161 BufferD3D *bufferImpl = GetImplAs<BufferD3D>(buffer);
162 bufferImpl->reinitOutOfDateStaticData();
163 }
Jamie Madill9c385802015-06-22 13:57:18 -0400164 }
Jamie Madill27c08912015-06-22 13:57:20 -0400165 else
166 {
167 mActiveDisabledAttributes.push_back(attribIndex);
168 }
shannon.woods@transgaming.coma9a509e2013-02-28 23:10:44 +0000169 }
170 }
171
172 // Reserve the required space in the buffers
Jamie Madill16f99b72015-07-02 14:09:06 -0400173 for (const TranslatedAttribute *activeAttrib : mActiveEnabledAttributes)
shannon.woods@transgaming.coma9a509e2013-02-28 23:10:44 +0000174 {
Jamie Madill16f99b72015-07-02 14:09:06 -0400175 gl::Error error = reserveSpaceForAttrib(*activeAttrib, count, instances);
Jamie Madill27c08912015-06-22 13:57:20 -0400176 if (error.isError())
shannon.woods@transgaming.coma9a509e2013-02-28 23:10:44 +0000177 {
Jamie Madill27c08912015-06-22 13:57:20 -0400178 return error;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000179 }
180 }
181
182 // Perform the vertex data translations
Jamie Madill16f99b72015-07-02 14:09:06 -0400183 for (TranslatedAttribute *activeAttrib : mActiveEnabledAttributes)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000184 {
Jamie Madill16f99b72015-07-02 14:09:06 -0400185 gl::Error error = storeAttribute(activeAttrib, start, count, instances);
Jamie Madill27c08912015-06-22 13:57:20 -0400186
187 if (error.isError())
daniel@transgaming.com83921382011-01-08 05:46:00 +0000188 {
Jamie Madill27c08912015-06-22 13:57:20 -0400189 hintUnmapAllResources(vertexAttributes);
190 return error;
191 }
192 }
Shannon Woods1a965482014-09-22 18:00:32 -0400193
Jamie Madill27c08912015-06-22 13:57:20 -0400194 for (size_t attribIndex : mActiveDisabledAttributes)
195 {
196 if (mCurrentValueCache[attribIndex].buffer == nullptr)
197 {
198 mCurrentValueCache[attribIndex].buffer = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE);
199 }
jbauman@chromium.org83b61bc2011-09-02 18:59:24 +0000200
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700201 gl::Error error = storeCurrentValue(
202 state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex)),
203 &(*translatedAttribs)[attribIndex], &mCurrentValueCache[attribIndex]);
Jamie Madill27c08912015-06-22 13:57:20 -0400204 if (error.isError())
205 {
206 hintUnmapAllResources(vertexAttributes);
207 return error;
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000208 }
209 }
apatrick@chromium.orgf99fbb72010-11-16 01:57:05 +0000210
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800211 // Hint to unmap all the resources
Geoff Lang5ead9272015-03-25 12:27:43 -0400212 hintUnmapAllResources(vertexAttributes);
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800213
Jamie Madill16f99b72015-07-02 14:09:06 -0400214 for (const TranslatedAttribute *activeAttrib : mActiveEnabledAttributes)
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000215 {
Jamie Madill16f99b72015-07-02 14:09:06 -0400216 gl::Buffer *buffer = activeAttrib->attribute->buffer.get();
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000217
Jamie Madill27c08912015-06-22 13:57:20 -0400218 if (buffer)
219 {
220 BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
Jamie Madill16f99b72015-07-02 14:09:06 -0400221 size_t typeSize = ComputeVertexAttributeTypeSize(*activeAttrib->attribute);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700222 bufferD3D->promoteStaticUsage(count * static_cast<int>(typeSize));
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000223 }
224 }
225
Geoff Langf7100b92014-09-08 16:17:08 -0400226 return gl::Error(GL_NO_ERROR);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000227}
228
Jamie Madill3d72cc72015-06-22 13:57:19 -0400229gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &translatedAttrib,
Geoff Langf7100b92014-09-08 16:17:08 -0400230 GLsizei count,
231 GLsizei instances) const
Jamie Madill6d113802014-08-25 15:47:52 -0400232{
Jamie Madill3d72cc72015-06-22 13:57:19 -0400233 const gl::VertexAttribute &attrib = *translatedAttrib.attribute;
Jamie Madill6d113802014-08-25 15:47:52 -0400234 gl::Buffer *buffer = attrib.buffer.get();
Jamie Madill9236b412015-02-02 16:51:52 -0500235 BufferD3D *bufferImpl = buffer ? GetImplAs<BufferD3D>(buffer) : NULL;
Austin Kinross84b0c3b2015-11-05 15:15:28 -0800236 StaticVertexBufferInterface *staticBuffer =
237 bufferImpl ? bufferImpl->getStaticVertexBuffer(attrib, D3D_BUFFER_CREATE_IF_NECESSARY)
238 : NULL;
Jamie Madill6d113802014-08-25 15:47:52 -0400239 VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
240
Jamie Madill3d72cc72015-06-22 13:57:19 -0400241 if (!vertexBuffer->directStoragePossible(attrib, translatedAttrib.currentValueType))
Jamie Madill6d113802014-08-25 15:47:52 -0400242 {
243 if (staticBuffer)
244 {
245 if (staticBuffer->getBufferSize() == 0)
246 {
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700247 int totalCount =
248 ElementsInBuffer(attrib, static_cast<unsigned int>(bufferImpl->getSize()));
Geoff Langf7100b92014-09-08 16:17:08 -0400249 gl::Error error = staticBuffer->reserveVertexSpace(attrib, totalCount, 0);
250 if (error.isError())
Jamie Madill6d113802014-08-25 15:47:52 -0400251 {
Geoff Langf7100b92014-09-08 16:17:08 -0400252 return error;
Jamie Madill6d113802014-08-25 15:47:52 -0400253 }
254 }
255 }
256 else
257 {
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400258 size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700259 ASSERT(!bufferImpl ||
260 ElementsInBuffer(attrib, static_cast<unsigned int>(bufferImpl->getSize())) >=
Jamie Madill846f1072015-09-01 09:07:15 -0400261 static_cast<int>(totalCount));
Jamie Madill6d113802014-08-25 15:47:52 -0400262
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400263 gl::Error error = mStreamingBuffer->reserveVertexSpace(
264 attrib, static_cast<GLsizei>(totalCount), instances);
Geoff Langf7100b92014-09-08 16:17:08 -0400265 if (error.isError())
Jamie Madill6d113802014-08-25 15:47:52 -0400266 {
Geoff Langf7100b92014-09-08 16:17:08 -0400267 return error;
Jamie Madill6d113802014-08-25 15:47:52 -0400268 }
269 }
270 }
271
Geoff Langf7100b92014-09-08 16:17:08 -0400272 return gl::Error(GL_NO_ERROR);
Jamie Madill6d113802014-08-25 15:47:52 -0400273}
274
Jamie Madill3d72cc72015-06-22 13:57:19 -0400275gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated,
Geoff Langf7100b92014-09-08 16:17:08 -0400276 GLint start,
277 GLsizei count,
278 GLsizei instances)
Jamie Madillf41522b2014-08-18 16:39:49 -0400279{
Jamie Madill9c385802015-06-22 13:57:18 -0400280 const gl::VertexAttribute &attrib = *translated->attribute;
281
Jamie Madillf41522b2014-08-18 16:39:49 -0400282 gl::Buffer *buffer = attrib.buffer.get();
Jamie Madill2b976812014-08-25 15:47:49 -0400283 ASSERT(buffer || attrib.pointer);
Jamie Madill7d112bb2015-06-22 13:57:19 -0400284 ASSERT(attrib.enabled);
Jamie Madillf41522b2014-08-18 16:39:49 -0400285
Jamie Madill9236b412015-02-02 16:51:52 -0500286 BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : NULL;
Austin Kinross84b0c3b2015-11-05 15:15:28 -0800287 StaticVertexBufferInterface *staticBuffer =
288 storage ? storage->getStaticVertexBuffer(attrib, D3D_BUFFER_DO_NOT_CREATE) : NULL;
Jamie Madillf41522b2014-08-18 16:39:49 -0400289 VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
Jamie Madill3d72cc72015-06-22 13:57:19 -0400290 bool directStorage = vertexBuffer->directStoragePossible(attrib, translated->currentValueType);
Jamie Madillf41522b2014-08-18 16:39:49 -0400291
Jamie Madilld4b55a02015-01-09 14:21:49 -0500292 // Instanced vertices do not apply the 'start' offset
293 GLint firstVertexIndex = (instances > 0 && attrib.divisor > 0 ? 0 : start);
294
Jamie Madill7d112bb2015-06-22 13:57:19 -0400295 translated->vertexBuffer = vertexBuffer->getVertexBuffer();
296
Jamie Madillf41522b2014-08-18 16:39:49 -0400297 if (directStorage)
298 {
Jamie Madill7d112bb2015-06-22 13:57:19 -0400299 translated->storage = storage;
300 translated->serial = storage->getSerial();
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700301 translated->stride = static_cast<unsigned int>(ComputeVertexAttributeStride(attrib));
Jamie Madill7d112bb2015-06-22 13:57:19 -0400302 translated->offset = static_cast<unsigned int>(attrib.offset + translated->stride * firstVertexIndex);
303
304 return gl::Error(GL_NO_ERROR);
Jamie Madillf41522b2014-08-18 16:39:49 -0400305 }
Jamie Madill7d112bb2015-06-22 13:57:19 -0400306
307 // Compute source data pointer
308 const uint8_t *sourceData = nullptr;
309
310 if (buffer)
311 {
312 gl::Error error = storage->getData(&sourceData);
313 if (error.isError())
314 {
315 return error;
316 }
317 sourceData += static_cast<int>(attrib.offset);
318 }
319 else
320 {
321 sourceData = static_cast<const uint8_t*>(attrib.pointer);
322 }
323
324 unsigned int streamOffset = 0;
325 unsigned int outputElementSize = 0;
326
327 if (staticBuffer)
Jamie Madillf41522b2014-08-18 16:39:49 -0400328 {
Geoff Langf7100b92014-09-08 16:17:08 -0400329 gl::Error error = staticBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
330 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400331 {
Geoff Langf7100b92014-09-08 16:17:08 -0400332 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400333 }
334
335 if (!staticBuffer->lookupAttribute(attrib, &streamOffset))
336 {
337 // Convert the entire buffer
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700338 int totalCount =
339 ElementsInBuffer(attrib, static_cast<unsigned int>(storage->getSize()));
340 int startIndex = static_cast<int>(attrib.offset) /
341 static_cast<int>(ComputeVertexAttributeStride(attrib));
Jamie Madillf41522b2014-08-18 16:39:49 -0400342
Jamie Madill7d112bb2015-06-22 13:57:19 -0400343 error = staticBuffer->storeVertexAttributes(attrib,
Jamie Madill3d72cc72015-06-22 13:57:19 -0400344 translated->currentValueType,
Jamie Madill7d112bb2015-06-22 13:57:19 -0400345 -startIndex,
346 totalCount,
347 0,
348 &streamOffset,
349 sourceData);
Geoff Langf7100b92014-09-08 16:17:08 -0400350 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400351 {
Geoff Langf7100b92014-09-08 16:17:08 -0400352 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400353 }
354 }
355
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700356 unsigned int firstElementOffset =
357 (static_cast<unsigned int>(attrib.offset) /
358 static_cast<unsigned int>(ComputeVertexAttributeStride(attrib))) *
359 outputElementSize;
Jamie Madilld4b55a02015-01-09 14:21:49 -0500360 unsigned int startOffset = (instances == 0 || attrib.divisor == 0) ? firstVertexIndex * outputElementSize : 0;
Jamie Madillf41522b2014-08-18 16:39:49 -0400361 if (streamOffset + firstElementOffset + startOffset < streamOffset)
362 {
Geoff Langf7100b92014-09-08 16:17:08 -0400363 return gl::Error(GL_OUT_OF_MEMORY);
Jamie Madillf41522b2014-08-18 16:39:49 -0400364 }
365
366 streamOffset += firstElementOffset + startOffset;
367 }
368 else
369 {
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400370 size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
Geoff Langf7100b92014-09-08 16:17:08 -0400371 gl::Error error = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
372 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400373 {
Geoff Langf7100b92014-09-08 16:17:08 -0400374 return error;
375 }
376
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400377 error = mStreamingBuffer->storeVertexAttributes(
378 attrib, translated->currentValueType, firstVertexIndex,
379 static_cast<GLsizei>(totalCount), instances, &streamOffset, sourceData);
Geoff Langf7100b92014-09-08 16:17:08 -0400380 if (error.isError())
381 {
382 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400383 }
384 }
385
Jamie Madill7d112bb2015-06-22 13:57:19 -0400386 translated->storage = nullptr;
387 translated->serial = vertexBuffer->getSerial();
Jamie Madillf41522b2014-08-18 16:39:49 -0400388 translated->stride = outputElementSize;
389 translated->offset = streamOffset;
390
Geoff Langf7100b92014-09-08 16:17:08 -0400391 return gl::Error(GL_NO_ERROR);
Jamie Madillf41522b2014-08-18 16:39:49 -0400392}
393
Jamie Madill9c385802015-06-22 13:57:18 -0400394gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribCurrentValueData &currentValue,
Geoff Langf7100b92014-09-08 16:17:08 -0400395 TranslatedAttribute *translated,
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400396 CurrentValueState *cachedState)
Jamie Madillf41522b2014-08-18 16:39:49 -0400397{
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400398 if (cachedState->data != currentValue)
Jamie Madillf41522b2014-08-18 16:39:49 -0400399 {
Jamie Madill9c385802015-06-22 13:57:18 -0400400 const gl::VertexAttribute &attrib = *translated->attribute;
Jamie Madill27c08912015-06-22 13:57:20 -0400401
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400402 gl::Error error = cachedState->buffer->reserveVertexSpace(attrib, 1, 0);
Geoff Langf7100b92014-09-08 16:17:08 -0400403 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400404 {
Geoff Langf7100b92014-09-08 16:17:08 -0400405 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400406 }
407
Jamie Madill7d112bb2015-06-22 13:57:19 -0400408 const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(currentValue.FloatValues);
Jamie Madillf41522b2014-08-18 16:39:49 -0400409 unsigned int streamOffset;
Jamie Madill3d72cc72015-06-22 13:57:19 -0400410 error = cachedState->buffer->storeVertexAttributes(attrib, currentValue.Type, 0, 1, 0, &streamOffset, sourceData);
Geoff Langf7100b92014-09-08 16:17:08 -0400411 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400412 {
Geoff Langf7100b92014-09-08 16:17:08 -0400413 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400414 }
415
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400416 cachedState->data = currentValue;
417 cachedState->offset = streamOffset;
Jamie Madillf41522b2014-08-18 16:39:49 -0400418 }
419
420 translated->storage = NULL;
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400421 translated->vertexBuffer = cachedState->buffer->getVertexBuffer();
422 translated->serial = cachedState->buffer->getSerial();
Jamie Madillf41522b2014-08-18 16:39:49 -0400423 translated->divisor = 0;
424
Jamie Madillf41522b2014-08-18 16:39:49 -0400425 translated->stride = 0;
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700426 translated->offset = static_cast<unsigned int>(cachedState->offset);
Jamie Madillf41522b2014-08-18 16:39:49 -0400427
Geoff Langf7100b92014-09-08 16:17:08 -0400428 return gl::Error(GL_NO_ERROR);
Jamie Madillf41522b2014-08-18 16:39:49 -0400429}
430
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000431}