Implement GL_OES_element_index_uint

TRAC #11951 Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Andrew Lewycky git-svn-id: https://angleproject.googlecode.com/svn/trunk@240 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 97bffae5
...@@ -239,6 +239,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) ...@@ -239,6 +239,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
if (!mHasBeenCurrent) if (!mHasBeenCurrent)
{ {
initExtensionString();
mState.viewportX = 0; mState.viewportX = 0;
mState.viewportY = 0; mState.viewportY = 0;
mState.viewportWidth = surface->getWidth(); mState.viewportWidth = surface->getWidth();
...@@ -1731,23 +1733,6 @@ void Context::lookupAttributeMapping(TranslatedAttribute *attributes) ...@@ -1731,23 +1733,6 @@ void Context::lookupAttributeMapping(TranslatedAttribute *attributes)
} }
} }
// The indices parameter to glDrawElements can have two interpretations:
// - as a pointer into client memory
// - as an offset into the current GL_ELEMENT_ARRAY_BUFFER buffer
// Handle these cases here and return a pointer to the index data.
const Index *Context::adjustIndexPointer(const void *indices)
{
if (mState.elementArrayBuffer)
{
Buffer *buffer = getBuffer(mState.elementArrayBuffer);
return reinterpret_cast<const Index*>(static_cast<unsigned char*>(buffer->data()) + reinterpret_cast<GLsizei>(indices));
}
else
{
return static_cast<const Index*>(indices);
}
}
void Context::applyVertexBuffer(GLint first, GLsizei count) void Context::applyVertexBuffer(GLint first, GLsizei count)
{ {
TranslatedAttribute translated[MAX_VERTEX_ATTRIBS]; TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];
...@@ -1763,7 +1748,7 @@ void Context::applyVertexBuffer(const TranslatedIndexData &indexInfo) ...@@ -1763,7 +1748,7 @@ void Context::applyVertexBuffer(const TranslatedIndexData &indexInfo)
{ {
TranslatedAttribute translated[MAX_VERTEX_ATTRIBS]; TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];
mVertexDataManager->preRenderValidate(indexInfo, translated); mVertexDataManager->preRenderValidate(indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, translated);
lookupAttributeMapping(translated); lookupAttributeMapping(translated);
...@@ -2256,7 +2241,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void* ...@@ -2256,7 +2241,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void*
if (!cullSkipsDraw(mode)) if (!cullSkipsDraw(mode))
{ {
display->startScene(); display->startScene();
device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, indexInfo.offset/sizeof(Index), primitiveCount); device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, indexInfo.offset/indexInfo.indexSize, primitiveCount);
} }
} }
...@@ -2575,6 +2560,25 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values) ...@@ -2575,6 +2560,25 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values)
mVertexDataManager->dirtyCurrentValues(); mVertexDataManager->dirtyCurrentValues();
} }
void Context::initExtensionString()
{
if (mBufferBackEnd->supportIntIndices())
{
mExtensionString += "GL_OES_element_index_uint ";
}
std::string::size_type end = mExtensionString.find_last_not_of(' ');
if (end != std::string::npos)
{
mExtensionString.resize(end+1);
}
}
const char *Context::getExtensionString() const
{
return mExtensionString.c_str();
}
} }
extern "C" extern "C"
......
...@@ -69,9 +69,6 @@ const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f; ...@@ -69,9 +69,6 @@ const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;
const float ALIASED_POINT_SIZE_RANGE_MIN = 1.0f; const float ALIASED_POINT_SIZE_RANGE_MIN = 1.0f;
const float ALIASED_POINT_SIZE_RANGE_MAX = 1.0f; const float ALIASED_POINT_SIZE_RANGE_MAX = 1.0f;
// Because indices are accessed internally, we convert them to a common format.
typedef unsigned short Index;
enum SamplerType enum SamplerType
{ {
SAMPLER_2D, SAMPLER_2D,
...@@ -376,13 +373,14 @@ class Context ...@@ -376,13 +373,14 @@ class Context
const char *getPixelShaderProfile(); const char *getPixelShaderProfile();
const char *getVertexShaderProfile(); const char *getVertexShaderProfile();
const char *getExtensionString() const;
Blit *getBlitter() { return mBlit; } Blit *getBlitter() { return mBlit; }
private: private:
DISALLOW_COPY_AND_ASSIGN(Context); DISALLOW_COPY_AND_ASSIGN(Context);
void lookupAttributeMapping(TranslatedAttribute *attributes); void lookupAttributeMapping(TranslatedAttribute *attributes);
const Index *adjustIndexPointer(const void *indices);
void detachBuffer(GLuint buffer); void detachBuffer(GLuint buffer);
void detachTexture(GLuint texture); void detachTexture(GLuint texture);
...@@ -423,6 +421,9 @@ class Context ...@@ -423,6 +421,9 @@ class Context
typedef std::map<GLuint, Renderbuffer*> RenderbufferMap; typedef std::map<GLuint, Renderbuffer*> RenderbufferMap;
RenderbufferMap mRenderbufferMap; RenderbufferMap mRenderbufferMap;
void initExtensionString();
std::string mExtensionString;
BufferBackEnd *mBufferBackEnd; BufferBackEnd *mBufferBackEnd;
VertexDataManager *mVertexDataManager; VertexDataManager *mVertexDataManager;
IndexDataManager *mIndexDataManager; IndexDataManager *mIndexDataManager;
......
...@@ -16,30 +16,40 @@ ...@@ -16,30 +16,40 @@
namespace namespace
{ {
enum { INITIAL_INDEX_BUFFER_SIZE = sizeof(gl::Index) * 8192 }; enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
} }
namespace gl namespace gl
{ {
IndexDataManager::IndexDataManager(Context *context, BufferBackEnd *backend) IndexDataManager::IndexDataManager(Context *context, BufferBackEnd *backend)
: mContext(context), mBackend(backend) : mContext(context), mBackend(backend), mIntIndicesSupported(backend->supportIntIndices())
{ {
mStreamBuffer = mBackend->createIndexBuffer(INITIAL_INDEX_BUFFER_SIZE); mStreamBufferShort = mBackend->createIndexBuffer(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT);
if (mIntIndicesSupported)
{
mStreamBufferInt = mBackend->createIndexBuffer(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
}
else
{
mStreamBufferInt = NULL;
}
} }
IndexDataManager::~IndexDataManager() IndexDataManager::~IndexDataManager()
{ {
delete mStreamBuffer; delete mStreamBufferShort;
delete mStreamBufferInt;
} }
namespace namespace
{ {
template <class InputIndexType> template <class InputIndexType, class OutputIndexType>
void copyIndices(const InputIndexType *in, GLsizei count, Index *out, GLuint *minIndex, GLuint *maxIndex) void copyIndices(const InputIndexType *in, GLsizei count, OutputIndexType *out, GLuint *minIndex, GLuint *maxIndex)
{ {
Index first = *in; InputIndexType first = *in;
GLuint minIndexSoFar = first; GLuint minIndexSoFar = first;
GLuint maxIndexSoFar = first; GLuint maxIndexSoFar = first;
...@@ -62,7 +72,7 @@ void copyIndices(const InputIndexType *in, GLsizei count, Index *out, GLuint *mi ...@@ -62,7 +72,7 @@ void copyIndices(const InputIndexType *in, GLsizei count, Index *out, GLuint *mi
TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices) TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices)
{ {
ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_BYTE); ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT);
ASSERT(count > 0); ASSERT(count > 0);
TranslatedIndexData translated; TranslatedIndexData translated;
...@@ -71,54 +81,100 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type ...@@ -71,54 +81,100 @@ TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type
std::size_t requiredSpace = spaceRequired(type, count); std::size_t requiredSpace = spaceRequired(type, count);
if (requiredSpace > mStreamBuffer->size()) TranslatedIndexBuffer *streamIb = prepareIndexBuffer(type, requiredSpace);
{
std::size_t newSize = std::max(requiredSpace, 2 * mStreamBuffer->size());
TranslatedIndexBuffer *newStreamBuffer = mBackend->createIndexBuffer(newSize);
delete mStreamBuffer;
mStreamBuffer = newStreamBuffer;
}
mStreamBuffer->reserveSpace(requiredSpace);
size_t offset; size_t offset;
void *output = mStreamBuffer->map(requiredSpace, &offset); void *output = streamIb->map(requiredSpace, &offset);
translated.buffer = mStreamBuffer; translated.buffer = streamIb;
translated.offset = offset; translated.offset = offset;
translated.indexSize = indexSize(type);
translated.indices = static_cast<const Index*>(output); translated.indices = output;
if (arrayElementBuffer != NULL) if (arrayElementBuffer != NULL)
{ {
indices = static_cast<const GLubyte*>(arrayElementBuffer->data()) + reinterpret_cast<GLsizei>(indices); indices = static_cast<const GLubyte*>(arrayElementBuffer->data()) + reinterpret_cast<GLsizei>(indices);
} }
Index *out = static_cast<Index*>(output); if (type == GL_UNSIGNED_BYTE)
{
const GLubyte *in = static_cast<const GLubyte*>(indices);
GLushort *out = static_cast<GLushort*>(output);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
}
else if (type == GL_UNSIGNED_INT)
{
const GLuint *in = static_cast<const GLuint*>(indices);
if (type == GL_UNSIGNED_SHORT) if (mIntIndicesSupported)
{ {
const GLushort *in = static_cast<const GLushort*>(indices); GLuint *out = static_cast<GLuint*>(output);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex); copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
} }
else else
{ {
const GLubyte *in = static_cast<const GLubyte*>(indices); // When 32-bit indices are unsupported, fake them by truncating to 16-bit.
GLushort *out = static_cast<GLushort*>(output);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
}
}
else
{
const GLushort *in = static_cast<const GLushort*>(indices);
GLushort *out = static_cast<GLushort*>(output);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex); copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
} }
mStreamBuffer->unmap(); streamIb->unmap();
return translated; return translated;
} }
std::size_t IndexDataManager::spaceRequired(GLenum type, GLsizei count) std::size_t IndexDataManager::indexSize(GLenum type) const
{
return (type == GL_UNSIGNED_INT && mIntIndicesSupported) ? sizeof(GLuint) : sizeof(GLushort);
}
std::size_t IndexDataManager::spaceRequired(GLenum type, GLsizei count) const
{ {
return (count + 1) * sizeof(Index); // +1 because we always leave an extra for line loops return (count + 1) * indexSize(type); // +1 because we always leave an extra for line loops
}
TranslatedIndexBuffer *IndexDataManager::prepareIndexBuffer(GLenum type, std::size_t requiredSpace)
{
bool use32 = (type == GL_UNSIGNED_INT && mIntIndicesSupported);
TranslatedIndexBuffer *streamIb = use32 ? mStreamBufferInt : mStreamBufferShort;
if (requiredSpace > streamIb->size())
{
std::size_t newSize = std::max(requiredSpace, 2 * streamIb->size());
TranslatedIndexBuffer *newStreamBuffer = mBackend->createIndexBuffer(newSize, use32 ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT);
delete streamIb;
streamIb = newStreamBuffer;
if (use32)
{
mStreamBufferInt = streamIb;
}
else
{
mStreamBufferShort = streamIb;
}
}
streamIb->reserveSpace(requiredSpace);
return streamIb;
} }
} }
...@@ -31,8 +31,9 @@ struct TranslatedIndexData ...@@ -31,8 +31,9 @@ struct TranslatedIndexData
GLuint minIndex; GLuint minIndex;
GLuint maxIndex; GLuint maxIndex;
GLuint count; GLuint count;
GLuint indexSize;
const Index *indices; const void *indices;
TranslatedIndexBuffer *buffer; TranslatedIndexBuffer *buffer;
GLsizei offset; GLsizei offset;
...@@ -47,12 +48,17 @@ class IndexDataManager ...@@ -47,12 +48,17 @@ class IndexDataManager
TranslatedIndexData preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices); TranslatedIndexData preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices);
private: private:
std::size_t spaceRequired(GLenum type, GLsizei count); std::size_t IndexDataManager::indexSize(GLenum type) const;
std::size_t spaceRequired(GLenum type, GLsizei count) const;
TranslatedIndexBuffer *prepareIndexBuffer(GLenum type, std::size_t requiredSpace);
Context *mContext; Context *mContext;
BufferBackEnd *mBackend; BufferBackEnd *mBackend;
TranslatedIndexBuffer *mStreamBuffer; bool mIntIndicesSupported;
TranslatedIndexBuffer *mStreamBufferShort;
TranslatedIndexBuffer *mStreamBufferInt;
}; };
} }
......
...@@ -46,27 +46,7 @@ VertexDataManager::~VertexDataManager() ...@@ -46,27 +46,7 @@ VertexDataManager::~VertexDataManager()
delete mCurrentValueBuffer; delete mCurrentValueBuffer;
} }
VertexDataManager::ArrayTranslationHelper::ArrayTranslationHelper(GLint first, GLsizei count) std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::getActiveAttribs() const
: mFirst(first), mCount(count)
{
}
void VertexDataManager::ArrayTranslationHelper::translate(const FormatConverter &converter, GLsizei stride, const void *source, void *dest)
{
converter.convertArray(source, stride, mCount, dest);
}
VertexDataManager::IndexedTranslationHelper::IndexedTranslationHelper(const Index *indices, Index minIndex, GLsizei count)
: mIndices(indices), mMinIndex(minIndex), mCount(count)
{
}
void VertexDataManager::IndexedTranslationHelper::translate(const FormatConverter &converter, GLsizei stride, const void *source, void *dest)
{
converter.convertIndexed(source, stride, mMinIndex, mCount, mIndices, dest);
}
std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::activeAttribs()
{ {
std::bitset<MAX_VERTEX_ATTRIBS> active; std::bitset<MAX_VERTEX_ATTRIBS> active;
...@@ -81,28 +61,11 @@ std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::activeAttribs() ...@@ -81,28 +61,11 @@ std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::activeAttribs()
} }
GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count, GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count,
TranslatedAttribute *outAttribs)
{
ArrayTranslationHelper translationHelper(start, count);
return internalPreRenderValidate(mContext->getVertexAttribBlock(), activeAttribs(), start, start+count-1, &translationHelper, outAttribs);
}
GLenum VertexDataManager::preRenderValidate(const TranslatedIndexData &indexInfo,
TranslatedAttribute *outAttribs)
{
IndexedTranslationHelper translationHelper(indexInfo.indices, indexInfo.minIndex, indexInfo.count);
return internalPreRenderValidate(mContext->getVertexAttribBlock(), activeAttribs(), indexInfo.minIndex, indexInfo.maxIndex, &translationHelper, outAttribs);
}
GLenum VertexDataManager::internalPreRenderValidate(const AttributeState *attribs,
const std::bitset<MAX_VERTEX_ATTRIBS> &activeAttribs,
Index minIndex,
Index maxIndex,
TranslationHelper *translator,
TranslatedAttribute *translated) TranslatedAttribute *translated)
{ {
const AttributeState *attribs = mContext->getVertexAttribBlock();
const std::bitset<MAX_VERTEX_ATTRIBS> activeAttribs = getActiveAttribs();
std::bitset<MAX_VERTEX_ATTRIBS> translateOrLift; std::bitset<MAX_VERTEX_ATTRIBS> translateOrLift;
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
...@@ -127,7 +90,7 @@ GLenum VertexDataManager::internalPreRenderValidate(const AttributeState *attrib ...@@ -127,7 +90,7 @@ GLenum VertexDataManager::internalPreRenderValidate(const AttributeState *attrib
if (attribs[i].mBoundBuffer != 0 && mBackend->getFormatConverter(attribs[i].mType, attribs[i].mSize, attribs[i].mNormalized).identity) if (attribs[i].mBoundBuffer != 0 && mBackend->getFormatConverter(attribs[i].mType, attribs[i].mSize, attribs[i].mNormalized).identity)
{ {
std::size_t stride = interpretGlStride(attribs[i]); std::size_t stride = interpretGlStride(attribs[i]);
std::size_t offset = static_cast<std::size_t>(static_cast<const char*>(attribs[i].mPointer) - static_cast<const char*>(NULL)) + stride * minIndex; std::size_t offset = static_cast<std::size_t>(static_cast<const char*>(attribs[i].mPointer) - static_cast<const char*>(NULL)) + stride * start;
if (mBackend->validateStream(attribs[i].mType, attribs[i].mSize, stride, offset)) if (mBackend->validateStream(attribs[i].mType, attribs[i].mSize, stride, offset))
{ {
...@@ -153,8 +116,6 @@ GLenum VertexDataManager::internalPreRenderValidate(const AttributeState *attrib ...@@ -153,8 +116,6 @@ GLenum VertexDataManager::internalPreRenderValidate(const AttributeState *attrib
// Handle any attributes needing translation or lifting. // Handle any attributes needing translation or lifting.
if (translateOrLift.any()) if (translateOrLift.any())
{ {
std::size_t count = maxIndex - minIndex + 1;
std::size_t requiredSpace = 0; std::size_t requiredSpace = 0;
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
...@@ -204,9 +165,9 @@ GLenum VertexDataManager::internalPreRenderValidate(const AttributeState *attrib ...@@ -204,9 +165,9 @@ GLenum VertexDataManager::internalPreRenderValidate(const AttributeState *attrib
size_t inputStride = interpretGlStride(attribs[i]); size_t inputStride = interpretGlStride(attribs[i]);
input = static_cast<const char*>(input) + inputStride * minIndex; input = static_cast<const char*>(input) + inputStride * start;
translator->translate(formatConverter, interpretGlStride(attribs[i]), input, output); formatConverter.convertArray(input, inputStride, count, output);
mStreamBuffer->unmap(); mStreamBuffer->unmap();
} }
......
...@@ -40,51 +40,8 @@ class VertexDataManager ...@@ -40,51 +40,8 @@ class VertexDataManager
GLsizei count, GLsizei count,
TranslatedAttribute *outAttribs); TranslatedAttribute *outAttribs);
GLenum preRenderValidate(const TranslatedIndexData &indexInfo,
TranslatedAttribute* outAttribs);
private: private:
std::bitset<MAX_VERTEX_ATTRIBS> activeAttribs(); std::bitset<MAX_VERTEX_ATTRIBS> getActiveAttribs() const;
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, Index minIndex, GLsizei count);
void translate(const FormatConverter &converter, GLint stride, const void *source, void *dest);
private:
const Index *mIndices;
Index mMinIndex;
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 reloadCurrentValues(const AttributeState *attribs, std::size_t *offset);
......
...@@ -26,7 +26,6 @@ struct FormatConverter ...@@ -26,7 +26,6 @@ struct FormatConverter
{ {
bool identity; bool identity;
std::size_t outputVertexSize; std::size_t outputVertexSize;
void (*convertIndexed)(const void *in, std::size_t stride, Index minIndex, std::size_t n, const Index *indices, void *out);
void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out); void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
}; };
...@@ -53,9 +52,11 @@ class BufferBackEnd ...@@ -53,9 +52,11 @@ class BufferBackEnd
public: public:
virtual ~BufferBackEnd() { } virtual ~BufferBackEnd() { }
virtual bool supportIntIndices() = 0;
virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size) = 0; virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size) = 0;
virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(std::size_t size) = 0; virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(std::size_t size) = 0;
virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size) = 0; virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size, GLenum type) = 0;
virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize) = 0; virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize) = 0;
// For an identity-mappable stream, verify that the stride and offset are okay. // For an identity-mappable stream, verify that the stride and offset are okay.
......
...@@ -32,7 +32,6 @@ class FormatConverterFactory ...@@ -32,7 +32,6 @@ class FormatConverterFactory
formatConverter.identity = gl::VertexDataConverter<InputType, WidenRule<IncomingWidth>, ElementConverter, DefaultValueRule>::identity; formatConverter.identity = gl::VertexDataConverter<InputType, WidenRule<IncomingWidth>, ElementConverter, DefaultValueRule>::identity;
formatConverter.outputVertexSize = gl::VertexDataConverter<InputType, WidenRule<IncomingWidth>, ElementConverter, DefaultValueRule>::finalSize; formatConverter.outputVertexSize = gl::VertexDataConverter<InputType, WidenRule<IncomingWidth>, ElementConverter, DefaultValueRule>::finalSize;
formatConverter.convertIndexed = gl::VertexDataConverter<InputType, WidenRule<IncomingWidth>, ElementConverter, DefaultValueRule>::convertIndexed;
formatConverter.convertArray = gl::VertexDataConverter<InputType, WidenRule<IncomingWidth>, ElementConverter, DefaultValueRule>::convertArray; formatConverter.convertArray = gl::VertexDataConverter<InputType, WidenRule<IncomingWidth>, ElementConverter, DefaultValueRule>::convertArray;
return formatConverter; return formatConverter;
...@@ -66,6 +65,14 @@ Dx9BackEnd::~Dx9BackEnd() ...@@ -66,6 +65,14 @@ Dx9BackEnd::~Dx9BackEnd()
mDevice->Release(); mDevice->Release();
} }
bool Dx9BackEnd::supportIntIndices()
{
D3DCAPS9 caps;
mDevice->GetDeviceCaps(&caps);
return (caps.MaxVertexIndex >= (1 << 16));
}
TranslatedVertexBuffer *Dx9BackEnd::createVertexBuffer(std::size_t size) TranslatedVertexBuffer *Dx9BackEnd::createVertexBuffer(std::size_t size)
{ {
return new Dx9VertexBuffer(mDevice, size); return new Dx9VertexBuffer(mDevice, size);
...@@ -76,9 +83,9 @@ TranslatedVertexBuffer *Dx9BackEnd::createVertexBufferForStrideZero(std::size_t ...@@ -76,9 +83,9 @@ TranslatedVertexBuffer *Dx9BackEnd::createVertexBufferForStrideZero(std::size_t
return new Dx9VertexBufferZeroStrideWorkaround(mDevice, size); return new Dx9VertexBufferZeroStrideWorkaround(mDevice, size);
} }
TranslatedIndexBuffer *Dx9BackEnd::createIndexBuffer(std::size_t size) TranslatedIndexBuffer *Dx9BackEnd::createIndexBuffer(std::size_t size, GLenum type)
{ {
return new Dx9IndexBuffer(mDevice, size); return new Dx9IndexBuffer(mDevice, size, type);
} }
// Mapping from OpenGL-ES vertex attrib type to D3D decl type: // Mapping from OpenGL-ES vertex attrib type to D3D decl type:
...@@ -325,10 +332,14 @@ void *Dx9BackEnd::Dx9VertexBufferZeroStrideWorkaround::streamingMap(std::size_t ...@@ -325,10 +332,14 @@ void *Dx9BackEnd::Dx9VertexBufferZeroStrideWorkaround::streamingMap(std::size_t
return mapPtr; return mapPtr;
} }
Dx9BackEnd::Dx9IndexBuffer::Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size) Dx9BackEnd::Dx9IndexBuffer::Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size, GLenum type)
: TranslatedIndexBuffer(size) : TranslatedIndexBuffer(size)
{ {
HRESULT hr = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &mIndexBuffer, NULL); ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT);
D3DFORMAT format = (type == GL_UNSIGNED_SHORT) ? D3DFMT_INDEX16 : D3DFMT_INDEX32;
HRESULT hr = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, D3DPOOL_DEFAULT, &mIndexBuffer, NULL);
if (hr != S_OK) if (hr != S_OK)
{ {
ERR("Out of memory allocating an index buffer of size %lu.", size); ERR("Out of memory allocating an index buffer of size %lu.", size);
......
...@@ -23,9 +23,11 @@ class Dx9BackEnd : public BufferBackEnd ...@@ -23,9 +23,11 @@ class Dx9BackEnd : public BufferBackEnd
explicit Dx9BackEnd(IDirect3DDevice9 *d3ddevice); explicit Dx9BackEnd(IDirect3DDevice9 *d3ddevice);
~Dx9BackEnd(); ~Dx9BackEnd();
virtual bool supportIntIndices();
virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size); virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size);
virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(std::size_t size); virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(std::size_t size);
virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size); virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size, GLenum type);
virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize); virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize);
virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const; virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const;
...@@ -70,7 +72,7 @@ class Dx9BackEnd : public BufferBackEnd ...@@ -70,7 +72,7 @@ class Dx9BackEnd : public BufferBackEnd
class Dx9IndexBuffer : public TranslatedIndexBuffer class Dx9IndexBuffer : public TranslatedIndexBuffer
{ {
public: public:
Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size); Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size, GLenum type);
virtual ~Dx9IndexBuffer(); virtual ~Dx9IndexBuffer();
IDirect3DIndexBuffer9 *getBuffer() const; IDirect3DIndexBuffer9 *getBuffer() const;
......
...@@ -149,7 +149,6 @@ struct NormalizedDefaultValues ...@@ -149,7 +149,6 @@ struct NormalizedDefaultValues
// static const bool identity: true if this is an identity transform (with no widening) // 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 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 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> > template <class InT, class WidenRule, class Converter, class DefaultValueRule = SimpleDefaultValues<InT> >
struct VertexDataConverter struct VertexDataConverter
...@@ -180,25 +179,6 @@ struct VertexDataConverter ...@@ -180,25 +179,6 @@ struct VertexDataConverter
return convertArray(static_cast<const InputType*>(in), stride, n, static_cast<OutputType*>(out)); return convertArray(static_cast<const InputType*>(in), stride, n, static_cast<OutputType*>(out));
} }
static void convertIndexed(const InputType *in, std::size_t stride, Index minIndex, 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] - minIndex) * stride);
OutputType *eout = pointerAddBytes(out, (indices[i] - minIndex) * 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, Index minIndex, std::size_t n, const Index *indices, void *out)
{
convertIndexed(static_cast<const InputType*>(in), stride, minIndex, n, indices, static_cast<OutputType*>(out));
}
private: private:
// Advance the given pointer by a number of bytes (not pointed-to elements). // Advance the given pointer by a number of bytes (not pointed-to elements).
template <class T> template <class T>
......
...@@ -1439,6 +1439,7 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv ...@@ -1439,6 +1439,7 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
{ {
case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_INT:
break; break;
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
...@@ -2735,6 +2736,8 @@ const GLubyte* __stdcall glGetString(GLenum name) ...@@ -2735,6 +2736,8 @@ const GLubyte* __stdcall glGetString(GLenum name)
try try
{ {
gl::Context *context = gl::getContext();
switch (name) switch (name)
{ {
case GL_VENDOR: case GL_VENDOR:
...@@ -2746,7 +2749,7 @@ const GLubyte* __stdcall glGetString(GLenum name) ...@@ -2746,7 +2749,7 @@ const GLubyte* __stdcall glGetString(GLenum name)
case GL_SHADING_LANGUAGE_VERSION: case GL_SHADING_LANGUAGE_VERSION:
return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")"; return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
case GL_EXTENSIONS: case GL_EXTENSIONS:
return (GLubyte*)""; return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
default: default:
return error(GL_INVALID_ENUM, (GLubyte*)NULL); return error(GL_INVALID_ENUM, (GLubyte*)NULL);
} }
......
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