rewrite buffers implementation to support static buffers more efficiently

Bug=89 Trac #13565 Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@526 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent d2fed1c7
......@@ -144,10 +144,6 @@
'common/angleutils.h',
'common/debug.cpp',
'common/debug.h',
'libGLESv2/geometry/backend.cpp',
'libGLESv2/geometry/backend.h',
'libGLESv2/geometry/dx9.cpp',
'libGLESv2/geometry/dx9.h',
'libGLESv2/geometry/IndexDataManager.cpp',
'libGLESv2/geometry/IndexDataManager.h',
'libGLESv2/geometry/vertexconversion.h',
......
......@@ -187,4 +187,3 @@ void TCompiler::collectAttribsUniforms(TIntermNode* root)
CollectAttribsUniforms collect(attribs, uniforms);
root->traverse(&collect);
}
......@@ -252,4 +252,3 @@ void ShGetActiveUniform(const ShHandle handle,
getVariableInfo(SH_ACTIVE_UNIFORMS,
handle, index, length, size, type, name);
}
......@@ -213,8 +213,6 @@ void Surface::writeRecordableFlipState(IDirect3DDevice9 *device)
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
device->SetStreamSourceFreq(0, 1); // DrawPrimitiveUP only cares about stream 0, not the rest.
RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
device->SetScissorRect(&scissorRect);
D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
......
......@@ -466,11 +466,6 @@ void Blit::setCommonBlitState()
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
for (int i = 0; i < MAX_VERTEX_ATTRIBS+1; i++)
{
device->SetStreamSourceFreq(i, 1);
}
RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
device->SetScissorRect(&scissorRect);
}
......
......@@ -10,6 +10,10 @@
#include "libGLESv2/Buffer.h"
#include "libGLESv2/main.h"
#include "libGLESv2/geometry/VertexDataManager.h"
#include "libGLESv2/geometry/IndexDataManager.h"
namespace gl
{
......@@ -18,11 +22,16 @@ Buffer::Buffer(GLuint id) : RefCountObject(id)
mContents = NULL;
mSize = 0;
mUsage = GL_DYNAMIC_DRAW;
mVertexBuffer = NULL;
mIndexBuffer = NULL;
}
Buffer::~Buffer()
{
delete[] mContents;
delete mVertexBuffer;
delete mIndexBuffer;
}
void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
......@@ -46,11 +55,49 @@ void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
mSize = size;
mUsage = usage;
invalidateStaticData();
if (usage == GL_STATIC_DRAW)
{
mVertexBuffer = new StaticVertexBuffer(getDevice());
mIndexBuffer = new StaticIndexBuffer(getDevice());
}
}
void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
{
memcpy(mContents + offset, data, size);
if ((mVertexBuffer && mVertexBuffer->size() != 0) || (mIndexBuffer && mIndexBuffer->size() != 0))
{
invalidateStaticData();
if (mUsage == GL_STATIC_DRAW)
{
mVertexBuffer = new StaticVertexBuffer(getDevice());
mIndexBuffer = new StaticIndexBuffer(getDevice());
}
}
}
StaticVertexBuffer *Buffer::getVertexBuffer()
{
return mVertexBuffer;
}
StaticIndexBuffer *Buffer::getIndexBuffer()
{
return mIndexBuffer;
}
void Buffer::invalidateStaticData()
{
delete mVertexBuffer;
mVertexBuffer = NULL;
delete mIndexBuffer;
mIndexBuffer = NULL;
}
}
......@@ -22,6 +22,8 @@
namespace gl
{
class StaticVertexBuffer;
class StaticIndexBuffer;
class Buffer : public RefCountObject
{
......@@ -37,12 +39,19 @@ class Buffer : public RefCountObject
size_t size() const { return mSize; }
GLenum usage() const { return mUsage; }
StaticVertexBuffer *getVertexBuffer();
StaticIndexBuffer *getIndexBuffer();
void invalidateStaticData();
private:
DISALLOW_COPY_AND_ASSIGN(Buffer);
GLubyte *mContents;
size_t mSize;
GLenum mUsage;
StaticVertexBuffer *mVertexBuffer;
StaticIndexBuffer *mIndexBuffer;
};
}
......
......@@ -25,10 +25,8 @@
#include "libGLESv2/RenderBuffer.h"
#include "libGLESv2/Shader.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/geometry/backend.h"
#include "libGLESv2/geometry/VertexDataManager.h"
#include "libGLESv2/geometry/IndexDataManager.h"
#include "libGLESv2/geometry/dx9.h"
#undef near
#undef far
......@@ -139,7 +137,6 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext)
mState.packAlignment = 4;
mState.unpackAlignment = 4;
mBufferBackEnd = NULL;
mVertexDataManager = NULL;
mIndexDataManager = NULL;
mBlit = NULL;
......@@ -212,7 +209,6 @@ Context::~Context()
mTexture2DZero.set(NULL);
mTextureCubeMapZero.set(NULL);
delete mBufferBackEnd;
delete mVertexDataManager;
delete mIndexDataManager;
delete mBlit;
......@@ -233,9 +229,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
{
mDeviceCaps = display->getDeviceCaps();
mBufferBackEnd = new Dx9BackEnd(this, device);
mVertexDataManager = new VertexDataManager(this, mBufferBackEnd);
mIndexDataManager = new IndexDataManager(this, mBufferBackEnd);
mVertexDataManager = new VertexDataManager(this, device);
mIndexDataManager = new IndexDataManager(this, device);
mBlit = new Blit(this);
mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
......@@ -281,6 +276,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mSupportsLuminanceTextures = display->getLuminanceTextureSupport();
mSupportsLuminanceAlphaTextures = display->getLuminanceAlphaTextureSupport();
mSupports32bitIndices = mDeviceCaps.MaxVertexIndex >= (1 << 16);
initExtensionString();
mState.viewportX = 0;
......@@ -339,11 +336,6 @@ void Context::markAllStateDirty()
mSampleStateDirty = true;
mDitherStateDirty = true;
mFrontFaceDirty = true;
if (mBufferBackEnd != NULL)
{
mBufferBackEnd->invalidate();
}
}
void Context::setClearColor(float red, float green, float blue, float alpha)
......@@ -743,12 +735,12 @@ GLuint Context::getArrayBufferHandle() const
return mState.arrayBuffer.id();
}
void Context::setVertexAttribEnabled(unsigned int attribNum, bool enabled)
void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
{
mState.vertexAttribute[attribNum].mEnabled = enabled;
mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
}
const AttributeState &Context::getVertexAttribState(unsigned int attribNum)
const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
{
return mState.vertexAttribute[attribNum];
}
......@@ -769,8 +761,7 @@ const void *Context::getVertexAttribPointer(unsigned int attribNum) const
return mState.vertexAttribute[attribNum].mPointer;
}
// returns entire set of attributes as a block
const AttributeState *Context::getVertexAttribBlock()
const VertexAttributeArray &Context::getVertexAttributes()
{
return mState.vertexAttribute;
}
......@@ -1963,18 +1954,18 @@ void Context::lookupAttributeMapping(TranslatedAttribute *attributes)
{
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
if (attributes[i].enabled)
if (attributes[i].active)
{
attributes[i].semanticIndex = getCurrentProgram()->getSemanticIndex(i);
}
}
}
GLenum Context::applyVertexBuffer(GLenum mode, GLint first, GLsizei count, bool *useIndexing, TranslatedIndexData *indexInfo)
GLenum Context::applyVertexBuffer(GLint first, GLsizei count)
{
TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];
GLenum err = mVertexDataManager->preRenderValidate(first, count, translated);
GLenum err = mVertexDataManager->prepareVertexData(first, count, translated);
if (err != GL_NO_ERROR)
{
return err;
......@@ -1982,53 +1973,20 @@ GLenum Context::applyVertexBuffer(GLenum mode, GLint first, GLsizei count, bool
lookupAttributeMapping(translated);
mBufferBackEnd->setupAttributesPreDraw(translated);
mVertexDataManager->setupAttributes(translated);
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
if (translated[i].enabled && translated[i].nonArray)
{
err = mIndexDataManager->preRenderValidateUnindexed(mode, count, indexInfo);
if (err != GL_NO_ERROR)
{
return err;
}
mBufferBackEnd->setupIndicesPreDraw(*indexInfo);
*useIndexing = true;
return GL_NO_ERROR;
}
}
*useIndexing = false;
return GL_NO_ERROR;
}
GLenum Context::applyVertexBuffer(const TranslatedIndexData &indexInfo)
{
TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];
GLenum err = mVertexDataManager->preRenderValidate(indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, translated);
if (err == GL_NO_ERROR)
{
lookupAttributeMapping(translated);
mBufferBackEnd->setupAttributesPreDraw(translated);
}
return err;
}
// Applies the indices and element array bindings to the Direct3D 9 device
GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
{
GLenum err = mIndexDataManager->preRenderValidate(mode, type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
IDirect3DDevice9 *device = getDevice();
GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
if (err == GL_NO_ERROR)
{
mBufferBackEnd->setupIndicesPreDraw(*indexInfo);
device->SetIndices(indexInfo->indexBuffer);
}
return err;
......@@ -2486,7 +2444,6 @@ void Context::clear(GLbitfield mask)
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
device->SetStreamSourceFreq(0, 1);
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
hr = device->EndStateBlock(&mMaskedClearSavedState);
......@@ -2542,7 +2499,6 @@ void Context::clear(GLbitfield mask)
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
device->SetStreamSourceFreq(0, 1);
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
struct Vertex
......@@ -2624,9 +2580,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
applyState(mode);
TranslatedIndexData indexInfo;
bool useIndexing;
GLenum err = applyVertexBuffer(mode, first, count, &useIndexing, &indexInfo);
GLenum err = applyVertexBuffer(first, count);
if (err != GL_NO_ERROR)
{
return error(err);
......@@ -2643,15 +2597,9 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
if (!cullSkipsDraw(mode))
{
display->startScene();
if (useIndexing)
{
device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, indexInfo.offset/indexInfo.indexSize, primitiveCount);
}
else
{
device->DrawPrimitive(primitiveType, 0, primitiveCount);
}
}
}
void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
......@@ -2693,7 +2641,8 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void*
return error(err);
}
err = applyVertexBuffer(indexInfo);
GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
err = applyVertexBuffer(indexInfo.minIndex, vertexCount);
if (err != GL_NO_ERROR)
{
return error(err);
......@@ -2710,7 +2659,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void*
if (!cullSkipsDraw(mode))
{
display->startScene();
device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, indexInfo.offset/indexInfo.indexSize, primitiveCount);
device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
}
}
......@@ -2738,7 +2687,6 @@ void Context::finish()
ASSERT(SUCCEEDED(result));
// Render something outside the render target
device->SetStreamSourceFreq(0, 1);
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW);
......@@ -2975,6 +2923,11 @@ bool Context::supportsLuminanceAlphaTextures() const
return mSupportsLuminanceAlphaTextures;
}
bool Context::supports32bitIndices() const
{
return mSupports32bitIndices;
}
void Context::detachBuffer(GLuint buffer)
{
// [OpenGL ES 2.0.24] section 2.9 page 22:
......@@ -3160,7 +3113,7 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values)
mState.vertexAttribute[index].mCurrentValue[2] = values[2];
mState.vertexAttribute[index].mCurrentValue[3] = values[3];
mVertexDataManager->dirtyCurrentValues();
mVertexDataManager->dirtyCurrentValue(index);
}
void Context::initExtensionString()
......@@ -3207,7 +3160,7 @@ void Context::initExtensionString()
mExtensionString += "GL_ANGLE_framebuffer_multisample ";
}
if (mBufferBackEnd->supportIntIndices())
if (supports32bitIndices())
{
mExtensionString += "GL_OES_element_index_uint ";
}
......
......@@ -50,13 +50,12 @@ class Stencilbuffer;
class DepthStencilbuffer;
class VertexDataManager;
class IndexDataManager;
class BufferBackEnd;
class Blit;
class Fence;
enum
{
MAX_VERTEX_ATTRIBS = 16 - 1, // Stream 0 reserved to enable instancing for non-array attributes
MAX_VERTEX_ATTRIBS = 16,
MAX_VERTEX_UNIFORM_VECTORS = 256 - 2, // 256 is the minimum for SM2, and in practice the maximum for DX9. Reserve space for dx_HalfPixelSize and dx_DepthRange.
MAX_VARYING_VECTORS_SM2 = 8,
MAX_VARYING_VECTORS_SM3 = 10,
......@@ -86,32 +85,56 @@ struct Color
};
// Helper structure describing a single vertex attribute
class AttributeState
class VertexAttribute
{
public:
AttributeState()
: mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mEnabled(false)
VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)
{
mCurrentValue[0] = 0;
mCurrentValue[1] = 0;
mCurrentValue[2] = 0;
mCurrentValue[3] = 1;
mCurrentValue[0] = 0.0f;
mCurrentValue[1] = 0.0f;
mCurrentValue[2] = 0.0f;
mCurrentValue[3] = 1.0f;
}
// From VertexArrayPointer
int typeSize() const
{
switch (mType)
{
case GL_BYTE: return mSize * sizeof(GLbyte);
case GL_UNSIGNED_BYTE: return mSize * sizeof(GLubyte);
case GL_SHORT: return mSize * sizeof(GLshort);
case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);
case GL_FIXED: return mSize * sizeof(GLfixed);
case GL_FLOAT: return mSize * sizeof(GLfloat);
default: UNREACHABLE(); return mSize * sizeof(GLfloat);
}
}
GLsizei stride() const
{
return mStride ? mStride : typeSize();
}
// From glVertexAttribPointer
GLenum mType;
GLint mSize;
bool mNormalized;
GLsizei mStride; // 0 means natural stride
const void *mPointer;
BindingPointer<Buffer> mBoundBuffer; // Captured when VertexArrayPointer is called.
union
{
const void *mPointer;
intptr_t mOffset;
};
bool mEnabled; // From Enable/DisableVertexAttribArray
BindingPointer<Buffer> mBoundBuffer; // Captured when glVertexAttribPointer is called.
float mCurrentValue[4]; // From VertexAttrib4f
bool mArrayEnabled; // From glEnable/DisableVertexAttribArray
float mCurrentValue[4]; // From glVertexAttrib
};
typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
// Helper structure to store all raw state
struct State
{
......@@ -188,7 +211,7 @@ struct State
BindingPointer<Renderbuffer> renderbuffer;
GLuint currentProgram;
AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS];
VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
BindingPointer<Texture> samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
GLint unpackAlignment;
......@@ -283,13 +306,13 @@ class Context
GLuint getArrayBufferHandle() const;
void setVertexAttribEnabled(unsigned int attribNum, bool enabled);
const AttributeState &getVertexAttribState(unsigned int attribNum);
void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
const VertexAttribute &getVertexAttribState(unsigned int attribNum);
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, GLsizei stride, const void *pointer);
const void *getVertexAttribPointer(unsigned int attribNum) const;
const AttributeState *getVertexAttribBlock();
const VertexAttributeArray &getVertexAttributes();
void setUnpackAlignment(GLint alignment);
GLint getUnpackAlignment() const;
......@@ -359,10 +382,8 @@ class Context
bool applyRenderTarget(bool ignoreViewport);
void applyState(GLenum drawMode);
GLenum applyVertexBuffer(GLenum mode, GLint first, GLsizei count, bool *useIndexing, TranslatedIndexData *indexInfo);
GLenum applyVertexBuffer(const TranslatedIndexData &indexInfo);
GLenum applyVertexBuffer(GLint first, GLsizei count);
GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
GLenum applyCountingIndexBuffer(GLenum mode, GLenum count, TranslatedIndexData *indexInfo);
void applyShaders();
void applyTextures();
......@@ -401,6 +422,7 @@ class Context
bool supportsHalfFloatRenderableTextures() const;
bool supportsLuminanceTextures() const;
bool supportsLuminanceAlphaTextures() const;
bool supports32bitIndices() const;
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
......@@ -432,7 +454,6 @@ class Context
BindingPointer<Texture2D> mTexture2DZero;
BindingPointer<TextureCubeMap> mTextureCubeMapZero;
typedef std::map<GLuint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap;
......@@ -442,7 +463,6 @@ class Context
void initExtensionString();
std::string mExtensionString;
BufferBackEnd *mBufferBackEnd;
VertexDataManager *mVertexDataManager;
IndexDataManager *mIndexDataManager;
......@@ -482,6 +502,7 @@ class Context
bool mSupportsHalfFloatRenderableTextures;
bool mSupportsLuminanceTextures;
bool mSupportsLuminanceAlphaTextures;
bool mSupports32bitIndices;
// state caching flags
bool mClearStateDirty;
......
......@@ -10,7 +10,7 @@
#ifndef LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
#define LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
#include <bitset>
#include <vector>
#include <cstddef>
#define GL_APICALL
......@@ -21,49 +21,98 @@
namespace gl
{
class Buffer;
class BufferBackEnd;
class TranslatedIndexBuffer;
struct FormatConverter;
struct TranslatedIndexData
{
GLuint minIndex;
GLuint maxIndex;
GLuint count;
GLuint indexSize;
UINT minIndex;
UINT maxIndex;
UINT startIndex;
TranslatedIndexBuffer *buffer;
GLsizei offset;
IDirect3DIndexBuffer9 *indexBuffer;
};
class IndexDataManager
class IndexBuffer
{
public:
IndexDataManager(Context *context, BufferBackEnd *backend);
~IndexDataManager();
IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format);
virtual ~IndexBuffer();
UINT size() const { return mBufferSize; }
virtual void *map(UINT requiredSpace, UINT *offset) = 0;
void unmap();
virtual void reserveSpace(UINT requiredSpace, GLenum type) = 0;
IDirect3DIndexBuffer9 *getBuffer() const;
GLenum preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
GLenum preRenderValidateUnindexed(GLenum mode, GLsizei count, TranslatedIndexData *indexInfo);
protected:
IDirect3DDevice9 *const mDevice;
IDirect3DIndexBuffer9 *mIndexBuffer;
UINT mBufferSize;
private:
std::size_t IndexDataManager::typeSize(GLenum type) const;
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);
DISALLOW_COPY_AND_ASSIGN(IndexBuffer);
};
Context *mContext;
BufferBackEnd *mBackend;
class StreamingIndexBuffer : public IndexBuffer
{
public:
StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format);
~StreamingIndexBuffer();
void *map(UINT requiredSpace, UINT *offset);
void reserveSpace(UINT requiredSpace, GLenum type);
private:
UINT mWritePosition;
};
class StaticIndexBuffer : public IndexBuffer
{
public:
explicit StaticIndexBuffer(IDirect3DDevice9 *device);
~StaticIndexBuffer();
bool mIntIndicesSupported;
void *map(UINT requiredSpace, UINT *offset);
void reserveSpace(UINT requiredSpace, GLenum type);
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;
GLsizei count;
UINT minIndex;
UINT maxIndex;
UINT streamOffset;
};
std::vector<IndexRange> mCache;
};
class IndexDataManager
{
public:
IndexDataManager(Context *context, IDirect3DDevice9 *evice);
virtual ~IndexDataManager();
GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
private:
DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
TranslatedIndexBuffer *mStreamBufferShort;
TranslatedIndexBuffer *mStreamBufferInt;
std::size_t typeSize(GLenum type) const;
std::size_t indexSize(D3DFORMAT format) const;
TranslatedIndexBuffer *mCountingBuffer;
GLsizei mCountingBufferSize;
IDirect3DDevice9 *const mDevice;
TranslatedIndexBuffer *mLineLoopBuffer;
StreamingIndexBuffer *mStreamingBufferShort;
StreamingIndexBuffer *mStreamingBufferInt;
};
}
......
......@@ -10,7 +10,7 @@
#ifndef LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
#define LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
#include <bitset>
#include <vector>
#include <cstddef>
#define GL_APICALL
......@@ -21,44 +21,148 @@
namespace gl
{
class Buffer;
class BufferBackEnd;
class TranslatedVertexBuffer;
struct TranslatedAttribute;
struct FormatConverter;
struct TranslatedIndexData;
struct TranslatedAttribute
{
bool active;
D3DDECLTYPE type;
UINT offset;
UINT stride; // 0 means not to advance the read pointer at all
UINT semanticIndex;
IDirect3DVertexBuffer9 *vertexBuffer;
};
class VertexBuffer
{
public:
VertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
virtual ~VertexBuffer();
void unmap();
IDirect3DVertexBuffer9 *getBuffer() const;
protected:
IDirect3DDevice9 *const mDevice;
IDirect3DVertexBuffer9 *mVertexBuffer;
private:
DISALLOW_COPY_AND_ASSIGN(VertexBuffer);
};
class ConstantVertexBuffer : public VertexBuffer
{
public:
ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w);
~ConstantVertexBuffer();
};
class ArrayVertexBuffer : public VertexBuffer
{
public:
ArrayVertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
~ArrayVertexBuffer();
UINT size() const { return mBufferSize; }
virtual void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset) = 0;
virtual void reserveRequiredSpace() = 0;
void addRequiredSpace(UINT requiredSpace);
void addRequiredSpaceFor(ArrayVertexBuffer *buffer);
protected:
UINT mBufferSize;
UINT mWritePosition;
UINT mRequiredSpace;
};
class StreamingVertexBuffer : public ArrayVertexBuffer
{
public:
StreamingVertexBuffer(IDirect3DDevice9 *device, UINT initialSize);
~StreamingVertexBuffer();
void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
void reserveRequiredSpace();
};
class StaticVertexBuffer : public ArrayVertexBuffer
{
public:
explicit StaticVertexBuffer(IDirect3DDevice9 *device);
~StaticVertexBuffer();
void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
void reserveRequiredSpace();
UINT lookupAttribute(const VertexAttribute &attribute); // Returns the offset into the vertex buffer, or -1 if not found
private:
struct VertexElement
{
GLenum type;
GLint size;
bool normalized;
int attributeOffset;
UINT streamOffset;
};
std::vector<VertexElement> mCache;
};
class VertexDataManager
{
public:
VertexDataManager(Context *context, BufferBackEnd *backend);
~VertexDataManager();
VertexDataManager(Context *context, IDirect3DDevice9 *backend);
virtual ~VertexDataManager();
void dirtyCurrentValues() { mDirtyCurrentValues = true; }
void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
GLenum preRenderValidate(GLint start,
GLsizei count,
TranslatedAttribute *outAttribs);
void setupAttributes(const TranslatedAttribute *attributes);
GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
private:
std::bitset<MAX_VERTEX_ATTRIBS> getActiveAttribs() const;
DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
UINT spaceRequired(const VertexAttribute &attrib, std::size_t count) const;
UINT writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
Context *const mContext;
IDirect3DDevice9 *const mDevice;
StreamingVertexBuffer *mStreamingBuffer;
bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
ConstantVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
// Attribute format conversion
struct FormatConverter
{
bool identity;
std::size_t outputElementSize;
void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
D3DDECLTYPE d3dDeclType;
};
GLenum processNonArrayAttributes(const AttributeState *attribs, const std::bitset<MAX_VERTEX_ATTRIBS> &activeAttribs, TranslatedAttribute *translated, std::size_t count);
enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
std::size_t typeSize(GLenum type) const;
std::size_t interpretGlStride(const AttributeState &attrib) const;
FormatConverter mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
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;
struct TranslationDescription
{
DWORD capsFlag;
FormatConverter preferredConversion;
FormatConverter fallbackConversion;
};
Context *mContext;
BufferBackEnd *mBackend;
// This table is used to generate mAttributeTypes.
static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
TranslatedVertexBuffer *mStreamBuffer;
void checkVertexCaps(DWORD declTypes);
bool mDirtyCurrentValues;
std::size_t mCurrentValueOffset; // Offset within mCurrentValueBuffer that the current attribute values were last loaded at.
TranslatedVertexBuffer *mCurrentValueBuffer;
unsigned int typeIndex(GLenum type) const;
const FormatConverter &formatConverter(const VertexAttribute &attribute) const;
};
}
......
//
// 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 "libGLESv2/geometry/backend.h"
#include "common/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 "libGLESv2/Context.h"
namespace gl
{
class TranslatedVertexBuffer;
class TranslatedIndexBuffer;
struct FormatConverter
{
bool identity;
std::size_t outputVertexSize;
void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
};
struct TranslatedAttribute
{
bool enabled;
bool nonArray;
// 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 semanticIndex;
TranslatedVertexBuffer *buffer;
};
class BufferBackEnd
{
public:
virtual ~BufferBackEnd() { }
virtual bool supportIntIndices() = 0;
virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size) = 0;
virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(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;
// For an identity-mappable stream, verify that the stride and offset are okay.
virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const = 0;
virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo) = 0;
virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes) = 0;
virtual void invalidate() = 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 "libGLESv2/Buffer.h"
#include "libGLESv2/geometry/backend.h"
namespace gl
{
class Dx9BackEnd : public BufferBackEnd
{
public:
explicit Dx9BackEnd(Context *context, IDirect3DDevice9 *d3ddevice);
~Dx9BackEnd();
virtual bool supportIntIndices();
virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size);
virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(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 bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const;
virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo);
virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes);
void invalidate();
private:
IDirect3DDevice9 *mDevice;
bool mUseInstancingForStrideZero;
bool mSupportIntIndices;
bool mAppliedAttribEnabled[MAX_VERTEX_ATTRIBS];
enum StreamFrequency
{
STREAM_FREQUENCY_UNINSTANCED = 0,
STREAM_FREQUENCY_INDEXED,
STREAM_FREQUENCY_INSTANCED,
STREAM_FREQUENCY_DIRTY
};
StreamFrequency mStreamFrequency[MAX_VERTEX_ATTRIBS+1]; // Stream frequencies as last set.
struct TranslationInfo
{
FormatConverter formatConverter;
D3DDECLTYPE d3dDeclType;
};
enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
TranslationInfo mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size-1]
struct TranslationDescription
{
DWORD capsFlag;
TranslationInfo preferredConversion;
TranslationInfo fallbackConversion;
};
// This table is used to generate mAttributeTypes.
static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size-1]
void checkVertexCaps(DWORD declTypes);
unsigned int typeIndex(GLenum type) const;
class Dx9VertexBuffer : public TranslatedVertexBuffer
{
public:
Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size);
virtual ~Dx9VertexBuffer();
IDirect3DVertexBuffer9 *getBuffer() const;
protected:
Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags);
virtual void *map();
virtual void unmap();
virtual void recycle();
virtual void *streamingMap(std::size_t offset, std::size_t size);
private:
IDirect3DVertexBuffer9 *mVertexBuffer;
};
class Dx9VertexBufferZeroStrideWorkaround : public Dx9VertexBuffer
{
public:
Dx9VertexBufferZeroStrideWorkaround(IDirect3DDevice9 *device, std::size_t size);
protected:
virtual void recycle();
virtual void *streamingMap(std::size_t offset, std::size_t size);
};
class Dx9IndexBuffer : public TranslatedIndexBuffer
{
public:
Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size, GLenum type);
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_
......@@ -1714,7 +1714,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index)
if (context)
{
context->setVertexAttribEnabled(index, false);
context->setEnableVertexAttribArray(index, false);
}
}
catch(std::bad_alloc&)
......@@ -1759,20 +1759,25 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
return error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getContext();
if (context)
{
switch (type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT:
break;
case GL_UNSIGNED_INT:
if (!context->supports32bitIndices())
{
return error(GL_INVALID_ENUM);
}
break;
default:
return error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getContext();
if (context)
{
context->drawElements(mode, count, type, indices);
}
}
......@@ -1829,7 +1834,7 @@ void __stdcall glEnableVertexAttribArray(GLuint index)
if (context)
{
context->setVertexAttribEnabled(index, true);
context->setEnableVertexAttribArray(index, true);
}
}
catch(std::bad_alloc&)
......@@ -3457,12 +3462,12 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
return error(GL_INVALID_VALUE);
}
const gl::AttributeState &attribState = context->getVertexAttribState(index);
const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
switch (pname)
{
case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
*params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
*params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_SIZE:
*params = (GLfloat)attribState.mSize;
......@@ -3510,12 +3515,12 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
return error(GL_INVALID_VALUE);
}
const gl::AttributeState &attribState = context->getVertexAttribState(index);
const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
switch (pname)
{
case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
*params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_SIZE:
*params = attribState.mSize;
......
......@@ -248,14 +248,6 @@
Name="Geometry"
>
<File
RelativePath=".\geometry\backend.cpp"
>
</File>
<File
RelativePath=".\geometry\dx9.cpp"
>
</File>
<File
RelativePath=".\geometry\IndexDataManager.cpp"
>
</File>
......@@ -342,14 +334,6 @@
Name="Geometry"
>
<File
RelativePath=".\geometry\backend.h"
>
</File>
<File
RelativePath=".\geometry\dx9.h"
>
</File>
<File
RelativePath=".\geometry\IndexDataManager.h"
>
</File>
......
......@@ -707,46 +707,46 @@ unsigned int GetDepthSize(D3DFORMAT depthFormat)
case D3DFMT_D16: return 16;
case D3DFMT_D32F_LOCKABLE: return 32;
case D3DFMT_D24FS8: return 24;
// case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
// case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
//case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
//case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
default:
UNREACHABLE();
}
return 0;
}
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
{
switch (primitiveType)
{
case GL_POINTS:
*d3dPrimitiveType = D3DPT_POINTLIST;
*d3dPrimitiveCount = primitiveCount;
*d3dPrimitiveCount = elementCount;
break;
case GL_LINES:
*d3dPrimitiveType = D3DPT_LINELIST;
*d3dPrimitiveCount = primitiveCount / 2;
*d3dPrimitiveCount = elementCount / 2;
break;
case GL_LINE_LOOP:
*d3dPrimitiveType = D3DPT_LINESTRIP;
*d3dPrimitiveCount = primitiveCount;
*d3dPrimitiveCount = elementCount - 1; // D3D doesn't support line loops, so we draw the last line separately
break;
case GL_LINE_STRIP:
*d3dPrimitiveType = D3DPT_LINESTRIP;
*d3dPrimitiveCount = primitiveCount - 1;
*d3dPrimitiveCount = elementCount - 1;
break;
case GL_TRIANGLES:
*d3dPrimitiveType = D3DPT_TRIANGLELIST;
*d3dPrimitiveCount = primitiveCount / 3;
*d3dPrimitiveCount = elementCount / 3;
break;
case GL_TRIANGLE_STRIP:
*d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
*d3dPrimitiveCount = primitiveCount - 2;
*d3dPrimitiveCount = elementCount - 2;
break;
case GL_TRIANGLE_FAN:
*d3dPrimitiveType = D3DPT_TRIANGLEFAN;
*d3dPrimitiveCount = primitiveCount - 2;
*d3dPrimitiveCount = elementCount - 2;
break;
default:
return false;
......
......@@ -61,7 +61,7 @@ unsigned int GetGreenSize(D3DFORMAT colorFormat);
unsigned int GetBlueSize(D3DFORMAT colorFormat);
unsigned int GetDepthSize(D3DFORMAT depthFormat);
unsigned int GetStencilSize(D3DFORMAT stencilFormat);
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount);
D3DFORMAT ConvertRenderbufferFormat(GLenum format);
D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples);
......
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