10bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 20bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// 30bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Licensed under the Apache License, Version 2.0 (the "License"); 40bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// you may not use this file except in compliance with the License. 50bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// You may obtain a copy of the License at 60bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// 70bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// http://www.apache.org/licenses/LICENSE-2.0 80bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// 90bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Unless required by applicable law or agreed to in writing, software 100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// distributed under the License is distributed on an "AS IS" BASIS, 110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// See the License for the specific language governing permissions and 130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// limitations under the License. 140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// VertexDataManager.h: Defines the VertexDataManager, a class that 160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// runs the Buffer translation process. 170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "VertexDataManager.h" 190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Buffer.h" 210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Program.h" 220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "IndexDataManager.h" 230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "common/debug.h" 240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensnamespace 260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens enum {INITIAL_STREAM_BUFFER_SIZE = 1024 * 1024}; 280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensnamespace es2 310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 330bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensVertexDataManager::VertexDataManager(Context *context) : mContext(context) 340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mDirtyCurrentValue[i] = true; 380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mCurrentValueBuffer[i] = nullptr; 390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mStreamingBuffer = new StreamingVertexBuffer(INITIAL_STREAM_BUFFER_SIZE); 420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!mStreamingBuffer) 440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens ERR("Failed to allocate the streaming vertex buffer."); 460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 490bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensVertexDataManager::~VertexDataManager() 500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens delete mStreamingBuffer; 520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens delete mCurrentValueBuffer[i]; 560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensunsigned int VertexDataManager::writeAttributeData(StreamingVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute) 600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Buffer *buffer = attribute.mBoundBuffer; 620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens int inputStride = attribute.stride(); 640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens int elementSize = attribute.typeSize(); 650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int streamOffset = 0; 660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens char *output = nullptr; 680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(vertexBuffer) 700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens output = (char*)vertexBuffer->map(attribute, attribute.typeSize() * count, &streamOffset); 720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!output) 750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens ERR("Failed to map vertex buffer."); 770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return ~0u; 780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens const char *input = nullptr; 810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(buffer) 830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens input = static_cast<const char*>(buffer->data()) + attribute.mOffset; 850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens input = static_cast<const char*>(attribute.mPointer); 890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens input += inputStride * start; 920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(inputStride == elementSize) 940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens memcpy(output, input, count * inputStride); 960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(int i = 0; i < count; i++) 1000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens memcpy(output, input, elementSize); 1020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens output += elementSize; 1030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens input += inputStride; 1040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vertexBuffer->unmap(); 1080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return streamOffset; 1100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 1110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1120bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensGLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instanceId) 1130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 1140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!mStreamingBuffer) 1150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return GL_OUT_OF_MEMORY; 1170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens const VertexAttributeArray &attribs = mContext->getVertexArrayAttributes(); 1200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens const VertexAttributeArray ¤tAttribs = mContext->getCurrentVertexAttributes(); 1210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Program *program = mContext->getCurrentProgram(); 1220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens // Determine the required storage size per used buffer 1240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 1250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens const VertexAttribute &attrib = attribs[i].mArrayEnabled ? attribs[i] : currentAttribs[i]; 1270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(program->getAttributeStream(i) != -1 && attrib.mArrayEnabled) 1290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!attrib.mBoundBuffer) 1310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens const bool isInstanced = attrib.mDivisor > 0; 1330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mStreamingBuffer->addRequiredSpace(attrib.typeSize() * (isInstanced ? 1 : count)); 1340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mStreamingBuffer->reserveRequiredSpace(); 1390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens // Perform the vertex data translations 1410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 1420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(program->getAttributeStream(i) != -1) 1440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens const VertexAttribute &attrib = attribs[i].mArrayEnabled ? attribs[i] : currentAttribs[i]; 1460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(attrib.mArrayEnabled) 1480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens const bool isInstanced = attrib.mDivisor > 0; 1500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens // Instanced vertices do not apply the 'start' offset 1520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens GLint firstVertexIndex = isInstanced ? instanceId / attrib.mDivisor : start; 1530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens Buffer *buffer = attrib.mBoundBuffer; 1550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1562d4b7be6248d1f8ae9898f74174fa4393ae36435Nicolas Capens if((!buffer && attrib.mPointer == nullptr) || (buffer && !buffer->data())) 1570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens // This is an application error that would normally result in a crash, but we catch it and return an error 1590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens ERR("An enabled vertex array has no buffer and no pointer."); 1600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return GL_INVALID_OPERATION; 1610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens sw::Resource *staticBuffer = buffer ? buffer->getResource() : nullptr; 1640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(staticBuffer) 1660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens translated[i].vertexBuffer = staticBuffer; 168bffe803cd29475ca68ab1fea8a04276726fa83b7Alexis Hetu translated[i].offset = firstVertexIndex * attrib.stride() + static_cast<int>(attrib.mOffset); 1690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens translated[i].stride = isInstanced ? 0 : attrib.stride(); 1700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 1720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens unsigned int streamOffset = writeAttributeData(mStreamingBuffer, firstVertexIndex, isInstanced ? 1 : count, attrib); 1740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(streamOffset == ~0u) 1760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return GL_OUT_OF_MEMORY; 1780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens translated[i].vertexBuffer = mStreamingBuffer->getResource(); 1810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens translated[i].offset = streamOffset; 1820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens translated[i].stride = isInstanced ? 0 : attrib.typeSize(); 1830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 1840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 1850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens switch(attrib.mType) 1860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 1870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case GL_BYTE: translated[i].type = sw::STREAMTYPE_SBYTE; break; 1880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case GL_UNSIGNED_BYTE: translated[i].type = sw::STREAMTYPE_BYTE; break; 1890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case GL_SHORT: translated[i].type = sw::STREAMTYPE_SHORT; break; 1900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case GL_UNSIGNED_SHORT: translated[i].type = sw::STREAMTYPE_USHORT; break; 1910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case GL_INT: translated[i].type = sw::STREAMTYPE_INT; break; 1920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case GL_UNSIGNED_INT: translated[i].type = sw::STREAMTYPE_UINT; break; 1930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case GL_FIXED: translated[i].type = sw::STREAMTYPE_FIXED; break; 1940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens case GL_FLOAT: translated[i].type = sw::STREAMTYPE_FLOAT; break; 19570085ba50becdb3b19b84e54383725e5cfeab17cAlexis Hetu case GL_HALF_FLOAT: translated[i].type = sw::STREAMTYPE_HALF; break; 19684d0e22331ea67a91156ddd57262adc1f0a38596Nicolas Capens case GL_HALF_FLOAT_OES: translated[i].type = sw::STREAMTYPE_HALF; break; 19770085ba50becdb3b19b84e54383725e5cfeab17cAlexis Hetu case GL_INT_2_10_10_10_REV: translated[i].type = sw::STREAMTYPE_2_10_10_10_INT; break; 19870085ba50becdb3b19b84e54383725e5cfeab17cAlexis Hetu case GL_UNSIGNED_INT_2_10_10_10_REV: translated[i].type = sw::STREAMTYPE_2_10_10_10_UINT; break; 1990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens default: UNREACHABLE(attrib.mType); translated[i].type = sw::STREAMTYPE_FLOAT; break; 2000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens translated[i].count = attrib.mSize; 2030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens translated[i].normalized = attrib.mNormalized; 2040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else 2060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(mDirtyCurrentValue[i]) 2080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens delete mCurrentValueBuffer[i]; 2100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mCurrentValueBuffer[i] = new ConstantVertexBuffer(attrib.getCurrentValueBitsAsFloat(0), attrib.getCurrentValueBitsAsFloat(1), attrib.getCurrentValueBitsAsFloat(2), attrib.getCurrentValueBitsAsFloat(3)); 2110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mDirtyCurrentValue[i] = false; 2120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens translated[i].vertexBuffer = mCurrentValueBuffer[i]->getResource(); 2150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2166125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu switch(attrib.currentValueType()) 2176125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu { 2186125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu case GL_INT: 2196125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu translated[i].type = sw::STREAMTYPE_INT; 2206125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu break; 2216125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu case GL_UNSIGNED_INT: 2226125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu translated[i].type = sw::STREAMTYPE_UINT; 2236125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu break; 2246125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu default: 2256125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu translated[i].type = sw::STREAMTYPE_FLOAT; 2266125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu break; 2276125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu } 2280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens translated[i].count = 4; 2290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens translated[i].stride = 0; 2300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens translated[i].offset = 0; 2316125b66df9208481b41d28c1f8b1b6576529d3c5Alexis Hetu translated[i].normalized = false; 2320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return GL_NO_ERROR; 2370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 2380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2390bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensVertexBuffer::VertexBuffer(unsigned int size) : mVertexBuffer(nullptr) 2400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 2410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(size > 0) 2420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mVertexBuffer = new sw::Resource(size + 1024); 2440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!mVertexBuffer) 2460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens ERR("Out of memory allocating a vertex buffer of size %u.", size); 2480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 2510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2520bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensVertexBuffer::~VertexBuffer() 2530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 2540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(mVertexBuffer) 2550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mVertexBuffer->destruct(); 2570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 2590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensvoid VertexBuffer::unmap() 2610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 2620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(mVertexBuffer) 2630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mVertexBuffer->unlock(); 2650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 2670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capenssw::Resource *VertexBuffer::getResource() const 2690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 2700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return mVertexBuffer; 2710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 2720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2730bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensConstantVertexBuffer::ConstantVertexBuffer(float x, float y, float z, float w) : VertexBuffer(4 * sizeof(float)) 2740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 2750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(mVertexBuffer) 2760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 2770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens float *vector = (float*)mVertexBuffer->lock(sw::PUBLIC); 2780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vector[0] = x; 2800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vector[1] = y; 2810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vector[2] = z; 2820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens vector[3] = w; 2830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mVertexBuffer->unlock(); 2850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 2860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 2870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2880bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensConstantVertexBuffer::~ConstantVertexBuffer() 2890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 2900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 2910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2920bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensStreamingVertexBuffer::StreamingVertexBuffer(unsigned int size) : VertexBuffer(size) 2930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 2940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mBufferSize = size; 2950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mWritePosition = 0; 2960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mRequiredSpace = 0; 2970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 2980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 2990bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensStreamingVertexBuffer::~StreamingVertexBuffer() 3000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 3010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 3020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensvoid StreamingVertexBuffer::addRequiredSpace(unsigned int requiredSpace) 3040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 3050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mRequiredSpace += requiredSpace; 3060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 3070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensvoid *StreamingVertexBuffer::map(const VertexAttribute &attribute, unsigned int requiredSpace, unsigned int *offset) 3090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 3100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens void *mapPtr = nullptr; 3110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(mVertexBuffer) 3130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens // We can use a private lock because we never overwrite the content 3150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mapPtr = (char*)mVertexBuffer->lock(sw::PRIVATE) + mWritePosition; 3160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens *offset = mWritePosition; 3180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mWritePosition += requiredSpace; 3190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens return mapPtr; 3220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 3230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensvoid StreamingVertexBuffer::reserveRequiredSpace() 3250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{ 3260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(mRequiredSpace > mBufferSize) 3270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(mVertexBuffer) 3290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mVertexBuffer->destruct(); 3310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mVertexBuffer = 0; 3320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 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. 3350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mVertexBuffer = new sw::Resource(mBufferSize); 3370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(!mVertexBuffer) 3390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens ERR("Out of memory allocating a vertex buffer of size %u.", mBufferSize); 3410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mWritePosition = 0; 3440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens else if(mWritePosition + mRequiredSpace > mBufferSize) // Recycle 3460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens if(mVertexBuffer) 3480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens { 3490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mVertexBuffer->destruct(); 3500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mVertexBuffer = new sw::Resource(mBufferSize); 3510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mWritePosition = 0; 3540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens } 3550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens mRequiredSpace = 0; 3570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 3580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens 3590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens} 360