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 @@ ...@@ -144,10 +144,6 @@
'common/angleutils.h', 'common/angleutils.h',
'common/debug.cpp', 'common/debug.cpp',
'common/debug.h', '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.cpp',
'libGLESv2/geometry/IndexDataManager.h', 'libGLESv2/geometry/IndexDataManager.h',
'libGLESv2/geometry/vertexconversion.h', 'libGLESv2/geometry/vertexconversion.h',
......
...@@ -187,4 +187,3 @@ void TCompiler::collectAttribsUniforms(TIntermNode* root) ...@@ -187,4 +187,3 @@ void TCompiler::collectAttribsUniforms(TIntermNode* root)
CollectAttribsUniforms collect(attribs, uniforms); CollectAttribsUniforms collect(attribs, uniforms);
root->traverse(&collect); root->traverse(&collect);
} }
...@@ -299,4 +299,4 @@ void TAllocation::checkAllocList() const ...@@ -299,4 +299,4 @@ void TAllocation::checkAllocList() const
{ {
for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc) for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc)
alloc->check(); alloc->check();
} }
\ No newline at end of file
...@@ -297,4 +297,4 @@ protected: ...@@ -297,4 +297,4 @@ protected:
TPoolAllocator& allocator; TPoolAllocator& allocator;
}; };
#endif // _POOLALLOC_INCLUDED_ #endif // _POOLALLOC_INCLUDED_
\ No newline at end of file
...@@ -101,4 +101,4 @@ private: ...@@ -101,4 +101,4 @@ private:
TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec); TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec);
void DeleteCompiler(TCompiler*); void DeleteCompiler(TCompiler*);
#endif // _SHHANDLE_INCLUDED_ #endif // _SHHANDLE_INCLUDED_
\ No newline at end of file
...@@ -252,4 +252,3 @@ void ShGetActiveUniform(const ShHandle handle, ...@@ -252,4 +252,3 @@ void ShGetActiveUniform(const ShHandle handle,
getVariableInfo(SH_ACTIVE_UNIFORMS, getVariableInfo(SH_ACTIVE_UNIFORMS,
handle, index, length, size, type, name); handle, index, length, size, type, name);
} }
...@@ -213,8 +213,6 @@ void Surface::writeRecordableFlipState(IDirect3DDevice9 *device) ...@@ -213,8 +213,6 @@ void Surface::writeRecordableFlipState(IDirect3DDevice9 *device)
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); 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 RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
device->SetScissorRect(&scissorRect); device->SetScissorRect(&scissorRect);
D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f}; D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
......
...@@ -466,11 +466,6 @@ void Blit::setCommonBlitState() ...@@ -466,11 +466,6 @@ void Blit::setCommonBlitState()
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
device->SetSamplerState(0, D3DSAMP_ADDRESSV, 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 RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
device->SetScissorRect(&scissorRect); device->SetScissorRect(&scissorRect);
} }
......
...@@ -10,6 +10,10 @@ ...@@ -10,6 +10,10 @@
#include "libGLESv2/Buffer.h" #include "libGLESv2/Buffer.h"
#include "libGLESv2/main.h"
#include "libGLESv2/geometry/VertexDataManager.h"
#include "libGLESv2/geometry/IndexDataManager.h"
namespace gl namespace gl
{ {
...@@ -18,11 +22,16 @@ Buffer::Buffer(GLuint id) : RefCountObject(id) ...@@ -18,11 +22,16 @@ Buffer::Buffer(GLuint id) : RefCountObject(id)
mContents = NULL; mContents = NULL;
mSize = 0; mSize = 0;
mUsage = GL_DYNAMIC_DRAW; mUsage = GL_DYNAMIC_DRAW;
mVertexBuffer = NULL;
mIndexBuffer = NULL;
} }
Buffer::~Buffer() Buffer::~Buffer()
{ {
delete[] mContents; delete[] mContents;
delete mVertexBuffer;
delete mIndexBuffer;
} }
void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
...@@ -46,11 +55,49 @@ 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; mSize = size;
mUsage = usage; 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) void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
{ {
memcpy(mContents + offset, data, size); 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 @@ ...@@ -22,6 +22,8 @@
namespace gl namespace gl
{ {
class StaticVertexBuffer;
class StaticIndexBuffer;
class Buffer : public RefCountObject class Buffer : public RefCountObject
{ {
...@@ -37,12 +39,19 @@ class Buffer : public RefCountObject ...@@ -37,12 +39,19 @@ class Buffer : public RefCountObject
size_t size() const { return mSize; } size_t size() const { return mSize; }
GLenum usage() const { return mUsage; } GLenum usage() const { return mUsage; }
StaticVertexBuffer *getVertexBuffer();
StaticIndexBuffer *getIndexBuffer();
void invalidateStaticData();
private: private:
DISALLOW_COPY_AND_ASSIGN(Buffer); DISALLOW_COPY_AND_ASSIGN(Buffer);
GLubyte *mContents; GLubyte *mContents;
size_t mSize; size_t mSize;
GLenum mUsage; GLenum mUsage;
StaticVertexBuffer *mVertexBuffer;
StaticIndexBuffer *mIndexBuffer;
}; };
} }
......
...@@ -25,10 +25,8 @@ ...@@ -25,10 +25,8 @@
#include "libGLESv2/RenderBuffer.h" #include "libGLESv2/RenderBuffer.h"
#include "libGLESv2/Shader.h" #include "libGLESv2/Shader.h"
#include "libGLESv2/Texture.h" #include "libGLESv2/Texture.h"
#include "libGLESv2/geometry/backend.h"
#include "libGLESv2/geometry/VertexDataManager.h" #include "libGLESv2/geometry/VertexDataManager.h"
#include "libGLESv2/geometry/IndexDataManager.h" #include "libGLESv2/geometry/IndexDataManager.h"
#include "libGLESv2/geometry/dx9.h"
#undef near #undef near
#undef far #undef far
...@@ -139,7 +137,6 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext) ...@@ -139,7 +137,6 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext)
mState.packAlignment = 4; mState.packAlignment = 4;
mState.unpackAlignment = 4; mState.unpackAlignment = 4;
mBufferBackEnd = NULL;
mVertexDataManager = NULL; mVertexDataManager = NULL;
mIndexDataManager = NULL; mIndexDataManager = NULL;
mBlit = NULL; mBlit = NULL;
...@@ -212,7 +209,6 @@ Context::~Context() ...@@ -212,7 +209,6 @@ Context::~Context()
mTexture2DZero.set(NULL); mTexture2DZero.set(NULL);
mTextureCubeMapZero.set(NULL); mTextureCubeMapZero.set(NULL);
delete mBufferBackEnd;
delete mVertexDataManager; delete mVertexDataManager;
delete mIndexDataManager; delete mIndexDataManager;
delete mBlit; delete mBlit;
...@@ -233,9 +229,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) ...@@ -233,9 +229,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
{ {
mDeviceCaps = display->getDeviceCaps(); mDeviceCaps = display->getDeviceCaps();
mBufferBackEnd = new Dx9BackEnd(this, device); mVertexDataManager = new VertexDataManager(this, device);
mVertexDataManager = new VertexDataManager(this, mBufferBackEnd); mIndexDataManager = new IndexDataManager(this, device);
mIndexDataManager = new IndexDataManager(this, mBufferBackEnd);
mBlit = new Blit(this); mBlit = new Blit(this);
mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0); mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
...@@ -281,6 +276,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) ...@@ -281,6 +276,8 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mSupportsLuminanceTextures = display->getLuminanceTextureSupport(); mSupportsLuminanceTextures = display->getLuminanceTextureSupport();
mSupportsLuminanceAlphaTextures = display->getLuminanceAlphaTextureSupport(); mSupportsLuminanceAlphaTextures = display->getLuminanceAlphaTextureSupport();
mSupports32bitIndices = mDeviceCaps.MaxVertexIndex >= (1 << 16);
initExtensionString(); initExtensionString();
mState.viewportX = 0; mState.viewportX = 0;
...@@ -339,11 +336,6 @@ void Context::markAllStateDirty() ...@@ -339,11 +336,6 @@ void Context::markAllStateDirty()
mSampleStateDirty = true; mSampleStateDirty = true;
mDitherStateDirty = true; mDitherStateDirty = true;
mFrontFaceDirty = true; mFrontFaceDirty = true;
if (mBufferBackEnd != NULL)
{
mBufferBackEnd->invalidate();
}
} }
void Context::setClearColor(float red, float green, float blue, float alpha) void Context::setClearColor(float red, float green, float blue, float alpha)
...@@ -743,12 +735,12 @@ GLuint Context::getArrayBufferHandle() const ...@@ -743,12 +735,12 @@ GLuint Context::getArrayBufferHandle() const
return mState.arrayBuffer.id(); 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]; return mState.vertexAttribute[attribNum];
} }
...@@ -769,8 +761,7 @@ const void *Context::getVertexAttribPointer(unsigned int attribNum) const ...@@ -769,8 +761,7 @@ const void *Context::getVertexAttribPointer(unsigned int attribNum) const
return mState.vertexAttribute[attribNum].mPointer; return mState.vertexAttribute[attribNum].mPointer;
} }
// returns entire set of attributes as a block const VertexAttributeArray &Context::getVertexAttributes()
const AttributeState *Context::getVertexAttribBlock()
{ {
return mState.vertexAttribute; return mState.vertexAttribute;
} }
...@@ -1963,18 +1954,18 @@ void Context::lookupAttributeMapping(TranslatedAttribute *attributes) ...@@ -1963,18 +1954,18 @@ void Context::lookupAttributeMapping(TranslatedAttribute *attributes)
{ {
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{ {
if (attributes[i].enabled) if (attributes[i].active)
{ {
attributes[i].semanticIndex = getCurrentProgram()->getSemanticIndex(i); 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]; TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];
GLenum err = mVertexDataManager->preRenderValidate(first, count, translated); GLenum err = mVertexDataManager->prepareVertexData(first, count, translated);
if (err != GL_NO_ERROR) if (err != GL_NO_ERROR)
{ {
return err; return err;
...@@ -1982,53 +1973,20 @@ GLenum Context::applyVertexBuffer(GLenum mode, GLint first, GLsizei count, bool ...@@ -1982,53 +1973,20 @@ GLenum Context::applyVertexBuffer(GLenum mode, GLint first, GLsizei count, bool
lookupAttributeMapping(translated); 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; 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 // 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 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) if (err == GL_NO_ERROR)
{ {
mBufferBackEnd->setupIndicesPreDraw(*indexInfo); device->SetIndices(indexInfo->indexBuffer);
} }
return err; return err;
...@@ -2486,7 +2444,6 @@ void Context::clear(GLbitfield mask) ...@@ -2486,7 +2444,6 @@ void Context::clear(GLbitfield mask)
device->SetPixelShader(NULL); device->SetPixelShader(NULL);
device->SetVertexShader(NULL); device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
device->SetStreamSourceFreq(0, 1);
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
hr = device->EndStateBlock(&mMaskedClearSavedState); hr = device->EndStateBlock(&mMaskedClearSavedState);
...@@ -2542,7 +2499,6 @@ void Context::clear(GLbitfield mask) ...@@ -2542,7 +2499,6 @@ void Context::clear(GLbitfield mask)
device->SetPixelShader(NULL); device->SetPixelShader(NULL);
device->SetVertexShader(NULL); device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
device->SetStreamSourceFreq(0, 1);
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
struct Vertex struct Vertex
...@@ -2624,9 +2580,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count) ...@@ -2624,9 +2580,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
applyState(mode); applyState(mode);
TranslatedIndexData indexInfo; GLenum err = applyVertexBuffer(first, count);
bool useIndexing;
GLenum err = applyVertexBuffer(mode, first, count, &useIndexing, &indexInfo);
if (err != GL_NO_ERROR) if (err != GL_NO_ERROR)
{ {
return error(err); return error(err);
...@@ -2643,14 +2597,8 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count) ...@@ -2643,14 +2597,8 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
if (!cullSkipsDraw(mode)) if (!cullSkipsDraw(mode))
{ {
display->startScene(); display->startScene();
if (useIndexing)
{ device->DrawPrimitive(primitiveType, 0, primitiveCount);
device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, indexInfo.offset/indexInfo.indexSize, primitiveCount);
}
else
{
device->DrawPrimitive(primitiveType, 0, primitiveCount);
}
} }
} }
...@@ -2693,7 +2641,8 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void* ...@@ -2693,7 +2641,8 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void*
return error(err); return error(err);
} }
err = applyVertexBuffer(indexInfo); GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
err = applyVertexBuffer(indexInfo.minIndex, vertexCount);
if (err != GL_NO_ERROR) if (err != GL_NO_ERROR)
{ {
return error(err); return error(err);
...@@ -2710,7 +2659,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void* ...@@ -2710,7 +2659,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/indexInfo.indexSize, primitiveCount); device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
} }
} }
...@@ -2738,7 +2687,6 @@ void Context::finish() ...@@ -2738,7 +2687,6 @@ void Context::finish()
ASSERT(SUCCEEDED(result)); ASSERT(SUCCEEDED(result));
// Render something outside the render target // Render something outside the render target
device->SetStreamSourceFreq(0, 1);
device->SetPixelShader(NULL); device->SetPixelShader(NULL);
device->SetVertexShader(NULL); device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW); device->SetFVF(D3DFVF_XYZRHW);
...@@ -2975,6 +2923,11 @@ bool Context::supportsLuminanceAlphaTextures() const ...@@ -2975,6 +2923,11 @@ bool Context::supportsLuminanceAlphaTextures() const
return mSupportsLuminanceAlphaTextures; return mSupportsLuminanceAlphaTextures;
} }
bool Context::supports32bitIndices() const
{
return mSupports32bitIndices;
}
void Context::detachBuffer(GLuint buffer) void Context::detachBuffer(GLuint buffer)
{ {
// [OpenGL ES 2.0.24] section 2.9 page 22: // [OpenGL ES 2.0.24] section 2.9 page 22:
...@@ -3160,7 +3113,7 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values) ...@@ -3160,7 +3113,7 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values)
mState.vertexAttribute[index].mCurrentValue[2] = values[2]; mState.vertexAttribute[index].mCurrentValue[2] = values[2];
mState.vertexAttribute[index].mCurrentValue[3] = values[3]; mState.vertexAttribute[index].mCurrentValue[3] = values[3];
mVertexDataManager->dirtyCurrentValues(); mVertexDataManager->dirtyCurrentValue(index);
} }
void Context::initExtensionString() void Context::initExtensionString()
...@@ -3207,7 +3160,7 @@ void Context::initExtensionString() ...@@ -3207,7 +3160,7 @@ void Context::initExtensionString()
mExtensionString += "GL_ANGLE_framebuffer_multisample "; mExtensionString += "GL_ANGLE_framebuffer_multisample ";
} }
if (mBufferBackEnd->supportIntIndices()) if (supports32bitIndices())
{ {
mExtensionString += "GL_OES_element_index_uint "; mExtensionString += "GL_OES_element_index_uint ";
} }
......
...@@ -50,13 +50,12 @@ class Stencilbuffer; ...@@ -50,13 +50,12 @@ class Stencilbuffer;
class DepthStencilbuffer; class DepthStencilbuffer;
class VertexDataManager; class VertexDataManager;
class IndexDataManager; class IndexDataManager;
class BufferBackEnd;
class Blit; class Blit;
class Fence; class Fence;
enum 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_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_SM2 = 8,
MAX_VARYING_VECTORS_SM3 = 10, MAX_VARYING_VECTORS_SM3 = 10,
...@@ -86,32 +85,56 @@ struct Color ...@@ -86,32 +85,56 @@ struct Color
}; };
// Helper structure describing a single vertex attribute // Helper structure describing a single vertex attribute
class AttributeState class VertexAttribute
{ {
public: public:
AttributeState() VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)
: mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mEnabled(false)
{ {
mCurrentValue[0] = 0; mCurrentValue[0] = 0.0f;
mCurrentValue[1] = 0; mCurrentValue[1] = 0.0f;
mCurrentValue[2] = 0; mCurrentValue[2] = 0.0f;
mCurrentValue[3] = 1; 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; GLenum mType;
GLint mSize; GLint mSize;
bool mNormalized; bool mNormalized;
GLsizei mStride; // 0 means natural stride 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 // Helper structure to store all raw state
struct State struct State
{ {
...@@ -188,7 +211,7 @@ struct State ...@@ -188,7 +211,7 @@ struct State
BindingPointer<Renderbuffer> renderbuffer; BindingPointer<Renderbuffer> renderbuffer;
GLuint currentProgram; GLuint currentProgram;
AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS]; VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
BindingPointer<Texture> samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS]; BindingPointer<Texture> samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
GLint unpackAlignment; GLint unpackAlignment;
...@@ -283,13 +306,13 @@ class Context ...@@ -283,13 +306,13 @@ class Context
GLuint getArrayBufferHandle() const; GLuint getArrayBufferHandle() const;
void setVertexAttribEnabled(unsigned int attribNum, bool enabled); void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
const AttributeState &getVertexAttribState(unsigned int attribNum); const VertexAttribute &getVertexAttribState(unsigned int attribNum);
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, GLsizei stride, const void *pointer); bool normalized, GLsizei stride, const void *pointer);
const void *getVertexAttribPointer(unsigned int attribNum) const; const void *getVertexAttribPointer(unsigned int attribNum) const;
const AttributeState *getVertexAttribBlock(); const VertexAttributeArray &getVertexAttributes();
void setUnpackAlignment(GLint alignment); void setUnpackAlignment(GLint alignment);
GLint getUnpackAlignment() const; GLint getUnpackAlignment() const;
...@@ -359,10 +382,8 @@ class Context ...@@ -359,10 +382,8 @@ class Context
bool applyRenderTarget(bool ignoreViewport); bool applyRenderTarget(bool ignoreViewport);
void applyState(GLenum drawMode); void applyState(GLenum drawMode);
GLenum applyVertexBuffer(GLenum mode, GLint first, GLsizei count, bool *useIndexing, TranslatedIndexData *indexInfo); GLenum applyVertexBuffer(GLint first, GLsizei count);
GLenum applyVertexBuffer(const TranslatedIndexData &indexInfo);
GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
GLenum applyCountingIndexBuffer(GLenum mode, GLenum count, TranslatedIndexData *indexInfo);
void applyShaders(); void applyShaders();
void applyTextures(); void applyTextures();
...@@ -401,6 +422,7 @@ class Context ...@@ -401,6 +422,7 @@ class Context
bool supportsHalfFloatRenderableTextures() const; bool supportsHalfFloatRenderableTextures() const;
bool supportsLuminanceTextures() const; bool supportsLuminanceTextures() const;
bool supportsLuminanceAlphaTextures() const; bool supportsLuminanceAlphaTextures() const;
bool supports32bitIndices() const;
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
...@@ -432,7 +454,6 @@ class Context ...@@ -432,7 +454,6 @@ class Context
BindingPointer<Texture2D> mTexture2DZero; BindingPointer<Texture2D> mTexture2DZero;
BindingPointer<TextureCubeMap> mTextureCubeMapZero; BindingPointer<TextureCubeMap> mTextureCubeMapZero;
typedef std::map<GLuint, Framebuffer*> FramebufferMap; typedef std::map<GLuint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap; FramebufferMap mFramebufferMap;
...@@ -442,7 +463,6 @@ class Context ...@@ -442,7 +463,6 @@ class Context
void initExtensionString(); void initExtensionString();
std::string mExtensionString; std::string mExtensionString;
BufferBackEnd *mBufferBackEnd;
VertexDataManager *mVertexDataManager; VertexDataManager *mVertexDataManager;
IndexDataManager *mIndexDataManager; IndexDataManager *mIndexDataManager;
...@@ -482,6 +502,7 @@ class Context ...@@ -482,6 +502,7 @@ class Context
bool mSupportsHalfFloatRenderableTextures; bool mSupportsHalfFloatRenderableTextures;
bool mSupportsLuminanceTextures; bool mSupportsLuminanceTextures;
bool mSupportsLuminanceAlphaTextures; bool mSupportsLuminanceAlphaTextures;
bool mSupports32bitIndices;
// state caching flags // state caching flags
bool mClearStateDirty; bool mClearStateDirty;
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#ifndef LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_ #ifndef LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
#define LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_ #define LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
#include <bitset> #include <vector>
#include <cstddef> #include <cstddef>
#define GL_APICALL #define GL_APICALL
...@@ -21,49 +21,98 @@ ...@@ -21,49 +21,98 @@
namespace gl namespace gl
{ {
class Buffer;
class BufferBackEnd;
class TranslatedIndexBuffer;
struct FormatConverter;
struct TranslatedIndexData struct TranslatedIndexData
{ {
GLuint minIndex; UINT minIndex;
GLuint maxIndex; UINT maxIndex;
GLuint count; UINT startIndex;
GLuint indexSize;
TranslatedIndexBuffer *buffer; IDirect3DIndexBuffer9 *indexBuffer;
GLsizei offset;
}; };
class IndexDataManager class IndexBuffer
{
public:
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;
protected:
IDirect3DDevice9 *const mDevice;
IDirect3DIndexBuffer9 *mIndexBuffer;
UINT mBufferSize;
private:
DISALLOW_COPY_AND_ASSIGN(IndexBuffer);
};
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: public:
IndexDataManager(Context *context, BufferBackEnd *backend); explicit StaticIndexBuffer(IDirect3DDevice9 *device);
~IndexDataManager(); ~StaticIndexBuffer();
void *map(UINT requiredSpace, UINT *offset);
void reserveSpace(UINT requiredSpace, GLenum type);
GLenum preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated); bool lookupType(GLenum type);
GLenum preRenderValidateUnindexed(GLenum mode, GLsizei count, TranslatedIndexData *indexInfo); 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: private:
std::size_t IndexDataManager::typeSize(GLenum type) const; GLenum mCacheType;
std::size_t IndexDataManager::indexSize(GLenum type) const;
std::size_t spaceRequired(GLenum type, GLsizei count) const; struct IndexRange
TranslatedIndexBuffer *prepareIndexBuffer(GLenum type, std::size_t requiredSpace); {
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();
Context *mContext; GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
BufferBackEnd *mBackend;
bool mIntIndicesSupported; private:
DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
TranslatedIndexBuffer *mStreamBufferShort; std::size_t typeSize(GLenum type) const;
TranslatedIndexBuffer *mStreamBufferInt; std::size_t indexSize(D3DFORMAT format) const;
TranslatedIndexBuffer *mCountingBuffer; IDirect3DDevice9 *const mDevice;
GLsizei mCountingBufferSize;
TranslatedIndexBuffer *mLineLoopBuffer; StreamingIndexBuffer *mStreamingBufferShort;
StreamingIndexBuffer *mStreamingBufferInt;
}; };
} }
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#ifndef LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_ #ifndef LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
#define LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_ #define LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
#include <bitset> #include <vector>
#include <cstddef> #include <cstddef>
#define GL_APICALL #define GL_APICALL
...@@ -21,44 +21,148 @@ ...@@ -21,44 +21,148 @@
namespace gl namespace gl
{ {
class Buffer; struct TranslatedAttribute
class BufferBackEnd; {
class TranslatedVertexBuffer; bool active;
struct TranslatedAttribute;
struct FormatConverter; D3DDECLTYPE type;
struct TranslatedIndexData; 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 class VertexDataManager
{ {
public: public:
VertexDataManager(Context *context, BufferBackEnd *backend); VertexDataManager(Context *context, IDirect3DDevice9 *backend);
~VertexDataManager(); virtual ~VertexDataManager();
void dirtyCurrentValues() { mDirtyCurrentValues = true; } void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
GLenum preRenderValidate(GLint start, void setupAttributes(const TranslatedAttribute *attributes);
GLsizei count, GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
TranslatedAttribute *outAttribs);
private: 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; FormatConverter mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
std::size_t interpretGlStride(const AttributeState &attrib) const;
std::size_t roundUp(std::size_t x, std::size_t multiple) const; struct TranslationDescription
std::size_t spaceRequired(const AttributeState &attrib, std::size_t maxVertex) const; {
DWORD capsFlag;
FormatConverter preferredConversion;
FormatConverter fallbackConversion;
};
Context *mContext; // This table is used to generate mAttributeTypes.
BufferBackEnd *mBackend; 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; unsigned int typeIndex(GLenum type) const;
std::size_t mCurrentValueOffset; // Offset within mCurrentValueBuffer that the current attribute values were last loaded at. const FormatConverter &formatConverter(const VertexAttribute &attribute) const;
TranslatedVertexBuffer *mCurrentValueBuffer;
}; };
} }
......
//
// 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) ...@@ -1714,7 +1714,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index)
if (context) if (context)
{ {
context->setVertexAttribEnabled(index, false); context->setEnableVertexAttribArray(index, false);
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -1759,20 +1759,25 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv ...@@ -1759,20 +1759,25 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
switch (type)
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT:
case GL_UNSIGNED_INT:
break;
default:
return error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getContext(); gl::Context *context = gl::getContext();
if (context) 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);
}
context->drawElements(mode, count, type, indices); context->drawElements(mode, count, type, indices);
} }
} }
...@@ -1829,7 +1834,7 @@ void __stdcall glEnableVertexAttribArray(GLuint index) ...@@ -1829,7 +1834,7 @@ void __stdcall glEnableVertexAttribArray(GLuint index)
if (context) if (context)
{ {
context->setVertexAttribEnabled(index, true); context->setEnableVertexAttribArray(index, true);
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
...@@ -3457,12 +3462,12 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) ...@@ -3457,12 +3462,12 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
const gl::AttributeState &attribState = context->getVertexAttribState(index); const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
switch (pname) switch (pname)
{ {
case GL_VERTEX_ATTRIB_ARRAY_ENABLED: case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
*params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE); *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
break; break;
case GL_VERTEX_ATTRIB_ARRAY_SIZE: case GL_VERTEX_ATTRIB_ARRAY_SIZE:
*params = (GLfloat)attribState.mSize; *params = (GLfloat)attribState.mSize;
...@@ -3510,12 +3515,12 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) ...@@ -3510,12 +3515,12 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
return error(GL_INVALID_VALUE); return error(GL_INVALID_VALUE);
} }
const gl::AttributeState &attribState = context->getVertexAttribState(index); const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
switch (pname) switch (pname)
{ {
case GL_VERTEX_ATTRIB_ARRAY_ENABLED: case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
*params = (attribState.mEnabled ? GL_TRUE : GL_FALSE); *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
break; break;
case GL_VERTEX_ATTRIB_ARRAY_SIZE: case GL_VERTEX_ATTRIB_ARRAY_SIZE:
*params = attribState.mSize; *params = attribState.mSize;
......
...@@ -248,14 +248,6 @@ ...@@ -248,14 +248,6 @@
Name="Geometry" Name="Geometry"
> >
<File <File
RelativePath=".\geometry\backend.cpp"
>
</File>
<File
RelativePath=".\geometry\dx9.cpp"
>
</File>
<File
RelativePath=".\geometry\IndexDataManager.cpp" RelativePath=".\geometry\IndexDataManager.cpp"
> >
</File> </File>
...@@ -342,14 +334,6 @@ ...@@ -342,14 +334,6 @@
Name="Geometry" Name="Geometry"
> >
<File <File
RelativePath=".\geometry\backend.h"
>
</File>
<File
RelativePath=".\geometry\dx9.h"
>
</File>
<File
RelativePath=".\geometry\IndexDataManager.h" RelativePath=".\geometry\IndexDataManager.h"
> >
</File> </File>
......
...@@ -707,46 +707,46 @@ unsigned int GetDepthSize(D3DFORMAT depthFormat) ...@@ -707,46 +707,46 @@ unsigned int GetDepthSize(D3DFORMAT depthFormat)
case D3DFMT_D16: return 16; case D3DFMT_D16: return 16;
case D3DFMT_D32F_LOCKABLE: return 32; case D3DFMT_D32F_LOCKABLE: return 32;
case D3DFMT_D24FS8: return 24; case D3DFMT_D24FS8: return 24;
// case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only //case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
// case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only //case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
default: default:
UNREACHABLE(); UNREACHABLE();
} }
return 0; return 0;
} }
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount, bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount) D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
{ {
switch (primitiveType) switch (primitiveType)
{ {
case GL_POINTS: case GL_POINTS:
*d3dPrimitiveType = D3DPT_POINTLIST; *d3dPrimitiveType = D3DPT_POINTLIST;
*d3dPrimitiveCount = primitiveCount; *d3dPrimitiveCount = elementCount;
break; break;
case GL_LINES: case GL_LINES:
*d3dPrimitiveType = D3DPT_LINELIST; *d3dPrimitiveType = D3DPT_LINELIST;
*d3dPrimitiveCount = primitiveCount / 2; *d3dPrimitiveCount = elementCount / 2;
break; break;
case GL_LINE_LOOP: case GL_LINE_LOOP:
*d3dPrimitiveType = D3DPT_LINESTRIP; *d3dPrimitiveType = D3DPT_LINESTRIP;
*d3dPrimitiveCount = primitiveCount; *d3dPrimitiveCount = elementCount - 1; // D3D doesn't support line loops, so we draw the last line separately
break; break;
case GL_LINE_STRIP: case GL_LINE_STRIP:
*d3dPrimitiveType = D3DPT_LINESTRIP; *d3dPrimitiveType = D3DPT_LINESTRIP;
*d3dPrimitiveCount = primitiveCount - 1; *d3dPrimitiveCount = elementCount - 1;
break; break;
case GL_TRIANGLES: case GL_TRIANGLES:
*d3dPrimitiveType = D3DPT_TRIANGLELIST; *d3dPrimitiveType = D3DPT_TRIANGLELIST;
*d3dPrimitiveCount = primitiveCount / 3; *d3dPrimitiveCount = elementCount / 3;
break; break;
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
*d3dPrimitiveType = D3DPT_TRIANGLESTRIP; *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
*d3dPrimitiveCount = primitiveCount - 2; *d3dPrimitiveCount = elementCount - 2;
break; break;
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
*d3dPrimitiveType = D3DPT_TRIANGLEFAN; *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
*d3dPrimitiveCount = primitiveCount - 2; *d3dPrimitiveCount = elementCount - 2;
break; break;
default: default:
return false; return false;
......
...@@ -61,7 +61,7 @@ unsigned int GetGreenSize(D3DFORMAT colorFormat); ...@@ -61,7 +61,7 @@ unsigned int GetGreenSize(D3DFORMAT colorFormat);
unsigned int GetBlueSize(D3DFORMAT colorFormat); unsigned int GetBlueSize(D3DFORMAT colorFormat);
unsigned int GetDepthSize(D3DFORMAT depthFormat); unsigned int GetDepthSize(D3DFORMAT depthFormat);
unsigned int GetStencilSize(D3DFORMAT stencilFormat); unsigned int GetStencilSize(D3DFORMAT stencilFormat);
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount, bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount); D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount);
D3DFORMAT ConvertRenderbufferFormat(GLenum format); D3DFORMAT ConvertRenderbufferFormat(GLenum format);
D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples); 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