Integrated new IndexBuffer into IndexDataManager and Renderer9.
TRAC #22237
Author: Geoff Lang
Signed-off-by: Shannon Woods
Signed-off-by: Nicolas Capens
Signed-off-by: Daniel Koch
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1607 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Buffer.cpp b/src/libGLESv2/Buffer.cpp
index bc1f24e..7573e50 100644
--- a/src/libGLESv2/Buffer.cpp
+++ b/src/libGLESv2/Buffer.cpp
@@ -70,7 +70,7 @@
{
memcpy(mContents + offset, data, size);
- if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->size() != 0))
+ if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0))
{
invalidateStaticData();
}
diff --git a/src/libGLESv2/renderer/IndexBuffer.cpp b/src/libGLESv2/renderer/IndexBuffer.cpp
index 37e8c3b..ba076f8 100644
--- a/src/libGLESv2/renderer/IndexBuffer.cpp
+++ b/src/libGLESv2/renderer/IndexBuffer.cpp
@@ -9,8 +9,6 @@
#include "libGLESv2/renderer/IndexBuffer.h"
-#include "libGLESv2/renderer/Renderer9.h"
-
namespace rx
{
@@ -36,172 +34,143 @@
}
-unsigned int IndexBufferInterface::mCurrentSerial = 1;
-
-IndexBufferInterface::IndexBufferInterface(rx::Renderer9 *renderer, UINT size, D3DFORMAT format) : mRenderer(renderer), mBufferSize(size), mIndexBuffer(NULL)
+IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer)
{
- if (size > 0)
- {
- // D3D9_REPLACE
- HRESULT result = mRenderer->createIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, &mIndexBuffer);
- mSerial = issueSerial();
+ mIndexBuffer = renderer->createIndexBuffer();
- if (FAILED(result))
- {
- ERR("Out of memory allocating an index buffer of size %lu.", size);
- }
- }
+ mDynamic = dynamic;
+ mWritePosition = 0;
}
IndexBufferInterface::~IndexBufferInterface()
{
if (mIndexBuffer)
{
- mIndexBuffer->Release();
+ delete mIndexBuffer;
}
}
-IDirect3DIndexBuffer9 *IndexBufferInterface::getBuffer() const
+GLenum IndexBufferInterface::getIndexType() const
{
- return mIndexBuffer;
+ return mIndexBuffer->getIndexType();
+}
+
+unsigned int IndexBufferInterface::getBufferSize() const
+{
+ return mIndexBuffer->getBufferSize();
}
unsigned int IndexBufferInterface::getSerial() const
{
- return mSerial;
+ return mIndexBuffer->getSerial();
}
-unsigned int IndexBufferInterface::issueSerial()
+int IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory)
{
- return mCurrentSerial++;
-}
-
-void IndexBufferInterface::unmap()
-{
- if (mIndexBuffer)
+ if (!mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory))
{
- mIndexBuffer->Unlock();
+ *outMappedMemory = NULL;
+ return -1;
+ }
+
+ int oldWritePos = static_cast<int>(mWritePosition);
+ mWritePosition += size;
+
+ return oldWritePos;
+}
+
+bool IndexBufferInterface::unmapBuffer()
+{
+ return mIndexBuffer->unmapBuffer();
+}
+
+IndexBuffer * IndexBufferInterface::getIndexBuffer() const
+{
+ return mIndexBuffer;
+}
+
+unsigned int IndexBufferInterface::getWritePosition() const
+{
+ return mWritePosition;
+}
+
+void IndexBufferInterface::setWritePosition(unsigned int writePosition)
+{
+ mWritePosition = writePosition;
+}
+
+bool IndexBufferInterface::discard()
+{
+ return mIndexBuffer->discard();
+}
+
+bool IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType)
+{
+ if (mIndexBuffer->getBufferSize() == 0)
+ {
+ return mIndexBuffer->initialize(bufferSize, indexType, mDynamic);
+ }
+ else
+ {
+ return mIndexBuffer->setSize(bufferSize, indexType);
}
}
-StreamingIndexBufferInterface::StreamingIndexBufferInterface(rx::Renderer9 *renderer, UINT initialSize, D3DFORMAT format) : IndexBufferInterface(renderer, initialSize, format)
+StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true)
{
- mWritePosition = 0;
}
StreamingIndexBufferInterface::~StreamingIndexBufferInterface()
{
}
-void *StreamingIndexBufferInterface::map(UINT requiredSpace, UINT *offset)
+bool StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
{
- void *mapPtr = NULL;
-
- if (mIndexBuffer)
+ bool result = true;
+ unsigned int curBufferSize = getBufferSize();
+ if (size > curBufferSize)
{
- HRESULT result = mIndexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
-
- if (FAILED(result))
+ result = setBufferSize(std::max(size, 2 * curBufferSize), indexType);
+ setWritePosition(0);
+ }
+ else if (getWritePosition() + size > curBufferSize)
+ {
+ if (!discard())
{
- ERR(" Lock failed with error 0x%08x", result);
- return NULL;
+ return false;
}
-
- *offset = mWritePosition;
- mWritePosition += requiredSpace;
+ setWritePosition(0);
}
- return mapPtr;
+ return result;
}
-void StreamingIndexBufferInterface::reserveSpace(UINT requiredSpace, GLenum type)
+
+StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false)
{
- if (requiredSpace > mBufferSize)
- {
- if (mIndexBuffer)
- {
- mIndexBuffer->Release();
- mIndexBuffer = NULL;
- }
-
- mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
-
- // D3D9_REPLACE
- HRESULT result = mRenderer->createIndexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, &mIndexBuffer);
- mSerial = issueSerial();
-
- if (FAILED(result))
- {
- ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
- }
-
- mWritePosition = 0;
- }
- else if (mWritePosition + requiredSpace > mBufferSize) // Recycle
- {
- void *dummy;
- mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
- mIndexBuffer->Unlock();
-
- mWritePosition = 0;
- }
-}
-
-StaticIndexBufferInterface::StaticIndexBufferInterface(rx::Renderer9 *renderer) : IndexBufferInterface(renderer, 0, D3DFMT_UNKNOWN)
-{
- mCacheType = GL_NONE;
}
StaticIndexBufferInterface::~StaticIndexBufferInterface()
{
}
-void *StaticIndexBufferInterface::map(UINT requiredSpace, UINT *offset)
+bool StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
{
- void *mapPtr = NULL;
-
- if (mIndexBuffer)
+ unsigned int curSize = getBufferSize();
+ if (curSize == 0)
{
- HRESULT result = mIndexBuffer->Lock(0, requiredSpace, &mapPtr, 0);
-
- if (FAILED(result))
- {
- ERR(" Lock failed with error 0x%08x", result);
- return NULL;
- }
-
- *offset = 0;
+ return setBufferSize(size, indexType);
}
-
- return mapPtr;
-}
-
-void StaticIndexBufferInterface::reserveSpace(UINT requiredSpace, GLenum type)
-{
- if (!mIndexBuffer && mBufferSize == 0)
+ else if (curSize >= size && indexType == getIndexType())
{
- // D3D9_REPLACE
- HRESULT result = mRenderer->createIndexBuffer(requiredSpace, D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, &mIndexBuffer);
- mSerial = issueSerial();
-
- if (FAILED(result))
- {
- ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
- }
-
- mBufferSize = requiredSpace;
- mCacheType = type;
+ return true;
}
- else if (mIndexBuffer && mBufferSize >= requiredSpace && mCacheType == type)
+ else
{
- // Already allocated
+ ERR("Static index buffers can't be resized");
+ UNREACHABLE();
+ return false;
}
- else UNREACHABLE(); // Static index buffers can't be resized
-}
-
-bool StaticIndexBufferInterface::lookupType(GLenum type)
-{
- return mCacheType == type;
}
UINT StaticIndexBufferInterface::lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex)
diff --git a/src/libGLESv2/renderer/IndexBuffer.h b/src/libGLESv2/renderer/IndexBuffer.h
index 04a189b..c7bc3b6 100644
--- a/src/libGLESv2/renderer/IndexBuffer.h
+++ b/src/libGLESv2/renderer/IndexBuffer.h
@@ -10,9 +10,6 @@
#ifndef LIBGLESV2_RENDERER_INDEXBUFFER_H_
#define LIBGLESV2_RENDERER_INDEXBUFFER_H_
-#include <vector>
-#include <cstddef>
-
#define GL_APICALL
#include <GLES2/gl2.h>
@@ -22,8 +19,6 @@
namespace rx
{
-class Renderer9;
-
class IndexBuffer
{
public:
@@ -56,60 +51,61 @@
class IndexBufferInterface
{
public:
- IndexBufferInterface(rx::Renderer9 *renderer, UINT size, D3DFORMAT format);
+ IndexBufferInterface(Renderer *renderer, bool dynamic);
virtual ~IndexBufferInterface();
- UINT size() const { return mBufferSize; }
- virtual void *map(UINT requiredSpace, UINT *offset) = 0;
- void unmap();
- virtual void reserveSpace(UINT requiredSpace, GLenum type) = 0;
+ virtual bool reserveBufferSpace(unsigned int size, GLenum indexType) = 0;
- IDirect3DIndexBuffer9 *getBuffer() const;
+ GLenum getIndexType() const;
+ unsigned int getBufferSize() const;
+
unsigned int getSerial() const;
+ int mapBuffer(unsigned int size, void** outMappedMemory);
+ bool unmapBuffer();
+
+ IndexBuffer *getIndexBuffer() const;
+
protected:
- rx::Renderer9 *const mRenderer; // D3D9_REPLACE
+ unsigned int getWritePosition() const;
+ void setWritePosition(unsigned int writePosition);
- IDirect3DIndexBuffer9 *mIndexBuffer;
- UINT mBufferSize;
+ bool discard();
- unsigned int mSerial;
- static unsigned int issueSerial();
- static unsigned int mCurrentSerial;
+ bool setBufferSize(unsigned int bufferSize, GLenum indexType);
private:
DISALLOW_COPY_AND_ASSIGN(IndexBufferInterface);
+
+ rx::Renderer *const mRenderer;
+
+ IndexBuffer* mIndexBuffer;
+
+ unsigned int mWritePosition;
+ bool mDynamic;
};
class StreamingIndexBufferInterface : public IndexBufferInterface
{
public:
- StreamingIndexBufferInterface(rx::Renderer9 *renderer, UINT initialSize, D3DFORMAT format);
+ StreamingIndexBufferInterface(Renderer *renderer);
~StreamingIndexBufferInterface();
- virtual void *map(UINT requiredSpace, UINT *offset);
- virtual void reserveSpace(UINT requiredSpace, GLenum type);
-
- private:
- UINT mWritePosition;
+ virtual bool reserveBufferSpace(unsigned int size, GLenum indexType);
};
class StaticIndexBufferInterface : public IndexBufferInterface
{
public:
- explicit StaticIndexBufferInterface(rx::Renderer9 *renderer);
+ explicit StaticIndexBufferInterface(Renderer *renderer);
~StaticIndexBufferInterface();
- virtual void *map(UINT requiredSpace, UINT *offset);
- virtual void reserveSpace(UINT requiredSpace, GLenum type);
+ virtual bool reserveBufferSpace(unsigned int size, GLenum indexType);
- bool lookupType(GLenum type);
UINT lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex); // Returns the offset into the index buffer, or -1 if not found
void addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset);
private:
- GLenum mCacheType;
-
struct IndexRange
{
intptr_t offset;
diff --git a/src/libGLESv2/renderer/IndexDataManager.cpp b/src/libGLESv2/renderer/IndexDataManager.cpp
index 4a02919..8c4e7e6 100644
--- a/src/libGLESv2/renderer/IndexDataManager.cpp
+++ b/src/libGLESv2/renderer/IndexDataManager.cpp
@@ -18,28 +18,28 @@
namespace rx
{
-IndexDataManager::IndexDataManager(rx::Renderer9 *renderer) : mRenderer(renderer)
+IndexDataManager::IndexDataManager(Renderer *renderer) : mRenderer(renderer)
{
- mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
-
- if (renderer->get32BitIndexSupport())
+ mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
+ if (!mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
{
- mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
-
- if (!mStreamingBufferInt)
- {
- // Don't leave it in a half-initialized state
- delete mStreamingBufferShort;
- mStreamingBufferShort = NULL;
- }
+ delete mStreamingBufferShort;
+ mStreamingBufferShort = NULL;
}
- else
+
+ mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
+ if (!mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
{
+ delete mStreamingBufferInt;
mStreamingBufferInt = NULL;
}
if (!mStreamingBufferShort)
{
+ // Make sure both buffers are deleted.
+ delete mStreamingBufferInt;
+ mStreamingBufferInt = NULL;
+
ERR("Failed to allocate the streaming index buffer(s).");
}
@@ -53,7 +53,18 @@
delete mCountingBuffer;
}
-void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
+static unsigned int indexTypeSize(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_INT: return sizeof(GLuint);
+ case GL_UNSIGNED_SHORT: return sizeof(GLushort);
+ case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
+ default: UNREACHABLE(); return sizeof(GLushort);
+ }
+}
+
+static void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
{
if (type == GL_UNSIGNED_BYTE)
{
@@ -77,7 +88,7 @@
}
template <class IndexType>
-void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+static void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
{
*minIndex = indices[0];
*maxIndex = indices[0];
@@ -89,7 +100,7 @@
}
}
-void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+static void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
{
if (type == GL_UNSIGNED_BYTE)
{
@@ -106,14 +117,14 @@
else UNREACHABLE();
}
-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated, IDirect3DIndexBuffer9 **d3dIndexBuffer, unsigned int *serial)
+GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
{
if (!mStreamingBufferShort)
{
return GL_OUT_OF_MEMORY;
}
- D3DFORMAT format = (type == GL_UNSIGNED_INT) ? D3DFMT_INDEX32 : D3DFMT_INDEX16;
+ GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
intptr_t offset = reinterpret_cast<intptr_t>(indices);
bool alignedOffset = false;
@@ -127,7 +138,7 @@
default: UNREACHABLE(); alignedOffset = false;
}
- if (typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
+ if (indexTypeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
{
return GL_INVALID_OPERATION;
}
@@ -141,14 +152,14 @@
IndexBufferInterface *indexBuffer = streamingBuffer;
UINT streamOffset = 0;
- if (staticBuffer && staticBuffer->lookupType(type) && alignedOffset)
+ if (staticBuffer && staticBuffer->getIndexType() == type && alignedOffset)
{
indexBuffer = staticBuffer;
streamOffset = staticBuffer->lookupRange(offset, count, &translated->minIndex, &translated->maxIndex);
if (streamOffset == -1)
{
- streamOffset = (offset / typeSize(type)) * indexSize(format);
+ streamOffset = (offset / indexTypeSize(type)) * indexTypeSize(destinationIndexType);
computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
}
@@ -159,10 +170,10 @@
if (staticBuffer)
{
- if (staticBuffer->size() == 0 && alignedOffset)
+ if (staticBuffer->getBufferSize() == 0 && alignedOffset)
{
indexBuffer = staticBuffer;
- convertCount = buffer->size() / typeSize(type);
+ convertCount = buffer->size() / indexTypeSize(type);
}
else
{
@@ -171,83 +182,81 @@
}
}
- void *output = NULL;
-
- if (indexBuffer)
+ if (!indexBuffer)
{
- indexBuffer->reserveSpace(convertCount * indexSize(format), type);
- output = indexBuffer->map(indexSize(format) * convertCount, &streamOffset);
+ ERR("No valid index buffer.");
+ return GL_INVALID_OPERATION;
}
- if (output == NULL)
+ unsigned int bufferSizeRequired = convertCount * indexTypeSize(destinationIndexType);
+ indexBuffer->reserveBufferSpace(bufferSizeRequired, type);
+
+ void* output = NULL;
+ streamOffset = indexBuffer->mapBuffer(bufferSizeRequired, &output);
+ if (streamOffset == -1 || output == NULL)
{
ERR("Failed to map index buffer.");
return GL_OUT_OF_MEMORY;
}
convertIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
- indexBuffer->unmap();
+
+ if (!indexBuffer->unmapBuffer())
+ {
+ ERR("Failed to unmap index buffer.");
+ return GL_OUT_OF_MEMORY;
+ }
computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
if (staticBuffer)
{
- streamOffset = (offset / typeSize(type)) * indexSize(format);
+ streamOffset = (offset / indexTypeSize(type)) * indexTypeSize(destinationIndexType);
staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
}
}
- *d3dIndexBuffer = indexBuffer->getBuffer();
- *serial = indexBuffer->getSerial();
- translated->startIndex = streamOffset / indexSize(format);
+ translated->indexBuffer = indexBuffer->getIndexBuffer();
+ translated->serial = indexBuffer->getSerial();
+ translated->startIndex = streamOffset / indexTypeSize(destinationIndexType);
if (buffer)
{
- buffer->promoteStaticUsage(count * typeSize(type));
+ buffer->promoteStaticUsage(count * indexTypeSize(type));
}
return GL_NO_ERROR;
}
-std::size_t IndexDataManager::indexSize(D3DFORMAT format) const
-{
- return (format == D3DFMT_INDEX32) ? sizeof(unsigned int) : sizeof(unsigned short);
-}
-
-std::size_t IndexDataManager::typeSize(GLenum type) const
-{
- switch (type)
- {
- case GL_UNSIGNED_INT: return sizeof(GLuint);
- case GL_UNSIGNED_SHORT: return sizeof(GLushort);
- case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
- default: UNREACHABLE(); return sizeof(GLushort);
- }
-}
-
StaticIndexBufferInterface *IndexDataManager::getCountingIndices(GLsizei count)
{
if (count <= 65536) // 16-bit indices
{
const unsigned int spaceNeeded = count * sizeof(unsigned short);
- if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
+ if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
{
delete mCountingBuffer;
mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
- mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
+ mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT);
- UINT offset;
- unsigned short *data = static_cast<unsigned short*>(mCountingBuffer->map(spaceNeeded, &offset));
-
- if (data)
+ void* mappedMemory = NULL;
+ if (mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory) == -1 || mappedMemory == NULL)
{
- for(int i = 0; i < count; i++)
- {
- data[i] = i;
- }
+ ERR("Failed to map counting buffer.");
+ return NULL;
+ }
- mCountingBuffer->unmap();
+ unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory);
+ for(int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+
+ if (!mCountingBuffer->unmapBuffer())
+ {
+ ERR("Failed to unmap counting buffer.");
+ return NULL;
}
}
}
@@ -255,27 +264,36 @@
{
const unsigned int spaceNeeded = count * sizeof(unsigned int);
- if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
+ if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
{
delete mCountingBuffer;
mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
- mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
+ mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
- UINT offset;
- unsigned int *data = static_cast<unsigned int*>(mCountingBuffer->map(spaceNeeded, &offset));
-
- if (data)
+ void* mappedMemory = NULL;
+ if (mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory) == -1 || mappedMemory == NULL)
{
- for(int i = 0; i < count; i++)
- {
- data[i] = i;
- }
+ ERR("Failed to map counting buffer.");
+ return NULL;
+ }
- mCountingBuffer->unmap();
+ unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+ for(int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+
+ if (!mCountingBuffer->unmapBuffer())
+ {
+ ERR("Failed to unmap counting buffer.");
+ return NULL;
}
}
}
- else return NULL;
+ else
+ {
+ return NULL;
+ }
return mCountingBuffer;
}
diff --git a/src/libGLESv2/renderer/IndexDataManager.h b/src/libGLESv2/renderer/IndexDataManager.h
index 3eb6558..a542f62 100644
--- a/src/libGLESv2/renderer/IndexDataManager.h
+++ b/src/libGLESv2/renderer/IndexDataManager.h
@@ -32,24 +32,24 @@
UINT minIndex;
UINT maxIndex;
UINT startIndex;
+
+ IndexBuffer *indexBuffer;
+ unsigned int serial;
};
class IndexDataManager
{
public:
- IndexDataManager(rx::Renderer9 *renderer);
+ explicit IndexDataManager(Renderer *renderer);
virtual ~IndexDataManager();
- GLenum prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated, IDirect3DIndexBuffer9 **indexBuffer, unsigned int *serial);
+ GLenum prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated);
StaticIndexBufferInterface *getCountingIndices(GLsizei count);
private:
DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
- std::size_t typeSize(GLenum type) const;
- std::size_t indexSize(D3DFORMAT format) const;
-
- rx::Renderer9 *const mRenderer; // D3D9_REPLACE
+ Renderer *const mRenderer;
StreamingIndexBufferInterface *mStreamingBufferShort;
StreamingIndexBufferInterface *mStreamingBufferInt;
diff --git a/src/libGLESv2/renderer/Renderer9.cpp b/src/libGLESv2/renderer/Renderer9.cpp
index 781276f..b974965 100644
--- a/src/libGLESv2/renderer/Renderer9.cpp
+++ b/src/libGLESv2/renderer/Renderer9.cpp
@@ -1200,16 +1200,16 @@
// Applies the indices and element array bindings to the Direct3D 9 device
GLenum Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
{
- IDirect3DIndexBuffer9 *indexBuffer;
- unsigned int serial;
- GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo, &indexBuffer, &serial);
+ GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
if (err == GL_NO_ERROR)
{
- if (serial != mAppliedIBSerial)
+ if (indexInfo->serial != mAppliedIBSerial)
{
- mDevice->SetIndices(indexBuffer);
- mAppliedIBSerial = serial;
+ IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer);
+
+ mDevice->SetIndices(indexBuffer->getBuffer());
+ mAppliedIBSerial = indexInfo->serial;
}
}
@@ -1231,7 +1231,9 @@
{
if (mAppliedIBSerial != countingIB->getSerial())
{
- mDevice->SetIndices(countingIB->getBuffer());
+ IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer());
+
+ mDevice->SetIndices(indexBuffer->getBuffer());
mAppliedIBSerial = countingIB->getSerial();
}
@@ -1281,138 +1283,161 @@
}
UINT startIndex = 0;
- bool succeeded = false;
if (get32BitIndexSupport())
{
+ if (!mLineLoopIB)
+ {
+ mLineLoopIB = new StreamingIndexBufferInterface(this);
+ if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+ {
+ delete mLineLoopIB;
+ mLineLoopIB = NULL;
+
+ ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP.");
+ return error(GL_OUT_OF_MEMORY);
+ }
+ }
+
const int spaceNeeded = (count + 1) * sizeof(unsigned int);
-
- if (!mLineLoopIB)
+ if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
{
- mLineLoopIB = new StreamingIndexBufferInterface(this, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
+ ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
+ return error(GL_OUT_OF_MEMORY);
}
- if (mLineLoopIB)
+ void* mappedMemory = NULL;
+ int offset = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory);
+ if (offset == -1 || mappedMemory == NULL)
{
- mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
+ ERR("Could not map index buffer for GL_LINE_LOOP.");
+ return error(GL_OUT_OF_MEMORY);
+ }
- UINT offset = 0;
- unsigned int *data = static_cast<unsigned int*>(mLineLoopIB->map(spaceNeeded, &offset));
- startIndex = offset / 4;
-
- if (data)
+ startIndex = static_cast<UINT>(offset) / 4;
+ unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (int i = 0; i < count; i++)
{
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (int i = 0; i < count; i++)
- {
- data[i] = i;
- }
- data[count] = 0;
- break;
- case GL_UNSIGNED_BYTE:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLubyte*>(indices)[i];
- }
- data[count] = static_cast<const GLubyte*>(indices)[0];
- break;
- case GL_UNSIGNED_SHORT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLushort*>(indices)[i];
- }
- data[count] = static_cast<const GLushort*>(indices)[0];
- break;
- case GL_UNSIGNED_INT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLuint*>(indices)[i];
- }
- data[count] = static_cast<const GLuint*>(indices)[0];
- break;
- default: UNREACHABLE();
- }
-
- mLineLoopIB->unmap();
- succeeded = true;
+ data[i] = i;
}
+ data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLubyte*>(indices)[i];
+ }
+ data[count] = static_cast<const GLubyte*>(indices)[0];
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLushort*>(indices)[i];
+ }
+ data[count] = static_cast<const GLushort*>(indices)[0];
+ break;
+ case GL_UNSIGNED_INT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLuint*>(indices)[i];
+ }
+ data[count] = static_cast<const GLuint*>(indices)[0];
+ break;
+ default: UNREACHABLE();
+ }
+
+ if (!mLineLoopIB->unmapBuffer())
+ {
+ ERR("Could not unmap index buffer for GL_LINE_LOOP.");
+ return error(GL_OUT_OF_MEMORY);
}
}
else
{
+ if (!mLineLoopIB)
+ {
+ mLineLoopIB = new StreamingIndexBufferInterface(this);
+ if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
+ {
+ delete mLineLoopIB;
+ mLineLoopIB = NULL;
+
+ ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP.");
+ return error(GL_OUT_OF_MEMORY);
+ }
+ }
+
const int spaceNeeded = (count + 1) * sizeof(unsigned short);
-
- if (!mLineLoopIB)
+ if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT))
{
- mLineLoopIB = new StreamingIndexBufferInterface(this, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
+ ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
+ return error(GL_OUT_OF_MEMORY);
}
- if (mLineLoopIB)
+ void* mappedMemory = NULL;
+ int offset = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory);
+ if (offset == -1 || mappedMemory == NULL)
{
- mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
+ ERR("Could not map index buffer for GL_LINE_LOOP.");
+ return error(GL_OUT_OF_MEMORY);
+ }
- UINT offset = 0;
- unsigned short *data = static_cast<unsigned short*>(mLineLoopIB->map(spaceNeeded, &offset));
- startIndex = offset / 2;
-
- if (data)
+ startIndex = static_cast<UINT>(offset) / 2;
+ unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory);
+
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (int i = 0; i < count; i++)
{
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (int i = 0; i < count; i++)
- {
- data[i] = i;
- }
- data[count] = 0;
- break;
- case GL_UNSIGNED_BYTE:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLubyte*>(indices)[i];
- }
- data[count] = static_cast<const GLubyte*>(indices)[0];
- break;
- case GL_UNSIGNED_SHORT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLushort*>(indices)[i];
- }
- data[count] = static_cast<const GLushort*>(indices)[0];
- break;
- case GL_UNSIGNED_INT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLuint*>(indices)[i];
- }
- data[count] = static_cast<const GLuint*>(indices)[0];
- break;
- default: UNREACHABLE();
- }
-
- mLineLoopIB->unmap();
- succeeded = true;
+ data[i] = i;
}
- }
- }
-
- if (succeeded)
- {
- if (mAppliedIBSerial != mLineLoopIB->getSerial())
- {
- mDevice->SetIndices(mLineLoopIB->getBuffer());
- mAppliedIBSerial = mLineLoopIB->getSerial();
+ data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLubyte*>(indices)[i];
+ }
+ data[count] = static_cast<const GLubyte*>(indices)[0];
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLushort*>(indices)[i];
+ }
+ data[count] = static_cast<const GLushort*>(indices)[0];
+ break;
+ case GL_UNSIGNED_INT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLuint*>(indices)[i];
+ }
+ data[count] = static_cast<const GLuint*>(indices)[0];
+ break;
+ default: UNREACHABLE();
}
- mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count);
+ if (!mLineLoopIB->unmapBuffer())
+ {
+ ERR("Could not unmap index buffer for GL_LINE_LOOP.");
+ return error(GL_OUT_OF_MEMORY);
+ }
}
- else
+
+ if (mAppliedIBSerial != mLineLoopIB->getSerial())
{
- ERR("Could not create a looping index buffer for GL_LINE_LOOP.");
- return error(GL_OUT_OF_MEMORY);
+ IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(mLineLoopIB->getIndexBuffer());
+
+ mDevice->SetIndices(indexBuffer->getBuffer());
+ mAppliedIBSerial = mLineLoopIB->getSerial();
}
+
+ mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count);
}
void Renderer9::applyShaders(gl::ProgramBinary *programBinary)