Hash :
cf9383ed
Author :
Date :
2019-01-31T19:52:49
Optimize VertexArray::bindVertexBufferImpl. Reduces the buffer nullptr checks to a single location. Also optimizes how the transform feedback binding counter is changed. Improves the score of the draw call vertex array change test. Bug: angleproject:3014 Change-Id: I08ff341e08194a407c24143965a3d568e92b97b7 Reviewed-on: https://chromium-review.googlesource.com/c/1406891 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
//
// Copyright (c) 2013 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.
//
// Helper structures about Generic Vertex Attribute.
//
#ifndef LIBANGLE_VERTEXATTRIBUTE_H_
#define LIBANGLE_VERTEXATTRIBUTE_H_
#include "libANGLE/Buffer.h"
#include "libANGLE/angletypes.h"
namespace gl
{
class VertexArray;
//
// Implementation of Generic Vertex Attribute Bindings for ES3.1. The members are intentionally made
// private in order to hide implementation details.
//
class VertexBinding final : angle::NonCopyable
{
public:
VertexBinding();
explicit VertexBinding(GLuint boundAttribute);
VertexBinding(VertexBinding &&binding);
~VertexBinding();
VertexBinding &operator=(VertexBinding &&binding);
GLuint getStride() const { return mStride; }
void setStride(GLuint strideIn) { mStride = strideIn; }
GLuint getDivisor() const { return mDivisor; }
void setDivisor(GLuint divisorIn) { mDivisor = divisorIn; }
GLintptr getOffset() const { return mOffset; }
void setOffset(GLintptr offsetIn) { mOffset = offsetIn; }
const BindingPointer<Buffer> &getBuffer() const { return mBuffer; }
ANGLE_INLINE void setBuffer(const gl::Context *context, Buffer *bufferIn)
{
mBuffer.set(context, bufferIn);
}
// Skips ref counting for better inlined performance.
ANGLE_INLINE void assignBuffer(Buffer *bufferIn) { mBuffer.assign(bufferIn); }
void onContainerBindingChanged(const Context *context, int incr) const;
const AttributesMask &getBoundAttributesMask() const { return mBoundAttributesMask; }
void setBoundAttribute(size_t index) { mBoundAttributesMask.set(index); }
void resetBoundAttribute(size_t index) { mBoundAttributesMask.reset(index); }
private:
GLuint mStride;
GLuint mDivisor;
GLintptr mOffset;
BindingPointer<Buffer> mBuffer;
// Mapping from this binding to all of the attributes that are using this binding.
AttributesMask mBoundAttributesMask;
};
//
// Implementation of Generic Vertex Attributes for ES3.1
//
struct VertexAttribute final : private angle::NonCopyable
{
explicit VertexAttribute(GLuint bindingIndex);
VertexAttribute(VertexAttribute &&attrib);
VertexAttribute &operator=(VertexAttribute &&attrib);
// Called from VertexArray.
void updateCachedElementLimit(const VertexBinding &binding);
GLint64 getCachedElementLimit() const { return mCachedElementLimit; }
bool enabled; // For glEnable/DisableVertexAttribArray
VertexAttribType type;
GLuint size;
bool normalized;
bool pureInteger;
const void *pointer;
GLuint relativeOffset;
GLuint vertexAttribArrayStride; // ONLY for queries of VERTEX_ATTRIB_ARRAY_STRIDE
GLuint bindingIndex;
// Special value for the cached element limit on the integer overflow case.
static constexpr GLint64 kIntegerOverflow = std::numeric_limits<GLint64>::min();
private:
// This is kept in sync by the VertexArray. It is used to optimize draw call validation.
GLint64 mCachedElementLimit;
};
ANGLE_INLINE size_t ComputeVertexAttributeTypeSize(const VertexAttribute &attrib)
{
switch (attrib.type)
{
case VertexAttribType::Byte:
return attrib.size * sizeof(GLbyte);
case VertexAttribType::UnsignedByte:
return attrib.size * sizeof(GLubyte);
case VertexAttribType::Short:
return attrib.size * sizeof(GLshort);
case VertexAttribType::UnsignedShort:
return attrib.size * sizeof(GLushort);
case VertexAttribType::Int:
return attrib.size * sizeof(GLint);
case VertexAttribType::UnsignedInt:
return attrib.size * sizeof(GLuint);
case VertexAttribType::Float:
return attrib.size * sizeof(GLfloat);
case VertexAttribType::HalfFloat:
return attrib.size * sizeof(GLhalf);
case VertexAttribType::Fixed:
return attrib.size * sizeof(GLfixed);
case VertexAttribType::Int2101010:
// Packed attribute types don't scale by their component size.
return 4;
case VertexAttribType::UnsignedInt2101010:
// Packed attribute types don't scale by their component size.
return 4;
default:
UNREACHABLE();
return 0;
}
}
// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
size_t ComputeVertexAttributeStride(const VertexAttribute &attrib, const VertexBinding &binding);
// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
GLintptr ComputeVertexAttributeOffset(const VertexAttribute &attrib, const VertexBinding &binding);
size_t ComputeVertexBindingElementCount(GLuint divisor, size_t drawCount, size_t instanceCount);
struct VertexAttribCurrentValueData
{
union
{
GLfloat FloatValues[4];
GLint IntValues[4];
GLuint UnsignedIntValues[4];
};
VertexAttribType Type;
VertexAttribCurrentValueData();
void setFloatValues(const GLfloat floatValues[4]);
void setIntValues(const GLint intValues[4]);
void setUnsignedIntValues(const GLuint unsignedIntValues[4]);
};
bool operator==(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b);
bool operator!=(const VertexAttribCurrentValueData &a, const VertexAttribCurrentValueData &b);
} // namespace gl
#include "VertexAttribute.inl"
#endif // LIBANGLE_VERTEXATTRIBUTE_H_