зеркало из https://github.com/AvaloniaUI/angle.git
Fix support for GL_MAX_ATTRIBS attributes.
*re-land with fix for AMD/ES2/OpenGL.* An off-by-one bug slipped in that broke support for these edge case shaders. Bug introduced in https://chromium-review.googlesource.com/#/c/266928/ BUG=angleproject:1045 BUG=500116 Change-Id: If44f809d432221d1e17afc407d49e87e0cb7504c Reviewed-on: https://chromium-review.googlesource.com/277664 Tested-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>
This commit is contained in:
Родитель
464a6b8bb7
Коммит
8e695edb8b
|
@ -1291,7 +1291,7 @@ bool Program::linkAttributes(const Data &data,
|
||||||
GLuint maxAttribs = data.caps->maxVertexAttributes;
|
GLuint maxAttribs = data.caps->maxVertexAttributes;
|
||||||
|
|
||||||
// TODO(jmadill): handle aliasing robustly
|
// TODO(jmadill): handle aliasing robustly
|
||||||
if (shaderAttributes.size() >= maxAttribs)
|
if (shaderAttributes.size() > maxAttribs)
|
||||||
{
|
{
|
||||||
infoLog << "Too many vertex attributes.";
|
infoLog << "Too many vertex attributes.";
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -129,6 +129,51 @@ class VertexAttributeTest : public ANGLETest
|
||||||
ANGLETest::TearDown();
|
ANGLETest::TearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint compileMultiAttribProgram(GLint attribCount)
|
||||||
|
{
|
||||||
|
std::stringstream shaderStream;
|
||||||
|
|
||||||
|
shaderStream << "attribute highp vec4 position;" << std::endl;
|
||||||
|
for (GLint attribIndex = 0; attribIndex < attribCount; ++attribIndex)
|
||||||
|
{
|
||||||
|
shaderStream << "attribute float a" << attribIndex << ";" << std::endl;
|
||||||
|
}
|
||||||
|
shaderStream << "varying highp float color;" << std::endl
|
||||||
|
<< "void main() {" << std::endl
|
||||||
|
<< " gl_Position = position;" << std::endl
|
||||||
|
<< " color = 0.0;" << std::endl;
|
||||||
|
for (GLint attribIndex = 0; attribIndex < attribCount; ++attribIndex)
|
||||||
|
{
|
||||||
|
shaderStream << " color += a" << attribIndex << ";" << std::endl;
|
||||||
|
}
|
||||||
|
shaderStream << "}" << std::endl;
|
||||||
|
|
||||||
|
const std::string testFragmentShaderSource = SHADER_SOURCE
|
||||||
|
(
|
||||||
|
varying highp float color;
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(color, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return CompileProgram(shaderStream.str(), testFragmentShaderSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupMultiAttribs(GLuint program, GLint attribCount, GLfloat value)
|
||||||
|
{
|
||||||
|
glUseProgram(program);
|
||||||
|
for (GLint attribIndex = 0; attribIndex < attribCount; ++attribIndex)
|
||||||
|
{
|
||||||
|
std::stringstream attribStream;
|
||||||
|
attribStream << "a" << attribIndex;
|
||||||
|
GLint location = glGetAttribLocation(program, attribStream.str().c_str());
|
||||||
|
ASSERT_NE(-1, location);
|
||||||
|
glVertexAttrib1f(location, value);
|
||||||
|
glDisableVertexAttribArray(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const size_t mVertexCount = 24;
|
static const size_t mVertexCount = 24;
|
||||||
|
|
||||||
GLuint mProgram;
|
GLuint mProgram;
|
||||||
|
@ -240,6 +285,54 @@ TEST_P(VertexAttributeTest, ShortNormalized)
|
||||||
runTest(data);
|
runTest(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate that we can support GL_MAX_ATTRIBS attribs
|
||||||
|
TEST_P(VertexAttributeTest, MaxAttribs)
|
||||||
|
{
|
||||||
|
// TODO(jmadill): Figure out why we get this error on AMD/ES2/OpenGL
|
||||||
|
if (isAMD() && GetParam() == ES2_OPENGL())
|
||||||
|
{
|
||||||
|
std::cout << "Test disabled on AMD/ES2/OpenGL" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint maxAttribs;
|
||||||
|
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs);
|
||||||
|
ASSERT_GL_NO_ERROR();
|
||||||
|
|
||||||
|
// Reserve one attrib for position
|
||||||
|
GLint drawAttribs = maxAttribs - 1;
|
||||||
|
|
||||||
|
GLuint program = compileMultiAttribProgram(drawAttribs);
|
||||||
|
ASSERT_NE(0u, program);
|
||||||
|
|
||||||
|
setupMultiAttribs(program, drawAttribs, 0.5f / static_cast<float>(drawAttribs));
|
||||||
|
drawQuad(program, "position", 0.5f);
|
||||||
|
|
||||||
|
EXPECT_GL_NO_ERROR();
|
||||||
|
EXPECT_PIXEL_NEAR(0, 0, 128, 0, 0, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate that we cannot support GL_MAX_ATTRIBS+1 attribs
|
||||||
|
TEST_P(VertexAttributeTest, MaxAttribsPlusOne)
|
||||||
|
{
|
||||||
|
// TODO(jmadill): Figure out why we get this error on AMD/ES2/OpenGL
|
||||||
|
if (isAMD() && GetParam() == ES2_OPENGL())
|
||||||
|
{
|
||||||
|
std::cout << "Test disabled on AMD/ES2/OpenGL" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint maxAttribs;
|
||||||
|
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs);
|
||||||
|
ASSERT_GL_NO_ERROR();
|
||||||
|
|
||||||
|
// Exceed attrib count by one (counting position)
|
||||||
|
GLint drawAttribs = maxAttribs;
|
||||||
|
|
||||||
|
GLuint program = compileMultiAttribProgram(drawAttribs);
|
||||||
|
ASSERT_EQ(0u, program);
|
||||||
|
}
|
||||||
|
|
||||||
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
|
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
|
||||||
// D3D11 Feature Level 9_3 uses different D3D formats for vertex attribs compared to Feature Levels 10_0+, so we should test them separately.
|
// D3D11 Feature Level 9_3 uses different D3D formats for vertex attribs compared to Feature Levels 10_0+, so we should test them separately.
|
||||||
ANGLE_INSTANTIATE_TEST(VertexAttributeTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3(), ES2_OPENGL(), ES3_OPENGL());
|
ANGLE_INSTANTIATE_TEST(VertexAttributeTest, ES2_D3D9(), ES2_D3D11(), ES2_D3D11_FL9_3(), ES2_OPENGL(), ES3_OPENGL());
|
||||||
|
|
|
@ -42,6 +42,13 @@ bool operator<(const PlatformParameters &a, const PlatformParameters &b)
|
||||||
return a.eglParameters < b.eglParameters;
|
return a.eglParameters < b.eglParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const PlatformParameters &a, const PlatformParameters &b)
|
||||||
|
{
|
||||||
|
return (a.majorVersion == b.majorVersion) &&
|
||||||
|
(a.minorVersion == b.minorVersion) &&
|
||||||
|
(a.eglParameters == b.eglParameters);
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream& stream, const PlatformParameters &pp)
|
std::ostream &operator<<(std::ostream& stream, const PlatformParameters &pp)
|
||||||
{
|
{
|
||||||
stream << "ES" << pp.majorVersion << "_" ;
|
stream << "ES" << pp.majorVersion << "_" ;
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct PlatformParameters
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator<(const PlatformParameters &a, const PlatformParameters &b);
|
bool operator<(const PlatformParameters &a, const PlatformParameters &b);
|
||||||
|
bool operator==(const PlatformParameters &a, const PlatformParameters &b);
|
||||||
std::ostream &operator<<(std::ostream& stream, const PlatformParameters &pp);
|
std::ostream &operator<<(std::ostream& stream, const PlatformParameters &pp);
|
||||||
|
|
||||||
// EGL platforms
|
// EGL platforms
|
||||||
|
|
|
@ -67,6 +67,14 @@ bool operator<(const EGLPlatformParameters &a, const EGLPlatformParameters &b)
|
||||||
return a.deviceType < b.deviceType;
|
return a.deviceType < b.deviceType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator==(const EGLPlatformParameters &a, const EGLPlatformParameters &b)
|
||||||
|
{
|
||||||
|
return (a.renderer == b.renderer) &&
|
||||||
|
(a.majorVersion == b.majorVersion) &&
|
||||||
|
(a.minorVersion == b.minorVersion) &&
|
||||||
|
(a.deviceType == b.deviceType);
|
||||||
|
}
|
||||||
|
|
||||||
EGLWindow::EGLWindow(size_t width, size_t height, EGLint glesMajorVersion, const EGLPlatformParameters &platform)
|
EGLWindow::EGLWindow(size_t width, size_t height, EGLint glesMajorVersion, const EGLPlatformParameters &platform)
|
||||||
: mDisplay(EGL_NO_DISPLAY),
|
: mDisplay(EGL_NO_DISPLAY),
|
||||||
mSurface(EGL_NO_SURFACE),
|
mSurface(EGL_NO_SURFACE),
|
||||||
|
|
|
@ -44,6 +44,7 @@ struct EGLPlatformParameters
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator<(const EGLPlatformParameters &a, const EGLPlatformParameters &b);
|
bool operator<(const EGLPlatformParameters &a, const EGLPlatformParameters &b);
|
||||||
|
bool operator==(const EGLPlatformParameters &a, const EGLPlatformParameters &b);
|
||||||
|
|
||||||
class EGLWindow : angle::NonCopyable
|
class EGLWindow : angle::NonCopyable
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче