Implement glDrawArraysInstanced by constructing a 'counting' index buffer since…

Implement glDrawArraysInstanced by constructing a 'counting' index buffer since D3D9 only supports instancing on indexed draw calls. TRAC #19489 Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@972 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent c41a6fe3
...@@ -2964,7 +2964,29 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan ...@@ -2964,7 +2964,29 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
{ {
mDisplay->startScene(); mDisplay->startScene();
mDevice->DrawPrimitive(primitiveType, 0, primitiveCount); if (instances == 0)
{
mDevice->DrawPrimitive(primitiveType, 0, primitiveCount);
}
else
{
StaticIndexBuffer *countingIB = mIndexDataManager->getCountingIndices(count);
if (countingIB)
{
if (mAppliedIBSerial != countingIB->getSerial())
{
mDevice->SetIndices(countingIB->getBuffer());
mAppliedIBSerial = countingIB->getSerial();
}
mDevice->DrawIndexedPrimitive(primitiveType, 0, 0, count, 0, primitiveCount);
}
else
{
ERR("Could not create a counting index buffer for glDrawArraysInstanced.");
return error(GL_OUT_OF_MEMORY);
}
}
if (mode == GL_LINE_LOOP) // Draw the last segment separately if (mode == GL_LINE_LOOP) // Draw the last segment separately
{ {
......
// //
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
...@@ -48,12 +48,15 @@ IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) : ...@@ -48,12 +48,15 @@ IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) :
{ {
ERR("Failed to allocate the streaming index buffer(s)."); ERR("Failed to allocate the streaming index buffer(s).");
} }
mCountingBuffer = NULL;
} }
IndexDataManager::~IndexDataManager() IndexDataManager::~IndexDataManager()
{ {
delete mStreamingBufferShort; delete mStreamingBufferShort;
delete mStreamingBufferInt; delete mStreamingBufferInt;
delete mCountingBuffer;
} }
void convertIndices(GLenum type, const void *input, GLsizei count, void *output) void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
...@@ -228,6 +231,61 @@ std::size_t IndexDataManager::typeSize(GLenum type) const ...@@ -228,6 +231,61 @@ std::size_t IndexDataManager::typeSize(GLenum type) const
} }
} }
StaticIndexBuffer *IndexDataManager::getCountingIndices(GLsizei count)
{
if (count <= 65536) // 16-bit indices
{
const unsigned int spaceNeeded = count * sizeof(unsigned short);
if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
{
delete mCountingBuffer;
mCountingBuffer = new StaticIndexBuffer(mDevice);
mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
UINT offset;
unsigned short *data = static_cast<unsigned short*>(mCountingBuffer->map(spaceNeeded, &offset));
if (data)
{
for(int i = 0; i < count; i++)
{
data[i] = i;
}
mCountingBuffer->unmap();
}
}
}
else if (mStreamingBufferInt) // 32-bit indices supported
{
const unsigned int spaceNeeded = count * sizeof(unsigned int);
if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
{
delete mCountingBuffer;
mCountingBuffer = new StaticIndexBuffer(mDevice);
mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
UINT offset;
unsigned int *data = static_cast<unsigned int*>(mCountingBuffer->map(spaceNeeded, &offset));
if (data)
{
for(int i = 0; i < count; i++)
{
data[i] = i;
}
mCountingBuffer->unmap();
}
}
}
else return NULL;
return mCountingBuffer;
}
IndexBuffer::IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format) : mDevice(device), mBufferSize(size), mIndexBuffer(NULL) IndexBuffer::IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format) : mDevice(device), mBufferSize(size), mIndexBuffer(NULL)
{ {
if (size > 0) if (size > 0)
......
// //
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
...@@ -124,6 +124,7 @@ class IndexDataManager ...@@ -124,6 +124,7 @@ class IndexDataManager
virtual ~IndexDataManager(); virtual ~IndexDataManager();
GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated); GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated);
StaticIndexBuffer *getCountingIndices(GLsizei count);
private: private:
DISALLOW_COPY_AND_ASSIGN(IndexDataManager); DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
...@@ -135,6 +136,7 @@ class IndexDataManager ...@@ -135,6 +136,7 @@ class IndexDataManager
StreamingIndexBuffer *mStreamingBufferShort; StreamingIndexBuffer *mStreamingBufferShort;
StreamingIndexBuffer *mStreamingBufferInt; StreamingIndexBuffer *mStreamingBufferInt;
StaticIndexBuffer *mCountingBuffer;
}; };
} }
......
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