blob: bca4aa434f8fb5729ad86b86a41541867ee0bac5 [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"
Jamie Madilldbfc6c62016-02-29 01:08:57 -050013#include "libANGLE/formatutils.h"
Geoff Lang7dd2e102014-11-10 15:19:26 -050014#include "libANGLE/Program.h"
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040015#include "libANGLE/State.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050016#include "libANGLE/VertexAttribute.h"
Geoff Lang5ead9272015-03-25 12:27:43 -040017#include "libANGLE/VertexArray.h"
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040018#include "libANGLE/renderer/d3d/BufferD3D.h"
Jamie Madilldbfc6c62016-02-29 01:08:57 -050019#include "libANGLE/renderer/d3d/RendererD3D.h"
Jamie Madillfd1bf4e2015-03-31 09:46:02 -040020#include "libANGLE/renderer/d3d/VertexBuffer.h"
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +000021
daniel@transgaming.com31240482012-11-28 21:06:41 +000022namespace rx
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +000023{
Jamie Madilldbfc6c62016-02-29 01:08:57 -050024namespace
25{
26enum
27{
28 INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024
29};
30// This has to be at least 4k or else it fails on ATI cards.
31enum
32{
33 CONSTANT_VERTEX_BUFFER_SIZE = 4096
34};
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +000035
Jamie Madilldbfc6c62016-02-29 01:08:57 -050036int ElementsInBuffer(const gl::VertexAttribute &attrib, unsigned int size)
jbauman@chromium.org059fc152011-11-18 19:26:17 +000037{
Geoff Langa36ead42013-08-02 11:54:08 -040038 // Size cannot be larger than a GLsizei
39 if (size > static_cast<unsigned int>(std::numeric_limits<int>::max()))
40 {
41 size = static_cast<unsigned int>(std::numeric_limits<int>::max());
42 }
43
Cooper Partin4d61f7e2015-08-12 10:56:50 -070044 GLsizei stride = static_cast<GLsizei>(ComputeVertexAttributeStride(attrib));
45 return (size - attrib.offset % stride +
46 (stride - static_cast<GLsizei>(ComputeVertexAttributeTypeSize(attrib)))) /
47 stride;
jbauman@chromium.org059fc152011-11-18 19:26:17 +000048}
49
Jamie Madilldbfc6c62016-02-29 01:08:57 -050050bool DirectStoragePossible(const gl::VertexAttribute &attrib)
51{
52 // Current value attribs may not use direct storage.
53 if (!attrib.enabled)
54 {
55 return false;
56 }
57
58 gl::Buffer *buffer = attrib.buffer.get();
59 if (!buffer)
60 {
61 return false;
62 }
63
64 BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
65 ASSERT(bufferD3D);
66 if (!bufferD3D->supportsDirectBinding())
67 {
68 return false;
69 }
70
Jamie Madilldbfc6c62016-02-29 01:08:57 -050071 // Alignment restrictions: In D3D, vertex data must be aligned to the format stride, or to a
72 // 4-byte boundary, whichever is smaller. (Undocumented, and experimentally confirmed)
Jamie Madilld8fa9212016-03-02 11:51:43 -050073 size_t alignment = 4;
Jamie Madilldbfc6c62016-02-29 01:08:57 -050074
75 if (attrib.type != GL_FLOAT)
76 {
77 gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib);
78
Jamie Madilldbfc6c62016-02-29 01:08:57 -050079 // TODO(jmadill): add VertexFormatCaps
80 BufferFactoryD3D *factory = bufferD3D->getFactory();
Jamie Madilld8fa9212016-03-02 11:51:43 -050081
82 auto errorOrElementSize = factory->getVertexSpaceRequired(attrib, 1, 0);
83 if (errorOrElementSize.isError())
84 {
85 ERR("Unlogged error in DirectStoragePossible.");
86 return false;
87 }
88
89 alignment = std::min<size_t>(errorOrElementSize.getResult(), 4);
90
91 // CPU-converted vertex data must be converted (naturally).
92 if ((factory->getVertexConversionType(vertexFormatType) & VERTEX_CONVERT_CPU) != 0)
93 {
94 return false;
95 }
Jamie Madilldbfc6c62016-02-29 01:08:57 -050096 }
97
Jamie Madilld8fa9212016-03-02 11:51:43 -050098 // Final alignment check - unaligned data must be converted.
99 return (static_cast<size_t>(ComputeVertexAttributeStride(attrib)) % alignment == 0) &&
100 (static_cast<size_t>(attrib.offset) % alignment == 0);
Jamie Madilldbfc6c62016-02-29 01:08:57 -0500101}
102} // anonymous namespace
103
Jamie Madille36b92d2016-03-04 15:46:58 -0500104TranslatedAttribute::TranslatedAttribute()
105 : active(false),
106 attribute(nullptr),
107 currentValueType(GL_NONE),
108 offset(0),
109 stride(0),
110 vertexBuffer(),
111 storage(nullptr),
112 serial(0),
113 divisor(0)
114{
115}
116
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400117VertexDataManager::CurrentValueState::CurrentValueState()
118 : buffer(nullptr),
119 offset(0)
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000120{
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400121 data.FloatValues[0] = std::numeric_limits<float>::quiet_NaN();
122 data.FloatValues[1] = std::numeric_limits<float>::quiet_NaN();
123 data.FloatValues[2] = std::numeric_limits<float>::quiet_NaN();
124 data.FloatValues[3] = std::numeric_limits<float>::quiet_NaN();
125 data.Type = GL_FLOAT;
126}
daniel@transgaming.com83921382011-01-08 05:46:00 +0000127
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400128VertexDataManager::CurrentValueState::~CurrentValueState()
129{
130 SafeDelete(buffer);
131}
132
133VertexDataManager::VertexDataManager(BufferFactoryD3D *factory)
134 : mFactory(factory),
135 mStreamingBuffer(nullptr),
136 // TODO(jmadill): use context caps
137 mCurrentValueCache(gl::MAX_VERTEX_ATTRIBS)
138{
Jamie Madillfd1bf4e2015-03-31 09:46:02 -0400139 mStreamingBuffer = new StreamingVertexBufferInterface(factory, INITIAL_STREAM_BUFFER_SIZE);
daniel@transgaming.com72b9e182011-04-13 14:58:33 +0000140
141 if (!mStreamingBuffer)
142 {
143 ERR("Failed to allocate the streaming vertex buffer.");
144 }
Jamie Madill27c08912015-06-22 13:57:20 -0400145
146 // TODO(jmadill): use context caps
147 mActiveEnabledAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
148 mActiveDisabledAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000149}
150
151VertexDataManager::~VertexDataManager()
152{
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400153 SafeDelete(mStreamingBuffer);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000154}
155
Jamie Madille36b92d2016-03-04 15:46:58 -0500156void VertexDataManager::unmapStreamingBuffer()
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800157{
158 mStreamingBuffer->getVertexBuffer()->hintUnmapResource();
Austin Kinrossbe0facc2015-01-07 16:22:29 -0800159}
160
Jamie Madill476682e2015-06-30 10:04:29 -0400161gl::Error VertexDataManager::prepareVertexData(const gl::State &state,
162 GLint start,
163 GLsizei count,
164 std::vector<TranslatedAttribute> *translatedAttribs,
165 GLsizei instances)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000166{
daniel@transgaming.com72b9e182011-04-13 14:58:33 +0000167 if (!mStreamingBuffer)
168 {
Geoff Langf7100b92014-09-08 16:17:08 -0400169 return gl::Error(GL_OUT_OF_MEMORY, "Internal streaming vertex buffer is unexpectedly NULL.");
daniel@transgaming.com72b9e182011-04-13 14:58:33 +0000170 }
171
Jamie Madill27c08912015-06-22 13:57:20 -0400172 // Compute active enabled and active disable attributes, for speed.
173 // TODO(jmadill): don't recompute if there was no state change
Geoff Lang5ead9272015-03-25 12:27:43 -0400174 const gl::VertexArray *vertexArray = state.getVertexArray();
Jamie Madill63805b42015-08-25 13:17:39 -0400175 const gl::Program *program = state.getProgram();
176 const auto &vertexAttributes = vertexArray->getVertexAttributes();
Geoff Lang5ead9272015-03-25 12:27:43 -0400177
Jamie Madill27c08912015-06-22 13:57:20 -0400178 mActiveEnabledAttributes.clear();
179 mActiveDisabledAttributes.clear();
Jamie Madill476682e2015-06-30 10:04:29 -0400180 translatedAttribs->clear();
Jamie Madill27c08912015-06-22 13:57:20 -0400181
Jamie Madill9c385802015-06-22 13:57:18 -0400182 for (size_t attribIndex = 0; attribIndex < vertexAttributes.size(); ++attribIndex)
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000183 {
Jamie Madill63805b42015-08-25 13:17:39 -0400184 if (program->isAttribLocationActive(attribIndex))
daniel@transgaming.comc828b142010-05-12 03:42:04 +0000185 {
Jamie Madill476682e2015-06-30 10:04:29 -0400186 // Resize automatically puts in empty attribs
187 translatedAttribs->resize(attribIndex + 1);
188
189 TranslatedAttribute *translated = &(*translatedAttribs)[attribIndex];
190
Jamie Madill9c385802015-06-22 13:57:18 -0400191 // Record the attribute now
Jamie Madill476682e2015-06-30 10:04:29 -0400192 translated->active = true;
193 translated->attribute = &vertexAttributes[attribIndex];
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700194 translated->currentValueType =
195 state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex)).Type;
Jamie Madill476682e2015-06-30 10:04:29 -0400196 translated->divisor = vertexAttributes[attribIndex].divisor;
Jamie Madill9c385802015-06-22 13:57:18 -0400197
198 if (vertexAttributes[attribIndex].enabled)
199 {
Jamie Madill476682e2015-06-30 10:04:29 -0400200 mActiveEnabledAttributes.push_back(translated);
Jamie Madill9c385802015-06-22 13:57:18 -0400201 }
Jamie Madill27c08912015-06-22 13:57:20 -0400202 else
203 {
204 mActiveDisabledAttributes.push_back(attribIndex);
205 }
shannon.woods@transgaming.coma9a509e2013-02-28 23:10:44 +0000206 }
207 }
208
209 // Reserve the required space in the buffers
Jamie Madill16f99b72015-07-02 14:09:06 -0400210 for (const TranslatedAttribute *activeAttrib : mActiveEnabledAttributes)
shannon.woods@transgaming.coma9a509e2013-02-28 23:10:44 +0000211 {
Jamie Madill16f99b72015-07-02 14:09:06 -0400212 gl::Error error = reserveSpaceForAttrib(*activeAttrib, count, instances);
Jamie Madill27c08912015-06-22 13:57:20 -0400213 if (error.isError())
shannon.woods@transgaming.coma9a509e2013-02-28 23:10:44 +0000214 {
Jamie Madill27c08912015-06-22 13:57:20 -0400215 return error;
daniel@transgaming.com83921382011-01-08 05:46:00 +0000216 }
217 }
218
219 // Perform the vertex data translations
Jamie Madill16f99b72015-07-02 14:09:06 -0400220 for (TranslatedAttribute *activeAttrib : mActiveEnabledAttributes)
daniel@transgaming.com83921382011-01-08 05:46:00 +0000221 {
Jamie Madill16f99b72015-07-02 14:09:06 -0400222 gl::Error error = storeAttribute(activeAttrib, start, count, instances);
Jamie Madill27c08912015-06-22 13:57:20 -0400223
224 if (error.isError())
daniel@transgaming.com83921382011-01-08 05:46:00 +0000225 {
Jamie Madille36b92d2016-03-04 15:46:58 -0500226 unmapStreamingBuffer();
Jamie Madill27c08912015-06-22 13:57:20 -0400227 return error;
228 }
229 }
Shannon Woods1a965482014-09-22 18:00:32 -0400230
Jamie Madille36b92d2016-03-04 15:46:58 -0500231 unmapStreamingBuffer();
232
Jamie Madill27c08912015-06-22 13:57:20 -0400233 for (size_t attribIndex : mActiveDisabledAttributes)
234 {
235 if (mCurrentValueCache[attribIndex].buffer == nullptr)
236 {
237 mCurrentValueCache[attribIndex].buffer = new StreamingVertexBufferInterface(mFactory, CONSTANT_VERTEX_BUFFER_SIZE);
238 }
jbauman@chromium.org83b61bc2011-09-02 18:59:24 +0000239
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700240 gl::Error error = storeCurrentValue(
241 state.getVertexAttribCurrentValue(static_cast<unsigned int>(attribIndex)),
242 &(*translatedAttribs)[attribIndex], &mCurrentValueCache[attribIndex]);
Jamie Madill27c08912015-06-22 13:57:20 -0400243 if (error.isError())
244 {
Jamie Madill27c08912015-06-22 13:57:20 -0400245 return error;
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000246 }
247 }
apatrick@chromium.orgf99fbb72010-11-16 01:57:05 +0000248
Jamie Madill16f99b72015-07-02 14:09:06 -0400249 for (const TranslatedAttribute *activeAttrib : mActiveEnabledAttributes)
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000250 {
Jamie Madill16f99b72015-07-02 14:09:06 -0400251 gl::Buffer *buffer = activeAttrib->attribute->buffer.get();
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000252
Jamie Madill27c08912015-06-22 13:57:20 -0400253 if (buffer)
254 {
255 BufferD3D *bufferD3D = GetImplAs<BufferD3D>(buffer);
Jamie Madill16f99b72015-07-02 14:09:06 -0400256 size_t typeSize = ComputeVertexAttributeTypeSize(*activeAttrib->attribute);
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700257 bufferD3D->promoteStaticUsage(count * static_cast<int>(typeSize));
daniel@transgaming.com78624ca2011-04-22 04:17:57 +0000258 }
259 }
260
Geoff Langf7100b92014-09-08 16:17:08 -0400261 return gl::Error(GL_NO_ERROR);
daniel@transgaming.com0f7aaf52010-03-11 19:41:38 +0000262}
263
Jamie Madill3d72cc72015-06-22 13:57:19 -0400264gl::Error VertexDataManager::reserveSpaceForAttrib(const TranslatedAttribute &translatedAttrib,
Geoff Langf7100b92014-09-08 16:17:08 -0400265 GLsizei count,
266 GLsizei instances) const
Jamie Madill6d113802014-08-25 15:47:52 -0400267{
Jamie Madill3d72cc72015-06-22 13:57:19 -0400268 const gl::VertexAttribute &attrib = *translatedAttrib.attribute;
Jamie Madille36b92d2016-03-04 15:46:58 -0500269 if (DirectStoragePossible(attrib))
Jamie Madill6d113802014-08-25 15:47:52 -0400270 {
Jamie Madille36b92d2016-03-04 15:46:58 -0500271 return gl::Error(GL_NO_ERROR);
Jamie Madill6d113802014-08-25 15:47:52 -0400272 }
273
Jamie Madille36b92d2016-03-04 15:46:58 -0500274 gl::Buffer *buffer = attrib.buffer.get();
275 BufferD3D *bufferD3D = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr;
276 StaticVertexBufferInterface *staticBuffer =
277 bufferD3D ? bufferD3D->getStaticVertexBuffer(attrib) : nullptr;
278
279 if (staticBuffer)
280 {
281 return gl::Error(GL_NO_ERROR);
282 }
283
284 size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
285 ASSERT(!bufferD3D ||
286 ElementsInBuffer(attrib, static_cast<unsigned int>(bufferD3D->getSize())) >=
287 static_cast<int>(totalCount));
288
289 return mStreamingBuffer->reserveVertexSpace(attrib, static_cast<GLsizei>(totalCount),
290 instances);
Jamie Madill6d113802014-08-25 15:47:52 -0400291}
292
Jamie Madill3d72cc72015-06-22 13:57:19 -0400293gl::Error VertexDataManager::storeAttribute(TranslatedAttribute *translated,
Geoff Langf7100b92014-09-08 16:17:08 -0400294 GLint start,
295 GLsizei count,
296 GLsizei instances)
Jamie Madillf41522b2014-08-18 16:39:49 -0400297{
Jamie Madill9c385802015-06-22 13:57:18 -0400298 const gl::VertexAttribute &attrib = *translated->attribute;
299
Jamie Madillf41522b2014-08-18 16:39:49 -0400300 gl::Buffer *buffer = attrib.buffer.get();
Jamie Madill2b976812014-08-25 15:47:49 -0400301 ASSERT(buffer || attrib.pointer);
Jamie Madill7d112bb2015-06-22 13:57:19 -0400302 ASSERT(attrib.enabled);
Jamie Madillf41522b2014-08-18 16:39:49 -0400303
Jamie Madilldbfc6c62016-02-29 01:08:57 -0500304 BufferD3D *storage = buffer ? GetImplAs<BufferD3D>(buffer) : nullptr;
Jamie Madillf41522b2014-08-18 16:39:49 -0400305
Jamie Madilld4b55a02015-01-09 14:21:49 -0500306 // Instanced vertices do not apply the 'start' offset
Jamie Madilla0537332015-11-19 13:55:26 -0500307 GLint firstVertexIndex = (attrib.divisor > 0 ? 0 : start);
Jamie Madilld4b55a02015-01-09 14:21:49 -0500308
Jamie Madilldbfc6c62016-02-29 01:08:57 -0500309 if (DirectStoragePossible(attrib))
Jamie Madillf41522b2014-08-18 16:39:49 -0400310 {
Jamie Madille36b92d2016-03-04 15:46:58 -0500311 translated->vertexBuffer.set(nullptr);
Jamie Madill7d112bb2015-06-22 13:57:19 -0400312 translated->storage = storage;
313 translated->serial = storage->getSerial();
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700314 translated->stride = static_cast<unsigned int>(ComputeVertexAttributeStride(attrib));
Jamie Madill7d112bb2015-06-22 13:57:19 -0400315 translated->offset = static_cast<unsigned int>(attrib.offset + translated->stride * firstVertexIndex);
Jamie Madill7d112bb2015-06-22 13:57:19 -0400316 return gl::Error(GL_NO_ERROR);
Jamie Madillf41522b2014-08-18 16:39:49 -0400317 }
Jamie Madill7d112bb2015-06-22 13:57:19 -0400318
319 // Compute source data pointer
320 const uint8_t *sourceData = nullptr;
321
322 if (buffer)
323 {
324 gl::Error error = storage->getData(&sourceData);
325 if (error.isError())
326 {
327 return error;
328 }
329 sourceData += static_cast<int>(attrib.offset);
330 }
331 else
332 {
333 sourceData = static_cast<const uint8_t*>(attrib.pointer);
334 }
335
336 unsigned int streamOffset = 0;
Jamie Madilld8fa9212016-03-02 11:51:43 -0500337
338 auto errorOrOutputElementSize = mFactory->getVertexSpaceRequired(attrib, 1, 0);
339 if (errorOrOutputElementSize.isError())
340 {
341 return errorOrOutputElementSize.getError();
342 }
343
344 translated->storage = nullptr;
345 translated->stride = errorOrOutputElementSize.getResult();
Jamie Madilld8fa9212016-03-02 11:51:43 -0500346
347 gl::Error error(GL_NO_ERROR);
Jamie Madill7d112bb2015-06-22 13:57:19 -0400348
Jamie Madille36b92d2016-03-04 15:46:58 -0500349 auto *staticBuffer = storage ? storage->getStaticVertexBuffer(attrib) : nullptr;
350
Jamie Madill7d112bb2015-06-22 13:57:19 -0400351 if (staticBuffer)
Jamie Madillf41522b2014-08-18 16:39:49 -0400352 {
Jamie Madille36b92d2016-03-04 15:46:58 -0500353 if (staticBuffer->empty())
Jamie Madillf41522b2014-08-18 16:39:49 -0400354 {
355 // Convert the entire buffer
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700356 int totalCount =
357 ElementsInBuffer(attrib, static_cast<unsigned int>(storage->getSize()));
358 int startIndex = static_cast<int>(attrib.offset) /
359 static_cast<int>(ComputeVertexAttributeStride(attrib));
Jamie Madillf41522b2014-08-18 16:39:49 -0400360
Jamie Madille36b92d2016-03-04 15:46:58 -0500361 error =
362 staticBuffer->storeStaticAttribute(attrib, -startIndex, totalCount, 0, sourceData);
Geoff Langf7100b92014-09-08 16:17:08 -0400363 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400364 {
Geoff Langf7100b92014-09-08 16:17:08 -0400365 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400366 }
367 }
368
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700369 unsigned int firstElementOffset =
370 (static_cast<unsigned int>(attrib.offset) /
371 static_cast<unsigned int>(ComputeVertexAttributeStride(attrib))) *
Jamie Madilld8fa9212016-03-02 11:51:43 -0500372 translated->stride;
Jamie Madilla0537332015-11-19 13:55:26 -0500373 ASSERT(attrib.divisor == 0 || firstVertexIndex == 0);
Jamie Madilld8fa9212016-03-02 11:51:43 -0500374 unsigned int startOffset = firstVertexIndex * translated->stride;
Jamie Madillf41522b2014-08-18 16:39:49 -0400375 if (streamOffset + firstElementOffset + startOffset < streamOffset)
376 {
Geoff Langf7100b92014-09-08 16:17:08 -0400377 return gl::Error(GL_OUT_OF_MEMORY);
Jamie Madillf41522b2014-08-18 16:39:49 -0400378 }
379
380 streamOffset += firstElementOffset + startOffset;
Jamie Madille36b92d2016-03-04 15:46:58 -0500381 translated->vertexBuffer.set(staticBuffer->getVertexBuffer());
Jamie Madillf41522b2014-08-18 16:39:49 -0400382 }
383 else
384 {
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400385 size_t totalCount = ComputeVertexAttributeElementCount(attrib, count, instances);
Geoff Langf7100b92014-09-08 16:17:08 -0400386
Jamie Madille36b92d2016-03-04 15:46:58 -0500387 error = mStreamingBuffer->storeDynamicAttribute(
Geoff Lang3cf12ce2015-08-27 14:40:48 -0400388 attrib, translated->currentValueType, firstVertexIndex,
389 static_cast<GLsizei>(totalCount), instances, &streamOffset, sourceData);
Geoff Langf7100b92014-09-08 16:17:08 -0400390 if (error.isError())
391 {
392 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400393 }
Jamie Madille36b92d2016-03-04 15:46:58 -0500394 translated->vertexBuffer.set(mStreamingBuffer->getVertexBuffer());
Jamie Madillf41522b2014-08-18 16:39:49 -0400395 }
396
Jamie Madille36b92d2016-03-04 15:46:58 -0500397 ASSERT(translated->vertexBuffer.get());
398 translated->serial = translated->vertexBuffer.get()->getSerial();
Jamie Madillf41522b2014-08-18 16:39:49 -0400399 translated->offset = streamOffset;
400
Geoff Langf7100b92014-09-08 16:17:08 -0400401 return gl::Error(GL_NO_ERROR);
Jamie Madillf41522b2014-08-18 16:39:49 -0400402}
403
Jamie Madill9c385802015-06-22 13:57:18 -0400404gl::Error VertexDataManager::storeCurrentValue(const gl::VertexAttribCurrentValueData &currentValue,
Geoff Langf7100b92014-09-08 16:17:08 -0400405 TranslatedAttribute *translated,
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400406 CurrentValueState *cachedState)
Jamie Madillf41522b2014-08-18 16:39:49 -0400407{
Jamie Madille36b92d2016-03-04 15:46:58 -0500408 auto *buffer = cachedState->buffer;
409
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400410 if (cachedState->data != currentValue)
Jamie Madillf41522b2014-08-18 16:39:49 -0400411 {
Jamie Madill9c385802015-06-22 13:57:18 -0400412 const gl::VertexAttribute &attrib = *translated->attribute;
Jamie Madill27c08912015-06-22 13:57:20 -0400413
Jamie Madille36b92d2016-03-04 15:46:58 -0500414 gl::Error error = buffer->reserveVertexSpace(attrib, 1, 0);
Geoff Langf7100b92014-09-08 16:17:08 -0400415 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400416 {
Geoff Langf7100b92014-09-08 16:17:08 -0400417 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400418 }
419
Jamie Madill7d112bb2015-06-22 13:57:19 -0400420 const uint8_t *sourceData = reinterpret_cast<const uint8_t*>(currentValue.FloatValues);
Jamie Madillf41522b2014-08-18 16:39:49 -0400421 unsigned int streamOffset;
Jamie Madille36b92d2016-03-04 15:46:58 -0500422 error = buffer->storeDynamicAttribute(attrib, currentValue.Type, 0, 1, 0, &streamOffset,
423 sourceData);
Geoff Langf7100b92014-09-08 16:17:08 -0400424 if (error.isError())
Jamie Madillf41522b2014-08-18 16:39:49 -0400425 {
Geoff Langf7100b92014-09-08 16:17:08 -0400426 return error;
Jamie Madillf41522b2014-08-18 16:39:49 -0400427 }
428
Jamie Madille36b92d2016-03-04 15:46:58 -0500429 buffer->getVertexBuffer()->hintUnmapResource();
430
Jamie Madillb3f4e8d2015-06-22 13:57:17 -0400431 cachedState->data = currentValue;
432 cachedState->offset = streamOffset;
Jamie Madillf41522b2014-08-18 16:39:49 -0400433 }
434
Jamie Madille36b92d2016-03-04 15:46:58 -0500435 translated->vertexBuffer.set(buffer->getVertexBuffer());
Jamie Madillf41522b2014-08-18 16:39:49 -0400436
Jamie Madille36b92d2016-03-04 15:46:58 -0500437 translated->storage = nullptr;
438 translated->serial = buffer->getSerial();
439 translated->divisor = 0;
440 translated->stride = 0;
441 translated->offset = static_cast<unsigned int>(cachedState->offset);
Jamie Madillf41522b2014-08-18 16:39:49 -0400442
Geoff Langf7100b92014-09-08 16:17:08 -0400443 return gl::Error(GL_NO_ERROR);
Jamie Madillf41522b2014-08-18 16:39:49 -0400444}
445
Jamie Madille36b92d2016-03-04 15:46:58 -0500446// VertexBufferBinding implementation
447VertexBufferBinding::VertexBufferBinding() : mBoundVertexBuffer(nullptr)
448{
449}
450
451VertexBufferBinding::VertexBufferBinding(const VertexBufferBinding &other)
452 : mBoundVertexBuffer(other.mBoundVertexBuffer)
453{
454 if (mBoundVertexBuffer)
455 {
456 mBoundVertexBuffer->addRef();
457 }
458}
459
460VertexBufferBinding::~VertexBufferBinding()
461{
462 if (mBoundVertexBuffer)
463 {
464 mBoundVertexBuffer->release();
465 }
466}
467
468VertexBufferBinding &VertexBufferBinding::operator=(const VertexBufferBinding &other)
469{
470 mBoundVertexBuffer = other.mBoundVertexBuffer;
471 if (mBoundVertexBuffer)
472 {
473 mBoundVertexBuffer->addRef();
474 }
475 return *this;
476}
477
478void VertexBufferBinding::set(VertexBuffer *vertexBuffer)
479{
480 if (mBoundVertexBuffer == vertexBuffer)
481 return;
482
483 if (mBoundVertexBuffer)
484 {
485 mBoundVertexBuffer->release();
486 }
487 if (vertexBuffer)
488 {
489 vertexBuffer->addRef();
490 }
491
492 mBoundVertexBuffer = vertexBuffer;
493}
494
495VertexBuffer *VertexBufferBinding::get() const
496{
497 return mBoundVertexBuffer;
498}
499
Jamie Madilldbfc6c62016-02-29 01:08:57 -0500500} // namespace rx