Add support for Vertex Buffer Data Translation

TRAC #11024 Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Andrew Lewycky <andrew.lewycky@transgaming.com> git-svn-id: https://angleproject.googlecode.com/svn/trunk@15 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 45d03580
......@@ -29,6 +29,8 @@ class Config;
namespace gl
{
struct TranslatedAttribute;
class Buffer;
class Shader;
class Program;
......@@ -40,6 +42,8 @@ class Renderbuffer;
class Colorbuffer;
class Depthbuffer;
class Stencilbuffer;
class VertexDataManager;
class BufferBackEnd;
enum
{
......@@ -57,6 +61,9 @@ enum
IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_SHORT_5_6_5
};
// Because indices are accessed internally, we convert them to a common format.
typedef unsigned short Index;
struct Color
{
float red;
......@@ -65,18 +72,31 @@ struct Color
float alpha;
};
// Helper structure describing a single vertex attribute array
struct Array
// Helper structure describing a single vertex attribute
class AttributeState
{
Array();
bool enabled;
GLuint boundBuffer;
GLint size;
GLenum type;
GLboolean normalized;
GLsizei stride;
const void *pointer;
public:
AttributeState()
: mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mBoundBuffer(0), mEnabled(false)
{
mCurrentValue[0] = 0;
mCurrentValue[1] = 0;
mCurrentValue[2] = 0;
mCurrentValue[3] = 1;
}
// From VertexArrayPointer
GLenum mType;
GLint mSize;
bool mNormalized;
GLsizei mStride; // 0 means natural stride
const void *mPointer;
GLuint mBoundBuffer; // Captured when VertexArrayPointer is called.
bool mEnabled; // From Enable/DisableVertexAttribArray
float mCurrentValue[4]; // From VertexAttrib4f
};
// Helper structure to store all raw state
......@@ -149,7 +169,7 @@ struct State
GLuint renderbuffer;
GLuint currentProgram;
Array vertexAttribute[MAX_VERTEX_ATTRIBS];
AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS];
GLuint samplerTexture[MAX_TEXTURE_IMAGE_UNITS];
unsigned int startIndex;
......@@ -216,8 +236,9 @@ class Context : public State
bool applyRenderTarget(bool ignoreViewport);
void applyState();
void applyVertexBuffer(int count);
void applyIndexBuffer(const void *indices, int length);
void applyVertexBuffer(GLint first, GLsizei count);
void applyVertexBuffer(GLsizei count, const void *indices, GLenum indexType);
void applyIndexBuffer(const void *indices, GLsizei count);
void applyShaders();
void applyTextures();
......@@ -239,6 +260,9 @@ class Context : public State
private:
DISALLOW_COPY_AND_ASSIGN(Context);
void lookupAttributeMapping(TranslatedAttribute *attributes);
const Index *adjustIndexPointer(const void *indices);
void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture);
void detachFramebuffer(GLuint framebuffer);
......@@ -271,6 +295,9 @@ class Context : public State
typedef std::map<GLuint, Renderbuffer*> RenderbufferMap;
RenderbufferMap mRenderbufferMap;
BufferBackEnd *mBufferBackEnd;
VertexDataManager *mVertexDataManager;
// Recorded errors
bool mInvalidEnum;
bool mInvalidValue;
......
......@@ -10,111 +10,79 @@
#include "Buffer.h"
#include "main.h"
#include <cstdlib>
#include <limits>
#include <utility>
#include "debug.h"
#include "geometry/backend.h"
namespace gl
{
Buffer::Buffer()
{
mSize = 0;
mData = NULL;
mVertexBuffer = NULL;
mIndexBuffer = NULL;
Buffer::Buffer(BufferBackEnd *backEnd)
: mBackEnd(backEnd), mIdentityTranslation(NULL)
{
}
Buffer::~Buffer()
{
erase();
delete mIdentityTranslation;
}
void Buffer::storeData(GLsizeiptr size, const void *data)
GLenum Buffer::bufferData(const void* data, GLsizeiptr size, GLenum usage)
{
erase();
if (size < 0) return GL_INVALID_VALUE;
mSize = size;
mData = new unsigned char[size];
const data_t* newdata = static_cast<const data_t*>(data);
if (data)
if (size != mContents.size())
{
memcpy(mData, data, size);
}
}
// vector::resize only provides the basic exception guarantee, so use temporaries & swap to get the strong exception guarantee.
// We don't want to risk having mContents and mIdentityTranslation that have different contents or even different sizes.
std::vector<data_t> newContents(newdata, newdata + size);
IDirect3DVertexBuffer9 *Buffer::getVertexBuffer()
{
if (!mVertexBuffer)
{
IDirect3DDevice9 *device = getDevice();
HRESULT result = device->CreateVertexBuffer(mSize, 0, 0, D3DPOOL_MANAGED, &mVertexBuffer, NULL);
TranslatedVertexBuffer *newIdentityTranslation = mBackEnd->createVertexBuffer(size);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(GL_OUT_OF_MEMORY, (IDirect3DVertexBuffer9*)NULL);
}
// No exceptions allowed after this point.
ASSERT(SUCCEEDED(result));
mContents.swap(newContents);
if (mVertexBuffer && mData)
{
void *dataStore;
mVertexBuffer->Lock(0, mSize, &dataStore, 0);
memcpy(dataStore, mData, mSize);
mVertexBuffer->Unlock();
}
delete mIdentityTranslation;
mIdentityTranslation = newIdentityTranslation;
}
else
{
const data_t* newdata = static_cast<const data_t*>(data);
mContents.assign(newdata, newdata + size);
}
return mVertexBuffer;
return copyToIdentityBuffer(0, size);
}
IDirect3DIndexBuffer9 *Buffer::getIndexBuffer()
GLenum Buffer::bufferSubData(const void* data, GLsizeiptr size, GLintptr offset)
{
if (!mIndexBuffer)
{
IDirect3DDevice9 *device = getDevice();
if (size < 0 || offset < 0) return GL_INVALID_VALUE;
if (std::numeric_limits<GLsizeiptr>::max() - offset < size) return GL_INVALID_VALUE;
if (size + offset > static_cast<GLsizeiptr>(mContents.size())) return GL_INVALID_VALUE;
HRESULT result = device->CreateIndexBuffer(mSize, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &mIndexBuffer, NULL);
const data_t *newdata = static_cast<const data_t*>(data);
copy(newdata, newdata + size, mContents.begin() + offset);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(GL_OUT_OF_MEMORY, (IDirect3DIndexBuffer9*)NULL);
}
ASSERT(SUCCEEDED(result));
if (mIndexBuffer && mData)
{
void *dataStore;
mIndexBuffer->Lock(0, mSize, &dataStore, 0);
memcpy(dataStore, mData, mSize);
mIndexBuffer->Unlock();
}
}
return mIndexBuffer;
return copyToIdentityBuffer(offset, size);
}
void Buffer::erase()
GLenum Buffer::copyToIdentityBuffer(GLintptr offset, GLsizeiptr length)
{
mSize = 0;
ASSERT(offset >= 0 && length >= 0);
if (mData)
{
delete[] mData;
mData = NULL;
}
// This is a stalling map. Not great for performance.
data_t *p = static_cast<data_t*>(mIdentityTranslation->map());
if (mVertexBuffer)
{
mVertexBuffer->Release();
mVertexBuffer = NULL;
}
memcpy(p + offset, &mContents[0] + offset, length);
mIdentityTranslation->unmap();
if (mIndexBuffer)
{
mIndexBuffer->Release();
mIndexBuffer = NULL;
}
return GL_NO_ERROR;
}
}
......@@ -11,37 +11,47 @@
#ifndef LIBGLESV2_BUFFER_H_
#define LIBGLESV2_BUFFER_H_
#include <cstddef>
#include <vector>
#define GL_APICALL
#include <GLES2/gl2.h>
#include <d3d9.h>
#include "angleutils.h"
namespace gl
{
class BufferBackEnd;
class TranslatedVertexBuffer;
class Buffer
{
public:
Buffer();
explicit Buffer(BufferBackEnd *backEnd);
~Buffer();
void storeData(GLsizeiptr size, const void *data);
GLenum bufferData(const void *data, GLsizeiptr size, GLenum usage);
GLenum bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
IDirect3DVertexBuffer9 *getVertexBuffer();
IDirect3DIndexBuffer9 *getIndexBuffer();
void *data() { return &mContents[0]; }
GLsizeiptr size() const { return mContents.size(); }
TranslatedVertexBuffer *identityBuffer() { return mIdentityTranslation; }
private:
DISALLOW_COPY_AND_ASSIGN(Buffer);
void erase();
typedef unsigned char data_t;
std::vector<data_t> mContents;
unsigned int mSize;
void *mData;
BufferBackEnd *mBackEnd;
TranslatedVertexBuffer *mIdentityTranslation;
IDirect3DVertexBuffer9 *mVertexBuffer;
IDirect3DIndexBuffer9 *mIndexBuffer;
GLenum copyToIdentityBuffer(GLintptr offset, GLsizeiptr length);
};
}
#endif // LIBGLESV2_BUFFER_H_
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// geometry/VertexDataManager.h: Defines the VertexDataManager, a class that
// runs the Buffer translation process.
#ifndef LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
#define LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
#include <bitset>
#include <cstddef>
#define GL_APICALL
#include <GLES2/gl2.h>
#include "Context.h"
namespace gl
{
class Buffer;
class BufferBackEnd;
class TranslatedVertexBuffer;
struct TranslatedAttribute;
struct FormatConverter;
class VertexDataManager
{
public:
VertexDataManager(Context *context, BufferBackEnd *backend);
~VertexDataManager();
void dirtyCurrentValues() { mDirtyCurrentValues = true; }
GLenum preRenderValidate(GLint start,
GLsizei count,
TranslatedAttribute *outAttribs);
GLenum preRenderValidate(const Index *indices,
GLsizei count,
TranslatedAttribute* outAttribs);
private:
std::bitset<MAX_VERTEX_ATTRIBS> activeAttribs();
class TranslationHelper
{
public:
virtual ~TranslationHelper() { }
virtual void translate(const FormatConverter &converter, GLsizei stride, const void *source, void *dest) = 0;
};
class ArrayTranslationHelper : public TranslationHelper
{
public:
ArrayTranslationHelper(GLint first, GLsizei count);
void translate(const FormatConverter &converter, GLsizei stride, const void *source, void *dest);
private:
GLint mFirst;
GLsizei mCount;
};
class IndexedTranslationHelper : public TranslationHelper
{
public:
IndexedTranslationHelper(const Index *indices, GLsizei count);
void translate(const FormatConverter &converter, GLint stride, const void *source, void *dest);
private:
const Index *mIndices;
GLsizei mCount;
};
GLenum internalPreRenderValidate(const AttributeState *attribs,
const std::bitset<MAX_VERTEX_ATTRIBS> &activeAttribs,
Index minIndex,
Index maxIndex,
TranslationHelper *translator,
TranslatedAttribute *outAttribs);
void reloadCurrentValues(const AttributeState *attribs, std::size_t *offset);
void processNonArrayAttributes(const AttributeState *attribs, const std::bitset<MAX_VERTEX_ATTRIBS> &activeAttribs, TranslatedAttribute *translated);
std::size_t typeSize(GLenum type) const;
std::size_t interpretGlStride(const AttributeState &attrib) const;
std::size_t roundUp(std::size_t x, std::size_t multiple) const;
std::size_t spaceRequired(const AttributeState &attrib, std::size_t maxVertex) const;
Context *mContext;
BufferBackEnd *mBackend;
TranslatedVertexBuffer *mCurrentValueBuffer;
TranslatedVertexBuffer *mStreamBuffer;
bool mDirtyCurrentValues;
};
}
#endif // LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// geometry/backend.h: Abstract classes BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer
// that must be implemented by any API-specific implementation of ANGLE.
#include "geometry/backend.h"
#include "debug.h"
namespace gl
{
void *TranslatedBuffer::map(std::size_t requiredSpace, std::size_t *offset)
{
ASSERT(requiredSpace < mBufferSize);
reserveSpace(requiredSpace);
*offset = mCurrentPoint;
mCurrentPoint += requiredSpace;
return streamingMap(*offset, requiredSpace);
}
void TranslatedBuffer::reserveSpace(std::size_t requiredSpace)
{
if (mCurrentPoint + requiredSpace > mBufferSize)
{
recycle();
mCurrentPoint = 0;
}
}
}
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// geometry/backend.h: Abstract classes BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer
// that must be implemented by any API-specific implementation of ANGLE.
#ifndef LIBGLESV2_GEOMETRY_BACKEND_H_
#define LIBGLESV2_GEOMETRY_BACKEND_H_
#include <cstddef>
#define GL_APICALL
#include <GLES2/gl2.h>
#include "Context.h"
namespace gl
{
class TranslatedVertexBuffer;
class TranslatedIndexBuffer;
struct FormatConverter
{
bool identity;
std::size_t outputVertexSize;
void (*convertIndexed)(const void *in, std::size_t stride, std::size_t n, const Index *indices, void *out);
void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
};
struct TranslatedAttribute
{
bool enabled;
// These are the original untranslated values. (Or just have some sort of BufferBackEnd::TranslatedTypeKey.)
GLenum type;
std::size_t size;
bool normalized;
std::size_t offset;
std::size_t stride; // 0 means not to advance the read pointer at all
std::size_t programAttribute;
TranslatedVertexBuffer *buffer;
};
class BufferBackEnd
{
public:
virtual ~BufferBackEnd() { }
virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size) = 0;
virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size) = 0;
virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize) = 0;
virtual GLenum preDraw(const TranslatedAttribute *attributes) = 0;
};
class TranslatedBuffer
{
public:
explicit TranslatedBuffer(std::size_t size) : mBufferSize(size), mCurrentPoint(0) { }
virtual ~TranslatedBuffer() { }
std::size_t size() const { return mBufferSize; }
virtual void *map() = 0;
virtual void unmap() = 0;
void reserveSpace(std::size_t requiredSpace);
void *map(std::size_t requiredSpace, std::size_t *offset);
protected:
virtual void recycle() = 0;
virtual void *streamingMap(std::size_t offset, std::size_t size) = 0;
private:
std::size_t mBufferSize;
std::size_t mCurrentPoint;
DISALLOW_COPY_AND_ASSIGN(TranslatedBuffer);
};
class TranslatedVertexBuffer : public TranslatedBuffer
{
public:
explicit TranslatedVertexBuffer(std::size_t size) : TranslatedBuffer(size) { }
};
class TranslatedIndexBuffer : public TranslatedBuffer
{
public:
explicit TranslatedIndexBuffer(std::size_t size) : TranslatedBuffer(size) { }
};
}
#endif // LIBGLESV2_GEOMETRY_BACKEND_H_
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// geometry/dx9.h: Direct3D 9-based implementation of BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer.
#ifndef LIBGLESV2_GEOMETRY_DX9_H_
#define LIBGLESV2_GEOMETRY_DX9_H_
#include <d3d9.h>
#include "Buffer.h"
#include "geometry/backend.h"
namespace gl
{
class Dx9BackEnd : public BufferBackEnd
{
public:
explicit Dx9BackEnd(IDirect3DDevice9 *d3ddevice);
~Dx9BackEnd();
virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size);
virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size);
virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize);
virtual GLenum preDraw(const TranslatedAttribute *attributes);
private:
IDirect3DDevice9 *mDevice;
class Dx9VertexBuffer : public TranslatedVertexBuffer
{
public:
Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size);
virtual ~Dx9VertexBuffer();
IDirect3DVertexBuffer9 *getBuffer() const;
protected:
virtual void *map();
virtual void unmap();
virtual void recycle();
virtual void *streamingMap(std::size_t offset, std::size_t size);
private:
IDirect3DVertexBuffer9 *mVertexBuffer;
};
class Dx9IndexBuffer : public TranslatedIndexBuffer
{
public:
Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size);
virtual ~Dx9IndexBuffer();
IDirect3DIndexBuffer9 *getBuffer() const;
protected:
virtual void *map();
virtual void unmap();
virtual void recycle();
virtual void *streamingMap(std::size_t offset, std::size_t size);
private:
IDirect3DIndexBuffer9 *mIndexBuffer;
};
IDirect3DVertexBuffer9 *getDxBuffer(TranslatedVertexBuffer *vb) const;
IDirect3DIndexBuffer9 *getDxBuffer(TranslatedIndexBuffer *ib) const;
D3DDECLTYPE mapAttributeType(GLenum type, std::size_t size, bool normalized) const;
};
}
#endif // LIBGLESV2_GEOMETRY_DX9_H_
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// geometry/vertexconversion.h: A library of vertex conversion classes that can be used to build
// the FormatConverter objects used by the buffer conversion system.
#ifndef LIBGLESV2_GEOMETRY_VERTEXCONVERSION_H_
#define LIBGLESV2_GEOMETRY_VERTEXCONVERSION_H_
#include <cstddef>
#include <limits>
#include "Context.h" // Defines Index
namespace gl
{
// Conversion types:
// static const bool identity: true if this is an identity transform, false otherwise
// static U convert(T): convert a single element from the input type to the output type
// typedef ... OutputType: the type produced by this conversion
template <class T>
struct Identity
{
static const bool identity = true;
typedef T OutputType;
static T convert(T x)
{
return x;
}
};
template <class FromT, class ToT>
struct Cast
{
static const bool identity = false;
typedef ToT OutputType;
static ToT convert(FromT x)
{
return static_cast<ToT>(x);
}
};
template <class T>
struct Cast<T, T>
{
static const bool identity = true;
typedef T OutputType;
static T convert(T x)
{
return static_cast<T>(x);
}
};
template <class T>
struct Normalize
{
static const bool identity = false;
typedef float OutputType;
static float convert(T x)
{
typedef std::numeric_limits<T> NL;
float f = static_cast<float>(x);
if (NL::is_signed)
{
// const float => VC2008 computes it at compile time
// static const float => VC2008 computes it the first time we get here, stores it to memory with static guard and all that.
const float divisor = 1.0f/(2*static_cast<float>(NL::max())+1);
return (2*f+1)*divisor;
}
else
{
return f/NL::max();
}
}
};
template <class FromType, std::size_t ScaleBits>
struct FixedToFloat
{
static const bool identity = false;
typedef float OutputType;
static float convert(FromType x)
{
const float divisor = 1.0f / static_cast<float>(static_cast<FromType>(1) << ScaleBits);
return static_cast<float>(x) * divisor;
}
};
// Widen types:
// static const unsigned int initialWidth: number of components before conversion
// static const unsigned int finalWidth: number of components after conversion
// Float is supported at any size.
template <std::size_t N>
struct NoWiden
{
static const std::size_t initialWidth = N;
static const std::size_t finalWidth = N;
};
// SHORT, norm-SHORT, norm-UNSIGNED_SHORT are supported but only with 2 or 4 components
template <std::size_t N>
struct WidenToEven
{
static const std::size_t initialWidth = N;
static const std::size_t finalWidth = N+(N&1);
};
template <unsigned int N>
struct WidenToFour
{
static const std::size_t initialWidth = N;
static const std::size_t finalWidth = 4;
};
// Most types have 0 and 1 that are just that.
template <class T>
struct SimpleDefaultValues
{
static T zero() { return static_cast<T>(0); }
static T one() { return static_cast<T>(1); }
};
// But normalised types only store [0,1] or [-1,1] so 1.0 is represented by the max value.
template <class T>
struct NormalizedDefaultValues
{
static T zero() { return static_cast<T>(0); }
static T one() { return std::numeric_limits<T>::max(); }
};
// Converter:
// static const bool identity: true if this is an identity transform (with no widening)
// static const std::size_t finalSize: number of bytes per output vertex
// static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out): convert an array of vertices. Input may be strided, but output will be unstrided.
// static void convertIndexed(const void *in, std::size_t stride, std::size_t n, const Index *indices, void *out): convert an indexed array of vertices. Input may be strided, but output will be unstrided.
template <class InT, class WidenRule, class Converter, class DefaultValueRule = SimpleDefaultValues<InT> >
struct VertexDataConverter
{
typedef typename Converter::OutputType OutputType;
typedef InT InputType;
static const bool identity = (WidenRule::initialWidth == WidenRule::finalWidth) && Converter::identity;
static const std::size_t finalSize = WidenRule::finalWidth * sizeof(OutputType);
static void convertArray(const InputType *in, std::size_t stride, std::size_t n, OutputType *out)
{
for (std::size_t i = 0; i < n; i++)
{
const InputType *ein = pointerAddBytes(in, i * stride);
copyComponent(out, ein, 0, static_cast<OutputType>(DefaultValueRule::zero()));
copyComponent(out, ein, 1, static_cast<OutputType>(DefaultValueRule::zero()));
copyComponent(out, ein, 2, static_cast<OutputType>(DefaultValueRule::zero()));
copyComponent(out, ein, 3, static_cast<OutputType>(DefaultValueRule::one()));
out += WidenRule::finalWidth;
}
}
static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out)
{
return convertArray(static_cast<const InputType*>(in), stride, n, static_cast<OutputType*>(out));
}
static void convertIndexed(const InputType *in, std::size_t stride, std::size_t n, const Index *indices, OutputType *out)
{
for (std::size_t i = 0; i < n; i++)
{
const InputType *ein = pointerAddBytes(in, indices[i] * stride);
OutputType *eout = pointerAddBytes(out, indices[i] * finalSize);
copyComponent(eout, ein, 0, static_cast<OutputType>(DefaultValueRule::zero()));
copyComponent(eout, ein, 1, static_cast<OutputType>(DefaultValueRule::zero()));
copyComponent(eout, ein, 2, static_cast<OutputType>(DefaultValueRule::zero()));
copyComponent(eout, ein, 3, static_cast<OutputType>(DefaultValueRule::one()));
}
}
static void convertIndexed(const void *in, std::size_t stride, std::size_t n, const Index *indices, void *out)
{
convertIndexed(static_cast<const InputType*>(in), stride, n, indices, static_cast<OutputType*>(out));
}
private:
// Advance the given pointer by a number of bytes (not pointed-to elements).
template <class T>
static T *pointerAddBytes(T *basePtr, std::size_t numBytes)
{
return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(basePtr) + numBytes);
}
static void copyComponent(OutputType *out, const InputType *in, std::size_t elementindex, OutputType defaultvalue)
{
if (WidenRule::finalWidth > elementindex)
{
if (WidenRule::initialWidth > elementindex)
{
*out = Converter::convert(in[elementindex]);
}
else
{
*out = defaultvalue;
}
}
}
};
}
#endif // LIBGLESV2_GEOMETRY_VERTEXCONVERSION_H_
......@@ -454,7 +454,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const void* data, GL
return error(GL_INVALID_OPERATION);
}
buffer->storeData(size, data);
buffer->bufferData(data, size, usage);
}
}
catch(std::bad_alloc&)
......@@ -474,7 +474,36 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
return error(GL_INVALID_VALUE);
}
UNIMPLEMENTED(); // FIXME
gl::Context *context = gl::getContext();
if (context)
{
gl::Buffer *buffer;
switch (target)
{
case GL_ARRAY_BUFFER:
buffer = context->getArrayBuffer();
break;
case GL_ELEMENT_ARRAY_BUFFER:
buffer = context->getElementArrayBuffer();
break;
default:
return error(GL_INVALID_ENUM);
}
if (!buffer)
{
return error(GL_INVALID_OPERATION);
}
GLenum err = buffer->bufferSubData(data, size, offset);
if (err != GL_NO_ERROR)
{
return error(err);
}
}
}
catch(std::bad_alloc&)
{
......@@ -1100,7 +1129,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index)
if (context)
{
context->vertexAttribute[index].enabled = false;
context->vertexAttribute[index].mEnabled = false;
}
}
catch(std::bad_alloc&)
......@@ -1214,7 +1243,7 @@ void __stdcall glEnableVertexAttribArray(GLuint index)
if (context)
{
context->vertexAttribute[index].enabled = true;
context->vertexAttribute[index].mEnabled = true;
}
}
catch(std::bad_alloc&)
......@@ -3777,12 +3806,12 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo
if (context)
{
context->vertexAttribute[index].boundBuffer = context->arrayBuffer;
context->vertexAttribute[index].size = size;
context->vertexAttribute[index].type = type;
context->vertexAttribute[index].normalized = normalized;
context->vertexAttribute[index].stride = stride;
context->vertexAttribute[index].pointer = ptr;
context->vertexAttribute[index].mBoundBuffer = context->arrayBuffer;
context->vertexAttribute[index].mSize = size;
context->vertexAttribute[index].mType = type;
context->vertexAttribute[index].mNormalized = normalized;
context->vertexAttribute[index].mStride = stride;
context->vertexAttribute[index].mPointer = ptr;
}
}
catch(std::bad_alloc&)
......
......@@ -41,7 +41,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../Include/; ../Compiler/"
AdditionalIncludeDirectories="../Include/; ../Compiler/;."
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBGLESV2_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
MinimalRebuild="true"
BasicRuntimeChecks="3"
......@@ -118,7 +118,7 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../Include/; ../Compiler/"
AdditionalIncludeDirectories="../Include/; ../Compiler/;."
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBGLESV2_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
......@@ -224,6 +224,22 @@
RelativePath=".\utilities.cpp"
>
</File>
<Filter
Name="Geometry"
>
<File
RelativePath=".\geometry\backend.cpp"
>
</File>
<File
RelativePath=".\geometry\dx9.cpp"
>
</File>
<File
RelativePath=".\geometry\VertexDataManager.cpp"
>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
......@@ -302,6 +318,26 @@
RelativePath=".\utilities.h"
>
</File>
<Filter
Name="Geometry"
>
<File
RelativePath=".\geometry\backend.h"
>
</File>
<File
RelativePath=".\geometry\dx9.h"
>
</File>
<File
RelativePath=".\geometry\vertexconversion.h"
>
</File>
<File
RelativePath=".\geometry\VertexDataManager.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="Resource Files"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment