TRAC #11393

Signed-off-by: Nicolas Capens
Signed-off-by: Daniel Koch
Author:    Andrew Lewycky

git-svn-id: https://angleproject.googlecode.com/svn/trunk@72 736b8ea6-26fd-11df-bfd4-992fa37f6226
This commit is contained in:
daniel@transgaming.com 2010-03-26 04:08:45 +00:00
Родитель d989add518
Коммит f8b58a0cb3
11 изменённых файлов: 245 добавлений и 89 удалений

Просмотреть файл

@ -23,6 +23,7 @@
#include "utilities.h"
#include "geometry/backend.h"
#include "geometry/VertexDataManager.h"
#include "geometry/IndexDataManager.h"
#include "geometry/dx9.h"
#undef near
@ -138,6 +139,7 @@ Context::Context(const egl::Config *config)
mBufferBackEnd = NULL;
mVertexDataManager = NULL;
mIndexDataManager = NULL;
mInvalidEnum = false;
mInvalidValue = false;
@ -166,6 +168,7 @@ Context::~Context()
delete mBufferBackEnd;
delete mVertexDataManager;
delete mIndexDataManager;
while (!mBufferMap.empty())
{
@ -206,6 +209,7 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
{
mBufferBackEnd = new Dx9BackEnd(device);
mVertexDataManager = new VertexDataManager(this, mBufferBackEnd);
mIndexDataManager = new IndexDataManager(this, mBufferBackEnd);
}
// Wrap the existing Direct3D 9 resources into GL objects and assign them to the '0' names
@ -1020,50 +1024,26 @@ void Context::applyVertexBuffer(GLint first, GLsizei count)
lookupAttributeMapping(translated);
mBufferBackEnd->preDraw(translated);
mBufferBackEnd->setupAttributesPreDraw(translated);
}
void Context::applyVertexBuffer(GLsizei count, const void *indices, GLenum indexType)
void Context::applyVertexBuffer(const TranslatedIndexData &indexInfo)
{
TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];
mVertexDataManager->preRenderValidate(adjustIndexPointer(indices), count, translated);
mVertexDataManager->preRenderValidate(indexInfo, translated);
lookupAttributeMapping(translated);
mBufferBackEnd->preDraw(translated);
mBufferBackEnd->setupAttributesPreDraw(translated);
}
// Applies the indices and element array bindings to the Direct3D 9 device
void Context::applyIndexBuffer(const void *indices, GLsizei count)
TranslatedIndexData Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type)
{
GLsizei length = count * sizeof(Index);
IDirect3DDevice9 *device = getDevice();
IDirect3DIndexBuffer9 *indexBuffer = NULL;
void *data;
HRESULT result = device->CreateIndexBuffer(length, 0, D3DFMT_INDEX16, D3DPOOL_MANAGED, &indexBuffer, NULL);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
return error(GL_OUT_OF_MEMORY);
}
ASSERT(SUCCEEDED(result));
if (indexBuffer)
{
indexBuffer->Lock(0, length, &data, 0);
memcpy(data, adjustIndexPointer(indices), length);
indexBuffer->Unlock();
device->SetIndices(indexBuffer);
indexBuffer->Release(); // Will only effectively be deleted when no longer in use
}
startIndex = 0;
TranslatedIndexData indexInfo = mIndexDataManager->preRenderValidate(mode, type, count, getBuffer(elementArrayBuffer), indices);
mBufferBackEnd->setupIndicesPreDraw(indexInfo);
return indexInfo;
}
// Applies the shaders and shader constants to the Direct3D 9 device
@ -1480,7 +1460,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
if (!cullSkipsDraw(mode))
{
device->BeginScene();
device->DrawPrimitive(primitiveType, first, primitiveCount);
device->DrawPrimitive(primitiveType, 0, primitiveCount);
device->EndScene();
}
}
@ -1515,15 +1495,15 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void*
}
applyState();
applyVertexBuffer(count, indices, type);
applyIndexBuffer(indices, count);
TranslatedIndexData indexInfo = applyIndexBuffer(indices, count, mode, type);
applyVertexBuffer(indexInfo);
applyShaders();
applyTextures();
if (!cullSkipsDraw(mode))
{
device->BeginScene();
device->DrawIndexedPrimitive(primitiveType, 0, 0, count, startIndex, primitiveCount);
device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, indexInfo.offset/sizeof(Index), primitiveCount);
device->EndScene();
}
}

Просмотреть файл

@ -30,6 +30,7 @@ class Config;
namespace gl
{
struct TranslatedAttribute;
struct TranslatedIndexData;
class Buffer;
class Shader;
@ -43,6 +44,7 @@ class Colorbuffer;
class Depthbuffer;
class Stencilbuffer;
class VertexDataManager;
class IndexDataManager;
class BufferBackEnd;
enum
@ -189,8 +191,6 @@ struct State
AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS];
GLuint samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
unsigned int startIndex;
GLint unpackAlignment;
GLint packAlignment;
};
@ -257,8 +257,8 @@ class Context : public State
bool applyRenderTarget(bool ignoreViewport);
void applyState();
void applyVertexBuffer(GLint first, GLsizei count);
void applyVertexBuffer(GLsizei count, const void *indices, GLenum indexType);
void applyIndexBuffer(const void *indices, GLsizei count);
void applyVertexBuffer(const TranslatedIndexData &indexInfo);
TranslatedIndexData applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type);
void applyShaders();
void applyTextures();
@ -321,6 +321,7 @@ class Context : public State
BufferBackEnd *mBufferBackEnd;
VertexDataManager *mVertexDataManager;
IndexDataManager *mIndexDataManager;
Texture *mIncompleteTextures[SAMPLER_TYPE_COUNT];

Просмотреть файл

@ -0,0 +1,119 @@
//
// 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/IndexDataManager.cpp: Defines the IndexDataManager, a class that
// runs the Buffer translation process for index buffers.
#include "geometry/IndexDataManager.h"
#include "common/debug.h"
#include "Buffer.h"
#include "geometry/backend.h"
namespace
{
enum { INITIAL_INDEX_BUFFER_SIZE = sizeof(gl::Index) * 8192 };
}
namespace gl
{
IndexDataManager::IndexDataManager(Context *context, BufferBackEnd *backend)
: mContext(context), mBackend(backend)
{
mStreamBuffer = mBackend->createIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);
}
IndexDataManager::~IndexDataManager()
{
delete mStreamBuffer;
}
namespace
{
template <class InputIndexType>
void copyIndices(const InputIndexType *in, GLsizei count, Index *out, GLuint *minIndex, GLuint *maxIndex)
{
GLuint minIndexSoFar = *in;
GLuint maxIndexSoFar = *in;
for (GLsizei i = 0; i < count; i++)
{
if (minIndexSoFar > *in) minIndexSoFar = *in;
if (maxIndexSoFar < *in) maxIndexSoFar = *in;
*out++ = *in++;
}
*minIndex = minIndexSoFar;
*maxIndex = maxIndexSoFar;
}
}
TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices)
{
ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_BYTE);
ASSERT(count > 0);
TranslatedIndexData translated;
translated.count = count;
std::size_t requiredSpace = spaceRequired(mode, type, count);
if (requiredSpace > mStreamBuffer->size())
{
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;
void *output = mStreamBuffer->map(requiredSpace, &offset);
translated.buffer = mStreamBuffer;
translated.offset = offset;
translated.indices = static_cast<const Index*>(output);
if (arrayElementBuffer != NULL)
{
indices = static_cast<const GLubyte*>(arrayElementBuffer->data()) + reinterpret_cast<GLsizei>(indices);
}
Index *out = static_cast<Index*>(output);
if (type == GL_UNSIGNED_SHORT)
{
const GLushort *in = static_cast<const GLushort*>(indices);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
}
else
{
const GLubyte *in = static_cast<const GLubyte*>(indices);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
}
mStreamBuffer->unmap();
return translated;
}
std::size_t IndexDataManager::spaceRequired(GLenum mode, GLenum type, GLsizei count)
{
return count * sizeof(Index);
}
}

Просмотреть файл

@ -0,0 +1,60 @@
//
// 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/IndexDataManager.h: Defines the IndexDataManager, a class that
// runs the Buffer translation process for index buffers.
#ifndef LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
#define LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
#include <bitset>
#include <cstddef>
#define GL_APICALL
#include <GLES2/gl2.h>
#include "Context.h"
namespace gl
{
class Buffer;
class BufferBackEnd;
class TranslatedIndexBuffer;
struct FormatConverter;
struct TranslatedIndexData
{
GLuint minIndex;
GLuint maxIndex;
GLuint count;
const Index *indices;
TranslatedIndexBuffer *buffer;
GLsizei offset;
};
class IndexDataManager
{
public:
IndexDataManager(Context *context, BufferBackEnd *backend);
~IndexDataManager();
TranslatedIndexData preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices);
private:
std::size_t spaceRequired(GLenum mode, GLenum type, GLsizei count);
Context *mContext;
BufferBackEnd *mBackend;
TranslatedIndexBuffer *mStreamBuffer;
};
}
#endif // LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_

Просмотреть файл

@ -14,6 +14,7 @@
#include "Buffer.h"
#include "geometry/backend.h"
#include "geometry/IndexDataManager.h"
namespace
{
@ -51,17 +52,17 @@ VertexDataManager::ArrayTranslationHelper::ArrayTranslationHelper(GLint first, G
void VertexDataManager::ArrayTranslationHelper::translate(const FormatConverter &converter, GLsizei stride, const void *source, void *dest)
{
converter.convertArray(source, stride, mFirst+mCount, dest);
converter.convertArray(source, stride, mCount, dest);
}
VertexDataManager::IndexedTranslationHelper::IndexedTranslationHelper(const Index *indices, GLsizei count)
: mIndices(indices), mCount(count)
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, mCount, mIndices, dest);
converter.convertIndexed(source, stride, mMinIndex, mCount, mIndices, dest);
}
std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::activeAttribs()
@ -85,43 +86,16 @@ GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count,
{
ArrayTranslationHelper translationHelper(start, count);
return internalPreRenderValidate(mContext->vertexAttribute, activeAttribs(), start, start+count, &translationHelper, outAttribs);
return internalPreRenderValidate(mContext->vertexAttribute, activeAttribs(), start, start+count-1, &translationHelper, outAttribs);
}
namespace
{
void indexRange(const Index *indices, std::size_t count, Index *minOut, Index *maxOut)
{
ASSERT(count > 0);
Index minSoFar = indices[0];
Index maxSoFar = indices[0];
for (std::size_t i = 1; i < count; i++)
{
if (indices[i] > maxSoFar) maxSoFar = indices[i];
if (indices[i] < minSoFar) minSoFar = indices[i];
}
*minOut = minSoFar;
*maxOut = maxSoFar;
}
}
GLenum VertexDataManager::preRenderValidate(const Index *indices, GLsizei count,
GLenum VertexDataManager::preRenderValidate(const TranslatedIndexData &indexInfo,
TranslatedAttribute *outAttribs)
{
Index minIndex;
Index maxIndex;
IndexedTranslationHelper translationHelper(indexInfo.indices, indexInfo.minIndex, indexInfo.count);
indexRange(indices, count, &minIndex, &maxIndex);
IndexedTranslationHelper translationHelper(indices, count);
return internalPreRenderValidate(mContext->vertexAttribute, activeAttribs(), minIndex, maxIndex, &translationHelper, outAttribs);
return internalPreRenderValidate(mContext->vertexAttribute, activeAttribs(), indexInfo.minIndex, indexInfo.maxIndex, &translationHelper, outAttribs);
}
GLenum VertexDataManager::internalPreRenderValidate(const AttributeState *attribs,
@ -159,8 +133,8 @@ GLenum VertexDataManager::internalPreRenderValidate(const AttributeState *attrib
translated[i].type = attribs[i].mType;
translated[i].size = attribs[i].mSize;
translated[i].normalized = attribs[i].mNormalized;
translated[i].offset = static_cast<std::size_t>(static_cast<const char*>(attribs[i].mPointer) - static_cast<const char*>(NULL));
translated[i].stride = interpretGlStride(attribs[i]);
translated[i].offset = static_cast<std::size_t>(static_cast<const char*>(attribs[i].mPointer) - static_cast<const char*>(NULL)) + translated[i].stride * minIndex;
translated[i].buffer = mContext->getBuffer(attribs[i].mBoundBuffer)->identityBuffer();
}
else
@ -173,7 +147,7 @@ GLenum VertexDataManager::internalPreRenderValidate(const AttributeState *attrib
// Handle any attributes needing translation or lifting.
if (translateOrLift.any())
{
std::size_t count = maxIndex + 1;
std::size_t count = maxIndex - minIndex + 1;
std::size_t requiredSpace = 0;
@ -222,6 +196,10 @@ GLenum VertexDataManager::internalPreRenderValidate(const AttributeState *attrib
input = attribs[i].mPointer;
}
size_t inputStride = interpretGlStride(attribs[i]);
input = static_cast<const char*>(input) + inputStride * minIndex;
translator->translate(formatConverter, interpretGlStride(attribs[i]), input, output);
mStreamBuffer->unmap();

Просмотреть файл

@ -26,6 +26,7 @@ class BufferBackEnd;
class TranslatedVertexBuffer;
struct TranslatedAttribute;
struct FormatConverter;
struct TranslatedIndexData;
class VertexDataManager
{
@ -39,8 +40,7 @@ class VertexDataManager
GLsizei count,
TranslatedAttribute *outAttribs);
GLenum preRenderValidate(const Index *indices,
GLsizei count,
GLenum preRenderValidate(const TranslatedIndexData &indexInfo,
TranslatedAttribute* outAttribs);
private:
@ -69,12 +69,13 @@ class VertexDataManager
class IndexedTranslationHelper : public TranslationHelper
{
public:
IndexedTranslationHelper(const Index *indices, GLsizei count);
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;
};

Просмотреть файл

@ -26,7 +26,7 @@ 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 (*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);
};
@ -57,7 +57,8 @@ class BufferBackEnd
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;
virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo) = 0;
virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes) = 0;
};
class TranslatedBuffer

Просмотреть файл

@ -17,6 +17,7 @@
#include "common/debug.h"
#include "geometry/vertexconversion.h"
#include "geometry/IndexDataManager.h"
namespace
{
@ -179,7 +180,13 @@ IDirect3DIndexBuffer9 *Dx9BackEnd::getDxBuffer(TranslatedIndexBuffer *ib) const
return ib ? static_cast<Dx9IndexBuffer*>(ib)->getBuffer() : NULL;
}
GLenum Dx9BackEnd::preDraw(const TranslatedAttribute *attributes)
GLenum Dx9BackEnd::setupIndicesPreDraw(const TranslatedIndexData &indexInfo)
{
mDevice->SetIndices(getDxBuffer(indexInfo.buffer));
return GL_NO_ERROR;
}
GLenum Dx9BackEnd::setupAttributesPreDraw(const TranslatedAttribute *attributes)
{
HRESULT hr;

Просмотреть файл

@ -27,7 +27,8 @@ class Dx9BackEnd : public BufferBackEnd
virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size);
virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize);
virtual GLenum preDraw(const TranslatedAttribute *attributes);
virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo);
virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes);
private:
IDirect3DDevice9 *mDevice;

Просмотреть файл

@ -180,12 +180,12 @@ struct VertexDataConverter
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)
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] * stride);
OutputType *eout = pointerAddBytes(out, indices[i] * finalSize);
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()));
@ -194,9 +194,9 @@ struct VertexDataConverter
}
}
static void convertIndexed(const void *in, std::size_t stride, std::size_t n, const Index *indices, void *out)
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, n, indices, static_cast<OutputType*>(out));
convertIndexed(static_cast<const InputType*>(in), stride, minIndex, n, indices, static_cast<OutputType*>(out));
}
private:

Просмотреть файл

@ -237,6 +237,10 @@
RelativePath=".\geometry\dx9.cpp"
>
</File>
<File
RelativePath=".\geometry\IndexDataManager.cpp"
>
</File>
<File
RelativePath=".\geometry\VertexDataManager.cpp"
>
@ -315,6 +319,10 @@
RelativePath=".\geometry\dx9.h"
>
</File>
<File
RelativePath=".\geometry\IndexDataManager.h"
>
</File>
<File
RelativePath=".\geometry\vertexconversion.h"
>