blob: 559e633eaa8ddc78e7342f428a16c2454f042b8c [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;
91 StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : nullptr;
Austin Kinrossbe0facc2015-01-07 16:22:29 -080092
Jamie Madill27c08912015-06-22 13:57:20 -040093 if (staticBuffer)
94 {
95 staticBuffer->getVertexBuffer()->hintUnmapResource();
Austin Kinrossbe0facc2015-01-07 16:22:29 -080096 }
97 }
98
Jamie Madillb3f4e8d2015-06-22 13:57:17 -040099 for (auto &currentValue : mCurrentValueCache)
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800100 {
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400101 if (currentValue.buffer != nullptr)
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800102 {
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400103 currentValue.buffer->getVertexBuffer()->hintUnmapResource();
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800104 }
105 }
106}
107
Jamie Madill476682e2015-06-30 10:04:29 -0400108gl::Error VertexDataManager::prepareVertexData(const gl::State &state,
109 GLint start,
110 GLsizei count,
111 std::vector<TranslatedAttribute> *translatedAttribs,
112 GLsizei instances)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000113{
daniel@transgaming.com72b9e182011-04-13 14:58:33 +0000114 if (!mStreamingBuffer)
115 {
Geoff Langf7100b92014-09-08 16:17:08 -0400116 return gl::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL.");
daniel@transgaming.com72b9e182011-04-13 14:58:33 +0000117 }
118
Jamie Madill27c08912015-06-22 13:57:20 -0400119 // Compute active enabled and active disable attributes, for speed.
120 // TODO(jmadill): don't recompute if there was no state change
Geoff Lang5ead9272015-03-25 12:27:43 -0400121 const gl::VertexArray *vertexArray = state.getVertexArray();
Jamie Madill63805b42015-08-25 13:17:39 -0400122 const gl::Program *program = state.getProgram();
123 const auto &vertexAttributes = vertexArray->getVertexAttributes();
Geoff Lang5ead9272015-03-25 12:27:43 -0400124
Jamie Madill27c08912015-06-22 13:57:20 -0400125 mActiveEnabledAttributes.clear();
126 mActiveDisabledAttributes.clear();
Jamie Madill476682e2015-06-30 10:04:29 -0400127 translatedAttribs->clear();
Jamie Madill27c08912015-06-22 13:57:20 -0400128
Jamie Madill9c385802015-06-22 13:57:18 -0400129 for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex)
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000130 {
Jamie Madill63805b42015-08-25 13:17:39 -0400131 if (program->isAttribLocationActive(attribIndex))
daniel@transgaming.comc828b142010-05-12 03:42:04 +0000132 {
Jamie Madill476682e2015-06-30 10:04:29 -0400133 // Resize automatically puts in empty attribs
134 translatedAttribs->resize(attribIndex + 1);
135
136 TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex];
137
Jamie Madill9c385802015-06-22 13:57:18 -0400138 // Record the attribute now
Jamie Madill476682e2015-06-30 10:04:29 -0400139 translated->active = true;
140 translated->attribute = &vertexAttributes[attribIndex];
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700141 translated->currentValueType =
142 state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex)).Type;
Jamie Madill476682e2015-06-30 10:04:29 -0400143 translated->divisor = vertexAttributes[attribIndex].divisor;
Jamie Madill9c385802015-06-22 13:57:18 -0400144
145 if (vertexAttributes[attribIndex].enabled)
146 {
Jamie Madill476682e2015-06-30 10:04:29 -0400147 mActiveEnabledAttributes.push_back(translated);
Jamie Madill27c08912015-06-22 13:57:20 -0400148
Jamie Madill9c385802015-06-22 13:57:18 -0400149 // Also invalidate static buffers that don't contain matching attributes
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700150 invalidateMatchingStaticData(
151 vertexAttributes[attribIndex],
152 state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex)));
Jamie Madill9c385802015-06-22 13:57:18 -0400153 }
Jamie Madill27c08912015-06-22 13:57:20 -0400154 else
155 {
156 mActiveDisabledAttributes.push_back(attribIndex);
157 }
shannon.woods@transgaming.coma9a509e2013-02-28 23:10:44 +0000158 }
159 }
160
161 // Reserve the required space in the buffers
Jamie Madill16f99b72015-07-02 14:09:06 -0400162 for (const TranslatedAttribute *activeAttrib : mActiveEnabledAttributes)
shannon.woods@transgaming.coma9a509e2013-02-28 23:10:44 +0000163 {
Jamie Madill16f99b72015-07-02 14:09:06 -0400164 gl::Error error = reserveSpaceForAttrib(*activeAttrib, count, instances);
Jamie Madill27c08912015-06-22 13:57:20 -0400165 if (error.isError())
shannon.woods@transgaming.coma9a509e2013-02-28 23:10:44 +0000166 {
Jamie Madill27c08912015-06-22 13:57:20 -0400167 return error;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000168 }
169 }
170
171 // Perform the vertex data translations
Jamie Madill16f99b72015-07-02 14:09:06 -0400172 for (TranslatedAttribute *activeAttrib : mActiveEnabledAttributes)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000173 {
Jamie Madill16f99b72015-07-02 14:09:06 -0400174 gl::Error error = storeAttribute(activeAttrib, start, count, instances);
Jamie Madill27c08912015-06-22 13:57:20 -0400175
176 if (error.isError())
daniel@transgaming.com83921382011-01-08 05:46:00 +0000177 {
Jamie Madill27c08912015-06-22 13:57:20 -0400178 hintUnmapAllResources(vertexAttributes);
179 return error;
180 }
181 }
Shannon Woods1a965482014-09-22 18:00:32 -0400182
Jamie Madill27c08912015-06-22 13:57:20 -0400183 for (size_t attribIndex : mActiveDisabledAttributes)
184 {
185 if (mCurrentValueCache[attribIndex].buffer == nullptr)
186 {
187 mCurrentValueCache[attribIndex].buffer = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE);
188 }
jbauman@chromium.org83b61bc2011-09-02 18:59:24 +0000189
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700190 gl::Error error = storeCurrentValue(
191 state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex)),
192 &(*translatedAttribs)[attribIndex], &mCurrentValueCache[attribIndex]);
Jamie Madill27c08912015-06-22 13:57:20 -0400193 if (error.isError())
194 {
195 hintUnmapAllResources(vertexAttributes);
196 return error;
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000197 }
198 }
apatrick@chromium.orgf99fbb72010-11-16 01:57:05 +0000199
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800200 // Hint to unmap all the resources
Geoff Lang5ead9272015-03-25 12:27:43 -0400201 hintUnmapAllResources(vertexAttributes);
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800202
Jamie Madill16f99b72015-07-02 14:09:06 -0400203 for (const TranslatedAttribute *activeAttrib : mActiveEnabledAttributes)
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000204 {
Jamie Madill16f99b72015-07-02 14:09:06 -0400205 gl::Buffer *buffer = activeAttrib->attribute->buffer.get();
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000206
Jamie Madill27c08912015-06-22 13:57:20 -0400207 if (buffer)
208 {
209 BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
Jamie Madill16f99b72015-07-02 14:09:06 -0400210 size_t typeSize = ComputeVertexAttributeTypeSize(*activeAttrib->attribute);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700211 bufferD3D->promoteStaticUsage(count * static_cast<int>(typeSize));
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000212 }
213 }
214
Geoff Langf7100b92014-09-08 16:17:08 -0400215 return gl::Error(GL_NO_ERROR);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000216}
217
Jamie Madill6d113802014-08-25 15:47:52 -0400218void VertexDataManager::invalidateMatchingStaticData(const gl::VertexAttribute &attrib,
219 const gl::VertexAttribCurrentValueData &currentValue) const
220{
221 gl::Buffer *buffer = attrib.buffer.get();
222
223 if (buffer)
224 {
Jamie Madill9236b412015-02-02 16:51:52 -0500225 BufferD3D *bufferImpl = GetImplAs<BufferD3D>(buffer);
Jamie Madill6d113802014-08-25 15:47:52 -0400226 StaticVertexBufferInterface *staticBuffer = bufferImpl->getStaticVertexBuffer();
227
228 if (staticBuffer &&
229 staticBuffer->getBufferSize() > 0 &&
230 !staticBuffer->lookupAttribute(attrib, NULL) &&
Jamie Madill3d72cc72015-06-22 13:57:19 -0400231 !staticBuffer->directStoragePossible(attrib, currentValue.Type))
Jamie Madill6d113802014-08-25 15:47:52 -0400232 {
233 bufferImpl->invalidateStaticData();
234 }
235 }
236}
237
Jamie Madill3d72cc72015-06-22 13:57:19 -0400238gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &translatedAttrib,
Geoff Langf7100b92014-09-08 16:17:08 -0400239 GLsizei count,
240 GLsizei instances) const
Jamie Madill6d113802014-08-25 15:47:52 -0400241{
Jamie Madill3d72cc72015-06-22 13:57:19 -0400242 const gl::VertexAttribute &attrib = *translatedAttrib.attribute;
Jamie Madill6d113802014-08-25 15:47:52 -0400243 gl::Buffer *buffer = attrib.buffer.get();
Jamie Madill9236b412015-02-02 16:51:52 -0500244 BufferD3D *bufferImpl = buffer ? GetImplAs<BufferD3D>(buffer) : NULL;
Jamie Madill6d113802014-08-25 15:47:52 -0400245 StaticVertexBufferInterface *staticBuffer = bufferImpl ? bufferImpl->getStaticVertexBuffer() : NULL;
246 VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
247
Jamie Madill3d72cc72015-06-22 13:57:19 -0400248 if (!vertexBuffer->directStoragePossible(attrib, translatedAttrib.currentValueType))
Jamie Madill6d113802014-08-25 15:47:52 -0400249 {
250 if (staticBuffer)
251 {
252 if (staticBuffer->getBufferSize() == 0)
253 {
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700254 int totalCount =
255 ElementsInBuffer(attrib, static_cast<unsigned int>(bufferImpl->getSize()));
Geoff Langf7100b92014-09-08 16:17:08 -0400256 gl::Error error = staticBuffer->reserveVertexSpace(attrib, totalCount, 0);
257 if (error.isError())
Jamie Madill6d113802014-08-25 15:47:52 -0400258 {
Geoff Langf7100b92014-09-08 16:17:08 -0400259 return error;
Jamie Madill6d113802014-08-25 15:47:52 -0400260 }
261 }
262 }
263 else
264 {
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400265 size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700266 ASSERT(!bufferImpl ||
267 ElementsInBuffer(attrib, static_cast<unsigned int>(bufferImpl->getSize())) >=
Jamie Madill846f1072015-09-01 09:07:15 -0400268 static_cast<int>(totalCount));
Jamie Madill6d113802014-08-25 15:47:52 -0400269
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400270 gl::Error error = mStreamingBuffer->reserveVertexSpace(
271 attrib, static_cast<GLsizei>(totalCount), instances);
Geoff Langf7100b92014-09-08 16:17:08 -0400272 if (error.isError())
Jamie Madill6d113802014-08-25 15:47:52 -0400273 {
Geoff Langf7100b92014-09-08 16:17:08 -0400274 return error;
Jamie Madill6d113802014-08-25 15:47:52 -0400275 }
276 }
277 }
278
Geoff Langf7100b92014-09-08 16:17:08 -0400279 return gl::Error(GL_NO_ERROR);
Jamie Madill6d113802014-08-25 15:47:52 -0400280}
281
Jamie Madill3d72cc72015-06-22 13:57:19 -0400282gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated,
Geoff Langf7100b92014-09-08 16:17:08 -0400283 GLint start,
284 GLsizei count,
285 GLsizei instances)
Jamie Madillf41522b2014-08-18 16:39:49 -0400286{
Jamie Madill9c385802015-06-22 13:57:18 -0400287 const gl::VertexAttribute &attrib = *translated->attribute;
288
Jamie Madillf41522b2014-08-18 16:39:49 -0400289 gl::Buffer *buffer = attrib.buffer.get();
Jamie Madill2b976812014-08-25 15:47:49 -0400290 ASSERT(buffer || attrib.pointer);
Jamie Madill7d112bb2015-06-22 13:57:19 -0400291 ASSERT(attrib.enabled);
Jamie Madillf41522b2014-08-18 16:39:49 -0400292
Jamie Madill9236b412015-02-02 16:51:52 -0500293 BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : NULL;
Jamie Madillf41522b2014-08-18 16:39:49 -0400294 StaticVertexBufferInterface *staticBuffer = storage ? storage->getStaticVertexBuffer() : NULL;
295 VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
Jamie Madill3d72cc72015-06-22 13:57:19 -0400296 bool directStorage = vertexBuffer->directStoragePossible(attrib, translated->currentValueType);
Jamie Madillf41522b2014-08-18 16:39:49 -0400297
Jamie Madilld4b55a02015-01-09 14:21:49 -0500298 // Instanced vertices do not apply the 'start' offset
299 GLint firstVertexIndex = (instances > 0 && attrib.divisor > 0 ? 0 : start);
300
Jamie Madill7d112bb2015-06-22 13:57:19 -0400301 translated->vertexBuffer = vertexBuffer->getVertexBuffer();
302
Jamie Madillf41522b2014-08-18 16:39:49 -0400303 if (directStorage)
304 {
Jamie Madill7d112bb2015-06-22 13:57:19 -0400305 translated->storage = storage;
306 translated->serial = storage->getSerial();
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700307 translated->stride = static_cast<unsigned int>(ComputeVertexAttributeStride(attrib));
Jamie Madill7d112bb2015-06-22 13:57:19 -0400308 translated->offset = static_cast<unsigned int>(attrib.offset + translated->stride * firstVertexIndex);
309
310 return gl::Error(GL_NO_ERROR);
Jamie Madillf41522b2014-08-18 16:39:49 -0400311 }
Jamie Madill7d112bb2015-06-22 13:57:19 -0400312
313 // Compute source data pointer
314 const uint8_t *sourceData = nullptr;
315
316 if (buffer)
317 {
318 gl::Error error = storage->getData(&sourceData);
319 if (error.isError())
320 {
321 return error;
322 }
323 sourceData += static_cast<int>(attrib.offset);
324 }
325 else
326 {
327 sourceData = static_cast<const uint8_t*>(attrib.pointer);
328 }
329
330 unsigned int streamOffset = 0;
331 unsigned int outputElementSize = 0;
332
333 if (staticBuffer)
Jamie Madillf41522b2014-08-18 16:39:49 -0400334 {
Geoff Langf7100b92014-09-08 16:17:08 -0400335 gl::Error error = staticBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
336 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400337 {
Geoff Langf7100b92014-09-08 16:17:08 -0400338 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400339 }
340
341 if (!staticBuffer->lookupAttribute(attrib, &streamOffset))
342 {
343 // Convert the entire buffer
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700344 int totalCount =
345 ElementsInBuffer(attrib, static_cast<unsigned int>(storage->getSize()));
346 int startIndex = static_cast<int>(attrib.offset) /
347 static_cast<int>(ComputeVertexAttributeStride(attrib));
Jamie Madillf41522b2014-08-18 16:39:49 -0400348
Jamie Madill7d112bb2015-06-22 13:57:19 -0400349 error = staticBuffer->storeVertexAttributes(attrib,
Jamie Madill3d72cc72015-06-22 13:57:19 -0400350 translated->currentValueType,
Jamie Madill7d112bb2015-06-22 13:57:19 -0400351 -startIndex,
352 totalCount,
353 0,
354 &streamOffset,
355 sourceData);
Geoff Langf7100b92014-09-08 16:17:08 -0400356 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400357 {
Geoff Langf7100b92014-09-08 16:17:08 -0400358 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400359 }
360 }
361
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700362 unsigned int firstElementOffset =
363 (static_cast<unsigned int>(attrib.offset) /
364 static_cast<unsigned int>(ComputeVertexAttributeStride(attrib))) *
365 outputElementSize;
Jamie Madilld4b55a02015-01-09 14:21:49 -0500366 unsigned int startOffset = (instances == 0 || attrib.divisor == 0) ? firstVertexIndex * outputElementSize : 0;
Jamie Madillf41522b2014-08-18 16:39:49 -0400367 if (streamOffset + firstElementOffset + startOffset < streamOffset)
368 {
Geoff Langf7100b92014-09-08 16:17:08 -0400369 return gl::Error(GL_OUT_OF_MEMORY);
Jamie Madillf41522b2014-08-18 16:39:49 -0400370 }
371
372 streamOffset += firstElementOffset + startOffset;
373 }
374 else
375 {
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400376 size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
Geoff Langf7100b92014-09-08 16:17:08 -0400377 gl::Error error = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attrib, 1, 0, &outputElementSize);
378 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400379 {
Geoff Langf7100b92014-09-08 16:17:08 -0400380 return error;
381 }
382
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400383 error = mStreamingBuffer->storeVertexAttributes(
384 attrib, translated->currentValueType, firstVertexIndex,
385 static_cast<GLsizei>(totalCount), instances, &streamOffset, sourceData);
Geoff Langf7100b92014-09-08 16:17:08 -0400386 if (error.isError())
387 {
388 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400389 }
390 }
391
Jamie Madill7d112bb2015-06-22 13:57:19 -0400392 translated->storage = nullptr;
393 translated->serial = vertexBuffer->getSerial();
Jamie Madillf41522b2014-08-18 16:39:49 -0400394 translated->stride = outputElementSize;
395 translated->offset = streamOffset;
396
Geoff Langf7100b92014-09-08 16:17:08 -0400397 return gl::Error(GL_NO_ERROR);
Jamie Madillf41522b2014-08-18 16:39:49 -0400398}
399
Jamie Madill9c385802015-06-22 13:57:18 -0400400gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribCurrentValueData &currentValue,
Geoff Langf7100b92014-09-08 16:17:08 -0400401 TranslatedAttribute *translated,
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400402 CurrentValueState *cachedState)
Jamie Madillf41522b2014-08-18 16:39:49 -0400403{
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400404 if (cachedState->data != currentValue)
Jamie Madillf41522b2014-08-18 16:39:49 -0400405 {
Jamie Madill9c385802015-06-22 13:57:18 -0400406 const gl::VertexAttribute &attrib = *translated->attribute;
Jamie Madill27c08912015-06-22 13:57:20 -0400407
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400408 gl::Error error = cachedState->buffer->reserveVertexSpace(attrib, 1, 0);
Geoff Langf7100b92014-09-08 16:17:08 -0400409 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400410 {
Geoff Langf7100b92014-09-08 16:17:08 -0400411 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400412 }
413
Jamie Madill7d112bb2015-06-22 13:57:19 -0400414 const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(currentValue.FloatValues);
Jamie Madillf41522b2014-08-18 16:39:49 -0400415 unsigned int streamOffset;
Jamie Madill3d72cc72015-06-22 13:57:19 -0400416 error = cachedState->buffer->storeVertexAttributes(attrib, currentValue.Type, 0, 1, 0, &streamOffset, sourceData);
Geoff Langf7100b92014-09-08 16:17:08 -0400417 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400418 {
Geoff Langf7100b92014-09-08 16:17:08 -0400419 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400420 }
421
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400422 cachedState->data = currentValue;
423 cachedState->offset = streamOffset;
Jamie Madillf41522b2014-08-18 16:39:49 -0400424 }
425
426 translated->storage = NULL;
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400427 translated->vertexBuffer = cachedState->buffer->getVertexBuffer();
428 translated->serial = cachedState->buffer->getSerial();
Jamie Madillf41522b2014-08-18 16:39:49 -0400429 translated->divisor = 0;
430
Jamie Madillf41522b2014-08-18 16:39:49 -0400431 translated->stride = 0;
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700432 translated->offset = static_cast<unsigned int>(cachedState->offset);
Jamie Madillf41522b2014-08-18 16:39:49 -0400433
Geoff Langf7100b92014-09-08 16:17:08 -0400434 return gl::Error(GL_NO_ERROR);
Jamie Madillf41522b2014-08-18 16:39:49 -0400435}
436
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000437}