blob: f5a1643c6118e51efdc423555f1ef06a4c31af17 [file] [log] [blame]
/*-------------------------------------------------------------------------
* OpenGL Conformance Test Suite
* -----------------------------
*
* Copyright (c) 2014-2016 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/ /*!
* \file
* \brief
*/ /*-------------------------------------------------------------------*/
#include "gl4cVertexAttribBindingTests.hpp"
#include "glwEnums.hpp"
#include "tcuMatrix.hpp"
#include "tcuRenderTarget.hpp"
#include <cstdarg>
#include <cmath>
namespace gl4cts
{
using namespace glw;
using tcu::Vec4;
using tcu::IVec4;
using tcu::UVec4;
using tcu::DVec4;
using tcu::Vec3;
using tcu::IVec3;
using tcu::DVec3;
using tcu::Vec2;
using tcu::IVec2;
using tcu::UVec2;
using tcu::Mat4;
namespace
{
class VertexAttribBindingBase : public deqp::SubcaseBase
{
virtual std::string Title()
{
return NL "";
}
virtual std::string Purpose()
{
return NL "";
}
virtual std::string Method()
{
return NL "";
}
virtual std::string PassCriteria()
{
return NL "";
}
public:
int getWindowWidth()
{
const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
return renderTarget.getWidth();
}
int getWindowHeight()
{
const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
return renderTarget.getHeight();
}
inline bool ColorEqual(const Vec4& c0, const Vec4& c1, const Vec4& epsilon)
{
if (fabs(c0[0] - c1[0]) > epsilon[0])
return false;
if (fabs(c0[1] - c1[1]) > epsilon[1])
return false;
if (fabs(c0[2] - c1[2]) > epsilon[2])
return false;
if (fabs(c0[3] - c1[3]) > epsilon[3])
return false;
return true;
}
inline bool ColorEqual(const Vec3& c0, const Vec3& c1, const Vec4& epsilon)
{
if (fabs(c0[0] - c1[0]) > epsilon[0])
return false;
if (fabs(c0[1] - c1[1]) > epsilon[1])
return false;
if (fabs(c0[2] - c1[2]) > epsilon[2])
return false;
return true;
}
bool CheckRectColor(const std::vector<Vec3>& fb, int fb_w, int rx, int ry, int rw, int rh, const Vec3& expected)
{
const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
const tcu::PixelFormat& pixelFormat = renderTarget.getPixelFormat();
Vec4 g_color_eps = Vec4(
1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits),
1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits));
for (int y = ry; y < ry + rh; ++y)
{
for (int x = rx; x < rx + rw; ++x)
{
const int idx = y * fb_w + x;
if (!ColorEqual(fb[idx], expected, g_color_eps))
{
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "Incorrect framebuffer color at pixel (" << x << " " << y
<< "). Color is (" << fb[idx][0] << " " << fb[idx][1] << " " << fb[idx][2]
<< "). Color should be (" << expected[0] << " " << expected[1] << " " << expected[2] << ")"
<< tcu::TestLog::EndMessage;
return false;
}
}
}
return true;
}
bool CheckRectColor(const std::vector<Vec4>& fb, int fb_w, int rx, int ry, int rw, int rh, const Vec4& expected)
{
const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
const tcu::PixelFormat& pixelFormat = renderTarget.getPixelFormat();
Vec4 g_color_eps = Vec4(
1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits),
1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits));
for (int y = ry; y < ry + rh; ++y)
{
for (int x = rx; x < rx + rw; ++x)
{
const int idx = y * fb_w + x;
if (!ColorEqual(fb[idx], expected, g_color_eps))
{
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "Incorrect framebuffer color at pixel (" << x << " " << y
<< "). Color is (" << fb[idx][0] << " " << fb[idx][1] << " " << fb[idx][2] << " " << fb[idx][3]
<< "). Color should be (" << expected[0] << " " << expected[1] << " " << expected[2] << " "
<< expected[3] << ")" << tcu::TestLog::EndMessage;
return false;
}
}
}
return true;
}
bool CheckProgram(GLuint program)
{
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
GLint attached_shaders;
glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
if (attached_shaders > 0)
{
std::vector<GLuint> shaders(attached_shaders);
glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
for (GLint i = 0; i < attached_shaders; ++i)
{
GLenum type;
glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
switch (type)
{
case GL_VERTEX_SHADER:
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
break;
case GL_TESS_CONTROL_SHADER:
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "*** Tessellation Control Shader ***"
<< tcu::TestLog::EndMessage;
break;
case GL_TESS_EVALUATION_SHADER:
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
<< tcu::TestLog::EndMessage;
break;
case GL_GEOMETRY_SHADER:
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
break;
case GL_FRAGMENT_SHADER:
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
break;
case GL_COMPUTE_SHADER:
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
break;
default:
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
break;
}
GLint length;
glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
if (length > 0)
{
std::vector<GLchar> source(length);
glGetShaderSource(shaders[i], length, NULL, &source[0]);
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
}
glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
if (length > 0)
{
std::vector<GLchar> log(length);
glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
}
}
}
GLint length;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
if (length > 0)
{
std::vector<GLchar> log(length);
glGetProgramInfoLog(program, length, NULL, &log[0]);
m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
}
}
return status == GL_TRUE ? true : false;
}
bool IsEqual(IVec4 a, IVec4 b)
{
return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
}
bool IsEqual(UVec4 a, UVec4 b)
{
return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
}
bool IsEqual(Vec2 a, Vec2 b)
{
return (a[0] == b[0]) && (a[1] == b[1]);
}
bool IsEqual(IVec2 a, IVec2 b)
{
return (a[0] == b[0]) && (a[1] == b[1]);
}
bool IsEqual(UVec2 a, UVec2 b)
{
return (a[0] == b[0]) && (a[1] == b[1]);
}
const Mat4 Translation(float tx, float ty, float tz)
{
float d[] = { 1.0f, 0.0f, 0.0f, tx, 0.0f, 1.0f, 0.0f, ty, 0.0f, 0.0f, 1.0f, tz, 0.0f, 0.0f, 0.0f, 1.0f };
return Mat4(d);
}
};
//=============================================================================
// 1.1 BasicUsage
//-----------------------------------------------------------------------------
class BasicUsage : public VertexAttribBindingBase
{
GLuint m_vsp, m_fsp, m_ppo, m_vao, m_vbo;
virtual long Setup()
{
m_vsp = m_fsp = 0;
glGenProgramPipelines(1, &m_ppo);
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
glDeleteProgram(m_vsp);
glDeleteProgram(m_fsp);
glDeleteProgramPipelines(1, &m_ppo);
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Run()
{
const char* const glsl_vs =
"#version 430 core" NL "layout(location = 0) in vec4 vs_in_position;" NL
"layout(location = 1) in vec3 vs_in_color;" NL "out StageData {" NL " vec3 color;" NL "} vs_out;" NL
"out gl_PerVertex { vec4 gl_Position; };" NL "void main() {" NL " gl_Position = vs_in_position;" NL
" vs_out.color = vs_in_color;" NL "}";
const char* const glsl_fs = "#version 430 core" NL "in StageData {" NL " vec3 color;" NL "} fs_in;" NL
"layout(location = 0) out vec4 fs_out_color;" NL "void main() {" NL
" fs_out_color = vec4(fs_in.color, 1);" NL "}";
m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
m_fsp = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);
if (!CheckProgram(m_vsp) || !CheckProgram(m_fsp))
return ERROR;
glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);
glUseProgramStages(m_ppo, GL_FRAGMENT_SHADER_BIT, m_fsp);
{
const float data[] = {
-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f,
1.0f, 0.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
};
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
glBindVertexArray(m_vao);
glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 8);
glVertexAttribBinding(0, 0);
glVertexAttribBinding(1, 0);
glBindVertexBuffer(0, m_vbo, 0, 20);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindVertexArray(0);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(m_vao);
glBindProgramPipeline(m_ppo);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
bool status = true;
std::vector<Vec3> fb(getWindowWidth() * getWindowHeight());
glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 1, 0)))
status = false;
if (!status)
return ERROR;
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(1, 1, 0)))
status = false;
if (!status)
return ERROR;
return NO_ERROR;
}
};
//=============================================================================
// BasicInputBase
//-----------------------------------------------------------------------------
class BasicInputBase : public VertexAttribBindingBase
{
GLuint m_po, m_xfbo;
protected:
Vec4 expected_data[64];
GLsizei instance_count;
GLint base_instance;
virtual long Setup()
{
m_po = 0;
glGenBuffers(1, &m_xfbo);
for (int i = 0; i < 64; ++i)
expected_data[i] = Vec4(0.0f);
instance_count = 1;
base_instance = -1;
return NO_ERROR;
}
virtual long Cleanup()
{
glDisable(GL_RASTERIZER_DISCARD);
glUseProgram(0);
glDeleteProgram(m_po);
glDeleteBuffers(1, &m_xfbo);
return NO_ERROR;
}
virtual long Run()
{
const char* const glsl_vs = "#version 430 core" NL "layout(location = 0) in vec4 vs_in_attrib[16];" NL
"out StageData {" NL " vec4 attrib[16];" NL "} vs_out;" NL "void main() {" NL
" for (int i = 0; i < vs_in_attrib.length(); ++i) {" NL
" vs_out.attrib[i] = vs_in_attrib[i];" NL " }" NL "}";
m_po = glCreateProgram();
{
const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(sh, 1, &glsl_vs, NULL);
glCompileShader(sh);
glAttachShader(m_po, sh);
glDeleteShader(sh);
}
{
const GLchar* const v[16] = { "StageData.attrib[0]", "StageData.attrib[1]", "StageData.attrib[2]",
"StageData.attrib[3]", "StageData.attrib[4]", "StageData.attrib[5]",
"StageData.attrib[6]", "StageData.attrib[7]", "StageData.attrib[8]",
"StageData.attrib[9]", "StageData.attrib[10]", "StageData.attrib[11]",
"StageData.attrib[12]", "StageData.attrib[13]", "StageData.attrib[14]",
"StageData.attrib[15]" };
glTransformFeedbackVaryings(m_po, 16, v, GL_INTERLEAVED_ATTRIBS);
}
glLinkProgram(m_po);
if (!CheckProgram(m_po))
return ERROR;
{
std::vector<GLubyte> zero(sizeof(expected_data));
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(expected_data), &zero[0], GL_DYNAMIC_DRAW);
}
glEnable(GL_RASTERIZER_DISCARD);
glUseProgram(m_po);
glBeginTransformFeedback(GL_POINTS);
if (base_instance != -1)
{
glDrawArraysInstancedBaseInstance(GL_POINTS, 0, 2, instance_count, static_cast<GLuint>(base_instance));
}
else
{
glDrawArraysInstanced(GL_POINTS, 0, 2, instance_count);
}
glEndTransformFeedback();
Vec4 data[64];
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(Vec4) * 64, &data[0]);
long status = NO_ERROR;
for (int i = 0; i < 64; ++i)
{
if (!ColorEqual(expected_data[i], data[i], Vec4(0.01f)))
{
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "Data is: " << data[i][0] << " " << data[i][1] << " " << data[i][2]
<< " " << data[i][3] << ", data should be: " << expected_data[i][0] << " " << expected_data[i][1]
<< " " << expected_data[i][2] << " " << expected_data[i][3] << ", index is: " << i
<< tcu::TestLog::EndMessage;
status = ERROR;
break;
}
}
return status;
}
};
//=============================================================================
// 1.2.1 BasicInputCase1
//-----------------------------------------------------------------------------
class BasicInputCase1 : public BasicInputBase
{
GLuint m_vao, m_vbo;
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glBindVertexBuffer(0, m_vbo, 0, 12);
glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
glVertexAttribBinding(1, 0);
glEnableVertexAttribArray(1);
expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
expected_data[17] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// 1.2.2 BasicInputCase2
//-----------------------------------------------------------------------------
class BasicInputCase2 : public BasicInputBase
{
GLuint m_vao, m_vbo;
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribBinding(1, 0);
glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(7, 1, GL_FLOAT, GL_FALSE, 8);
glVertexAttribFormat(15, 2, GL_FLOAT, GL_FALSE, 4);
glVertexAttribBinding(0, 0);
glVertexAttribBinding(7, 0);
glVertexAttribBinding(15, 0);
glBindVertexBuffer(0, m_vbo, 0, 12);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(7);
glEnableVertexAttribArray(15);
expected_data[0] = Vec4(1.0f, 2.0f, 0.0f, 1.0f);
expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
expected_data[7] = Vec4(3.0f, 0.0f, 0.0f, 1.0f);
expected_data[15] = Vec4(2.0f, 3.0f, 0.0f, 1.0f);
expected_data[16] = Vec4(4.0f, 5.0f, 0.0f, 1.0f);
expected_data[17] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
expected_data[23] = Vec4(6.0f, 0.0f, 0.0f, 1.0f);
expected_data[31] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// 1.2.3 BasicInputCase3
//-----------------------------------------------------------------------------
class BasicInputCase3 : public BasicInputBase
{
GLuint m_vao, m_vbo;
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, 36 * 2, NULL, GL_STATIC_DRAW);
{
GLubyte d[] = { 1, 2, 3, 4 };
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
}
glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec3), &Vec3(5.0f, 6.0f, 7.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(Vec2), &Vec2(8.0f, 9.0f)[0]);
{
GLubyte d[] = { 10, 11, 12, 13 };
glBufferSubData(GL_ARRAY_BUFFER, 0 + 36, sizeof(d), d);
}
glBufferSubData(GL_ARRAY_BUFFER, 16 + 36, sizeof(Vec3), &Vec3(14.0f, 15.0f, 16.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 28 + 36, sizeof(Vec2), &Vec2(17.0f, 18.0f)[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glEnableVertexAttribArray(1);
glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0);
glVertexAttribBinding(1, 3);
glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 16);
glVertexAttribBinding(2, 3);
glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 28);
glVertexAttribBinding(0, 3);
glBindVertexBuffer(3, m_vbo, 0, 36);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
expected_data[1] = Vec4(5.0f, 6.0f, 7.0f, 1.0f);
expected_data[2] = Vec4(8.0f, 9.0f, 0.0f, 1.0f);
expected_data[0 + 16] = Vec4(10.0f, 11.0f, 12.0f, 13.0f);
expected_data[1 + 16] = Vec4(14.0f, 15.0f, 16.0f, 1.0f);
expected_data[2 + 16] = Vec4(17.0f, 18.0f, 0.0f, 1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// 1.2.4 BasicInputCase4
//-----------------------------------------------------------------------------
class BasicInputCase4 : public BasicInputBase
{
GLuint m_vao, m_vbo[2];
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
glBufferData(GL_ARRAY_BUFFER, 20 * 2, NULL, GL_STATIC_DRAW);
{
GLbyte d[] = { -127, 127, -127, 127 };
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
}
{
GLushort d[] = { 1, 2, 3, 4 };
glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
}
{
GLuint d[] = { 5, 6 };
glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
}
{
GLbyte d[] = { 127, -127, 127, -127 };
glBufferSubData(GL_ARRAY_BUFFER, 0 + 20, sizeof(d), d);
}
{
GLushort d[] = { 7, 8, 9, 10 };
glBufferSubData(GL_ARRAY_BUFFER, 4 + 20, sizeof(d), d);
}
{
GLuint d[] = { 11, 12 };
glBufferSubData(GL_ARRAY_BUFFER, 12 + 20, sizeof(d), d);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
glBufferData(GL_ARRAY_BUFFER, 24 * 2 + 8, NULL, GL_STATIC_DRAW);
{
GLdouble d[] = { 0.0, 100.0, 200.0 };
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
}
{
GLdouble d[] = { 300.0, 400.0 };
glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribFormat(0, 4, GL_BYTE, GL_TRUE, 0);
glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_FALSE, 4);
glVertexAttribFormat(2, 2, GL_UNSIGNED_INT, GL_FALSE, 12);
glVertexAttribFormat(5, 2, GL_DOUBLE, GL_FALSE, 0);
glVertexAttribBinding(0, 0);
glVertexAttribBinding(1, 0);
glVertexAttribBinding(2, 0);
glVertexAttribBinding(5, 6);
glBindVertexBuffer(0, m_vbo[0], 0, 20);
glBindVertexBuffer(6, m_vbo[1], 8, 24);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(5);
expected_data[0] = Vec4(-1.0f, 1.0f, -1.0f, 1.0f);
expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
expected_data[2] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
expected_data[5] = Vec4(100.0f, 200.0f, 0.0f, 1.0f);
expected_data[0 + 16] = Vec4(1.0f, -1.0f, 1.0f, -1.0f);
expected_data[1 + 16] = Vec4(7.0f, 8.0f, 9.0f, 10.0f);
expected_data[2 + 16] = Vec4(11.0f, 12.0f, 0.0f, 1.0f);
expected_data[5 + 16] = Vec4(300.0f, 400.0f, 0.0f, 1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// 1.2.5 BasicInputCase5
//-----------------------------------------------------------------------------
class BasicInputCase5 : public BasicInputBase
{
GLuint m_vao, m_vbo;
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
const int kStride = 116;
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
{
GLubyte d[] = { 0, 0xff, 0xff / 2, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
}
{
GLushort d[] = { 0, 0xffff, 0xffff / 2, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
}
{
GLuint d[] = { 0, 0xffffffff, 0xffffffff / 2, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
}
{
GLbyte d[] = { 0, -127, 127, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
}
{
GLshort d[] = { 0, -32767, 32767, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
}
{
GLint d[] = { 0, -2147483647, 2147483647, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
}
{
GLfloat d[] = { 0, 1.0f, 2.0f, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
}
{
GLdouble d[] = { 0, 10.0, 20.0, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
}
{
GLubyte d[] = { 0, 0xff / 4, 0xff / 2, 0xff };
glBufferSubData(GL_ARRAY_BUFFER, 104, sizeof(d), d);
}
{
GLuint d = 0 | (1023 << 10) | (511 << 20) | (1 << 30);
glBufferSubData(GL_ARRAY_BUFFER, 108, sizeof(d), &d);
}
{
GLint d = 0 | (511 << 10) | (255 << 20) | (0 << 30);
glBufferSubData(GL_ARRAY_BUFFER, 112, sizeof(d), &d);
}
{
GLubyte d[] = { 0xff, 0xff, 0xff / 2, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
}
{
GLushort d[] = { 0xffff, 0xffff, 0xffff / 2, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
}
{
GLuint d[] = { 0xffffffff, 0xffffffff, 0xffffffff / 2, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
}
{
GLbyte d[] = { 127, -127, 127, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
}
{
GLshort d[] = { 32767, -32767, 32767, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
}
{
GLint d[] = { 2147483647, -2147483647, 2147483647, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
}
{
GLfloat d[] = { 0, 3.0f, 4.0f, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
}
{
GLdouble d[] = { 0, 30.0, 40.0, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
}
{
GLubyte d[] = { 0xff, 0xff / 2, 0xff / 4, 0 };
glBufferSubData(GL_ARRAY_BUFFER, 104 + kStride, sizeof(d), d);
}
{
GLuint d = 0 | (1023 << 10) | (511 << 20) | (2u << 30);
glBufferSubData(GL_ARRAY_BUFFER, 108 + kStride, sizeof(d), &d);
}
{
GLint d = (-511 & 0x3ff) | (511 << 10) | (255 << 20) | 3 << 30;
glBufferSubData(GL_ARRAY_BUFFER, 112 + kStride, sizeof(d), &d);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0);
glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_TRUE, 4);
glVertexAttribFormat(2, 4, GL_UNSIGNED_INT, GL_TRUE, 12);
glVertexAttribFormat(3, 4, GL_BYTE, GL_TRUE, 28);
glVertexAttribFormat(4, 4, GL_SHORT, GL_TRUE, 32);
glVertexAttribFormat(5, 4, GL_INT, GL_TRUE, 40);
glVertexAttribFormat(6, 4, GL_FLOAT, GL_TRUE, 56);
glVertexAttribFormat(7, 4, GL_DOUBLE, GL_TRUE, 72);
glVertexAttribFormat(8, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, 104);
glVertexAttribFormat(9, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 108);
glVertexAttribFormat(10, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 108);
glVertexAttribFormat(11, 4, GL_INT_2_10_10_10_REV, GL_TRUE, 112);
glVertexAttribFormat(12, GL_BGRA, GL_INT_2_10_10_10_REV, GL_TRUE, 112);
for (GLuint i = 0; i < 13; ++i)
{
glVertexAttribBinding(i, 0);
glEnableVertexAttribArray(i);
}
glBindVertexBuffer(0, m_vbo, 0, kStride);
expected_data[0] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
expected_data[1] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
expected_data[2] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
expected_data[3] = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
expected_data[4] = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
expected_data[5] = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
expected_data[6] = Vec4(0.0f, 1.0f, 2.0f, 0.0f);
expected_data[7] = Vec4(0.0f, 10.0f, 20.0f, 0.0f);
expected_data[8] = Vec4(0.5f, 0.25f, 0.0f, 1.0f);
expected_data[9] = Vec4(0.0f, 1.0f, 0.5f, 0.33f);
expected_data[10] = Vec4(0.5f, 1.0f, 0.0f, 0.33f);
expected_data[11] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
expected_data[12] = Vec4(0.5f, 1.0f, 0.0f, 0.0f);
expected_data[0 + 16] = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
expected_data[1 + 16] = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
expected_data[2 + 16] = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
expected_data[3 + 16] = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
expected_data[4 + 16] = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
expected_data[5 + 16] = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
expected_data[6 + 16] = Vec4(0.0f, 3.0f, 4.0f, 0.0f);
expected_data[7 + 16] = Vec4(0.0f, 30.0f, 40.0f, 0.0f);
expected_data[8 + 16] = Vec4(0.25f, 0.5f, 1.0f, 0.0f);
expected_data[9 + 16] = Vec4(0.0f, 1.0f, 0.5f, 0.66f);
expected_data[10 + 16] = Vec4(0.5f, 1.0f, 0.0f, 0.66f);
expected_data[11 + 16] = Vec4(-1.0f, 1.0f, 0.5f, -1.0f);
expected_data[12 + 16] = Vec4(0.5f, 1.0f, -1.0f, -1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// 1.2.6 BasicInputCase6
//-----------------------------------------------------------------------------
class BasicInputCase6 : public BasicInputBase
{
GLuint m_vao, m_vbo;
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
const int kStride = 112;
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
{
GLubyte d[] = { 1, 2, 3, 4 };
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
}
{
GLushort d[] = { 5, 6, 7, 8 };
glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
}
{
GLuint d[] = { 9, 10, 11, 12 };
glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
}
{
GLbyte d[] = { -1, 2, -3, 4 };
glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
}
{
GLshort d[] = { -5, 6, -7, 8 };
glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
}
{
GLint d[] = { -9, 10, -11, 12 };
glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
}
{
GLfloat d[] = { -13.0f, 14.0f, -15.0f, 16.0f };
glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
}
{
GLdouble d[] = { -18.0, 19.0, -20.0, 21.0 };
glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
}
{
GLuint d = 0 | (11 << 10) | (12 << 20) | (2u << 30);
glBufferSubData(GL_ARRAY_BUFFER, 104, sizeof(d), &d);
}
{
GLint d = 0 | ((0xFFFFFFF5 << 10) & (0x3ff << 10)) | (12 << 20) | (1 << 30);
glBufferSubData(GL_ARRAY_BUFFER, 108, sizeof(d), &d);
}
{
GLubyte d[] = { 22, 23, 24, 25 };
glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
}
{
GLushort d[] = { 26, 27, 28, 29 };
glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
}
{
GLuint d[] = { 30, 31, 32, 33 };
glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
}
{
GLbyte d[] = { -34, 35, -36, 37 };
glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
}
{
GLshort d[] = { -38, 39, -40, 41 };
glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
}
{
GLint d[] = { -42, 43, -44, 45 };
glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
}
{
GLfloat d[] = { -46.0f, 47.0f, -48.0f, 49.0f };
glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
}
{
GLdouble d[] = { -50.0, 51.0, -52.0, 53.0 };
glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
}
{
GLuint d = 0 | (11 << 10) | (12 << 20) | (1 << 30);
glBufferSubData(GL_ARRAY_BUFFER, 104 + kStride, sizeof(d), &d);
}
{
GLint d = 123 | ((0xFFFFFFFD << 10) & (0x3ff << 10)) | ((0xFFFFFE0C << 20) & (0x3ff << 20)) |
((0xFFFFFFFF << 30) & (0x3 << 30));
glBufferSubData(GL_ARRAY_BUFFER, 108 + kStride, sizeof(d), &d);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0);
glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_FALSE, 4);
glVertexAttribFormat(2, 4, GL_UNSIGNED_INT, GL_FALSE, 12);
glVertexAttribFormat(3, 4, GL_BYTE, GL_FALSE, 28);
glVertexAttribFormat(4, 4, GL_SHORT, GL_FALSE, 32);
glVertexAttribFormat(5, 4, GL_INT, GL_FALSE, 40);
glVertexAttribFormat(6, 4, GL_FLOAT, GL_FALSE, 56);
glVertexAttribFormat(7, 4, GL_DOUBLE, GL_FALSE, 72);
glVertexAttribFormat(8, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 104);
glVertexAttribFormat(9, 4, GL_INT_2_10_10_10_REV, GL_FALSE, 108);
for (GLuint i = 0; i < 10; ++i)
{
glVertexAttribBinding(i, 0);
glEnableVertexAttribArray(i);
}
glBindVertexBuffer(0, m_vbo, 0, kStride);
expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
expected_data[1] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
expected_data[2] = Vec4(9.0f, 10.0f, 11.0f, 12.0f);
expected_data[3] = Vec4(-1.0f, 2.0f, -3.0f, 4.0f);
expected_data[4] = Vec4(-5.0f, 6.0f, -7.0f, 8.0f);
expected_data[5] = Vec4(-9.0f, 10.0f, -11.0f, 12.0f);
expected_data[6] = Vec4(-13.0f, 14.0f, -15.0f, 16.0f);
expected_data[7] = Vec4(-18.0f, 19.0f, -20.0f, 21.0f);
expected_data[8] = Vec4(0.0f, 11.0f, 12.0f, 2.0f);
expected_data[9] = Vec4(0.0f, -11.0f, 12.0f, 1.0f);
expected_data[0 + 16] = Vec4(22.0f, 23.0f, 24.0f, 25.0f);
expected_data[1 + 16] = Vec4(26.0f, 27.0f, 28.0f, 29.0f);
expected_data[2 + 16] = Vec4(30.0f, 31.0f, 32.0f, 33.0f);
expected_data[3 + 16] = Vec4(-34.0f, 35.0f, -36.0f, 37.0f);
expected_data[4 + 16] = Vec4(-38.0f, 39.0f, -40.0f, 41.0f);
expected_data[5 + 16] = Vec4(-42.0f, 43.0f, -44.0f, 45.0f);
expected_data[6 + 16] = Vec4(-46.0f, 47.0f, -48.0f, 49.0f);
expected_data[7 + 16] = Vec4(-50.0f, 51.0f, -52.0f, 53.0f);
expected_data[8 + 16] = Vec4(0.0f, 11.0f, 12.0f, 1.0f);
expected_data[9 + 16] = Vec4(123.0f, -3.0f, -500.0f, -1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// 1.2.7 BasicInputCase7
//-----------------------------------------------------------------------------
class BasicInputCase7 : public BasicInputBase
{
GLuint m_vao, m_vbo[2];
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
glBufferData(GL_ARRAY_BUFFER, 6 * 4, NULL, GL_STATIC_DRAW);
{
GLfloat d[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
glBufferData(GL_ARRAY_BUFFER, 10 * 4, NULL, GL_STATIC_DRAW);
{
GLfloat d[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f, -9.0f, -10.0f };
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 4);
glVertexAttribFormat(5, 4, GL_FLOAT, GL_FALSE, 12);
glVertexAttribFormat(14, 2, GL_FLOAT, GL_FALSE, 8);
glVertexAttribBinding(0, 0);
glVertexAttribBinding(1, 1);
glVertexAttribBinding(2, 1);
glVertexAttribBinding(5, 15);
glVertexAttribBinding(14, 7);
glBindVertexBuffer(0, m_vbo[0], 0, 12);
glBindVertexBuffer(1, m_vbo[0], 4, 4);
glBindVertexBuffer(7, m_vbo[1], 8, 16);
glBindVertexBuffer(15, m_vbo[1], 12, 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(5);
glEnableVertexAttribArray(14);
base_instance = 0;
expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
expected_data[1] = Vec4(2.0f, 3.0f, 4.0f, 1.0f);
expected_data[2] = Vec4(3.0f, 0.0f, 0.0f, 1.0f);
expected_data[5] = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
expected_data[14] = Vec4(-5.0f, -6.0f, 0.0f, 1.0f);
expected_data[0 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
expected_data[1 + 16] = Vec4(3.0f, 4.0f, 5.0f, 1.0f);
expected_data[2 + 16] = Vec4(4.0f, 0.0f, 0.0f, 1.0f);
expected_data[5 + 16] = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
expected_data[14 + 16] = Vec4(-9.0f, -10.0f, 0.0f, 1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// 1.2.8 BasicInputCase8
//-----------------------------------------------------------------------------
class BasicInputCase8 : public BasicInputBase
{
GLuint m_vao, m_vbo[2];
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
glBufferData(GL_ARRAY_BUFFER, 6 * 4, NULL, GL_STATIC_DRAW);
{
GLfloat d[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
glBufferData(GL_ARRAY_BUFFER, 10 * 4, NULL, GL_STATIC_DRAW);
{
GLfloat d[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f, -9.0f, -10.0f };
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 4);
glVertexAttribFormat(5, 4, GL_FLOAT, GL_FALSE, 12);
glVertexAttribFormat(14, 2, GL_FLOAT, GL_FALSE, 8);
glVertexAttribBinding(0, 0);
glVertexAttribBinding(1, 1);
glVertexAttribBinding(2, 1);
glVertexAttribBinding(5, 15);
glVertexAttribBinding(14, 7);
glBindVertexBuffer(0, m_vbo[0], 0, 12);
glBindVertexBuffer(1, m_vbo[0], 4, 4);
glBindVertexBuffer(7, m_vbo[1], 8, 16);
glBindVertexBuffer(15, m_vbo[1], 12, 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(5);
glEnableVertexAttribArray(14);
expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
expected_data[1] = Vec4(2.0f, 3.0f, 4.0f, 1.0f);
expected_data[2] = Vec4(3.0f, 0.0f, 0.0f, 1.0f);
expected_data[5] = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
expected_data[14] = Vec4(-5.0f, -6.0f, 0.0f, 1.0f);
expected_data[0 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
expected_data[1 + 16] = Vec4(3.0f, 4.0f, 5.0f, 1.0f);
expected_data[2 + 16] = Vec4(4.0f, 0.0f, 0.0f, 1.0f);
expected_data[5 + 16] = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
expected_data[14 + 16] = Vec4(-9.0f, -10.0f, 0.0f, 1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// 1.2.9 BasicInputCase9
//-----------------------------------------------------------------------------
class BasicInputCase9 : public BasicInputBase
{
GLuint m_vao, m_vbo[2];
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(1.0f, 2.0f, 3.0f, 4.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(5.0f, 6.0f, 7.0f, 8.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(Vec4), &Vec4(9.0f, 10.0f, 11.0f, 12.0f)[0]);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(10.0f, 20.0f, 30.0f, 40.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(50.0f, 60.0f, 70.0f, 80.0f)[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(2, 4, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(4, 2, GL_FLOAT, GL_FALSE, 4);
glVertexAttribBinding(0, 0);
glVertexAttribBinding(2, 1);
glVertexAttribBinding(4, 3);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(4);
glBindVertexBuffer(0, m_vbo[0], 0, 16);
glBindVertexBuffer(1, m_vbo[0], 0, 16);
glBindVertexBuffer(3, m_vbo[1], 4, 8);
glVertexBindingDivisor(1, 1);
instance_count = 2;
base_instance = 0;
expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
expected_data[2] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
expected_data[4] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
expected_data[0 + 16] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
expected_data[2 + 16] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
expected_data[4 + 16] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
expected_data[0 + 32] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
expected_data[2 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
expected_data[4 + 32] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
expected_data[0 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
expected_data[2 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
expected_data[4 + 16 + 32] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// 1.2.10 BasicInputCase10
//-----------------------------------------------------------------------------
class BasicInputCase10 : public BasicInputBase
{
GLuint m_vao, m_vbo;
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 3, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 24, sizeof(Vec3), &Vec3(7.0f, 8.0f, 9.0f)[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 4);
glVertexAttribBinding(0, 0);
glVertexAttribBinding(2, 3);
glBindVertexBuffer(0, m_vbo, 0, 12);
glBindVertexBuffer(3, m_vbo, 4, 8);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
glVertexBindingDivisor(0, 1);
glVertexBindingDivisor(3, 0);
instance_count = 2;
base_instance = 1;
expected_data[0] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
expected_data[2] = Vec4(3.0f, 4.0f, 0.0f, 1.0f);
expected_data[0 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
expected_data[2 + 16] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
expected_data[0 + 32] = Vec4(7.0f, 8.0f, 9.0f, 1.0f);
expected_data[2 + 32] = Vec4(3.0f, 4.0f, 0.0f, 1.0f);
expected_data[0 + 16 + 32] = Vec4(7.0f, 8.0f, 9.0f, 1.0f);
expected_data[2 + 16 + 32] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// 1.2.11 BasicInputCase11
//-----------------------------------------------------------------------------
class BasicInputCase11 : public BasicInputBase
{
GLuint m_vao, m_vbo[2];
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(1.0f, 2.0f, 3.0f, 4.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(5.0f, 6.0f, 7.0f, 8.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(Vec4), &Vec4(9.0f, 10.0f, 11.0f, 12.0f)[0]);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(10.0f, 20.0f, 30.0f, 40.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(50.0f, 60.0f, 70.0f, 80.0f)[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(2, 4, GL_FLOAT, GL_FALSE, 0);
glVertexAttribFormat(4, 2, GL_FLOAT, GL_FALSE, 4);
glVertexAttribBinding(0, 0);
glVertexAttribBinding(2, 1);
glVertexAttribBinding(4, 2);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(4);
glBindVertexBuffer(0, m_vbo[0], 0, 16);
glBindVertexBuffer(1, m_vbo[0], 0, 16);
glBindVertexBuffer(2, m_vbo[1], 4, 8);
glVertexBindingDivisor(1, 1);
instance_count = 2;
expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
expected_data[2] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
expected_data[4] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
expected_data[0 + 16] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
expected_data[2 + 16] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
expected_data[4 + 16] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
expected_data[0 + 32] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
expected_data[2 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
expected_data[4 + 32] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
expected_data[0 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
expected_data[2 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
expected_data[4 + 16 + 32] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// 1.2.12 BasicInputCase12
//-----------------------------------------------------------------------------
class BasicInputCase12 : public BasicInputBase
{
GLuint m_vao, m_vbo;
virtual long Setup()
{
BasicInputBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 16; ++i)
{
glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 12, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexAttribBinding(0, 1);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
expected_data[0 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
expected_data[1 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
return BasicInputBase::Run();
}
};
//=============================================================================
// BasicInputIBase
//-----------------------------------------------------------------------------
class BasicInputIBase : public VertexAttribBindingBase
{
GLuint m_po, m_xfbo;
protected:
IVec4 expected_datai[32];
UVec4 expected_dataui[32];
GLsizei instance_count;
GLuint base_instance;
virtual long Setup()
{
m_po = 0;
glGenBuffers(1, &m_xfbo);
for (int i = 0; i < 32; ++i)
{
expected_datai[i] = IVec4(0);
expected_dataui[i] = UVec4(0);
}
instance_count = 1;
base_instance = 0;
return NO_ERROR;
}
virtual long Cleanup()
{
glDisable(GL_RASTERIZER_DISCARD);
glUseProgram(0);
glDeleteProgram(m_po);
glDeleteBuffers(1, &m_xfbo);
return NO_ERROR;
}
virtual long Run()
{
const char* const glsl_vs =
"#version 430 core" NL "layout(location = 0) in ivec4 vs_in_attribi[8];" NL
"layout(location = 8) in uvec4 vs_in_attribui[8];" NL "out StageData {" NL " ivec4 attribi[8];" NL
" uvec4 attribui[8];" NL "} vs_out;" NL "void main() {" NL
" for (int i = 0; i < vs_in_attribi.length(); ++i) {" NL " vs_out.attribi[i] = vs_in_attribi[i];" NL
" }" NL " for (int i = 0; i < vs_in_attribui.length(); ++i) {" NL
" vs_out.attribui[i] = vs_in_attribui[i];" NL " }" NL "}";
m_po = glCreateProgram();
{
const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(sh, 1, &glsl_vs, NULL);
glCompileShader(sh);
glAttachShader(m_po, sh);
glDeleteShader(sh);
}
{
const GLchar* const v[16] = { "StageData.attribi[0]", "StageData.attribi[1]", "StageData.attribi[2]",
"StageData.attribi[3]", "StageData.attribi[4]", "StageData.attribi[5]",
"StageData.attribi[6]", "StageData.attribi[7]", "StageData.attribui[0]",
"StageData.attribui[1]", "StageData.attribui[2]", "StageData.attribui[3]",
"StageData.attribui[4]", "StageData.attribui[5]", "StageData.attribui[6]",
"StageData.attribui[7]" };
glTransformFeedbackVaryings(m_po, 16, v, GL_INTERLEAVED_ATTRIBS);
}
glLinkProgram(m_po);
if (!CheckProgram(m_po))
return ERROR;
{
std::vector<GLubyte> zero(64 * 16);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (GLsizeiptr)zero.size(), &zero[0], GL_DYNAMIC_COPY);
}
glEnable(GL_RASTERIZER_DISCARD);
glUseProgram(m_po);
glBeginTransformFeedback(GL_POINTS);
glDrawArraysInstancedBaseInstance(GL_POINTS, 0, 2, instance_count, base_instance);
glEndTransformFeedback();
IVec4 datai[32];
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0 * 16 * 8, 16 * 8, &datai[0]);
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 2 * 16 * 8, 16 * 8, &datai[8]);
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 4 * 16 * 8, 16 * 8, &datai[16]);
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 6 * 16 * 8, 16 * 8, &datai[24]);
UVec4 dataui[32];
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 1 * 16 * 8, 16 * 8, &dataui[0]);
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 3 * 16 * 8, 16 * 8, &dataui[8]);
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 5 * 16 * 8, 16 * 8, &dataui[16]);
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 7 * 16 * 8, 16 * 8, &dataui[24]);
for (int i = 0; i < 32; ++i)
{
if (!IsEqual(expected_datai[i], datai[i]))
{
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "Datai is: " << datai[i][0] << " " << datai[i][1] << " " << datai[i][2]
<< " " << datai[i][3] << ", datai should be: " << expected_datai[i][0] << " "
<< expected_datai[i][1] << " " << expected_datai[i][2] << " " << expected_datai[i][3]
<< ", index is: " << i << tcu::TestLog::EndMessage;
return ERROR;
}
if (!IsEqual(expected_dataui[i], dataui[i]))
{
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "Dataui is: " << dataui[i][0] << " " << dataui[i][1] << " "
<< dataui[i][2] << " " << dataui[i][3] << ", dataui should be: " << expected_dataui[i][0] << " "
<< expected_dataui[i][1] << " " << expected_dataui[i][2] << " " << expected_dataui[i][3]
<< ", index is: " << i << tcu::TestLog::EndMessage;
return ERROR;
}
}
return NO_ERROR;
}
};
//=============================================================================
// 1.3.1 BasicInputICase1
//-----------------------------------------------------------------------------
class BasicInputICase1 : public BasicInputIBase
{
GLuint m_vao, m_vbo;
virtual long Setup()
{
BasicInputIBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputIBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 8; ++i)
{
glVertexAttribI4i(i, 0, 0, 0, 0);
glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
}
const int kStride = 88;
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
{
GLbyte d[] = { 1, -2, 3, -4 };
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
}
{
GLshort d[] = { 5, -6, 7, -8 };
glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
}
{
GLint d[] = { 9, -10, 11, -12 };
glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
}
{
GLubyte d[] = { 13, 14, 15, 16 };
glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
}
{
GLushort d[] = { 17, 18, 19, 20 };
glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
}
{
GLuint d[] = { 21, 22, 23, 24 };
glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
}
{
GLint d[] = { 90, -91, 92, -93 };
glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
}
{
GLuint d[] = { 94, 95, 96, 97 };
glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
}
{
GLbyte d[] = { 25, -26, 27, -28 };
glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
}
{
GLshort d[] = { 29, -30, 31, -32 };
glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
}
{
GLint d[] = { 33, -34, 35, -36 };
glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
}
{
GLubyte d[] = { 37, 38, 39, 40 };
glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
}
{
GLushort d[] = { 41, 42, 43, 44 };
glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
}
{
GLuint d[] = { 45, 46, 47, 48 };
glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
}
{
GLint d[] = { 98, -99, 100, -101 };
glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
}
{
GLuint d[] = { 102, 103, 104, 105 };
glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribIFormat(0, 1, GL_BYTE, 0);
glVertexAttribIFormat(1, 2, GL_SHORT, 4);
glVertexAttribIFormat(2, 3, GL_INT, 12);
glVertexAttribIFormat(3, 4, GL_INT, 56);
glVertexAttribIFormat(8, 3, GL_UNSIGNED_BYTE, 28);
glVertexAttribIFormat(9, 2, GL_UNSIGNED_SHORT, 32);
glVertexAttribIFormat(10, 1, GL_UNSIGNED_INT, 40);
glVertexAttribIFormat(11, 4, GL_UNSIGNED_INT, 72);
glVertexAttribBinding(0, 0);
glVertexAttribBinding(1, 0);
glVertexAttribBinding(2, 0);
glVertexAttribBinding(3, 0);
glVertexAttribBinding(8, 0);
glVertexAttribBinding(9, 0);
glVertexAttribBinding(10, 0);
glVertexAttribBinding(11, 0);
glBindVertexBuffer(0, m_vbo, 0, kStride);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(8);
glEnableVertexAttribArray(9);
glEnableVertexAttribArray(10);
glEnableVertexAttribArray(11);
expected_datai[0] = IVec4(1, 0, 0, 1);
expected_datai[1] = IVec4(5, -6, 0, 1);
expected_datai[2] = IVec4(9, -10, 11, 1);
expected_datai[3] = IVec4(90, -91, 92, -93);
expected_dataui[0] = UVec4(13, 14, 15, 1);
expected_dataui[1] = UVec4(17, 18, 0, 1);
expected_dataui[2] = UVec4(21, 0, 0, 1);
expected_dataui[3] = UVec4(94, 95, 96, 97);
expected_datai[8] = IVec4(25, 0, 0, 1);
expected_datai[9] = IVec4(29, -30, 0, 1);
expected_datai[10] = IVec4(33, -34, 35, 1);
expected_datai[11] = IVec4(98, -99, 100, -101);
expected_dataui[8] = UVec4(37, 38, 39, 1);
expected_dataui[9] = UVec4(41, 42, 0, 1);
expected_dataui[10] = UVec4(45, 0, 0, 1);
expected_dataui[11] = UVec4(102, 103, 104, 105);
return BasicInputIBase::Run();
}
};
//=============================================================================
// 1.3.2 BasicInputICase2
//-----------------------------------------------------------------------------
class BasicInputICase2 : public BasicInputIBase
{
GLuint m_vao, m_vbo[2];
virtual long Setup()
{
BasicInputIBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputIBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 8; ++i)
{
glVertexAttribI4i(i, 0, 0, 0, 0);
glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(IVec3) * 2, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(IVec3), &IVec3(1, 2, 3)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(IVec3), &IVec3(4, 5, 6)[0]);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(UVec4), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(UVec4), &UVec4(10, 20, 30, 40)[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribIFormat(0, 3, GL_INT, 0);
glVertexAttribIFormat(2, 2, GL_INT, 4);
glVertexAttribIFormat(15, 1, GL_UNSIGNED_INT, 0);
glVertexAttribBinding(0, 2);
glVertexAttribBinding(2, 0);
glVertexAttribBinding(15, 7);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(15);
glBindVertexBuffer(0, m_vbo[0], 0, 8);
glBindVertexBuffer(2, m_vbo[0], 0, 12);
glBindVertexBuffer(7, m_vbo[1], 4, 16);
glVertexBindingDivisor(0, 1);
glVertexBindingDivisor(2, 0);
glVertexBindingDivisor(7, 2);
instance_count = 2;
expected_datai[0] = IVec4(1, 2, 3, 1);
expected_datai[2] = IVec4(2, 3, 0, 1);
expected_dataui[7] = UVec4(20, 0, 0, 1);
expected_datai[8] = IVec4(4, 5, 6, 1);
expected_datai[10] = IVec4(2, 3, 0, 1);
expected_dataui[15] = UVec4(20, 0, 0, 1);
expected_datai[16] = IVec4(1, 2, 3, 1);
expected_datai[18] = IVec4(4, 5, 0, 1);
expected_dataui[23] = UVec4(20, 0, 0, 1);
expected_datai[24] = IVec4(4, 5, 6, 1);
expected_datai[26] = IVec4(4, 5, 0, 1);
expected_dataui[31] = UVec4(20, 0, 0, 1);
return BasicInputIBase::Run();
}
};
//=============================================================================
// 1.3.3 BasicInputICase3
//-----------------------------------------------------------------------------
class BasicInputICase3 : public BasicInputIBase
{
GLuint m_vao, m_vbo;
virtual long Setup()
{
BasicInputIBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputIBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 8; ++i)
{
glVertexAttribI4i(i, 0, 0, 0, 0);
glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(IVec3) * 2, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(IVec3), &IVec3(1, 2, 3)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(IVec3), &IVec3(4, 5, 6)[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glVertexAttribIPointer(7, 3, GL_INT, 12, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexAttribIFormat(0, 2, GL_INT, 4);
glVertexAttribBinding(0, 7);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(7);
expected_datai[0] = IVec4(2, 3, 0, 1);
expected_datai[7] = IVec4(1, 2, 3, 1);
expected_datai[0 + 8] = IVec4(5, 6, 0, 1);
expected_datai[7 + 8] = IVec4(4, 5, 6, 1);
return BasicInputIBase::Run();
}
};
//=============================================================================
// BasicInputLBase
//-----------------------------------------------------------------------------
class BasicInputLBase : public VertexAttribBindingBase
{
GLuint m_po, m_xfbo;
protected:
DVec4 expected_data[32];
GLsizei instance_count;
GLuint base_instance;
virtual long Setup()
{
m_po = 0;
glGenBuffers(1, &m_xfbo);
for (int i = 0; i < 32; ++i)
{
expected_data[i] = DVec4(0.0);
}
instance_count = 1;
base_instance = 0;
return NO_ERROR;
}
virtual long Cleanup()
{
glDisable(GL_RASTERIZER_DISCARD);
glUseProgram(0);
glDeleteProgram(m_po);
glDeleteBuffers(1, &m_xfbo);
return NO_ERROR;
}
virtual long Run()
{
const char* const glsl_vs =
"#version 430 core" NL "layout(location = 0) in dvec4 vs_in_attrib[8];" NL "out StageData {" NL
" dvec4 attrib[8];" NL "} vs_out;" NL "void main() {" NL " vs_out.attrib[0] = vs_in_attrib[0];" NL
" vs_out.attrib[1] = vs_in_attrib[1];" NL " vs_out.attrib[2] = vs_in_attrib[2];" NL
" vs_out.attrib[3] = vs_in_attrib[3];" NL " vs_out.attrib[4] = vs_in_attrib[4];" NL
" vs_out.attrib[5] = vs_in_attrib[5];" NL " vs_out.attrib[6] = vs_in_attrib[6];" NL
" vs_out.attrib[7] = vs_in_attrib[7];" NL "}";
m_po = glCreateProgram();
{
const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(sh, 1, &glsl_vs, NULL);
glCompileShader(sh);
glAttachShader(m_po, sh);
glDeleteShader(sh);
}
{
const GLchar* const v[8] = {
"StageData.attrib[0]", "StageData.attrib[1]", "StageData.attrib[2]", "StageData.attrib[3]",
"StageData.attrib[4]", "StageData.attrib[5]", "StageData.attrib[6]", "StageData.attrib[7]",
};
glTransformFeedbackVaryings(m_po, 8, v, GL_INTERLEAVED_ATTRIBS);
}
glLinkProgram(m_po);
if (!CheckProgram(m_po))
return ERROR;
{
std::vector<GLubyte> zero(sizeof(expected_data));
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (GLsizeiptr)zero.size(), &zero[0], GL_DYNAMIC_COPY);
}
glEnable(GL_RASTERIZER_DISCARD);
glUseProgram(m_po);
glBeginTransformFeedback(GL_POINTS);
glDrawArraysInstancedBaseInstance(GL_POINTS, 0, 2, instance_count, base_instance);
glEndTransformFeedback();
DVec4 data[32];
glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(DVec4) * 32, &data[0]);
for (int i = 0; i < 32; ++i)
{
for (int j = 0; j < 4; ++j)
{
if (expected_data[i][j] != 12345.0 && expected_data[i][j] != data[i][j])
{
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "Data is: " << data[i][0] << " " << data[i][1] << " " << data[i][2]
<< " " << data[i][3] << ", data should be: " << expected_data[i][0] << " "
<< expected_data[i][1] << " " << expected_data[i][2] << " " << expected_data[i][3]
<< ", index is: " << i << tcu::TestLog::EndMessage;
return ERROR;
}
}
}
return NO_ERROR;
}
};
//=============================================================================
// 1.4.1 BasicInputLCase1
//-----------------------------------------------------------------------------
class BasicInputLCase1 : public BasicInputLBase
{
GLuint m_vao, m_vbo;
virtual long Setup()
{
BasicInputLBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputLBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 8; ++i)
{
glVertexAttribL4d(i, 0.0, 0.0, 0.0, 0.0);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(DVec4) * 3, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(DVec4), &DVec4(1.0, 2.0, 3.0, 4.0)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(DVec4), &DVec4(5.0, 6.0, 7.0, 8.0)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 64, sizeof(DVec4), &DVec4(9.0, 10.0, 11.0, 12.0)[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribLFormat(0, 4, GL_DOUBLE, 0);
glVertexAttribLFormat(3, 3, GL_DOUBLE, 8);
glVertexAttribLFormat(5, 2, GL_DOUBLE, 0);
glVertexAttribLFormat(7, 1, GL_DOUBLE, 24);
glVertexAttribBinding(0, 0);
glVertexAttribBinding(3, 2);
glVertexAttribBinding(5, 0);
glVertexAttribBinding(7, 6);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(5);
glEnableVertexAttribArray(7);
glBindVertexBuffer(0, m_vbo, 0, 32);
glBindVertexBuffer(2, m_vbo, 0, 16);
glBindVertexBuffer(6, m_vbo, 16, 0);
expected_data[0] = DVec4(1.0, 2.0, 3.0, 4.0);
expected_data[3] = DVec4(2.0, 3.0, 4.0, 12345.0);
expected_data[5] = DVec4(1.0, 2.0, 12345.0, 12345.0);
expected_data[7] = DVec4(6.0, 12345.0, 12345.0, 12345.0);
expected_data[0 + 8] = DVec4(5.0, 6.0, 7.0, 8.0);
expected_data[3 + 8] = DVec4(4.0, 5.0, 6.0, 12345.0);
expected_data[5 + 8] = DVec4(5.0, 6.0, 12345.0, 12345.0);
expected_data[7 + 8] = DVec4(6.0, 12345.0, 12345.0, 12345.0);
return BasicInputLBase::Run();
}
};
//=============================================================================
// 1.4.2 BasicInputLCase2
//-----------------------------------------------------------------------------
class BasicInputLCase2 : public BasicInputLBase
{
GLuint m_vao, m_vbo[2];
virtual long Setup()
{
BasicInputLBase::Setup();
glGenVertexArrays(1, &m_vao);
glGenBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
BasicInputLBase::Cleanup();
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Run()
{
for (GLuint i = 0; i < 8; ++i)
{
glVertexAttribL4d(i, 0.0, 0.0, 0.0, 0.0);
}
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(DVec4) * 3, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(DVec4), &DVec4(1.0, 2.0, 3.0, 4.0)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(DVec4), &DVec4(5.0, 6.0, 7.0, 8.0)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 64, sizeof(DVec4), &DVec4(9.0, 10.0, 11.0, 12.0)[0]);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(DVec4) * 3, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(DVec4), &DVec4(10.0, 20.0, 30.0, 40.0)[0]);
glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(DVec4), &DVec4(50.0, 60.0, 70.0, 80.0)[0]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(m_vao);
glVertexAttribLFormat(0, 4, GL_DOUBLE, 0);
glVertexAttribLFormat(2, 4, GL_DOUBLE, 0);
glVertexAttribLFormat(4, 2, GL_DOUBLE, 8);
glVertexAttribBinding(0, 0);
glVertexAttribBinding(2, 1);
glVertexAttribBinding(4, 2);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(4);
glBindVertexBuffer(0, m_vbo[0], 0, 32);
glBindVertexBuffer(1, m_vbo[0], 0, 32);
glBindVertexBuffer(2, m_vbo[1], 8, 16);
glVertexBindingDivisor(1, 1);
instance_count = 2;
expected_data[0] = DVec4(1.0, 2.0, 3.0, 4.0);
expected_data[2] = DVec4(1.0, 2.0, 3.0, 4.0);
expected_data[4] = DVec4(30.0, 40.0, 12345.0, 12345.0);
expected_data[0 + 8] = DVec4(5.0, 6.0, 7.0, 8.0);
expected_data[2 + 8] = DVec4(1.0, 2.0, 3.0, 4.0);
expected_data[4 + 8] = DVec4(50.0, 60.0, 12345.0, 12345.0);
expected_data[0 + 16] = DVec4(1.0, 2.0, 3.0, 4.0);
expected_data[2 + 16] = DVec4(5.0, 6.0, 7.0, 8.0);
expected_data[4 + 16] = DVec4(30.0, 40.0, 12345.0, 12345.0);
expected_data[0 + 8 + 16] = DVec4(5.0, 6.0, 7.0, 8.0);
expected_data[2 + 8 + 16] = DVec4(5.0, 6.0, 7.0, 8.0);
expected_data[4 + 8 + 16] = DVec4(50.0, 60.0, 12345.0, 12345.0);
return BasicInputLBase::Run();
}
};
//=============================================================================
// 1.5 BasicState1
//-----------------------------------------------------------------------------
class BasicState1 : public VertexAttribBindingBase
{
GLuint m_vao, m_vbo[2];
virtual long Setup()
{
glGenVertexArrays(1, &m_vao);
glGenBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Cleanup()
{
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(2, m_vbo);
return NO_ERROR;
}
virtual long Run()
{
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_DYNAMIC_COPY);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_DYNAMIC_COPY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLint p;
glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);
if (p < 16)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_BINDINGS is " << p
<< " but must be at least 16." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
if (p < 2047)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET is "
<< p << " but must be at least 2047." << tcu::TestLog::EndMessage;
return ERROR;
}
glBindVertexArray(m_vao);
// check default state
for (GLuint i = 0; i < 16; ++i)
{
glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_BINDING, &p);
if (static_cast<GLint>(i) != p)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_BINDING(" << i
<< ") is " << p << " should be " << i << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
if (p != 0)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(" << i
<< ") is " << p << " should be 0." << tcu::TestLog::EndMessage;
return ERROR;
}
GLint64 p64;
glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, i, &p64);
if (p64 != 0)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(" << i
<< ") should be 0." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, i, &p);
if (p != 16)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(" << i
<< ") is " << p << " should be 16." << tcu::TestLog::EndMessage;
return ERROR;
}
}
glVertexAttribFormat(0, 2, GL_BYTE, GL_TRUE, 16);
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
if (p != 2)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(0) is " << p
<< " should be 2." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
if (p != GL_BYTE)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(0) is " << p
<< " should be GL_BYTE." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &p);
if (p != GL_TRUE)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED(0) is "
<< p << " should be GL_TRUE." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
if (p != 16)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(0) is "
<< p << " should be 16." << tcu::TestLog::EndMessage;
return ERROR;
}
glVertexAttribIFormat(2, 3, GL_INT, 512);
glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
if (p != 3)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(2) is " << p
<< " should be 3." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
if (p != GL_INT)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(2) is " << p
<< " should be GL_INT." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
if (p != 512)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(2) is "
<< p << " should be 512." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_ARRAY_INTEGER, &p);
if (p != GL_TRUE)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_INTEGER(2) is " << p
<< " should be GL_TRUE." << tcu::TestLog::EndMessage;
return ERROR;
}
glVertexAttribLFormat(15, 1, GL_DOUBLE, 1024);
glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
if (p != 1)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(15) is " << p
<< " should be 1." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
if (p != GL_DOUBLE)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(15) is " << p
<< " should be GL_DOUBLE." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
if (p != 1024)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(15) is " << p
<< " should be 1024." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_LONG, &p);
if (p != GL_TRUE)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_LONG(15) is " << p
<< " should be GL_TRUE." << tcu::TestLog::EndMessage;
return ERROR;
}
glVertexAttribBinding(0, 7);
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_BINDING, &p);
if (p != 7)
return ERROR;
glVertexAttribBinding(3, 7);
glGetVertexAttribiv(3, GL_VERTEX_ATTRIB_BINDING, &p);
if (p != 7)
return ERROR;
glVertexAttribBinding(9, 0);
glGetVertexAttribiv(9, GL_VERTEX_ATTRIB_BINDING, &p);
if (p != 0)
return ERROR;
glVertexAttribBinding(15, 1);
glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_BINDING, &p);
if (p != 1)
return ERROR;
glVertexAttribBinding(15, 15);
glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_BINDING, &p);
if (p != 15)
return ERROR;
glBindVertexBuffer(0, m_vbo[0], 1024, 128);
GLint64 p64;
glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, 0, &p64);
if (p64 != 1024)
{
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(0) should be 1024." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, 0, &p);
if (p != 128)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(0) is " << p
<< "should be 128." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &p);
if (p != 0)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_STRIDE(0) is " << p
<< "should be 0." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &p);
if (p != 0)
{
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(0) is " << p << "should be 0."
<< tcu::TestLog::EndMessage;
return ERROR;
}
glBindVertexBuffer(15, m_vbo[1], 16, 32);
glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, 15, &p64);
if (p64 != 16)
{
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(15) should be 16." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, 15, &p);
if (p != 32)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(15) is " << p
<< " should be 32." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &p);
if (p != 0)
{
m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_STRIDE(15) is " << p
<< " should be 0." << tcu::TestLog::EndMessage;
return ERROR;
}
glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &p);
if (p != static_cast<GLint>(m_vbo[1]))
{
m_context.getTestContext().getLog()
<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(15) is " << p << " should be "
<< m_vbo[1] << tcu::TestLog::EndMessage;
return ERROR;
}