Commit a857c36b by Jamie Madill Committed by Shannon Woods

Refactor VertexAttribute to split the "current value" for generic attributes into its own class.

VAOs in GLES 3 do not store the current values, so these must be handled separately from other Vertex Attribute data. TRAC #23390 Signed-off-by: Shannon Woods Signed-off-by: Geoff Lang Authored-by: Jamie Madill
parent 87939710
......@@ -244,9 +244,11 @@ Context::~Context()
mIncompleteTextures[type].set(NULL);
}
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
{
mState.vertexAttribute[i].mBoundBuffer.set(NULL);
mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
mState.vertexAttribute[attribIndex].mBoundBuffer.set(NULL);
}
for (int i = 0; i < QUERY_TYPE_COUNT; i++)
......@@ -685,14 +687,22 @@ GLuint Context::getActiveQuery(GLenum target) const
void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
{
ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
}
const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
{
ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
return mState.vertexAttribute[attribNum];
}
const VertexAttribCurrentValueData &Context::getVertexAttribCurrentValue(unsigned int attribNum) const
{
ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
return mState.vertexAttribCurrentValues[attribNum];
}
void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
bool pureInteger, GLsizei stride, const void *pointer)
{
......@@ -2256,7 +2266,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instan
ProgramBinary *programBinary = getCurrentProgramBinary();
GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, first, count, instances);
GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, mState.vertexAttribCurrentValues, first, count, instances);
if (err != GL_NO_ERROR)
{
return gl::error(err);
......@@ -2315,7 +2325,7 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
ProgramBinary *programBinary = getCurrentProgramBinary();
GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, indexInfo.minIndex, vertexCount, instances);
err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, mState.vertexAttribCurrentValues, indexInfo.minIndex, vertexCount, instances);
if (err != GL_NO_ERROR)
{
return gl::error(err);
......@@ -2845,37 +2855,19 @@ bool Context::skipDraw(GLenum drawMode)
void Context::setVertexAttribf(GLuint index, const GLfloat values[4])
{
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
mState.vertexAttribute[index].mCurrentValue.FloatValues[0] = values[0];
mState.vertexAttribute[index].mCurrentValue.FloatValues[1] = values[1];
mState.vertexAttribute[index].mCurrentValue.FloatValues[2] = values[2];
mState.vertexAttribute[index].mCurrentValue.FloatValues[3] = values[3];
mState.vertexAttribute[index].mCurrentValue.Type = GL_FLOAT;
mState.vertexAttribute[index].mPureInteger = false;
mState.vertexAttribCurrentValues[index].setFloatValues(values);
}
void Context::setVertexAttribu(GLuint index, const GLuint values[4])
{
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
mState.vertexAttribute[index].mCurrentValue.UnsignedIntValues[0] = values[0];
mState.vertexAttribute[index].mCurrentValue.UnsignedIntValues[1] = values[1];
mState.vertexAttribute[index].mCurrentValue.UnsignedIntValues[2] = values[2];
mState.vertexAttribute[index].mCurrentValue.UnsignedIntValues[3] = values[3];
mState.vertexAttribute[index].mCurrentValue.Type = GL_UNSIGNED_INT;
mState.vertexAttribute[index].mPureInteger = true;
mState.vertexAttribCurrentValues[index].setUnsignedIntValues(values);
}
void Context::setVertexAttribi(GLuint index, const GLint values[4])
{
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
mState.vertexAttribute[index].mCurrentValue.IntValues[0] = values[0];
mState.vertexAttribute[index].mCurrentValue.IntValues[1] = values[1];
mState.vertexAttribute[index].mCurrentValue.IntValues[2] = values[2];
mState.vertexAttribute[index].mCurrentValue.IntValues[3] = values[3];
mState.vertexAttribute[index].mCurrentValue.Type = GL_INT;
mState.vertexAttribute[index].mPureInteger = true;
mState.vertexAttribCurrentValues[index].setIntValues(values);
}
void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
......
......@@ -114,7 +114,9 @@ struct State
BindingPointer<Renderbuffer> renderbuffer;
GLuint currentProgram;
VertexAttribCurrentValueData vertexAttribCurrentValues[MAX_VERTEX_ATTRIBS]; // From glVertexAttrib
VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];
......@@ -227,7 +229,8 @@ class Context
GLuint getActiveQuery(GLenum target) const;
void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
const VertexAttribute &getVertexAttribState(unsigned int attribNum);
const VertexAttribute &getVertexAttribState(unsigned int attribNum) const;
const VertexAttribCurrentValueData &getVertexAttribCurrentValue(unsigned int attribNum) const;
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
const void *getVertexAttribPointer(unsigned int attribNum) const;
......
......@@ -21,11 +21,6 @@ class VertexAttribute
VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mPureInteger(false),
mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0)
{
mCurrentValue.FloatValues[0] = 0.0f;
mCurrentValue.FloatValues[1] = 0.0f;
mCurrentValue.FloatValues[2] = 0.0f;
mCurrentValue.FloatValues[3] = 1.0f;
mCurrentValue.Type = GL_FLOAT;
}
int typeSize() const
......@@ -67,20 +62,45 @@ class VertexAttribute
BindingPointer<Buffer> mBoundBuffer; // Captured when glVertexAttribPointer is called.
bool mArrayEnabled; // From glEnable/DisableVertexAttribArray
unsigned int mDivisor;
};
struct CurrentValueData
struct VertexAttribCurrentValueData
{
union
{
union
{
GLfloat FloatValues[4];
GLint IntValues[4];
GLuint UnsignedIntValues[4];
};
GLenum Type;
GLfloat FloatValues[4];
GLint IntValues[4];
GLuint UnsignedIntValues[4];
};
CurrentValueData mCurrentValue; // From glVertexAttrib
GLenum Type;
unsigned int mDivisor;
void setFloatValues(const GLfloat floatValues[4])
{
for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++)
{
FloatValues[valueIndex] = floatValues[valueIndex];
}
Type = GL_FLOAT;
}
void setIntValues(const GLint intValues[4])
{
for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++)
{
IntValues[valueIndex] = intValues[valueIndex];
}
Type = GL_INT;
}
void setUnsignedIntValues(const GLuint unsignedIntValues[4])
{
for (unsigned int valueIndex = 0; valueIndex < 4; valueIndex++)
{
UnsignedIntValues[valueIndex] = unsignedIntValues[valueIndex];
}
Type = GL_UNSIGNED_INT;
}
};
}
......
......@@ -5878,9 +5878,12 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
*params = (GLfloat)attribState.mBoundBuffer.id();
break;
case GL_CURRENT_VERTEX_ATTRIB:
for (int i = 0; i < 4; ++i)
{
params[i] = attribState.mCurrentValue.FloatValues[i];
const gl::VertexAttribCurrentValueData &currentValueData = context->getVertexAttribCurrentValue(index);
for (int i = 0; i < 4; ++i)
{
params[i] = currentValueData.FloatValues[i];
}
}
break;
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
......@@ -5936,10 +5939,13 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
*params = attribState.mBoundBuffer.id();
break;
case GL_CURRENT_VERTEX_ATTRIB:
for (int i = 0; i < 4; ++i)
{
float currentValue = attribState.mCurrentValue.FloatValues[i];
params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
const gl::VertexAttribCurrentValueData &currentValueData = context->getVertexAttribCurrentValue(index);
for (int i = 0; i < 4; ++i)
{
float currentValue = currentValueData.FloatValues[i];
params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
}
}
break;
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
......
......@@ -79,6 +79,9 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M
BufferStorage11 *bufferStorage = attributes[i].storage ? BufferStorage11::makeBufferStorage11(attributes[i].storage) : NULL;
D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
DXGI_FORMAT dxgiFormat = attributes[i].attribute->mArrayEnabled ?
VertexBuffer11::getAttributeDXGIFormat(*attributes[i].attribute) :
VertexBuffer11::getCurrentValueDXGIFormat(attributes[i].currentValueType);
// Record the type of the associated vertex shader vector in our key
// This will prevent mismatched vertex shaders from using the same input layout
......@@ -87,7 +90,7 @@ GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::M
ilKey.elements[ilKey.elementCount].SemanticName = semanticName;
ilKey.elements[ilKey.elementCount].SemanticIndex = sortedSemanticIndices[i];
ilKey.elements[ilKey.elementCount].Format = vertexBuffer->getDXGIFormat(*attributes[i].attribute);
ilKey.elements[ilKey.elementCount].Format = dxgiFormat;
ilKey.elements[ilKey.elementCount].InputSlot = i;
ilKey.elements[ilKey.elementCount].AlignedByteOffset = 0;
ilKey.elements[ilKey.elementCount].InputSlotClass = inputClass;
......
......@@ -43,6 +43,7 @@ class VertexAttribute;
class Buffer;
class Texture;
class Framebuffer;
struct VertexAttribCurrentValueData;
}
namespace rx
......@@ -130,7 +131,8 @@ class Renderer
virtual void applyShaders(gl::ProgramBinary *programBinary) = 0;
virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) = 0;
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) = 0;
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances) = 0;
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances) = 0;
......
......@@ -1034,10 +1034,11 @@ bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
return true;
}
GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances);
GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
if (err != GL_NO_ERROR)
{
return err;
......
......@@ -74,7 +74,8 @@ class Renderer11 : public Renderer
virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
virtual void applyShaders(gl::ProgramBinary *programBinary);
virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances);
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
......
......@@ -1338,10 +1338,11 @@ bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
return true;
}
GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances)
{
TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances);
GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, currentValues, programBinary, first, count, attributes, instances);
if (err != GL_NO_ERROR)
{
return err;
......
......@@ -88,7 +88,8 @@ class Renderer9 : public Renderer
virtual void applyShaders(gl::ProgramBinary *programBinary);
virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], gl::VertexAttribCurrentValueData currentValues[],
GLint first, GLsizei count, GLsizei instances);
virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
......
......@@ -87,7 +87,8 @@ bool VertexBufferInterface::discard()
return mVertexBuffer->discard();
}
int VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
int VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
GLint start, GLsizei count, GLsizei instances)
{
if (!reserveSpace(mReservedSpace))
{
......@@ -95,7 +96,7 @@ int VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attr
}
mReservedSpace = 0;
if (!mVertexBuffer->storeVertexAttributes(attrib, start, count, instances, mWritePosition))
if (!mVertexBuffer->storeVertexAttributes(attrib, currentValue, start, count, instances, mWritePosition))
{
return -1;
}
......@@ -194,13 +195,14 @@ bool StaticVertexBufferInterface::reserveSpace(unsigned int size)
}
}
int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
GLint start, GLsizei count, GLsizei instances)
{
int attributeOffset = attrib.mOffset % attrib.stride();
VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attrib.mPureInteger, attributeOffset, getWritePosition() };
mCache.push_back(element);
return VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances);
return VertexBufferInterface::storeVertexAttributes(attrib, currentValue, start, count, instances);
}
}
......@@ -15,6 +15,7 @@
namespace gl
{
class VertexAttribute;
struct VertexAttribCurrentValueData;
}
namespace rx
......@@ -29,12 +30,13 @@ class VertexBuffer
virtual bool initialize(unsigned int size, bool dynamicUsage) = 0;
virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count,
GLsizei instances, unsigned int offset) = 0;
virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
GLint start, GLsizei count, GLsizei instances, unsigned int offset) = 0;
virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
GLsizei instances) const = 0;
virtual bool requiresConversion(const gl::VertexAttribute &attrib) const = 0;
virtual bool requiresConversion(const gl::VertexAttribCurrentValueData &currentValue) const = 0;
virtual unsigned int getBufferSize() const = 0;
virtual bool setBufferSize(unsigned int size) = 0;
......@@ -64,7 +66,8 @@ class VertexBufferInterface
unsigned int getSerial() const;
virtual int storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances);
virtual int storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
GLint start, GLsizei count, GLsizei instances);
VertexBuffer* getVertexBuffer() const;
......@@ -106,7 +109,8 @@ class StaticVertexBufferInterface : public VertexBufferInterface
explicit StaticVertexBufferInterface(rx::Renderer *renderer);
~StaticVertexBufferInterface();
int storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances);
int storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
GLint start, GLsizei count, GLsizei instances);
// Returns the offset into the vertex buffer, or -1 if not found
int lookupAttribute(const gl::VertexAttribute &attribute);
......
......@@ -14,6 +14,46 @@
#include "libGLESv2/renderer/Renderer11.h"
#include "libGLESv2/VertexAttribute.h"
namespace
{
unsigned int GetIntegerTypeIndex(GLenum type)
{
switch (type)
{
case GL_BYTE: return 0;
case GL_UNSIGNED_BYTE: return 1;
case GL_SHORT: return 2;
case GL_UNSIGNED_SHORT: return 3;
case GL_INT: return 4;
case GL_UNSIGNED_INT: return 5;
case GL_INT_2_10_10_10_REV: return 6;
case GL_UNSIGNED_INT_2_10_10_10_REV: return 7;
default: UNREACHABLE(); return 0;
}
}
unsigned int GetFloatTypeIndex(GLenum type)
{
switch (type)
{
case GL_BYTE: return 0;
case GL_UNSIGNED_BYTE: return 1;
case GL_SHORT: return 2;
case GL_UNSIGNED_SHORT: return 3;
case GL_INT: return 4;
case GL_UNSIGNED_INT: return 5;
case GL_INT_2_10_10_10_REV: return 6;
case GL_UNSIGNED_INT_2_10_10_10_REV: return 7;
case GL_FIXED: return 8;
case GL_HALF_FLOAT: return 9;
case GL_FLOAT: return 10;
default: UNREACHABLE(); return 0;
}
}
}
namespace rx
{
......@@ -73,15 +113,17 @@ VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
return static_cast<VertexBuffer11*>(vetexBuffer);
}
bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count,
GLsizei instances, unsigned int offset)
bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
GLint start, GLsizei count, GLsizei instances, unsigned int offset)
{
if (mBuffer)
{
gl::Buffer *buffer = attrib.mBoundBuffer.get();
int inputStride = attrib.stride();
const VertexConverter &converter = getVertexConversion(attrib);
const VertexConverter &converter = attrib.mArrayEnabled ?
getVertexConversion(attrib) :
getVertexConversion(currentValue.Type, currentValue.Type != GL_FLOAT, false, 4);
ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
......@@ -110,7 +152,7 @@ bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, GL
}
else
{
input = reinterpret_cast<const char*>(attrib.mCurrentValue.FloatValues);
input = reinterpret_cast<const char*>(currentValue.FloatValues);
}
if (instances == 0 || attrib.mDivisor == 0)
......@@ -135,10 +177,10 @@ bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, GL
unsigned int VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
GLsizei instances) const
{
unsigned int elementSize = getVertexConversion(attrib).outputElementSize;
if (attrib.mArrayEnabled)
{
unsigned int elementSize = getVertexConversion(attrib).outputElementSize;
if (instances == 0 || attrib.mDivisor == 0)
{
return elementSize * count;
......@@ -150,6 +192,7 @@ unsigned int VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib,
}
else
{
unsigned int elementSize = 4;
return elementSize * 4;
}
}
......@@ -159,6 +202,11 @@ bool VertexBuffer11::requiresConversion(const gl::VertexAttribute &attrib) const
return !getVertexConversion(attrib).identity;
}
bool VertexBuffer11::requiresConversion(const gl::VertexAttribCurrentValueData &currentValue) const
{
return !getVertexConversion(currentValue.Type, currentValue.Type != GL_FLOAT, false, 4).identity;
}
unsigned int VertexBuffer11::getBufferSize() const
{
return mBufferSize;
......@@ -201,14 +249,22 @@ bool VertexBuffer11::discard()
}
}
unsigned int VertexBuffer11::getVertexSize(const gl::VertexAttribute &attrib) const
DXGI_FORMAT VertexBuffer11::getAttributeDXGIFormat(const gl::VertexAttribute &attrib)
{
return getVertexConversion(attrib).outputElementSize;
return getVertexConversion(attrib).dxgiFormat;
}
DXGI_FORMAT VertexBuffer11::getDXGIFormat(const gl::VertexAttribute &attrib) const
DXGI_FORMAT VertexBuffer11::getCurrentValueDXGIFormat(GLenum currentValueType)
{
return getVertexConversion(attrib).dxgiFormat;
if (currentValueType == GL_FLOAT)
{
return mFloatVertexTranslations[GetFloatTypeIndex(GL_FLOAT)][0][3].dxgiFormat;
}
else
{
ASSERT(currentValueType == GL_INT || currentValueType == GL_UNSIGNED_INT);
return mIntegerVertexTranslations[GetIntegerTypeIndex(currentValueType)][3].dxgiFormat;
}
}
ID3D11Buffer *VertexBuffer11::getBuffer() const
......@@ -722,45 +778,20 @@ const VertexBuffer11::VertexConverter VertexBuffer11::mIntegerVertexTranslations
const VertexBuffer11::VertexConverter &VertexBuffer11::getVertexConversion(const gl::VertexAttribute &attribute)
{
GLenum type = attribute.mArrayEnabled ? attribute.mType : attribute.mCurrentValue.Type;
if (attribute.mPureInteger)
{
unsigned int typeIndex = 0;
switch (type)
{
case GL_BYTE: typeIndex = 0; break;
case GL_UNSIGNED_BYTE: typeIndex = 1; break;
case GL_SHORT: typeIndex = 2; break;
case GL_UNSIGNED_SHORT: typeIndex = 3; break;
case GL_INT: typeIndex = 4; break;
case GL_UNSIGNED_INT: typeIndex = 5; break;
case GL_INT_2_10_10_10_REV: typeIndex = 6; break;
case GL_UNSIGNED_INT_2_10_10_10_REV: typeIndex = 7; break;
default: UNREACHABLE(); break;
}
return getVertexConversion(attribute.mType, attribute.mPureInteger, attribute.mNormalized, attribute.mSize);
}
return mIntegerVertexTranslations[typeIndex][attribute.mSize - 1];
const VertexBuffer11::VertexConverter &VertexBuffer11::getVertexConversion(GLenum type, bool pureInteger, bool normalized, int size)
{
if (pureInteger)
{
const unsigned int typeIndex = GetIntegerTypeIndex(type);
return mIntegerVertexTranslations[typeIndex][size - 1];
}
else
{
unsigned int typeIndex = 0;
switch (type)
{
case GL_BYTE: typeIndex = 0; break;
case GL_UNSIGNED_BYTE: typeIndex = 1; break;
case GL_SHORT: typeIndex = 2; break;
case GL_UNSIGNED_SHORT: typeIndex = 3; break;
case GL_INT: typeIndex = 4; break;
case GL_UNSIGNED_INT: typeIndex = 5; break;
case GL_INT_2_10_10_10_REV: typeIndex = 6; break;
case GL_UNSIGNED_INT_2_10_10_10_REV: typeIndex = 7; break;
case GL_FIXED: typeIndex = 8; break;
case GL_HALF_FLOAT: typeIndex = 9; break;
case GL_FLOAT: typeIndex = 10; break;
default: UNREACHABLE(); break;
}
return mFloatVertexTranslations[typeIndex][attribute.mNormalized ? 1 : 0][attribute.mSize - 1];
const unsigned int typeIndex = GetFloatTypeIndex(type);
return mFloatVertexTranslations[typeIndex][normalized ? 1 : 0][size - 1];
}
}
......
......@@ -25,19 +25,20 @@ class VertexBuffer11 : public VertexBuffer
static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer);
virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances,
unsigned int offset);
virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
GLint start, GLsizei count, GLsizei instances, unsigned int offset);
virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) const;
virtual bool requiresConversion(const gl::VertexAttribute &attrib) const;
virtual bool requiresConversion(const gl::VertexAttribCurrentValueData &currentValue) const;
virtual unsigned int getBufferSize() const;
virtual bool setBufferSize(unsigned int size);
virtual bool discard();
unsigned int getVertexSize(const gl::VertexAttribute &attrib) const;
DXGI_FORMAT getDXGIFormat(const gl::VertexAttribute &attrib) const;
static DXGI_FORMAT getAttributeDXGIFormat(const gl::VertexAttribute &attrib);
static DXGI_FORMAT getCurrentValueDXGIFormat(GLenum currentValueType);
ID3D11Buffer *getBuffer() const;
......@@ -66,6 +67,7 @@ class VertexBuffer11 : public VertexBuffer
static const VertexConverter mIntegerVertexTranslations[NUM_GL_INTEGER_VERTEX_ATTRIB_TYPES][4]; // [GL types as enumerated by typeIndex()][size - 1]
static const VertexConverter &getVertexConversion(const gl::VertexAttribute &attribute);
static const VertexConverter &getVertexConversion(GLenum type, bool pureInteger, bool normalized, int size);
};
}
......
......@@ -81,8 +81,8 @@ VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer)
return static_cast<VertexBuffer9*>(vertexBuffer);
}
bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count,
GLsizei instances, unsigned int offset)
bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
GLint start, GLsizei count, GLsizei instances, unsigned int offset)
{
if (mVertexBuffer)
{
......@@ -118,7 +118,7 @@ bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, GLi
}
else
{
input = reinterpret_cast<const char*>(attrib.mCurrentValue.FloatValues);
input = reinterpret_cast<const char*>(currentValue.FloatValues);
}
if (instances == 0 || attrib.mDivisor == 0)
......@@ -156,9 +156,10 @@ bool VertexBuffer9::requiresConversion(const gl::VertexAttribute &attrib) const
return formatConverter(attrib).identity;
}
unsigned int VertexBuffer9::getVertexSize(const gl::VertexAttribute &attrib) const
bool VertexBuffer9::requiresConversion(const gl::VertexAttribCurrentValueData &currentValue) const
{
return spaceRequired(attrib, 1, 0);
ASSERT(currentValue.Type == GL_FLOAT);
return getCurrentValueFormatConverter().identity;
}
D3DDECLTYPE VertexBuffer9::getDeclType(const gl::VertexAttribute &attrib) const
......@@ -445,11 +446,19 @@ unsigned int VertexBuffer9::typeIndex(GLenum type)
const VertexBuffer9::FormatConverter &VertexBuffer9::formatConverter(const gl::VertexAttribute &attribute)
{
if (!attribute.mArrayEnabled)
{
return getCurrentValueFormatConverter();
}
// Pure integer attributes only supported in ES3.0
ASSERT(!attribute.mPureInteger);
return mFormatConverters[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1];
}
GLenum type = attribute.mArrayEnabled ? attribute.mType : attribute.mCurrentValue.Type;
return mFormatConverters[typeIndex(type)][attribute.mNormalized][attribute.mSize - 1];
const VertexBuffer9::FormatConverter &VertexBuffer9::getCurrentValueFormatConverter()
{
return mFormatConverters[typeIndex(GL_FLOAT)][0][3];
}
unsigned int VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances)
......
......@@ -25,14 +25,14 @@ class VertexBuffer9 : public VertexBuffer
static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer);
virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances,
unsigned int offset);
virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue,
GLint start, GLsizei count, GLsizei instances, unsigned int offset);
virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) const;
virtual bool requiresConversion(const gl::VertexAttribute &attrib) const;
virtual bool requiresConversion(const gl::VertexAttribCurrentValueData &currentValue) const;
unsigned int getVertexSize(const gl::VertexAttribute &attrib) const;
D3DDECLTYPE getDeclType(const gl::VertexAttribute &attrib) const;
virtual unsigned int getBufferSize() const;
......@@ -80,6 +80,7 @@ class VertexBuffer9 : public VertexBuffer
static unsigned int typeIndex(GLenum type);
static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute);
static const FormatConverter &getCurrentValueFormatConverter();
static unsigned int spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances);
};
......
......@@ -26,12 +26,25 @@ namespace
namespace rx
{
static int elementsInBuffer(const gl::VertexAttribute &attribute, int size)
static int ElementsInBuffer(const gl::VertexAttribute &attribute, int size)
{
int stride = attribute.stride();
return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride;
}
static bool DirectStoragePossible(VertexBufferInterface *vb, const gl::VertexAttribute &attrib, const gl::VertexAttribCurrentValueData &currentValue)
{
gl::Buffer *buffer = attrib.mBoundBuffer.get();
BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
const bool isAligned = (attrib.stride() % 4 == 0) && (attrib.mOffset % 4 == 0);
const bool requiresConversion = attrib.mArrayEnabled ?
vb->getVertexBuffer()->requiresConversion(attrib) :
vb->getVertexBuffer()->requiresConversion(currentValue);
return storage && storage->supportsDirectBinding() && !requiresConversion && isAligned;
}
VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer)
{
for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
......@@ -63,17 +76,8 @@ VertexDataManager::~VertexDataManager()
}
}
static bool directStoragePossible(VertexBufferInterface* vb, const gl::VertexAttribute& attrib)
{
gl::Buffer *buffer = attrib.mBoundBuffer.get();
BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
const bool isAligned = (attrib.stride() % 4 == 0) && (attrib.mOffset % 4 == 0);
return storage && storage->supportsDirectBinding() && !vb->getVertexBuffer()->requiresConversion(attrib) && isAligned;
}
GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
{
if (!mStreamingBuffer)
{
......@@ -94,7 +98,7 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[],
StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
if (staticBuffer && staticBuffer->getBufferSize() > 0 && staticBuffer->lookupAttribute(attribs[i]) == -1 &&
!directStoragePossible(staticBuffer, attribs[i]))
!DirectStoragePossible(staticBuffer, attribs[i], currentValues[i]))
{
buffer->invalidateStaticData();
}
......@@ -110,13 +114,13 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[],
StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
if (!directStoragePossible(vertexBuffer, attribs[i]))
if (!DirectStoragePossible(vertexBuffer, attribs[i], currentValues[i]))
{
if (staticBuffer)
{
if (staticBuffer->getBufferSize() == 0)
{
int totalCount = elementsInBuffer(attribs[i], buffer->size());
int totalCount = ElementsInBuffer(attribs[i], buffer->size());
staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0);
}
}
......@@ -148,7 +152,7 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[],
VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
bool directStorage = directStoragePossible(vertexBuffer, attribs[i]);
bool directStorage = DirectStoragePossible(vertexBuffer, attribs[i], currentValues[i]);
std::size_t streamOffset = -1;
unsigned int outputElementSize = 0;
......@@ -166,10 +170,10 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[],
if (streamOffset == -1)
{
// Convert the entire buffer
int totalCount = elementsInBuffer(attribs[i], storage->getSize());
int totalCount = ElementsInBuffer(attribs[i], storage->getSize());
int startIndex = attribs[i].mOffset / attribs[i].stride();
streamOffset = staticBuffer->storeVertexAttributes(attribs[i], -startIndex, totalCount, 0);
streamOffset = staticBuffer->storeVertexAttributes(attribs[i], currentValues[i], -startIndex, totalCount, 0);
}
if (streamOffset != -1)
......@@ -185,7 +189,7 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[],
else
{
outputElementSize = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0);
streamOffset = mStreamingBuffer->storeVertexAttributes(attribs[i], start, count, instances);
streamOffset = mStreamingBuffer->storeVertexAttributes(attribs[i], currentValues[i], start, count, instances);
}
if (streamOffset == -1)
......@@ -199,6 +203,7 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[],
translated[i].divisor = attribs[i].mDivisor;
translated[i].attribute = &attribs[i];
translated[i].currentValueType = currentValues[i].Type;
translated[i].stride = outputElementSize;
translated[i].offset = streamOffset;
}
......@@ -211,10 +216,10 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[],
StreamingVertexBufferInterface *buffer = mCurrentValueBuffer[i];
if (memcmp(&mCurrentValue[i], &attribs[i].mCurrentValue, sizeof(gl::VertexAttribute::CurrentValueData)) != 0)
if (memcmp(&mCurrentValue[i], &currentValues[i], sizeof(gl::VertexAttribCurrentValueData)) != 0)
{
buffer->reserveVertexSpace(attribs[i], 1, 0);
int streamOffset = buffer->storeVertexAttributes(attribs[i], 0, 1, 0);
int streamOffset = buffer->storeVertexAttributes(attribs[i], currentValues[i], 0, 1, 0);
if (streamOffset == -1)
{
return GL_OUT_OF_MEMORY;
......@@ -229,6 +234,7 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[],
translated[i].divisor = 0;
translated[i].attribute = &attribs[i];
translated[i].currentValueType = currentValues[i].Type;
translated[i].stride = 0;
translated[i].offset = mCurrentValueOffsets[i];
}
......
......@@ -32,6 +32,7 @@ struct TranslatedAttribute
bool active;
const gl::VertexAttribute *attribute;
GLenum currentValueType;
UINT offset;
UINT stride; // 0 means not to advance the read pointer at all
......@@ -47,7 +48,8 @@ class VertexDataManager
VertexDataManager(rx::Renderer *renderer);
virtual ~VertexDataManager();
GLenum prepareVertexData(const gl::VertexAttribute attribs[], gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances);
GLenum prepareVertexData(const gl::VertexAttribute attribs[], const gl::VertexAttribCurrentValueData currentValues[],
gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances);
private:
DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
......@@ -56,7 +58,7 @@ class VertexDataManager
StreamingVertexBufferInterface *mStreamingBuffer;
gl::VertexAttribute::CurrentValueData mCurrentValue[gl::MAX_VERTEX_ATTRIBS];
gl::VertexAttribCurrentValueData mCurrentValue[gl::MAX_VERTEX_ATTRIBS];
StreamingVertexBufferInterface *mCurrentValueBuffer[gl::MAX_VERTEX_ATTRIBS];
std::size_t mCurrentValueOffsets[gl::MAX_VERTEX_ATTRIBS];
......
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