Path: blob/main_old/src/tests/deqp_support/es31cVertexAttribBindingTests_override.cpp
1693 views
/*-------------------------------------------------------------------------1* OpenGL Conformance Test Suite2* -----------------------------3*4* Copyright (c) 2014-2016 The Khronos Group Inc.5*6* Licensed under the Apache License, Version 2.0 (the "License");7* you may not use this file except in compliance with the License.8* You may obtain a copy of the License at9*10* http://www.apache.org/licenses/LICENSE-2.011*12* Unless required by applicable law or agreed to in writing, software13* distributed under the License is distributed on an "AS IS" BASIS,14* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.15* See the License for the specific language governing permissions and16* limitations under the License.17*18*/ /*!19* \file20* \brief21*/ /*-------------------------------------------------------------------*/2223#include <cstdarg>24#include "es31cVertexAttribBindingTests.hpp"25#include "glwEnums.hpp"26#include "tcuMatrix.hpp"27#include "tcuRenderTarget.hpp"2829#include <cmath>3031namespace glcts32{33using namespace glw;34using tcu::IVec2;35using tcu::IVec3;36using tcu::IVec4;37using tcu::Mat4;38using tcu::UVec2;39using tcu::UVec3;40using tcu::UVec4;41using tcu::Vec2;42using tcu::Vec3;43using tcu::Vec4;4445namespace46{4748class VertexAttribBindingBase : public glcts::SubcaseBase49{50virtual std::string Title() { return NL ""; }5152virtual std::string Purpose() { return NL ""; }5354virtual std::string Method() { return NL ""; }5556virtual std::string PassCriteria() { return NL ""; }5758public:59bool IsSSBOInVSFSAvailable(int required)60{61GLint blocksVS, blocksFS;62glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &blocksVS);63glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &blocksFS);64if (blocksVS >= required && blocksFS >= required)65return true;66else67{68std::ostringstream reason;69reason << "Required " << required << " VS storage blocks but only " << blocksVS70<< " available." << std::endl71<< "Required " << required << " FS storage blocks but only " << blocksFS72<< " available." << std::endl;73OutputNotSupported(reason.str());74return false;75}76}7778int getWindowWidth()79{80const tcu::RenderTarget &renderTarget = m_context.getRenderTarget();81return renderTarget.getWidth();82}8384int getWindowHeight()85{86const tcu::RenderTarget &renderTarget = m_context.getRenderTarget();87return renderTarget.getHeight();88}8990inline bool ColorEqual(const Vec4 &c0, const Vec4 &c1, const Vec4 &epsilon)91{92if (fabs(c0[0] - c1[0]) > epsilon[0])93return false;94if (fabs(c0[1] - c1[1]) > epsilon[1])95return false;96if (fabs(c0[2] - c1[2]) > epsilon[2])97return false;98if (fabs(c0[3] - c1[3]) > epsilon[3])99return false;100return true;101}102103bool CheckProgram(GLuint program)104{105GLint status;106glGetProgramiv(program, GL_LINK_STATUS, &status);107108if (status == GL_FALSE)109{110GLint attached_shaders;111glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);112113if (attached_shaders > 0)114{115std::vector<GLuint> shaders(attached_shaders);116glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);117118for (GLint i = 0; i < attached_shaders; ++i)119{120GLenum type;121glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint *>(&type));122switch (type)123{124case GL_VERTEX_SHADER:125m_context.getTestContext().getLog()126<< tcu::TestLog::Message << "*** Vertex Shader ***"127<< tcu::TestLog::EndMessage;128break;129case GL_FRAGMENT_SHADER:130m_context.getTestContext().getLog()131<< tcu::TestLog::Message << "*** Fragment Shader ***"132<< tcu::TestLog::EndMessage;133break;134default:135m_context.getTestContext().getLog()136<< tcu::TestLog::Message << "*** Unknown Shader ***"137<< tcu::TestLog::EndMessage;138break;139}140GLint length;141glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);142if (length > 0)143{144std::vector<GLchar> source(length);145glGetShaderSource(shaders[i], length, NULL, &source[0]);146m_context.getTestContext().getLog()147<< tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;148}149glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);150if (length > 0)151{152std::vector<GLchar> log(length);153glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);154m_context.getTestContext().getLog()155<< tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;156}157}158}159GLint length;160glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);161if (length > 0)162{163std::vector<GLchar> log(length);164glGetProgramInfoLog(program, length, NULL, &log[0]);165m_context.getTestContext().getLog()166<< tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;167}168}169return status == GL_TRUE ? true : false;170}171172bool IsEqual(IVec4 a, IVec4 b)173{174return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);175}176177bool IsEqual(UVec4 a, UVec4 b)178{179return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);180}181182bool IsEqual(Vec2 a, Vec2 b) { return (a[0] == b[0]) && (a[1] == b[1]); }183184bool IsEqual(IVec2 a, IVec2 b) { return (a[0] == b[0]) && (a[1] == b[1]); }185186bool IsEqual(UVec2 a, UVec2 b) { return (a[0] == b[0]) && (a[1] == b[1]); }187188bool CheckFB(Vec3 expected)189{190const tcu::RenderTarget &renderTarget = m_context.getRenderContext().getRenderTarget();191const tcu::PixelFormat &pixelFormat = renderTarget.getPixelFormat();192Vec3 g_color_eps = Vec3(1.f / static_cast<float>(1 << pixelFormat.redBits),1931.f / static_cast<float>(1 << pixelFormat.greenBits),1941.f / static_cast<float>(1 << pixelFormat.blueBits));195Vec3 g_color_max = Vec3(255);196std::vector<GLubyte> fb(getWindowWidth() * getWindowHeight() * 4);197int fb_w = getWindowWidth();198int fb_h = getWindowHeight();199glReadPixels(0, 0, fb_w, fb_h, GL_RGBA, GL_UNSIGNED_BYTE, &fb[0]);200for (GLint i = 0, y = 0; y < fb_h; ++y)201for (GLint x = 0; x < fb_w; ++x, i += 4)202{203if (fabs(fb[i + 0] / g_color_max[0] - expected[0]) > g_color_eps[0] ||204fabs(fb[i + 1] / g_color_max[1] - expected[1]) > g_color_eps[1] ||205fabs(fb[i + 2] / g_color_max[2] - expected[2]) > g_color_eps[2])206{207m_context.getTestContext().getLog()208<< tcu::TestLog::Message << "Incorrect framebuffer color at pixel (" << x209<< " " << y << "). Color is (" << fb[i + 0] / g_color_max[0] << " "210<< fb[i + 1] / g_color_max[1] << " " << fb[i + 2] / g_color_max[2]211<< ". Color should be (" << expected[0] << " " << expected[1] << " "212<< expected[2] << ")." << tcu::TestLog::EndMessage;213return false;214}215}216return true;217}218219GLhalf FloatToHalf(float f)220{221const unsigned int HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP = 0x38000000;222/* max exponent value in single precision that will be converted */223/* to Inf or Nan when stored as a half-float */224const unsigned int HALF_FLOAT_MAX_BIASED_EXP_AS_SINGLE_FP_EXP = 0x47800000;225/* 255 is the max exponent biased value */226const unsigned int FLOAT_MAX_BIASED_EXP = (0xFF << 23);227const unsigned int HALF_FLOAT_MAX_BIASED_EXP = (0x1F << 10);228char *c = reinterpret_cast<char *>(&f);229unsigned int x = *reinterpret_cast<unsigned int *>(c);230unsigned int sign = (GLhalf)(x >> 31);231unsigned int mantissa;232unsigned int exp;233GLhalf hf;234235/* get mantissa */236mantissa = x & ((1 << 23) - 1);237/* get exponent bits */238exp = x & FLOAT_MAX_BIASED_EXP;239if (exp >= HALF_FLOAT_MAX_BIASED_EXP_AS_SINGLE_FP_EXP)240{241/* check if the original single precision float number is a NaN */242if (mantissa && (exp == FLOAT_MAX_BIASED_EXP))243{244/* we have a single precision NaN */245mantissa = (1 << 23) - 1;246}247else248{249/* 16-bit half-float representation stores number as Inf */250mantissa = 0;251}252hf = (GLhalf)((((GLhalf)sign) << 15) | (GLhalf)(HALF_FLOAT_MAX_BIASED_EXP) |253(GLhalf)(mantissa >> 13));254}255/* check if exponent is <= -15 */256else if (exp <= HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP)257{258/* store a denorm half-float value or zero */259exp = ((HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP - exp) >> 23) + 14;260// handle 0.0 specially to avoid a right-shift by too many bits261if (exp >= 32)262{263return 0;264}265mantissa |= (1 << 23);266mantissa >>= exp;267hf = (GLhalf)((((GLhalf)sign) << 15) | (GLhalf)(mantissa));268}269else270{271hf = (GLhalf)((((GLhalf)sign) << 15) |272(GLhalf)((exp - HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP) >> 13) |273(GLhalf)(mantissa >> 13));274}275276return hf;277}278};279//=============================================================================280// 1.1 BasicUsage281//-----------------------------------------------------------------------------282class BasicUsage : public VertexAttribBindingBase283{284bool pipeline;285286GLuint m_vsp, m_fsp, m_ppo, m_vao, m_vbo;287288virtual long Setup()289{290if (pipeline)291{292m_vsp = m_fsp = 0;293glGenProgramPipelines(1, &m_ppo);294}295else296{297m_ppo = 0;298}299glGenVertexArrays(1, &m_vao);300glGenBuffers(1, &m_vbo);301return NO_ERROR;302}303304virtual long Cleanup()305{306if (pipeline)307{308glDeleteProgram(m_vsp);309glDeleteProgram(m_fsp);310glDeleteProgramPipelines(1, &m_ppo);311}312else313{314glUseProgram(0);315glDeleteProgram(m_ppo);316}317glDeleteVertexArrays(1, &m_vao);318glDeleteBuffers(1, &m_vbo);319return NO_ERROR;320}321322virtual long Run()323{324const char *const glsl_vs =325"#version 310 es" NL "layout(location = 7) in vec4 vs_in_position;" NL326"layout(location = 1) in vec3 vs_in_color;" NL "out vec3 g_color;" NL "void main() {" NL327" gl_Position = vs_in_position;" NL " g_color = vs_in_color;" NL "}";328const char *const glsl_fs = "#version 310 es" NL "precision highp float;" NL329"in vec3 g_color;" NL "out vec4 fs_out_color;" NL330"void main() {" NL " fs_out_color = vec4(g_color, 1);" NL "}";331if (pipeline)332{333m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);334m_fsp = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);335if (!CheckProgram(m_vsp) || !CheckProgram(m_fsp))336return ERROR;337glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);338glUseProgramStages(m_ppo, GL_FRAGMENT_SHADER_BIT, m_fsp);339}340else341{342m_ppo = glCreateProgram();343const GLuint sh = glCreateShader(GL_VERTEX_SHADER);344const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);345glShaderSource(sh, 1, &glsl_vs, NULL);346glShaderSource(fsh, 1, &glsl_fs, NULL);347glCompileShader(sh);348glCompileShader(fsh);349glAttachShader(m_ppo, sh);350glAttachShader(m_ppo, fsh);351glDeleteShader(sh);352glDeleteShader(fsh);353glLinkProgram(m_ppo);354if (!CheckProgram(m_ppo))355return ERROR;356}357/* vbo */358{359const float data[] = {360-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f,361-1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f,362-1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f,363-1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,364};365glBindBuffer(GL_ARRAY_BUFFER, m_vbo);366glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);367glBindBuffer(GL_ARRAY_BUFFER, 0);368}369glBindVertexArray(m_vao);370glVertexAttribFormat(7, 2, GL_FLOAT, GL_FALSE, 0);371glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 8);372glVertexAttribBinding(7, 0);373glVertexAttribBinding(1, 0);374glBindVertexBuffer(0, m_vbo, 0, 20);375glEnableVertexAttribArray(7);376glEnableVertexAttribArray(1);377glBindVertexArray(0);378379glClear(GL_COLOR_BUFFER_BIT);380glBindVertexArray(m_vao);381if (pipeline)382glBindProgramPipeline(m_ppo);383else384glUseProgram(m_ppo);385386glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);387if (!CheckFB(Vec3(0, 1, 0)))388return ERROR;389390glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);391if (!CheckFB(Vec3(1, 1, 0)))392return ERROR;393394return NO_ERROR;395}396397public:398BasicUsage() : pipeline(true) {}399};400//=============================================================================401// BasicInputBase402//-----------------------------------------------------------------------------403class BasicInputBase : public VertexAttribBindingBase404{405406GLuint m_po, m_xfbo;407408protected:409Vec4 expected_data[60];410GLsizei instance_count;411GLint base_instance;412413virtual long Setup()414{415m_po = 0;416glGenBuffers(1, &m_xfbo);417for (int i = 0; i < 60; ++i)418expected_data[i] = Vec4(0.0f);419instance_count = 1;420base_instance = -1;421return NO_ERROR;422}423424virtual long Cleanup()425{426glDisable(GL_RASTERIZER_DISCARD);427glUseProgram(0);428glDeleteProgram(m_po);429glDeleteBuffers(1, &m_xfbo);430return NO_ERROR;431}432433virtual long Run()434{435const char *const glsl_vs =436"#version 310 es" NL "layout(location = 0) in vec4 vs_in_attrib0;" NL437"layout(location = 1) in vec4 vs_in_attrib1;" NL438"layout(location = 2) in vec4 vs_in_attrib2;" NL439"layout(location = 3) in vec4 vs_in_attrib3;" NL440"layout(location = 4) in vec4 vs_in_attrib4;" NL441"layout(location = 5) in vec4 vs_in_attrib5;" NL442"layout(location = 6) in vec4 vs_in_attrib6;" NL443"layout(location = 7) in vec4 vs_in_attrib7;" NL444"layout(location = 8) in vec4 vs_in_attrib8;" NL445"layout(location = 9) in vec4 vs_in_attrib9;" NL446"layout(location = 10) in vec4 vs_in_attrib10;" NL447"layout(location = 11) in vec4 vs_in_attrib11;" NL448"layout(location = 12) in vec4 vs_in_attrib12;" NL449"layout(location = 13) in vec4 vs_in_attrib13;" NL450"layout(location = 14) in vec4 vs_in_attrib14;" NL "out vec4 attrib[15];" NL451"void main() {" NL " attrib[0] = vs_in_attrib0;" NL " attrib[1] = vs_in_attrib1;" NL452" attrib[2] = vs_in_attrib2;" NL " attrib[3] = vs_in_attrib3;" NL453" attrib[4] = vs_in_attrib4;" NL " attrib[5] = vs_in_attrib5;" NL454" attrib[6] = vs_in_attrib6;" NL " attrib[7] = vs_in_attrib7;" NL455" attrib[8] = vs_in_attrib8;" NL " attrib[9] = vs_in_attrib9;" NL456" attrib[10] = vs_in_attrib10;" NL " attrib[11] = vs_in_attrib11;" NL457" attrib[12] = vs_in_attrib12;" NL " attrib[13] = vs_in_attrib13;" NL458" attrib[14] = vs_in_attrib14;" NL "}";459const char *const glsl_fs =460"#version 310 es" NL "precision mediump float;" NL "in vec4 attrib[15];" NL461"out vec4 fs_out_color;" NL "void main() {" NL " fs_out_color = attrib[8];" NL "}";462m_po = glCreateProgram();463/* attach shader */464{465const GLuint sh = glCreateShader(GL_VERTEX_SHADER);466const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);467glShaderSource(sh, 1, &glsl_vs, NULL);468glShaderSource(fsh, 1, &glsl_fs, NULL);469glCompileShader(sh);470glCompileShader(fsh);471glAttachShader(m_po, sh);472glAttachShader(m_po, fsh);473glDeleteShader(sh);474glDeleteShader(fsh);475}476/* setup XFB */477{478const GLchar *const v = "attrib";479glTransformFeedbackVaryings(m_po, 1, &v, GL_INTERLEAVED_ATTRIBS);480}481glLinkProgram(m_po);482if (!CheckProgram(m_po))483return ERROR;484485/* buffer data */486{487std::vector<GLubyte> zero(sizeof(expected_data));488glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);489glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(expected_data), &zero[0],490GL_DYNAMIC_DRAW);491}492493// capture494glEnable(GL_RASTERIZER_DISCARD);495glUseProgram(m_po);496glBeginTransformFeedback(GL_POINTS);497if (base_instance != -1)498{499glDrawArraysInstancedBaseInstance(GL_POINTS, 0, 2, instance_count,500static_cast<GLuint>(base_instance));501}502else503{504glDrawArraysInstanced(GL_POINTS, 0, 2, instance_count);505}506glEndTransformFeedback();507508Vec4 *data = static_cast<Vec4 *>(509glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(Vec4) * 60, GL_MAP_READ_BIT));510511long status = NO_ERROR;512for (int i = 0; i < 60; ++i)513{514if (!ColorEqual(expected_data[i], data[i], Vec4(0.01f)))515{516m_context.getTestContext().getLog()517<< tcu::TestLog::Message << "Data is: " << data[i][0] << " " << data[i][1]518<< " " << data[i][2] << " " << data[i][3]519<< ", data should be: " << expected_data[i][0] << " " << expected_data[i][1]520<< " " << expected_data[i][2] << " " << expected_data[i][3]521<< ", index is: " << i << tcu::TestLog::EndMessage;522status = ERROR;523break;524}525}526return status;527}528};529530//=============================================================================531// 1.2.1 BasicInputCase1532//-----------------------------------------------------------------------------533class BasicInputCase1 : public BasicInputBase534{535536GLuint m_vao, m_vbo;537538virtual long Setup()539{540BasicInputBase::Setup();541glGenVertexArrays(1, &m_vao);542glGenBuffers(1, &m_vbo);543return NO_ERROR;544}545546virtual long Cleanup()547{548BasicInputBase::Cleanup();549glDeleteVertexArrays(1, &m_vao);550glDeleteBuffers(1, &m_vbo);551return NO_ERROR;552}553554virtual long Run()555{556for (GLuint i = 0; i < 16; ++i)557{558glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);559}560glBindBuffer(GL_ARRAY_BUFFER, m_vbo);561glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);562glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);563glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);564glBindBuffer(GL_ARRAY_BUFFER, 0);565566glBindVertexArray(m_vao);567glBindVertexBuffer(0, m_vbo, 0, 12);568glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);569glVertexAttribBinding(1, 0);570glEnableVertexAttribArray(1);571expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);572expected_data[16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);573return BasicInputBase::Run();574}575};576//=============================================================================577// 1.2.2 BasicInputCase2578//-----------------------------------------------------------------------------579class BasicInputCase2 : public BasicInputBase580{581582GLuint m_vao, m_vbo;583584virtual long Setup()585{586BasicInputBase::Setup();587glGenVertexArrays(1, &m_vao);588glGenBuffers(1, &m_vbo);589return NO_ERROR;590}591592virtual long Cleanup()593{594BasicInputBase::Cleanup();595glDeleteVertexArrays(1, &m_vao);596glDeleteBuffers(1, &m_vbo);597return NO_ERROR;598}599600virtual long Run()601{602for (GLuint i = 0; i < 16; ++i)603{604glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);605}606glBindBuffer(GL_ARRAY_BUFFER, m_vbo);607glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);608glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);609glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);610glBindBuffer(GL_ARRAY_BUFFER, 0);611612glBindVertexArray(m_vao);613glVertexAttribBinding(1, 0);614glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);615glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);616glVertexAttribFormat(7, 1, GL_FLOAT, GL_FALSE, 8);617glVertexAttribFormat(14, 2, GL_FLOAT, GL_FALSE, 4);618glVertexAttribBinding(0, 0);619glVertexAttribBinding(7, 0);620glVertexAttribBinding(14, 0);621glBindVertexBuffer(0, m_vbo, 0, 12);622glEnableVertexAttribArray(0);623glEnableVertexAttribArray(1);624glEnableVertexAttribArray(7);625glEnableVertexAttribArray(14);626627expected_data[0] = Vec4(1.0f, 2.0f, 0.0f, 1.0f);628expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);629expected_data[7] = Vec4(3.0f, 0.0f, 0.0f, 1.0f);630expected_data[14] = Vec4(2.0f, 3.0f, 0.0f, 1.0f);631expected_data[15] = Vec4(4.0f, 5.0f, 0.0f, 1.0f);632expected_data[16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);633expected_data[22] = Vec4(6.0f, 0.0f, 0.0f, 1.0f);634expected_data[29] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);635return BasicInputBase::Run();636}637};638//=============================================================================639// 1.2.3 BasicInputCase3640//-----------------------------------------------------------------------------641class BasicInputCase3 : public BasicInputBase642{643644GLuint m_vao, m_vbo;645646virtual long Setup()647{648BasicInputBase::Setup();649glGenVertexArrays(1, &m_vao);650glGenBuffers(1, &m_vbo);651return NO_ERROR;652}653654virtual long Cleanup()655{656BasicInputBase::Cleanup();657glDeleteVertexArrays(1, &m_vao);658glDeleteBuffers(1, &m_vbo);659return NO_ERROR;660}661662virtual long Run()663{664for (GLuint i = 0; i < 16; ++i)665{666glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);667}668glBindBuffer(GL_ARRAY_BUFFER, m_vbo);669glBufferData(GL_ARRAY_BUFFER, 36 * 2, NULL, GL_STATIC_DRAW);670/* */671{672GLubyte d[] = {1, 2, 3, 4};673glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);674}675glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec3), &Vec3(5.0f, 6.0f, 7.0f)[0]);676glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(Vec2), &Vec2(8.0f, 9.0f)[0]);677/* */678{679GLubyte d[] = {10, 11, 12, 13};680glBufferSubData(GL_ARRAY_BUFFER, 0 + 36, sizeof(d), d);681}682glBufferSubData(GL_ARRAY_BUFFER, 16 + 36, sizeof(Vec3), &Vec3(14.0f, 15.0f, 16.0f)[0]);683glBufferSubData(GL_ARRAY_BUFFER, 28 + 36, sizeof(Vec2), &Vec2(17.0f, 18.0f)[0]);684glBindBuffer(GL_ARRAY_BUFFER, 0);685686glBindVertexArray(m_vao);687glEnableVertexAttribArray(1);688glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0);689glVertexAttribBinding(1, 3);690glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 16);691glVertexAttribBinding(2, 3);692glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 28);693glVertexAttribBinding(0, 3);694glBindVertexBuffer(3, m_vbo, 0, 36);695glEnableVertexAttribArray(0);696glEnableVertexAttribArray(2);697698expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);699expected_data[1] = Vec4(5.0f, 6.0f, 7.0f, 1.0f);700expected_data[2] = Vec4(8.0f, 9.0f, 0.0f, 1.0f);701expected_data[0 + 15] = Vec4(10.0f, 11.0f, 12.0f, 13.0f);702expected_data[1 + 15] = Vec4(14.0f, 15.0f, 16.0f, 1.0f);703expected_data[2 + 15] = Vec4(17.0f, 18.0f, 0.0f, 1.0f);704return BasicInputBase::Run();705}706};707//=============================================================================708// 1.2.4 BasicInputCase4709//-----------------------------------------------------------------------------710class BasicInputCase4 : public BasicInputBase711{712713GLuint m_vao, m_vbo[2];714715virtual long Setup()716{717BasicInputBase::Setup();718glGenVertexArrays(1, &m_vao);719glGenBuffers(2, m_vbo);720return NO_ERROR;721}722723virtual long Cleanup()724{725BasicInputBase::Cleanup();726glDeleteVertexArrays(1, &m_vao);727glDeleteBuffers(2, m_vbo);728return NO_ERROR;729}730731virtual long Run()732{733for (GLuint i = 0; i < 16; ++i)734{735glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);736}737glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);738glBufferData(GL_ARRAY_BUFFER, 20 * 2, NULL, GL_STATIC_DRAW);739/* */740{741GLbyte d[] = {-127, 127, -127, 127};742glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);743}744/* */745{746GLushort d[] = {1, 2, 3, 4};747glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);748}749/* */750{751GLuint d[] = {5, 6};752glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);753}754/* */755{756GLbyte d[] = {127, -127, 127, -127};757glBufferSubData(GL_ARRAY_BUFFER, 0 + 20, sizeof(d), d);758}759/* */760{761GLushort d[] = {7, 8, 9, 10};762glBufferSubData(GL_ARRAY_BUFFER, 4 + 20, sizeof(d), d);763}764/* */765{766GLuint d[] = {11, 12};767glBufferSubData(GL_ARRAY_BUFFER, 12 + 20, sizeof(d), d);768}769glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);770glBufferData(GL_ARRAY_BUFFER, 24 * 2 + 8, NULL, GL_STATIC_DRAW);771/* */772{773GLhalf d[] = {FloatToHalf(0.0), FloatToHalf(100.0), FloatToHalf(200.0)};774glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);775}776/* */777{778GLhalf d[] = {FloatToHalf(300.0), FloatToHalf(400.0)};779glBufferSubData(GL_ARRAY_BUFFER, 26, sizeof(d), d);780}781glBindBuffer(GL_ARRAY_BUFFER, 0);782783glBindVertexArray(m_vao);784glVertexAttribFormat(0, 4, GL_BYTE, GL_TRUE, 0);785glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_FALSE, 4);786glVertexAttribFormat(2, 2, GL_UNSIGNED_INT, GL_FALSE, 12);787glVertexAttribFormat(5, 2, GL_HALF_FLOAT, GL_FALSE, 0);788glVertexAttribBinding(0, 0);789glVertexAttribBinding(1, 0);790glVertexAttribBinding(2, 0);791glVertexAttribBinding(5, 6);792glBindVertexBuffer(0, m_vbo[0], 0, 20);793glBindVertexBuffer(6, m_vbo[1], 2, 24);794glEnableVertexAttribArray(0);795glEnableVertexAttribArray(1);796glEnableVertexAttribArray(2);797glEnableVertexAttribArray(5);798799expected_data[0] = Vec4(-1.0f, 1.0f, -1.0f, 1.0f);800expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);801expected_data[2] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);802expected_data[5] = Vec4(100.0f, 200.0f, 0.0f, 1.0f);803expected_data[0 + 15] = Vec4(1.0f, -1.0f, 1.0f, -1.0f);804expected_data[1 + 15] = Vec4(7.0f, 8.0f, 9.0f, 10.0f);805expected_data[2 + 15] = Vec4(11.0f, 12.0f, 0.0f, 1.0f);806expected_data[5 + 15] = Vec4(300.0f, 400.0f, 0.0f, 1.0f);807return BasicInputBase::Run();808}809};810//=============================================================================811// 1.2.5 BasicInputCase5812//-----------------------------------------------------------------------------813class BasicInputCase5 : public BasicInputBase814{815816GLuint m_vao, m_vbo;817818virtual long Setup()819{820BasicInputBase::Setup();821glGenVertexArrays(1, &m_vao);822glGenBuffers(1, &m_vbo);823return NO_ERROR;824}825826virtual long Cleanup()827{828BasicInputBase::Cleanup();829glDeleteVertexArrays(1, &m_vao);830glDeleteBuffers(1, &m_vbo);831return NO_ERROR;832}833834virtual long Run()835{836for (GLuint i = 0; i < 16; ++i)837{838glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);839}840const int kStride = 116;841glBindBuffer(GL_ARRAY_BUFFER, m_vbo);842glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);843/* */844{845GLubyte d[] = {0, 0xff, 0xff / 2, 0};846glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);847}848/* */849{850GLushort d[] = {0, 0xffff, 0xffff / 2, 0};851glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);852}853/* */854{855GLuint d[] = {0, 0xffffffff, 0xffffffff / 2, 0};856glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);857}858/* */859{860GLbyte d[] = {0, -127, 127, 0};861glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);862}863/* */864{865GLshort d[] = {0, -32767, 32767, 0};866glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);867}868/* */869{870GLint d[] = {0, -2147483647, 2147483647, 0};871glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);872}873/* */874{875GLfloat d[] = {0, 1.0f, 2.0f, 0};876glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);877}878/* */879{880GLhalf d[] = {FloatToHalf(0.0), FloatToHalf(10.0), FloatToHalf(20.0), FloatToHalf(0.0)};881glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);882}883/* */884{885GLubyte d[] = {0, 0xff / 4, 0xff / 2, 0xff};886glBufferSubData(GL_ARRAY_BUFFER, 104, sizeof(d), d);887}888/* */889{890GLuint d = 0 | (1023 << 10) | (511 << 20) | (1 << 30);891glBufferSubData(GL_ARRAY_BUFFER, 108, sizeof(d), &d);892}893/* */894{895GLint d = 0 | (511 << 10) | (255 << 20) | (0 << 30);896glBufferSubData(GL_ARRAY_BUFFER, 112, sizeof(d), &d);897}898899/* */900{901GLubyte d[] = {0xff, 0xff, 0xff / 2, 0};902glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);903}904/* */905{906GLushort d[] = {0xffff, 0xffff, 0xffff / 2, 0};907glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);908}909/* */910{911GLuint d[] = {0xffffffff, 0xffffffff, 0xffffffff / 2, 0};912glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);913}914/* */915{916GLbyte d[] = {127, -127, 127, 0};917glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);918}919/* */920{921GLshort d[] = {32767, -32767, 32767, 0};922glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);923}924/* */925{926GLint d[] = {2147483647, -2147483647, 2147483647, 0};927glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);928}929/* */930{931GLfloat d[] = {0, 3.0f, 4.0f, 0};932glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);933}934/* */935{936GLhalf d[] = {FloatToHalf(0.0), FloatToHalf(30.0), FloatToHalf(40.0), FloatToHalf(0.0)};937glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);938}939/* */940{941GLubyte d[] = {0xff, 0xff / 2, 0xff / 4, 0};942glBufferSubData(GL_ARRAY_BUFFER, 104 + kStride, sizeof(d), d);943}944/* */945{946GLuint d = 0 | (1023 << 10) | (511 << 20) | (2u << 30);947glBufferSubData(GL_ARRAY_BUFFER, 108 + kStride, sizeof(d), &d);948}949/* */950{951GLint d = (-511 & 0x3ff) | (511 << 10) | (255 << 20) | 3 << 30;952glBufferSubData(GL_ARRAY_BUFFER, 112 + kStride, sizeof(d), &d);953}954glBindBuffer(GL_ARRAY_BUFFER, 0);955956glBindVertexArray(m_vao);957glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0);958glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_TRUE, 4);959glVertexAttribFormat(2, 4, GL_UNSIGNED_INT, GL_TRUE, 12);960glVertexAttribFormat(3, 4, GL_BYTE, GL_TRUE, 28);961glVertexAttribFormat(4, 4, GL_SHORT, GL_TRUE, 32);962glVertexAttribFormat(5, 4, GL_INT, GL_TRUE, 40);963glVertexAttribFormat(6, 4, GL_FLOAT, GL_TRUE, 56);964glVertexAttribFormat(7, 4, GL_HALF_FLOAT, GL_TRUE, 72);965glVertexAttribFormat(8, 4, GL_UNSIGNED_BYTE, GL_TRUE, 104);966glVertexAttribFormat(9, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 108);967glVertexAttribFormat(10, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 108);968glVertexAttribFormat(11, 4, GL_INT_2_10_10_10_REV, GL_TRUE, 112);969glVertexAttribFormat(12, 4, GL_INT_2_10_10_10_REV, GL_TRUE, 112);970for (GLuint i = 0; i < 13; ++i)971{972glVertexAttribBinding(i, 0);973glEnableVertexAttribArray(i);974}975glBindVertexBuffer(0, m_vbo, 0, kStride);976977expected_data[0] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);978expected_data[1] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);979expected_data[2] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);980expected_data[3] = Vec4(0.0f, -1.0f, 1.0f, 0.0f);981expected_data[4] = Vec4(0.0f, -1.0f, 1.0f, 0.0f);982expected_data[5] = Vec4(0.0f, -1.0f, 1.0f, 0.0f);983expected_data[6] = Vec4(0.0f, 1.0f, 2.0f, 0.0f);984expected_data[7] = Vec4(0.0f, 10.0f, 20.0f, 0.0f);985expected_data[8] = Vec4(0.0f, 0.25f, 0.5f, 1.0f);986expected_data[9] = Vec4(0.0f, 1.0f, 0.5f, 0.33f);987expected_data[10] = Vec4(0.0f, 1.0f, 0.5f, 0.33f);988expected_data[11] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);989expected_data[12] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);990expected_data[0 + 15] = Vec4(1.0f, 1.0f, 0.5f, 0.0f);991expected_data[1 + 15] = Vec4(1.0f, 1.0f, 0.5f, 0.0f);992expected_data[2 + 15] = Vec4(1.0f, 1.0f, 0.5f, 0.0f);993expected_data[3 + 15] = Vec4(1.0f, -1.0f, 1.0f, 0.0f);994expected_data[4 + 15] = Vec4(1.0f, -1.0f, 1.0f, 0.0f);995expected_data[5 + 15] = Vec4(1.0f, -1.0f, 1.0f, 0.0f);996expected_data[6 + 15] = Vec4(0.0f, 3.0f, 4.0f, 0.0f);997expected_data[7 + 15] = Vec4(0.0f, 30.0f, 40.0f, 0.0f);998expected_data[8 + 15] = Vec4(1.0f, 0.5f, 0.25f, 0.0f);999expected_data[9 + 15] = Vec4(0.0f, 1.0f, 0.5f, 0.66f);1000expected_data[10 + 15] = Vec4(0.0f, 1.0f, 0.5f, 0.66f);1001expected_data[11 + 15] = Vec4(-1.0f, 1.0f, 0.5f, -1.0f);1002expected_data[12 + 15] = Vec4(-1.0f, 1.0f, 0.5f, -1.0f);1003return BasicInputBase::Run();1004}1005};1006//=============================================================================1007// 1.2.6 BasicInputCase61008//-----------------------------------------------------------------------------1009class BasicInputCase6 : public BasicInputBase1010{10111012GLuint m_vao, m_vbo;10131014virtual long Setup()1015{1016BasicInputBase::Setup();1017glGenVertexArrays(1, &m_vao);1018glGenBuffers(1, &m_vbo);1019return NO_ERROR;1020}10211022virtual long Cleanup()1023{1024BasicInputBase::Cleanup();1025glDeleteVertexArrays(1, &m_vao);1026glDeleteBuffers(1, &m_vbo);1027return NO_ERROR;1028}10291030virtual long Run()1031{1032for (GLuint i = 0; i < 16; ++i)1033{1034glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);1035}1036const int kStride = 112;1037glBindBuffer(GL_ARRAY_BUFFER, m_vbo);1038glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);1039/* */1040{1041GLubyte d[] = {1, 2, 3, 4};1042glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);1043}1044/* */1045{1046GLushort d[] = {5, 6, 7, 8};1047glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);1048}1049/* */1050{1051GLuint d[] = {9, 10, 11, 12};1052glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);1053}1054/* */1055{1056GLbyte d[] = {-1, 2, -3, 4};1057glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);1058}1059/* */1060{1061GLshort d[] = {-5, 6, -7, 8};1062glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);1063}1064/* */1065{1066GLint d[] = {-9, 10, -11, 12};1067glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);1068}1069/* */1070{1071GLfloat d[] = {-13.0f, 14.0f, -15.0f, 16.0f};1072glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);1073}1074/* */1075{1076GLhalf d[] = {FloatToHalf(-18.0), FloatToHalf(19.0), FloatToHalf(-20.0),1077FloatToHalf(21.0)};1078glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);1079}1080/* */1081{1082GLuint d = 0 | (11 << 10) | (12 << 20) | (2u << 30);1083glBufferSubData(GL_ARRAY_BUFFER, 104, sizeof(d), &d);1084}1085/* */1086{1087GLint d = 0 | ((0xFFFFFFF5 << 10) & (0x3ff << 10)) | (12 << 20) | (1 << 30);1088glBufferSubData(GL_ARRAY_BUFFER, 108, sizeof(d), &d);1089}10901091/* */1092{1093GLubyte d[] = {22, 23, 24, 25};1094glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);1095}1096/* */1097{1098GLushort d[] = {26, 27, 28, 29};1099glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);1100}1101/* */1102{1103GLuint d[] = {30, 31, 32, 33};1104glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);1105}1106/* */1107{1108GLbyte d[] = {-34, 35, -36, 37};1109glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);1110}1111/* */1112{1113GLshort d[] = {-38, 39, -40, 41};1114glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);1115}1116/* */1117{1118GLint d[] = {-42, 43, -44, 45};1119glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);1120}1121/* */1122{1123GLfloat d[] = {-46.0f, 47.0f, -48.0f, 49.0f};1124glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);1125}1126/* */1127{1128GLhalf d[] = {FloatToHalf(-50.0), FloatToHalf(51.0), FloatToHalf(-52.0),1129FloatToHalf(53.0)};1130glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);1131}1132/* */1133{1134GLuint d = 0 | (11 << 10) | (12 << 20) | (1 << 30);1135glBufferSubData(GL_ARRAY_BUFFER, 104 + kStride, sizeof(d), &d);1136}1137/* */1138{1139GLint d = 123 | ((0xFFFFFFFD << 10) & (0x3ff << 10)) |1140((0xFFFFFE0C << 20) & (0x3ff << 20)) | ((0xFFFFFFFF << 30) & (0x3 << 30));1141glBufferSubData(GL_ARRAY_BUFFER, 108 + kStride, sizeof(d), &d);1142}1143glBindBuffer(GL_ARRAY_BUFFER, 0);11441145glBindVertexArray(m_vao);1146glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0);1147glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_FALSE, 4);1148glVertexAttribFormat(2, 4, GL_UNSIGNED_INT, GL_FALSE, 12);1149glVertexAttribFormat(3, 4, GL_BYTE, GL_FALSE, 28);1150glVertexAttribFormat(4, 4, GL_SHORT, GL_FALSE, 32);1151glVertexAttribFormat(5, 4, GL_INT, GL_FALSE, 40);1152glVertexAttribFormat(6, 4, GL_FLOAT, GL_FALSE, 56);1153glVertexAttribFormat(7, 4, GL_HALF_FLOAT, GL_FALSE, 72);1154glVertexAttribFormat(8, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 104);1155glVertexAttribFormat(9, 4, GL_INT_2_10_10_10_REV, GL_FALSE, 108);1156for (GLuint i = 0; i < 10; ++i)1157{1158glVertexAttribBinding(i, 0);1159glEnableVertexAttribArray(i);1160}1161glBindVertexBuffer(0, m_vbo, 0, kStride);11621163expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);1164expected_data[1] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);1165expected_data[2] = Vec4(9.0f, 10.0f, 11.0f, 12.0f);1166expected_data[3] = Vec4(-1.0f, 2.0f, -3.0f, 4.0f);1167expected_data[4] = Vec4(-5.0f, 6.0f, -7.0f, 8.0f);1168expected_data[5] = Vec4(-9.0f, 10.0f, -11.0f, 12.0f);1169expected_data[6] = Vec4(-13.0f, 14.0f, -15.0f, 16.0f);1170expected_data[7] = Vec4(-18.0f, 19.0f, -20.0f, 21.0f);1171expected_data[8] = Vec4(0.0f, 11.0f, 12.0f, 2.0f);1172expected_data[9] = Vec4(0.0f, -11.0f, 12.0f, 1.0f);1173expected_data[0 + 15] = Vec4(22.0f, 23.0f, 24.0f, 25.0f);1174expected_data[1 + 15] = Vec4(26.0f, 27.0f, 28.0f, 29.0f);1175expected_data[2 + 15] = Vec4(30.0f, 31.0f, 32.0f, 33.0f);1176expected_data[3 + 15] = Vec4(-34.0f, 35.0f, -36.0f, 37.0f);1177expected_data[4 + 15] = Vec4(-38.0f, 39.0f, -40.0f, 41.0f);1178expected_data[5 + 15] = Vec4(-42.0f, 43.0f, -44.0f, 45.0f);1179expected_data[6 + 15] = Vec4(-46.0f, 47.0f, -48.0f, 49.0f);1180expected_data[7 + 15] = Vec4(-50.0f, 51.0f, -52.0f, 53.0f);1181expected_data[8 + 15] = Vec4(0.0f, 11.0f, 12.0f, 1.0f);1182expected_data[9 + 15] = Vec4(123.0f, -3.0f, -500.0f, -1.0f);1183return BasicInputBase::Run();1184}1185};1186//=============================================================================1187// 1.2.8 BasicInputCase81188//-----------------------------------------------------------------------------1189class BasicInputCase8 : public BasicInputBase1190{11911192GLuint m_vao, m_vbo[2];11931194virtual long Setup()1195{1196BasicInputBase::Setup();1197glGenVertexArrays(1, &m_vao);1198glGenBuffers(2, m_vbo);1199return NO_ERROR;1200}12011202virtual long Cleanup()1203{1204BasicInputBase::Cleanup();1205glDeleteVertexArrays(1, &m_vao);1206glDeleteBuffers(2, m_vbo);1207return NO_ERROR;1208}12091210virtual long Run()1211{1212for (GLuint i = 0; i < 16; ++i)1213{1214glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);1215}1216glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);1217glBufferData(GL_ARRAY_BUFFER, 6 * 4, NULL, GL_STATIC_DRAW);1218/* */1219{1220GLfloat d[] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f};1221glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);1222}12231224glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);1225glBufferData(GL_ARRAY_BUFFER, 10 * 4, NULL, GL_STATIC_DRAW);1226/* */1227{1228GLfloat d[] = {-1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f, -9.0f, -10.0f};1229glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);1230}1231glBindBuffer(GL_ARRAY_BUFFER, 0);12321233glBindVertexArray(m_vao);1234glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);1235glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);1236glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 4);1237glVertexAttribFormat(5, 4, GL_FLOAT, GL_FALSE, 12);1238glVertexAttribFormat(14, 2, GL_FLOAT, GL_FALSE, 8);1239glVertexAttribBinding(0, 0);1240glVertexAttribBinding(1, 1);1241glVertexAttribBinding(2, 1);1242glVertexAttribBinding(5, 15);1243glVertexAttribBinding(14, 7);1244glBindVertexBuffer(0, m_vbo[0], 0, 12);1245glBindVertexBuffer(1, m_vbo[0], 4, 4);1246glBindVertexBuffer(7, m_vbo[1], 8, 16);1247glBindVertexBuffer(15, m_vbo[1], 12, 0);1248glEnableVertexAttribArray(0);1249glEnableVertexAttribArray(1);1250glEnableVertexAttribArray(2);1251glEnableVertexAttribArray(5);1252glEnableVertexAttribArray(14);12531254expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);1255expected_data[1] = Vec4(2.0f, 3.0f, 4.0f, 1.0f);1256expected_data[2] = Vec4(3.0f, 0.0f, 0.0f, 1.0f);1257expected_data[5] = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);1258expected_data[14] = Vec4(-5.0f, -6.0f, 0.0f, 1.0f);1259expected_data[0 + 15] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);1260expected_data[1 + 15] = Vec4(3.0f, 4.0f, 5.0f, 1.0f);1261expected_data[2 + 15] = Vec4(4.0f, 0.0f, 0.0f, 1.0f);1262expected_data[5 + 15] = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);1263expected_data[14 + 15] = Vec4(-9.0f, -10.0f, 0.0f, 1.0f);1264return BasicInputBase::Run();1265}1266};1267//=============================================================================1268// 1.2.9 BasicInputCase91269//-----------------------------------------------------------------------------1270class BasicInputCase9 : public BasicInputBase1271{12721273GLuint m_vao, m_vbo[2];12741275virtual long Setup()1276{1277BasicInputBase::Setup();1278glGenVertexArrays(1, &m_vao);1279glGenBuffers(2, m_vbo);1280return NO_ERROR;1281}12821283virtual long Cleanup()1284{1285BasicInputBase::Cleanup();1286glDeleteVertexArrays(1, &m_vao);1287glDeleteBuffers(2, m_vbo);1288return NO_ERROR;1289}12901291virtual long Run()1292{1293for (GLuint i = 0; i < 16; ++i)1294{1295glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);1296}1297glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);1298glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);1299glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(1.0f, 2.0f, 3.0f, 4.0f)[0]);1300glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(5.0f, 6.0f, 7.0f, 8.0f)[0]);1301glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(Vec4), &Vec4(9.0f, 10.0f, 11.0f, 12.0f)[0]);1302glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);1303glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);1304glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(10.0f, 20.0f, 30.0f, 40.0f)[0]);1305glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(50.0f, 60.0f, 70.0f, 80.0f)[0]);1306glBindBuffer(GL_ARRAY_BUFFER, 0);13071308glBindVertexArray(m_vao);1309glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);1310glVertexAttribFormat(2, 4, GL_FLOAT, GL_FALSE, 0);1311glVertexAttribFormat(4, 2, GL_FLOAT, GL_FALSE, 4);1312glVertexAttribBinding(0, 0);1313glVertexAttribBinding(2, 1);1314glVertexAttribBinding(4, 3);1315glEnableVertexAttribArray(0);1316glEnableVertexAttribArray(2);1317glEnableVertexAttribArray(4);1318glBindVertexBuffer(0, m_vbo[0], 0, 16);1319glBindVertexBuffer(1, m_vbo[0], 0, 16);1320glBindVertexBuffer(3, m_vbo[1], 4, 8);1321glVertexBindingDivisor(1, 1);13221323instance_count = 2;1324expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);1325expected_data[2] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);1326expected_data[4] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);1327expected_data[0 + 15] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);1328expected_data[2 + 15] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);1329expected_data[4 + 15] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);13301331expected_data[0 + 30] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);1332expected_data[2 + 30] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);1333expected_data[4 + 30] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);1334expected_data[0 + 15 + 30] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);1335expected_data[2 + 15 + 30] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);1336expected_data[4 + 15 + 30] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);1337return BasicInputBase::Run();1338}1339};1340//=============================================================================1341// 1.2.11 BasicInputCase111342//-----------------------------------------------------------------------------1343class BasicInputCase11 : public BasicInputBase1344{13451346GLuint m_vao, m_vbo[2];13471348virtual long Setup()1349{1350BasicInputBase::Setup();1351glGenVertexArrays(1, &m_vao);1352glGenBuffers(2, m_vbo);1353return NO_ERROR;1354}13551356virtual long Cleanup()1357{1358BasicInputBase::Cleanup();1359glDeleteVertexArrays(1, &m_vao);1360glDeleteBuffers(2, m_vbo);1361return NO_ERROR;1362}13631364virtual long Run()1365{1366for (GLuint i = 0; i < 16; ++i)1367{1368glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);1369}1370glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);1371glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);1372glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(1.0f, 2.0f, 3.0f, 4.0f)[0]);1373glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(5.0f, 6.0f, 7.0f, 8.0f)[0]);1374glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(Vec4), &Vec4(9.0f, 10.0f, 11.0f, 12.0f)[0]);1375glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);1376glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);1377glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(10.0f, 20.0f, 30.0f, 40.0f)[0]);1378glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(50.0f, 60.0f, 70.0f, 80.0f)[0]);1379glBindBuffer(GL_ARRAY_BUFFER, 0);13801381glBindVertexArray(m_vao);1382glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);1383glVertexAttribFormat(2, 4, GL_FLOAT, GL_FALSE, 0);1384glVertexAttribFormat(4, 2, GL_FLOAT, GL_FALSE, 4);1385glVertexAttribBinding(0, 0);1386glVertexAttribBinding(2, 1);1387glVertexAttribBinding(4, 2);1388glEnableVertexAttribArray(0);1389glEnableVertexAttribArray(2);1390glEnableVertexAttribArray(4);1391glBindVertexBuffer(0, m_vbo[0], 0, 16);1392glBindVertexBuffer(1, m_vbo[0], 0, 16);1393glBindVertexBuffer(2, m_vbo[1], 4, 8);1394glVertexBindingDivisor(1, 1);13951396instance_count = 2;1397expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);1398expected_data[2] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);1399expected_data[4] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);1400expected_data[0 + 15] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);1401expected_data[2 + 15] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);1402expected_data[4 + 15] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);14031404expected_data[0 + 30] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);1405expected_data[2 + 30] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);1406expected_data[4 + 30] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);1407expected_data[0 + 15 + 30] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);1408expected_data[2 + 15 + 30] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);1409expected_data[4 + 15 + 30] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);1410return BasicInputBase::Run();1411}1412};1413//=============================================================================1414// 1.2.12 BasicInputCase121415//-----------------------------------------------------------------------------1416class BasicInputCase12 : public BasicInputBase1417{14181419GLuint m_vao, m_vbo;14201421virtual long Setup()1422{1423BasicInputBase::Setup();1424glGenVertexArrays(1, &m_vao);1425glGenBuffers(1, &m_vbo);1426return NO_ERROR;1427}14281429virtual long Cleanup()1430{1431BasicInputBase::Cleanup();1432glDeleteVertexArrays(1, &m_vao);1433glDeleteBuffers(1, &m_vbo);1434return NO_ERROR;1435}14361437virtual long Run()1438{1439for (GLuint i = 0; i < 16; ++i)1440{1441glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);1442}1443glBindBuffer(GL_ARRAY_BUFFER, m_vbo);1444glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);1445glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);1446glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);1447glBindBuffer(GL_ARRAY_BUFFER, 0);14481449glBindVertexArray(m_vao);14501451// glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);1452// glVertexAttribBinding(1, 1);1453// glBindVertexBuffer(1, m_vbo, 0, 12);1454glBindBuffer(GL_ARRAY_BUFFER, m_vbo);1455glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 12, 0);1456glBindBuffer(GL_ARRAY_BUFFER, 0);14571458glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);1459glVertexAttribBinding(0, 1);14601461glEnableVertexAttribArray(0);1462glEnableVertexAttribArray(1);14631464expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);1465expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);1466expected_data[0 + 15] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);1467expected_data[1 + 15] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);1468return BasicInputBase::Run();1469}1470};1471//=============================================================================1472// BasicInputIBase1473//-----------------------------------------------------------------------------1474class BasicInputIBase : public VertexAttribBindingBase1475{14761477GLuint m_po, m_xfbo;14781479protected:1480IVec4 expected_datai[32];1481UVec4 expected_dataui[32];1482GLsizei instance_count;1483GLuint base_instance;14841485virtual long Setup()1486{1487m_po = 0;1488glGenBuffers(1, &m_xfbo);1489for (int i = 0; i < 32; ++i)1490{1491expected_datai[i] = IVec4(0);1492expected_dataui[i] = UVec4(0);1493}1494instance_count = 1;1495return NO_ERROR;1496}14971498virtual long Cleanup()1499{1500glDisable(GL_RASTERIZER_DISCARD);1501glUseProgram(0);1502glDeleteProgram(m_po);1503glDeleteBuffers(1, &m_xfbo);1504return NO_ERROR;1505}15061507virtual long Run()1508{1509const char *const glsl_vs =1510"#version 310 es" NL "layout(location = 0) in ivec4 vs_in_attribi0;" NL1511"layout(location = 1) in ivec4 vs_in_attribi1;" NL1512"layout(location = 2) in ivec4 vs_in_attribi2;" NL1513"layout(location = 3) in ivec4 vs_in_attribi3;" NL1514"layout(location = 4) in ivec4 vs_in_attribi4;" NL1515"layout(location = 5) in ivec4 vs_in_attribi5;" NL1516"layout(location = 6) in ivec4 vs_in_attribi6;" NL1517"layout(location = 7) in ivec4 vs_in_attribi7;" NL1518"layout(location = 8) in uvec4 vs_in_attribui8;" NL1519"layout(location = 9) in uvec4 vs_in_attribui9;" NL1520"layout(location = 10) in uvec4 vs_in_attribui10;" NL1521"layout(location = 11) in uvec4 vs_in_attribui11;" NL1522"layout(location = 12) in uvec4 vs_in_attribui12;" NL1523"layout(location = 13) in uvec4 vs_in_attribui13;" NL1524"layout(location = 14) in uvec4 vs_in_attribui14;" NL1525"layout(location = 15) in uvec4 vs_in_attribui15;" NL "flat out ivec4 attribi[8];" NL1526"flat out uvec4 attribui[7];" NL "void main() {" NL " attribi[0] = vs_in_attribi0;" NL1527" attribi[1] = vs_in_attribi1;" NL " attribi[2] = vs_in_attribi2;" NL1528" attribi[3] = vs_in_attribi3;" NL " attribi[4] = vs_in_attribi4;" NL1529" attribi[5] = vs_in_attribi5;" NL " attribi[6] = vs_in_attribi6;" NL1530" attribi[7] = vs_in_attribi7;" NL " attribui[0] = vs_in_attribui8;" NL1531" attribui[1] = vs_in_attribui9;" NL " attribui[2] = vs_in_attribui10;" NL1532" attribui[3] = vs_in_attribui11;" NL " attribui[4] = vs_in_attribui12;" NL1533" attribui[5] = vs_in_attribui13;" NL " attribui[6] = vs_in_attribui14;" NL "}";1534const char *const glsl_fs =1535"#version 310 es" NL "precision mediump float;" NL "flat in ivec4 attribi[8];" NL1536"flat in uvec4 attribui[7];" NL "out vec4 fs_out_color;" NL "void main() {" NL1537" fs_out_color = vec4(attribui[1]);" NL "}";1538m_po = glCreateProgram();1539/* attach shader */1540{1541const GLuint sh = glCreateShader(GL_VERTEX_SHADER);1542const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);1543glShaderSource(sh, 1, &glsl_vs, NULL);1544glShaderSource(fsh, 1, &glsl_fs, NULL);1545glCompileShader(sh);1546glCompileShader(fsh);1547glAttachShader(m_po, sh);1548glAttachShader(m_po, fsh);1549glDeleteShader(sh);1550glDeleteShader(fsh);1551}1552/* setup XFB */1553{1554const GLchar *const v[2] = {"attribi", "attribui"};1555glTransformFeedbackVaryings(m_po, 2, v, GL_INTERLEAVED_ATTRIBS);1556}1557glLinkProgram(m_po);1558if (!CheckProgram(m_po))1559return ERROR;15601561/* buffer data */1562{1563std::vector<GLubyte> zero(64 * 16);1564glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);1565glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (GLsizeiptr)zero.size(), &zero[0],1566GL_DYNAMIC_COPY);1567}15681569glEnable(GL_RASTERIZER_DISCARD);1570glUseProgram(m_po);1571glBeginTransformFeedback(GL_POINTS);1572glDrawArraysInstanced(GL_POINTS, 0, 2, instance_count);1573glEndTransformFeedback();15741575void *data =1576glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(UVec4) * 64, GL_MAP_READ_BIT);1577IVec4 *datai = static_cast<IVec4 *>(data);1578UVec4 *dataui = (static_cast<UVec4 *>(data)) + 8;15791580for (int i = 0; i < 4; ++i)1581for (int j = 0; j < 8; ++j)1582{1583if (!IsEqual(expected_datai[i * 8 + j], datai[i * 15 + j]))1584{1585m_context.getTestContext().getLog()1586<< tcu::TestLog::Message << "Datai is: " << datai[i * 15 + j][0] << " "1587<< datai[i * 15 + j][1] << " " << datai[i * 15 + j][2] << " "1588<< datai[i * 15 + j][3]1589<< ", data should be: " << expected_datai[i * 8 + j][0] << " "1590<< expected_datai[i * 8 + j][1] << " " << expected_datai[i * 8 + j][2]1591<< " " << expected_datai[i * 8 + j][3] << ", index is: " << i * 8 + j1592<< tcu::TestLog::EndMessage;1593return ERROR;1594}1595if (j != 7 && !IsEqual(expected_dataui[i * 8 + j], dataui[i * 15 + j]))1596{1597m_context.getTestContext().getLog()1598<< tcu::TestLog::Message << "Dataui is: " << dataui[i * 15 + j][0] << " "1599<< dataui[i * 15 + j][1] << " " << dataui[i * 15 + j][2] << " "1600<< dataui[i * 15 + j][3]1601<< ", data should be: " << expected_datai[i * 8 + j][0] << " "1602<< expected_datai[i * 8 + j][1] << " " << expected_datai[i * 8 + j][2]1603<< " " << expected_datai[i * 8 + j][3] << ", index is: " << i * 8 + j1604<< tcu::TestLog::EndMessage;1605return ERROR;1606}1607}1608return NO_ERROR;1609}1610};1611//=============================================================================1612// 1.3.1 BasicInputICase11613//-----------------------------------------------------------------------------1614class BasicInputICase1 : public BasicInputIBase1615{16161617GLuint m_vao, m_vbo;16181619virtual long Setup()1620{1621BasicInputIBase::Setup();1622glGenVertexArrays(1, &m_vao);1623glGenBuffers(1, &m_vbo);1624return NO_ERROR;1625}16261627virtual long Cleanup()1628{1629BasicInputIBase::Cleanup();1630glDeleteVertexArrays(1, &m_vao);1631glDeleteBuffers(1, &m_vbo);1632return NO_ERROR;1633}16341635virtual long Run()1636{1637for (GLuint i = 0; i < 8; ++i)1638{1639glVertexAttribI4i(i, 0, 0, 0, 0);1640glVertexAttribI4ui(i + 8, 0, 0, 0, 0);1641}1642const int kStride = 88;1643glBindBuffer(GL_ARRAY_BUFFER, m_vbo);1644glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);1645/* */1646{1647GLbyte d[] = {1, -2, 3, -4};1648glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);1649}1650/* */1651{1652GLshort d[] = {5, -6, 7, -8};1653glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);1654}1655/* */1656{1657GLint d[] = {9, -10, 11, -12};1658glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);1659}1660/* */1661{1662GLubyte d[] = {13, 14, 15, 16};1663glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);1664}1665/* */1666{1667GLushort d[] = {17, 18, 19, 20};1668glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);1669}1670/* */1671{1672GLuint d[] = {21, 22, 23, 24};1673glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);1674}1675/* */1676{1677GLint d[] = {90, -91, 92, -93};1678glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);1679}1680/* */1681{1682GLuint d[] = {94, 95, 96, 97};1683glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);1684}16851686/* */1687{1688GLbyte d[] = {25, -26, 27, -28};1689glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);1690}1691/* */1692{1693GLshort d[] = {29, -30, 31, -32};1694glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);1695}1696/* */1697{1698GLint d[] = {33, -34, 35, -36};1699glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);1700}1701/* */1702{1703GLubyte d[] = {37, 38, 39, 40};1704glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);1705}1706/* */1707{1708GLushort d[] = {41, 42, 43, 44};1709glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);1710}1711/* */1712{1713GLuint d[] = {45, 46, 47, 48};1714glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);1715}1716/* */1717{1718GLint d[] = {98, -99, 100, -101};1719glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);1720}1721/* */1722{1723GLuint d[] = {102, 103, 104, 105};1724glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);1725}1726glBindBuffer(GL_ARRAY_BUFFER, 0);17271728glBindVertexArray(m_vao);1729glVertexAttribIFormat(0, 1, GL_BYTE, 0);1730glVertexAttribIFormat(1, 2, GL_SHORT, 4);1731glVertexAttribIFormat(2, 3, GL_INT, 12);1732glVertexAttribIFormat(3, 4, GL_INT, 56);1733glVertexAttribIFormat(8, 3, GL_UNSIGNED_BYTE, 28);1734glVertexAttribIFormat(9, 2, GL_UNSIGNED_SHORT, 32);1735glVertexAttribIFormat(10, 1, GL_UNSIGNED_INT, 40);1736glVertexAttribIFormat(11, 4, GL_UNSIGNED_INT, 72);1737glVertexAttribBinding(0, 0);1738glVertexAttribBinding(1, 0);1739glVertexAttribBinding(2, 0);1740glVertexAttribBinding(3, 0);1741glVertexAttribBinding(8, 0);1742glVertexAttribBinding(9, 0);1743glVertexAttribBinding(10, 0);1744glVertexAttribBinding(11, 0);1745glBindVertexBuffer(0, m_vbo, 0, kStride);1746glEnableVertexAttribArray(0);1747glEnableVertexAttribArray(1);1748glEnableVertexAttribArray(2);1749glEnableVertexAttribArray(3);1750glEnableVertexAttribArray(8);1751glEnableVertexAttribArray(9);1752glEnableVertexAttribArray(10);1753glEnableVertexAttribArray(11);17541755expected_datai[0] = IVec4(1, 0, 0, 1);1756expected_datai[1] = IVec4(5, -6, 0, 1);1757expected_datai[2] = IVec4(9, -10, 11, 1);1758expected_datai[3] = IVec4(90, -91, 92, -93);1759expected_dataui[0] = UVec4(13, 14, 15, 1);1760expected_dataui[1] = UVec4(17, 18, 0, 1);1761expected_dataui[2] = UVec4(21, 0, 0, 1);1762expected_dataui[3] = UVec4(94, 95, 96, 97);1763expected_datai[8] = IVec4(25, 0, 0, 1);1764expected_datai[9] = IVec4(29, -30, 0, 1);1765expected_datai[10] = IVec4(33, -34, 35, 1);1766expected_datai[11] = IVec4(98, -99, 100, -101);1767expected_dataui[8] = UVec4(37, 38, 39, 1);1768expected_dataui[9] = UVec4(41, 42, 0, 1);1769expected_dataui[10] = UVec4(45, 0, 0, 1);1770expected_dataui[11] = UVec4(102, 103, 104, 105);1771return BasicInputIBase::Run();1772}1773};1774//=============================================================================1775// 1.3.2 BasicInputICase21776//-----------------------------------------------------------------------------1777class BasicInputICase2 : public BasicInputIBase1778{17791780GLuint m_vao, m_vbo[2];17811782virtual long Setup()1783{1784BasicInputIBase::Setup();1785glGenVertexArrays(1, &m_vao);1786glGenBuffers(2, m_vbo);1787return NO_ERROR;1788}17891790virtual long Cleanup()1791{1792BasicInputIBase::Cleanup();1793glDeleteVertexArrays(1, &m_vao);1794glDeleteBuffers(2, m_vbo);1795return NO_ERROR;1796}17971798virtual long Run()1799{1800for (GLuint i = 0; i < 8; ++i)1801{1802glVertexAttribI4i(i, 0, 0, 0, 0);1803glVertexAttribI4ui(i + 8, 0, 0, 0, 0);1804}1805glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);1806glBufferData(GL_ARRAY_BUFFER, sizeof(IVec3) * 2, NULL, GL_STATIC_DRAW);1807glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(IVec3), &IVec3(1, 2, 3)[0]);1808glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(IVec3), &IVec3(4, 5, 6)[0]);18091810glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);1811glBufferData(GL_ARRAY_BUFFER, sizeof(UVec4), NULL, GL_STATIC_DRAW);1812glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(UVec4), &UVec4(10, 20, 30, 40)[0]);1813glBindBuffer(GL_ARRAY_BUFFER, 0);18141815glBindVertexArray(m_vao);1816glVertexAttribIFormat(0, 3, GL_INT, 0);1817glVertexAttribIFormat(2, 2, GL_INT, 4);1818glVertexAttribIFormat(14, 1, GL_UNSIGNED_INT, 0);1819glVertexAttribBinding(0, 2);1820glVertexAttribBinding(2, 0);1821glVertexAttribBinding(14, 7);1822glEnableVertexAttribArray(0);1823glEnableVertexAttribArray(2);1824glEnableVertexAttribArray(14);1825glBindVertexBuffer(0, m_vbo[0], 0, 8);1826glBindVertexBuffer(2, m_vbo[0], 0, 12);1827glBindVertexBuffer(7, m_vbo[1], 4, 16);1828glVertexBindingDivisor(0, 1);1829glVertexBindingDivisor(2, 0);1830glVertexBindingDivisor(7, 2);18311832instance_count = 2;1833expected_datai[0] = IVec4(1, 2, 3, 1);1834expected_datai[2] = IVec4(2, 3, 0, 1);1835expected_dataui[6] = UVec4(20, 0, 0, 1);1836expected_datai[8] = IVec4(4, 5, 6, 1);1837expected_datai[10] = IVec4(2, 3, 0, 1);1838expected_dataui[14] = UVec4(20, 0, 0, 1);18391840expected_datai[16] = IVec4(1, 2, 3, 1);1841expected_datai[18] = IVec4(4, 5, 0, 1);1842expected_dataui[22] = UVec4(20, 0, 0, 1);1843expected_datai[24] = IVec4(4, 5, 6, 1);1844expected_datai[26] = IVec4(4, 5, 0, 1);1845expected_dataui[30] = UVec4(20, 0, 0, 1);1846return BasicInputIBase::Run();1847}1848};1849//=============================================================================1850// 1.3.3 BasicInputICase31851//-----------------------------------------------------------------------------1852class BasicInputICase3 : public BasicInputIBase1853{18541855GLuint m_vao, m_vbo;18561857virtual long Setup()1858{1859BasicInputIBase::Setup();1860glGenVertexArrays(1, &m_vao);1861glGenBuffers(1, &m_vbo);1862return NO_ERROR;1863}18641865virtual long Cleanup()1866{1867BasicInputIBase::Cleanup();1868glDeleteVertexArrays(1, &m_vao);1869glDeleteBuffers(1, &m_vbo);1870return NO_ERROR;1871}18721873virtual long Run()1874{1875for (GLuint i = 0; i < 8; ++i)1876{1877glVertexAttribI4i(i, 0, 0, 0, 0);1878glVertexAttribI4ui(i + 8, 0, 0, 0, 0);1879}1880glBindBuffer(GL_ARRAY_BUFFER, m_vbo);1881glBufferData(GL_ARRAY_BUFFER, sizeof(IVec3) * 2, NULL, GL_STATIC_DRAW);1882glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(IVec3), &IVec3(1, 2, 3)[0]);1883glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(IVec3), &IVec3(4, 5, 6)[0]);1884glBindBuffer(GL_ARRAY_BUFFER, 0);18851886glBindVertexArray(m_vao);18871888glBindBuffer(GL_ARRAY_BUFFER, m_vbo);1889glVertexAttribIPointer(7, 3, GL_INT, 12, 0);1890glBindBuffer(GL_ARRAY_BUFFER, 0);18911892glVertexAttribIFormat(0, 2, GL_INT, 4);1893glVertexAttribBinding(0, 7);18941895glEnableVertexAttribArray(0);1896glEnableVertexAttribArray(7);18971898expected_datai[0] = IVec4(2, 3, 0, 1);1899expected_datai[7] = IVec4(1, 2, 3, 1);1900expected_datai[0 + 8] = IVec4(5, 6, 0, 1);1901expected_datai[7 + 8] = IVec4(4, 5, 6, 1);1902return BasicInputIBase::Run();1903}1904};19051906class VertexAttribState : public glcts::GLWrapper1907{1908public:1909int array_enabled;1910int array_size;1911int array_stride;1912int array_type;1913int array_normalized;1914int array_integer;1915int array_divisor;1916deUintptr array_pointer;1917int array_buffer_binding;1918int binding;1919int relative_offset;1920int index;19211922VertexAttribState(int attribindex)1923: array_enabled(0),1924array_size(4),1925array_stride(0),1926array_type(GL_FLOAT),1927array_normalized(0),1928array_integer(0),1929array_divisor(0),1930array_pointer(0),1931array_buffer_binding(0),1932binding(attribindex),1933relative_offset(0),1934index(attribindex)1935{}19361937bool stateVerify()1938{1939GLint p;1940bool status = true;1941glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &p);1942if (p != array_enabled)1943{1944m_context.getTestContext().getLog()1945<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_ENABLED(" << index << ") is "1946<< p << " should be " << array_enabled << tcu::TestLog::EndMessage;1947status = false;1948}1949glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);1950if (p != array_size)1951{1952m_context.getTestContext().getLog()1953<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(" << index << ") is " << p1954<< " should be " << array_size << tcu::TestLog::EndMessage;1955status = false;1956}1957glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &p);1958if (p != array_stride)1959{1960m_context.getTestContext().getLog()1961<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_STRIDE(" << index << ") is "1962<< p << " should be " << array_stride << tcu::TestLog::EndMessage;1963status = false;1964}1965glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);1966if (p != array_type)1967{1968m_context.getTestContext().getLog()1969<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(" << index << ") is "1970<< tcu::toHex(p) << " should be " << tcu::toHex(array_type)1971<< tcu::TestLog::EndMessage;1972status = false;1973}1974glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &p);1975if (p != array_normalized)1976{1977m_context.getTestContext().getLog()1978<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED(" << index << ") is "1979<< p << " should be " << array_normalized << tcu::TestLog::EndMessage;1980status = false;1981}1982glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_INTEGER, &p);1983if (p != array_integer)1984{1985m_context.getTestContext().getLog()1986<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_INTEGER(" << index << ") is "1987<< p << " should be " << array_integer << tcu::TestLog::EndMessage;1988status = false;1989}1990glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, &p);1991if (p != array_divisor)1992{1993m_context.getTestContext().getLog()1994<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_DIVISOR(" << index << ") is "1995<< p << " should be " << array_divisor << tcu::TestLog::EndMessage;1996status = false;1997}1998void *pp;1999glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &pp);2000if (reinterpret_cast<deUintptr>(pp) != array_pointer)2001{2002m_context.getTestContext().getLog()2003<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_POINTER(" << index << ") is "2004<< pp << " should be " << reinterpret_cast<void *>(array_pointer)2005<< tcu::TestLog::EndMessage;2006status = false;2007}2008glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &p);2009if (p != array_buffer_binding)2010{2011m_context.getTestContext().getLog()2012<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(" << index2013<< ") is " << p << " should be " << array_buffer_binding2014<< tcu::TestLog::EndMessage;2015status = false;2016}2017glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_BINDING, &p);2018if (static_cast<GLint>(binding) != p)2019{2020m_context.getTestContext().getLog()2021<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_BINDING(" << index << ") is " << p2022<< " should be " << binding << tcu::TestLog::EndMessage;2023status = false;2024}2025glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);2026if (p != relative_offset)2027{2028m_context.getTestContext().getLog()2029<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(" << index << ") is "2030<< p << " should be " << relative_offset << tcu::TestLog::EndMessage;2031status = false;2032}2033return status;2034}2035};2036class VertexBindingState : public glcts::GLWrapper2037{2038public:2039int buffer;2040long int offset;2041int stride;2042int divisor;2043int index;20442045VertexBindingState(int bindingindex)2046: buffer(0), offset(0), stride(16), divisor(0), index(bindingindex)2047{}2048bool stateVerify()2049{2050bool status = true;2051GLint p;2052glGetIntegeri_v(GL_VERTEX_BINDING_BUFFER, index, &p);2053if (p != buffer)2054{2055m_context.getTestContext().getLog()2056<< tcu::TestLog::Message << "GL_VERTEX_BINDING_BUFFER(" << index << ") is " << p2057<< " should be " << buffer << tcu::TestLog::EndMessage;2058status = false;2059}2060GLint64 p64;2061glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, index, &p64);2062if (p64 != offset)2063{2064m_context.getTestContext().getLog()2065<< tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(" << index << ") is " << p642066<< " should be " << offset << tcu::TestLog::EndMessage;2067status = false;2068}2069glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, index, &p);2070if (p != stride)2071{2072m_context.getTestContext().getLog()2073<< tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(" << index << ") is " << p2074<< " should be " << stride << tcu::TestLog::EndMessage;2075status = false;2076}2077glGetIntegeri_v(GL_VERTEX_BINDING_DIVISOR, index, &p);2078if (p != divisor)2079{2080m_context.getTestContext().getLog()2081<< tcu::TestLog::Message << "GL_VERTEX_BINDING_DIVISOR(" << index << ") is " << p2082<< " should be " << divisor << tcu::TestLog::EndMessage;2083status = false;2084}2085return status;2086}2087};2088//=============================================================================2089// 1.5 BasicState12090//-----------------------------------------------------------------------------2091class BasicState1 : public VertexAttribBindingBase2092{20932094GLuint m_vao, m_vbo[3];20952096virtual long Setup()2097{2098glGenVertexArrays(1, &m_vao);2099glGenBuffers(3, m_vbo);2100return NO_ERROR;2101}21022103virtual long Cleanup()2104{2105glDeleteVertexArrays(1, &m_vao);2106glDeleteBuffers(3, m_vbo);2107return NO_ERROR;2108}21092110virtual long Run()2111{2112bool status = true;2113glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);2114glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);2115glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);2116glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);2117glBindBuffer(GL_ARRAY_BUFFER, m_vbo[2]);2118glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);2119glBindBuffer(GL_ARRAY_BUFFER, 0);21202121GLint p;2122glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);2123if (p < 16)2124{2125m_context.getTestContext().getLog()2126<< tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_BINDINGS is" << p2127<< "but must be at least 16." << tcu::TestLog::EndMessage;2128status = false;2129}2130glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);2131if (p < 2047)2132{2133m_context.getTestContext().getLog()2134<< tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET is" << p2135<< "but must be at least 2047." << tcu::TestLog::EndMessage;2136status = false;2137}2138glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &p);2139if (p < 2048)2140{2141m_context.getTestContext().getLog()2142<< tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_STRIDE is" << p2143<< "but must be at least 2048." << tcu::TestLog::EndMessage;2144status = false;2145}21462147glBindVertexArray(m_vao);2148// check default state2149glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &p);2150if (0 != p)2151{2152m_context.getTestContext().getLog()2153<< tcu::TestLog::Message << "GL_ELEMENT_ARRAY_BUFFER_BINDING is" << p2154<< "should be 0." << tcu::TestLog::EndMessage;2155status = false;2156}2157for (GLuint i = 0; i < 16; ++i)2158{2159VertexAttribState va(i);2160if (!va.stateVerify())2161status = false;2162}2163for (GLuint i = 0; i < 16; ++i)2164{2165VertexBindingState vb(i);2166if (!vb.stateVerify())2167status = false;2168}2169if (!status)2170{2171m_context.getTestContext().getLog()2172<< tcu::TestLog::Message << "Default state check failed."2173<< tcu::TestLog::EndMessage;2174status = false;2175}21762177VertexAttribState va0(0);2178va0.array_size = 2;2179va0.array_type = GL_BYTE;2180va0.array_normalized = 1;2181va0.relative_offset = 16;2182VertexBindingState vb0(0);2183glVertexAttribFormat(0, 2, GL_BYTE, GL_TRUE, 16);2184if (!va0.stateVerify() || !vb0.stateVerify())2185{2186m_context.getTestContext().getLog()2187<< tcu::TestLog::Message << "glVertexAttribFormat state change check failed."2188<< tcu::TestLog::EndMessage;2189status = false;2190}21912192VertexAttribState va2(2);2193va2.array_size = 3;2194va2.array_type = GL_INT;2195va2.array_integer = 1;2196va2.relative_offset = 512;2197VertexBindingState vb2(2);2198glVertexAttribIFormat(2, 3, GL_INT, 512);2199if (!va2.stateVerify() || !vb2.stateVerify())2200{2201m_context.getTestContext().getLog()2202<< tcu::TestLog::Message << "glVertexAttribIFormat state change check failed."2203<< tcu::TestLog::EndMessage;2204status = false;2205}22062207va0.array_buffer_binding = m_vbo[0];2208vb0.buffer = m_vbo[0];2209vb0.offset = 2048;2210vb0.stride = 128;2211glBindVertexBuffer(0, m_vbo[0], 2048, 128);2212if (!va0.stateVerify() || !vb0.stateVerify())2213{2214m_context.getTestContext().getLog()2215<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed."2216<< tcu::TestLog::EndMessage;2217status = false;2218}22192220va2.array_buffer_binding = m_vbo[2];2221vb2.buffer = m_vbo[2];2222vb2.offset = 64;2223vb2.stride = 256;2224glBindVertexBuffer(2, m_vbo[2], 64, 256);2225if (!va2.stateVerify() || !vb2.stateVerify())2226{2227m_context.getTestContext().getLog()2228<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed."2229<< tcu::TestLog::EndMessage;2230status = false;2231}22322233glVertexAttribBinding(2, 0);2234va2.binding = 0;2235va2.array_buffer_binding = m_vbo[0];2236if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())2237{2238m_context.getTestContext().getLog()2239<< tcu::TestLog::Message << "glVertexAttribBinding state change check failed."2240<< tcu::TestLog::EndMessage;2241status = false;2242}22432244VertexAttribState va15(15);2245VertexBindingState vb15(15);2246glVertexAttribBinding(0, 15);2247va0.binding = 15;2248va0.array_buffer_binding = 0;2249if (!va0.stateVerify() || !vb0.stateVerify() || !va15.stateVerify() || !vb15.stateVerify())2250{2251m_context.getTestContext().getLog()2252<< tcu::TestLog::Message << "glVertexAttribBinding state change check failed."2253<< tcu::TestLog::EndMessage;2254status = false;2255}22562257glBindVertexBuffer(15, m_vbo[1], 16, 32);2258va0.array_buffer_binding = m_vbo[1];2259va15.array_buffer_binding = m_vbo[1];2260vb15.buffer = m_vbo[1];2261vb15.offset = 16;2262vb15.stride = 32;2263if (!va0.stateVerify() || !vb0.stateVerify() || !va15.stateVerify() || !vb15.stateVerify())2264{2265m_context.getTestContext().getLog()2266<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed."2267<< tcu::TestLog::EndMessage;2268status = false;2269}22702271glVertexAttribFormat(15, 1, GL_HALF_FLOAT, GL_FALSE, 1024);2272va15.array_size = 1;2273va15.array_type = GL_HALF_FLOAT;2274va15.relative_offset = 1024;2275if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||2276!va15.stateVerify() || !vb15.stateVerify())2277{2278m_context.getTestContext().getLog()2279<< tcu::TestLog::Message << "glVertexAttribFormat state change check failed."2280<< tcu::TestLog::EndMessage;2281status = false;2282}22832284glBindBuffer(GL_ARRAY_BUFFER, m_vbo[2]);2285glVertexAttribPointer(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 8, (void *)640);2286glBindBuffer(GL_ARRAY_BUFFER, 0);2287va0.array_size = 4;2288va0.array_type = GL_UNSIGNED_BYTE;2289va0.array_stride = 8;2290va0.array_pointer = 640;2291va0.relative_offset = 0;2292va0.array_normalized = 0;2293va0.binding = 0;2294va0.array_buffer_binding = m_vbo[2];2295vb0.buffer = m_vbo[2];2296vb0.offset = 640;2297vb0.stride = 8;2298va2.array_buffer_binding = m_vbo[2];2299if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||2300!va15.stateVerify() || !vb15.stateVerify())2301{2302m_context.getTestContext().getLog()2303<< tcu::TestLog::Message << "glVertexAttribPointer state change check failed."2304<< tcu::TestLog::EndMessage;2305status = false;2306}23072308glBindVertexBuffer(0, m_vbo[1], 80, 24);2309vb0.buffer = m_vbo[1];2310vb0.offset = 80;2311vb0.stride = 24;2312va2.array_buffer_binding = m_vbo[1];2313va0.array_buffer_binding = m_vbo[1];2314if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||2315!va15.stateVerify() || !vb15.stateVerify())2316{2317m_context.getTestContext().getLog()2318<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed."2319<< tcu::TestLog::EndMessage;2320status = false;2321}23222323if (status)2324return NO_ERROR;2325else2326return ERROR;2327}2328};2329//=============================================================================2330// 1.6 BasicState22331//-----------------------------------------------------------------------------2332class BasicState2 : public VertexAttribBindingBase2333{23342335GLuint m_vao;23362337virtual long Setup()2338{2339glGenVertexArrays(1, &m_vao);2340return NO_ERROR;2341}23422343virtual long Cleanup()2344{2345glDeleteVertexArrays(1, &m_vao);2346return NO_ERROR;2347}23482349virtual long Run()2350{2351bool status = true;2352glBindVertexArray(m_vao);23532354for (GLuint i = 0; i < 16; ++i)2355{2356VertexAttribState va(i);2357VertexBindingState vb(i);2358glVertexAttribDivisor(i, i + 7);2359va.array_divisor = i + 7;2360vb.divisor = i + 7;2361if (!va.stateVerify() || !vb.stateVerify())2362{2363m_context.getTestContext().getLog()2364<< tcu::TestLog::Message << "glVertexAttribDivisor state change check failed."2365<< tcu::TestLog::EndMessage;2366status = false;2367}2368}2369for (GLuint i = 0; i < 16; ++i)2370{2371VertexAttribState va(i);2372VertexBindingState vb(i);2373glVertexBindingDivisor(i, i);2374va.array_divisor = i;2375vb.divisor = i;2376if (!va.stateVerify() || !vb.stateVerify())2377{2378m_context.getTestContext().getLog()2379<< tcu::TestLog::Message << "glVertexBindingDivisor state change check failed."2380<< tcu::TestLog::EndMessage;2381status = false;2382}2383}23842385glVertexAttribBinding(2, 5);2386VertexAttribState va5(5);2387va5.array_divisor = 5;2388VertexBindingState vb5(5);2389vb5.divisor = 5;2390VertexAttribState va2(2);2391va2.array_divisor = 5; // binding state seen thru mapping2392VertexBindingState vb2(2);2393vb2.divisor = 2;2394va2.binding = 5;2395if (!va5.stateVerify() || !vb5.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())2396{2397m_context.getTestContext().getLog()2398<< tcu::TestLog::Message << "glVertexAttribBinding state change check failed."2399<< tcu::TestLog::EndMessage;2400status = false;2401}24022403glVertexAttribDivisor(2, 23);2404va2.binding = 2; // glVAD defaults mapping2405va2.array_divisor = 23;2406vb2.divisor = 23;2407if (!va5.stateVerify() || !vb5.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())2408{2409m_context.getTestContext().getLog()2410<< tcu::TestLog::Message << "glVertexAttribDivisor state change check failed."2411<< tcu::TestLog::EndMessage;2412status = false;2413}24142415if (status)2416return NO_ERROR;2417else2418return ERROR;2419}2420};2421//=============================================================================2422// 2.1 AdvancedBindingUpdate2423//-----------------------------------------------------------------------------2424class AdvancedBindingUpdate : public VertexAttribBindingBase2425{2426bool pipeline;2427GLuint m_vao[2], m_vbo[2], m_ebo[2], m_vsp, m_fsp, m_ppo;24282429virtual long Setup()2430{2431glGenVertexArrays(2, m_vao);2432glGenBuffers(2, m_vbo);2433glGenBuffers(2, m_ebo);2434if (pipeline)2435{2436m_vsp = m_fsp = 0;2437glGenProgramPipelines(1, &m_ppo);2438}2439else2440{2441m_ppo = 0;2442}2443return NO_ERROR;2444}24452446virtual long Cleanup()2447{2448glDeleteVertexArrays(2, m_vao);2449glDeleteBuffers(2, m_vbo);2450glDeleteBuffers(2, m_ebo);2451if (pipeline)2452{2453glDeleteProgram(m_vsp);2454glDeleteProgram(m_fsp);2455glDeleteProgramPipelines(1, &m_ppo);2456}2457else2458{2459glUseProgram(0);2460glDeleteProgram(m_ppo);2461}2462return NO_ERROR;2463}24642465virtual long Run()2466{2467const char *const glsl_vs =2468"#version 310 es" NL "layout(location = 0) in vec4 vs_in_position;" NL2469"layout(location = 1) in vec2 vs_in_color_rg;" NL2470"layout(location = 2) in float vs_in_color_b;" NL2471"layout(location = 3) in uvec3 vs_in_data0;" NL2472"layout(location = 4) in ivec2 vs_in_data1;" NL "out vec2 color_rg;" NL2473"out float color_b;" NL "flat out uvec3 data0;" NL "flat out ivec2 data1;" NL2474"void main() {" NL " data0 = vs_in_data0;" NL " data1 = vs_in_data1;" NL2475" color_b = vs_in_color_b;" NL " color_rg = vs_in_color_rg;" NL2476" gl_Position = vs_in_position;" NL "}";2477const char *const glsl_fs =2478"#version 310 es" NL "precision highp float;" NL "precision highp int;" NL2479"in vec2 color_rg;" NL "in float color_b;" NL "flat in uvec3 data0;" NL2480"flat in ivec2 data1;" NL "out vec4 fs_out_color;" NL2481"uniform uvec3 g_expected_data0;" NL "uniform ivec2 g_expected_data1;" NL2482"void main() {" NL " fs_out_color = vec4(color_rg, color_b, 1);" NL2483" if (data0 != g_expected_data0) fs_out_color = vec4(1);" NL2484" if (data1 != g_expected_data1) fs_out_color = vec4(1);" NL "}";2485if (pipeline)2486{2487m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);2488m_fsp = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);2489if (!CheckProgram(m_vsp) || !CheckProgram(m_fsp))2490return ERROR;2491glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);2492glUseProgramStages(m_ppo, GL_FRAGMENT_SHADER_BIT, m_fsp);2493}2494else2495{2496m_ppo = glCreateProgram();2497const GLuint sh = glCreateShader(GL_VERTEX_SHADER);2498const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);2499glShaderSource(sh, 1, &glsl_vs, NULL);2500glShaderSource(fsh, 1, &glsl_fs, NULL);2501glCompileShader(sh);2502glCompileShader(fsh);2503glAttachShader(m_ppo, sh);2504glAttachShader(m_ppo, fsh);2505glDeleteShader(sh);2506glDeleteShader(fsh);2507glLinkProgram(m_ppo);2508if (!CheckProgram(m_ppo))2509return ERROR;2510}25112512const GLsizei kStride[2] = {52, 64};2513const GLintptr kOffset[2] = {0, 8};2514glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);2515/* first VBO */2516{2517glBufferData(GL_ARRAY_BUFFER, kOffset[0] + 4 * kStride[0], NULL, GL_STATIC_DRAW);2518GLubyte *ptr = static_cast<GLubyte *>(glMapBufferRange(2519GL_ARRAY_BUFFER, 0, kOffset[0] + 4 * kStride[0], GL_MAP_WRITE_BIT));2520*reinterpret_cast<Vec2 *>(&ptr[kOffset[0] + 0 * kStride[0]]) = Vec2(-1.0f, -1.0f);2521*reinterpret_cast<Vec2 *>(&ptr[kOffset[0] + 1 * kStride[0]]) = Vec2(1.0f, -1.0f);2522*reinterpret_cast<Vec2 *>(&ptr[kOffset[0] + 2 * kStride[0]]) = Vec2(1.0f, 1.0f);2523*reinterpret_cast<Vec2 *>(&ptr[kOffset[0] + 3 * kStride[0]]) = Vec2(-1.0f, 1.0f);2524for (int i = 0; i < 4; ++i)2525{2526*reinterpret_cast<Vec2 *>(&ptr[kOffset[0] + 8 + i * kStride[0]]) = Vec2(0.0f, 1.0f);2527*reinterpret_cast<float *>(&ptr[kOffset[0] + 16 + i * kStride[0]]) = 0.0f;2528*reinterpret_cast<UVec3 *>(&ptr[kOffset[0] + 20 + i * kStride[0]]) = UVec3(1, 2, 3);2529*reinterpret_cast<IVec2 *>(&ptr[kOffset[0] + 44 + i * kStride[0]]) = IVec2(1, 2);2530}2531glUnmapBuffer(GL_ARRAY_BUFFER);2532}2533glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);2534/* second VBO */2535{2536glBufferData(GL_ARRAY_BUFFER, kOffset[1] + 4 * kStride[1], NULL, GL_STATIC_DRAW);2537GLubyte *ptr = static_cast<GLubyte *>(glMapBufferRange(2538GL_ARRAY_BUFFER, 0, kOffset[1] + 4 * kStride[1], GL_MAP_WRITE_BIT));2539*reinterpret_cast<Vec2 *>(&ptr[kOffset[1] + 0 * kStride[1]]) = Vec2(-1.0f, 1.0f);2540*reinterpret_cast<Vec2 *>(&ptr[kOffset[1] + 1 * kStride[1]]) = Vec2(1.0f, 1.0f);2541*reinterpret_cast<Vec2 *>(&ptr[kOffset[1] + 2 * kStride[1]]) = Vec2(1.0f, -1.0f);2542*reinterpret_cast<Vec2 *>(&ptr[kOffset[1] + 3 * kStride[1]]) = Vec2(-1.0f, -1.0f);2543for (int i = 0; i < 4; ++i)2544{2545*reinterpret_cast<Vec2 *>(&ptr[kOffset[1] + 8 + i * kStride[1]]) = Vec2(0.0f, 0.0f);2546*reinterpret_cast<float *>(&ptr[kOffset[1] + 16 + i * kStride[1]]) = 1.0f;2547*reinterpret_cast<UVec3 *>(&ptr[kOffset[1] + 20 + i * kStride[1]]) = UVec3(4, 5, 6);2548*reinterpret_cast<IVec2 *>(&ptr[kOffset[1] + 44 + i * kStride[1]]) = IVec2(3, 4);2549}2550glUnmapBuffer(GL_ARRAY_BUFFER);2551}2552glBindBuffer(GL_ARRAY_BUFFER, 0);25532554glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);2555/* first EBO */2556{2557GLushort data[4] = {0, 1, 3, 2};2558glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);2559}2560glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);2561/* second EBO */2562{2563GLuint data[4] = {3, 2, 0, 1};2564glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);2565}2566glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);25672568glBindVertexArray(m_vao[0]);2569glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);2570glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 8);2571glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 16);2572glVertexAttribIFormat(3, 3, GL_UNSIGNED_INT, 20);2573glVertexAttribIFormat(4, 2, GL_INT, 44);2574for (GLuint i = 0; i < 5; ++i)2575{2576glVertexAttribBinding(i, 0);2577glEnableVertexAttribArray(i);2578}2579glBindVertexArray(m_vao[1]);2580glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);2581glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 8);2582glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 16);2583glVertexAttribIFormat(3, 3, GL_UNSIGNED_INT, 20);2584glVertexAttribIFormat(4, 2, GL_INT, 44);2585glVertexAttribBinding(0, 1);2586glVertexAttribBinding(1, 8);2587glVertexAttribBinding(2, 1);2588glVertexAttribBinding(3, 1);2589glVertexAttribBinding(4, 8);2590glEnableVertexAttribArray(0);2591glEnableVertexAttribArray(1);2592glEnableVertexAttribArray(2);2593glEnableVertexAttribArray(3);2594glEnableVertexAttribArray(4);2595glBindVertexBuffer(1, m_vbo[1], kOffset[1], kStride[1]);2596glBindVertexBuffer(8, m_vbo[0], kOffset[0], kStride[0]);2597glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);2598glBindVertexArray(0);25992600glClear(GL_COLOR_BUFFER_BIT);2601GLuint ppo;2602if (pipeline)2603{2604glBindProgramPipeline(m_ppo);2605ppo = m_fsp;2606}2607else2608{2609glUseProgram(m_ppo);2610ppo = m_ppo;2611}2612glBindVertexArray(m_vao[0]);26132614// Bind first VBO2615glProgramUniform3ui(ppo, glGetUniformLocation(ppo, "g_expected_data0"), 1, 2, 3);2616glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 1, 2);2617glBindVertexBuffer(0, m_vbo[0], kOffset[0], kStride[0]);2618glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);2619glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1);26202621bool status = true;2622if (!CheckFB(Vec3(0, 1, 0)))2623status = false;2624if (!status)2625return ERROR;26262627// Bind second VBO (change all vertex attribs with one call)2628glProgramUniform3ui(ppo, glGetUniformLocation(ppo, "g_expected_data0"), 4, 5, 6);2629glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 3, 4);26302631glBindVertexBuffer(0, m_vbo[1], kOffset[1], kStride[1]);2632glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);2633glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1);26342635if (!CheckFB(Vec3(0, 0, 1)))2636status = false;2637if (!status)2638return ERROR;26392640// Change attrib bindings (all attribs from one buffer)2641glBindVertexBuffer(0, 0, 0, 0); // "unbind" buffer26422643glProgramUniform3ui(ppo, glGetUniformLocation(ppo, "g_expected_data0"), 1, 2, 3);2644glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 1, 2);26452646for (GLuint i = 0; i < 5; ++i)2647glVertexAttribBinding(i, 15);2648glBindVertexBuffer(15, m_vbo[0], kOffset[0], kStride[0]);2649glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);2650glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1);26512652if (!CheckFB(Vec3(0, 1, 0)))2653status = false;2654if (!status)2655return ERROR;26562657// Change attrib bindings (attribs from two buffers)2658glBindVertexBuffer(15, 0, 0, 0); // "unbind" buffer26592660glProgramUniform3ui(ppo, glGetUniformLocation(ppo, "g_expected_data0"), 1, 2, 3);2661glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 3, 4);26622663glBindVertexBuffer(7, m_vbo[0], kOffset[0], kStride[0]);2664glBindVertexBuffer(12, m_vbo[1], kOffset[1], kStride[1]);2665glVertexAttribBinding(0, 7);2666glVertexAttribBinding(1, 12);2667glVertexAttribBinding(2, 12);2668glVertexAttribBinding(3, 7);2669glVertexAttribBinding(4, 12);2670glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);2671glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1);26722673if (!CheckFB(Vec3(0, 0, 1)))2674status = false;2675if (!status)2676return ERROR;26772678// Disable one of the attribs2679glClear(GL_COLOR_BUFFER_BIT);2680glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 0, 0);2681glDisableVertexAttribArray(4);2682glVertexAttribI4i(4, 0, 0, 0, 0);2683glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1);26842685if (!CheckFB(Vec3(0, 0, 1)))2686status = false;2687if (!status)2688return ERROR;26892690// Change VAO2691glProgramUniform3ui(ppo, glGetUniformLocation(ppo, "g_expected_data0"), 4, 5, 6);2692glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 1, 2);26932694glBindVertexArray(m_vao[1]);2695glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1);26962697if (!CheckFB(Vec3(0, 1, 1)))2698status = false;2699if (!status)2700return ERROR;27012702return NO_ERROR;2703}27042705public:2706AdvancedBindingUpdate() : pipeline(true) {}2707};2708//=============================================================================2709// 2.3 AdvancedIterations2710//-----------------------------------------------------------------------------2711class AdvancedIterations : public VertexAttribBindingBase2712{27132714GLuint m_po, m_vao[2], m_buffer[2];27152716virtual long Setup()2717{2718m_po = 0;2719glGenVertexArrays(2, m_vao);2720glGenBuffers(2, m_buffer);2721return NO_ERROR;2722}27232724virtual long Cleanup()2725{2726glDisable(GL_RASTERIZER_DISCARD);2727glUseProgram(0);2728glDeleteProgram(m_po);2729glDeleteVertexArrays(2, m_vao);2730glDeleteBuffers(2, m_buffer);2731return NO_ERROR;2732}27332734virtual long Run()2735{2736const char *const glsl_vs =2737"#version 310 es" NL "in ivec4 vs_in_data;" NL "flat out ivec4 data;" NL2738"void main() {" NL " data = vs_in_data + 1;" NL "}";2739const char *const glsl_fs =2740"#version 310 es" NL "precision mediump float;" NL "flat in ivec4 data;" NL2741"out vec4 fs_out_color;" NL "void main() {" NL " fs_out_color = vec4(data);" NL "}";2742m_po = glCreateProgram();2743/* attach shader */2744{2745const GLuint sh = glCreateShader(GL_VERTEX_SHADER);2746const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);2747glShaderSource(sh, 1, &glsl_vs, NULL);2748glShaderSource(fsh, 1, &glsl_fs, NULL);2749glCompileShader(sh);2750glCompileShader(fsh);2751glAttachShader(m_po, sh);2752glAttachShader(m_po, fsh);2753glDeleteShader(sh);2754glDeleteShader(fsh);2755}2756if (!RelinkProgram(1))2757return ERROR;27582759glBindBuffer(GL_ARRAY_BUFFER, m_buffer[0]);2760IVec4 zero(0);2761glBufferData(GL_ARRAY_BUFFER, 16, &zero, GL_STATIC_DRAW);2762glBindBuffer(GL_ARRAY_BUFFER, 0);27632764glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer[1]);2765glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, &zero, GL_DYNAMIC_READ);2766glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);27672768glBindVertexArray(m_vao[0]);2769glVertexAttribIFormat(1, 4, GL_INT, 0);2770glEnableVertexAttribArray(1);2771glBindVertexBuffer(1, m_buffer[0], 0, 16);2772glBindVertexArray(m_vao[1]);2773glVertexAttribIFormat(1, 4, GL_INT, 0);2774glEnableVertexAttribArray(1);2775glBindVertexBuffer(1, m_buffer[1], 0, 16);2776glBindVertexArray(0);2777glEnable(GL_RASTERIZER_DISCARD);2778glUseProgram(m_po);27792780for (int i = 0; i < 10; ++i)2781{2782glBindVertexArray(m_vao[i % 2]);2783glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[(i + 1) % 2]);2784glBeginTransformFeedback(GL_POINTS);2785glDrawArrays(GL_POINTS, 0, 1);2786glEndTransformFeedback();2787}2788/* */2789{2790IVec4 *data = static_cast<IVec4 *>(2791glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));2792if (!IsEqual(*data, IVec4(10)))2793{2794m_context.getTestContext().getLog()2795<< tcu::TestLog::Message << "Data is: " << (*data)[0] << " " << (*data)[1]2796<< " " << (*data)[2] << " " << (*data)[3] << ", data should be: 10 10 10 10."2797<< tcu::TestLog::EndMessage;2798return ERROR;2799}2800glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);2801}28022803if (!RelinkProgram(5))2804return ERROR;2805glBindVertexArray(m_vao[0]);2806glDisableVertexAttribArray(1);2807glBindVertexBuffer(1, 0, 0, 0);2808glVertexAttribIFormat(5, 4, GL_INT, 0);2809glEnableVertexAttribArray(5);2810glBindVertexBuffer(5, m_buffer[0], 0, 16);2811glBindVertexArray(m_vao[1]);2812glDisableVertexAttribArray(1);2813glBindVertexBuffer(1, 0, 0, 0);2814glVertexAttribIFormat(5, 4, GL_INT, 0);2815glEnableVertexAttribArray(5);2816glBindVertexBuffer(7, m_buffer[1], 0, 16);2817glVertexAttribBinding(5, 7);2818glBindVertexArray(0);28192820for (int i = 0; i < 10; ++i)2821{2822glBindVertexArray(m_vao[i % 2]);2823glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[(i + 1) % 2]);2824glBeginTransformFeedback(GL_POINTS);2825glDrawArrays(GL_POINTS, 0, 1);2826glEndTransformFeedback();2827}2828/* */2829{2830IVec4 *data = static_cast<IVec4 *>(2831glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));2832if (!IsEqual(*data, IVec4(20)))2833{2834m_context.getTestContext().getLog()2835<< tcu::TestLog::Message << "Data is: " << (*data)[0] << " " << (*data)[1]2836<< " " << (*data)[2] << " " << (*data)[3] << ", data should be: 20 20 20 20."2837<< tcu::TestLog::EndMessage;2838return ERROR;2839}2840glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);2841}28422843if (!RelinkProgram(11))2844return ERROR;2845glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);2846glBindVertexArray(m_vao[0]);2847glDisableVertexAttribArray(5);2848glBindVertexBuffer(5, 0, 0, 0);2849glVertexAttribIFormat(11, 4, GL_INT, 0);2850glEnableVertexAttribArray(11);2851for (int i = 0; i < 10; ++i)2852{2853glBindVertexBuffer(11, m_buffer[i % 2], 0, 16);2854glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[(i + 1) % 2]);2855glBeginTransformFeedback(GL_POINTS);2856glDrawArrays(GL_POINTS, 0, 1);2857glEndTransformFeedback();2858}2859/* */2860{2861IVec4 *data = static_cast<IVec4 *>(2862glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));2863if (!IsEqual(*data, IVec4(30)))2864{2865m_context.getTestContext().getLog()2866<< tcu::TestLog::Message << "Data is: " << (*data)[0] << " " << (*data)[1]2867<< " " << (*data)[2] << " " << (*data)[3] << ", data should be: 30 30 30 30."2868<< tcu::TestLog::EndMessage;2869return ERROR;2870}2871}28722873return NO_ERROR;2874}28752876bool RelinkProgram(GLuint index)2877{2878glBindAttribLocation(m_po, index, "vs_in_data");2879/* setup XFB */2880{2881const GLchar *const v[1] = {"data"};2882glTransformFeedbackVaryings(m_po, 1, v, GL_INTERLEAVED_ATTRIBS);2883}2884glLinkProgram(m_po);2885if (!CheckProgram(m_po))2886return false;2887return true;2888}2889};2890//=============================================================================2891// 2.4 AdvancedLargeStrideAndOffsetsNewAndLegacyAPI2892//-----------------------------------------------------------------------------2893class AdvancedLargeStrideAndOffsetsNewAndLegacyAPI : public VertexAttribBindingBase2894{2895bool pipeline;2896GLuint m_vsp, m_fsp, m_ppo, m_ssbo, m_vao, m_vbo;28972898virtual long Setup()2899{2900m_vsp = 0;2901if (pipeline)2902{2903m_vsp = m_fsp = 0;2904glGenProgramPipelines(1, &m_ppo);2905}2906else2907{2908m_ppo = 0;2909}2910glGenBuffers(1, &m_ssbo);2911glGenVertexArrays(1, &m_vao);2912glGenBuffers(1, &m_vbo);2913return NO_ERROR;2914}29152916virtual long Cleanup()2917{2918glDisable(GL_RASTERIZER_DISCARD);2919if (pipeline)2920{2921glDeleteProgram(m_vsp);2922glDeleteProgram(m_fsp);2923glDeleteProgramPipelines(1, &m_ppo);2924}2925else2926{2927glUseProgram(0);2928glDeleteProgram(m_ppo);2929}2930glDeleteBuffers(1, &m_ssbo);2931glDeleteVertexArrays(1, &m_vao);2932glDeleteBuffers(1, &m_vbo);2933return NO_ERROR;2934}29352936virtual long Run()2937{2938if (!IsSSBOInVSFSAvailable(2))2939return NOT_SUPPORTED;2940const char *const glsl_vs =2941"#version 310 es" NL "layout(location = 0) in vec2 vs_in_attrib0;" NL2942"layout(location = 4) in ivec2 vs_in_attrib1;" NL2943"layout(location = 8) in uvec2 vs_in_attrib2;" NL2944"layout(location = 15) in float vs_in_attrib3;" NL2945"layout(std430, binding = 1) buffer Output {" NL " vec2 attrib0[4];" NL2946" ivec2 attrib1[4];" NL " uvec2 attrib2[4];" NL " float attrib3[4];" NL2947"} g_output;" NL "void main() {" NL2948" g_output.attrib0[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib0;" NL2949" g_output.attrib1[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib1;" NL2950" g_output.attrib2[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib2;" NL2951" g_output.attrib3[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib3;" NL "}";2952const char *const glsl_fs =2953"#version 310 es" NL "precision mediump float;" NL "out vec4 fs_out_color;" NL2954"void main() {" NL " fs_out_color = vec4(0.5,0.5,0.5,1.0);" NL "}";2955if (pipeline)2956{2957m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);2958m_fsp = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);2959if (!CheckProgram(m_vsp) || !CheckProgram(m_fsp))2960return ERROR;2961glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);2962glUseProgramStages(m_ppo, GL_FRAGMENT_SHADER_BIT, m_fsp);2963}2964else2965{2966m_ppo = glCreateProgram();2967const GLuint sh = glCreateShader(GL_VERTEX_SHADER);2968const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);2969glShaderSource(sh, 1, &glsl_vs, NULL);2970glShaderSource(fsh, 1, &glsl_fs, NULL);2971glCompileShader(sh);2972glCompileShader(fsh);2973glAttachShader(m_ppo, sh);2974glAttachShader(m_ppo, fsh);2975glDeleteShader(sh);2976glDeleteShader(fsh);2977glLinkProgram(m_ppo);2978if (!CheckProgram(m_ppo))2979return ERROR;2980}29812982/* vbo */2983{2984glBindBuffer(GL_ARRAY_BUFFER, m_vbo);2985glBufferData(GL_ARRAY_BUFFER, 100000, NULL, GL_STATIC_DRAW);2986GLubyte *ptr = static_cast<GLubyte *>(2987glMapBufferRange(GL_ARRAY_BUFFER, 0, 100000, GL_MAP_WRITE_BIT));2988// attrib02989*reinterpret_cast<Vec2 *>(&ptr[16 + 0 * 2048]) = Vec2(1.0f, 2.0f);2990*reinterpret_cast<Vec2 *>(&ptr[16 + 1 * 2048]) = Vec2(3.0f, 4.0f);2991// attrib12992*reinterpret_cast<IVec2 *>(&ptr[128 + 0 * 2048]) = IVec2(5, 6);2993*reinterpret_cast<IVec2 *>(&ptr[128 + 1 * 2048]) = IVec2(7, 8);2994// attrib22995*reinterpret_cast<UVec2 *>(&ptr[1024 + 0 * 2048]) = UVec2(9, 10);2996*reinterpret_cast<UVec2 *>(&ptr[1024 + 1 * 2048]) = UVec2(11, 12);2997// attrib32998*reinterpret_cast<float *>(&ptr[2032 + 0 * 2048]) = 13.0f;2999*reinterpret_cast<float *>(&ptr[2032 + 1 * 2048]) = 14.0f;3000glUnmapBuffer(GL_ARRAY_BUFFER);3001glBindBuffer(GL_ARRAY_BUFFER, 0);3002}3003// vao3004glBindVertexArray(m_vao);3005glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 16);3006glVertexAttribIFormat(8, 2, GL_UNSIGNED_INT, 1024);3007glVertexAttribFormat(15, 1, GL_FLOAT, GL_FALSE, 2032);3008glBindBuffer(GL_ARRAY_BUFFER, m_vbo);3009glVertexAttribIPointer(4, 2, GL_INT, 2048, reinterpret_cast<void *>(128));3010glBindBuffer(GL_ARRAY_BUFFER, 0);3011glVertexAttribBinding(8, 3);3012glVertexAttribBinding(15, 3);3013glBindVertexBuffer(0, m_vbo, 0, 2048);3014glBindVertexBuffer(3, m_vbo, 0, 2048);3015glEnableVertexAttribArray(0);3016glEnableVertexAttribArray(4);3017glEnableVertexAttribArray(8);3018glEnableVertexAttribArray(15);3019glBindVertexArray(0);30203021// ssbo3022std::vector<GLubyte> data(3023(sizeof(Vec2) + sizeof(IVec2) + sizeof(UVec2) + sizeof(float)) * 4, 0xff);3024glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_ssbo);3025glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)data.size(), &data[0], GL_DYNAMIC_DRAW);30263027glEnable(GL_RASTERIZER_DISCARD);3028if (pipeline)3029glBindProgramPipeline(m_ppo);3030else3031glUseProgram(m_ppo);3032glBindVertexArray(m_vao);3033glDrawArraysInstanced(GL_POINTS, 0, 2, 2);30343035/* */3036{3037glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_ssbo);3038GLubyte *ptr = static_cast<GLubyte *>(glMapBufferRange(3039GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)data.size(), GL_MAP_READ_BIT));3040// attrib03041Vec2 i0_v0_a0 = *reinterpret_cast<Vec2 *>(&ptr[0]);3042Vec2 i0_v1_a0 = *reinterpret_cast<Vec2 *>(&ptr[8]);3043Vec2 i1_v0_a0 = *reinterpret_cast<Vec2 *>(&ptr[16]);3044Vec2 i1_v1_a0 = *reinterpret_cast<Vec2 *>(&ptr[24]);3045if (!IsEqual(i0_v0_a0, Vec2(1.0f, 2.0f)))3046return ERROR;3047if (!IsEqual(i0_v1_a0, Vec2(3.0f, 4.0f)))3048return ERROR;3049if (!IsEqual(i1_v0_a0, Vec2(1.0f, 2.0f)))3050return ERROR;3051if (!IsEqual(i1_v1_a0, Vec2(3.0f, 4.0f)))3052return ERROR;3053// attrib13054IVec2 i0_v0_a1 = *reinterpret_cast<IVec2 *>(&ptr[32]);3055IVec2 i0_v1_a1 = *reinterpret_cast<IVec2 *>(&ptr[40]);3056IVec2 i1_v0_a1 = *reinterpret_cast<IVec2 *>(&ptr[48]);3057IVec2 i1_v1_a1 = *reinterpret_cast<IVec2 *>(&ptr[56]);3058if (!IsEqual(i0_v0_a1, IVec2(5, 6)))3059return ERROR;3060if (!IsEqual(i0_v1_a1, IVec2(7, 8)))3061return ERROR;3062if (!IsEqual(i1_v0_a1, IVec2(5, 6)))3063return ERROR;3064if (!IsEqual(i1_v1_a1, IVec2(7, 8)))3065return ERROR;3066// attrib23067UVec2 i0_v0_a2 = *reinterpret_cast<UVec2 *>(&ptr[64]);3068UVec2 i0_v1_a2 = *reinterpret_cast<UVec2 *>(&ptr[72]);3069UVec2 i1_v0_a2 = *reinterpret_cast<UVec2 *>(&ptr[80]);3070UVec2 i1_v1_a2 = *reinterpret_cast<UVec2 *>(&ptr[88]);3071if (!IsEqual(i0_v0_a2, UVec2(9, 10)))3072return ERROR;3073if (!IsEqual(i0_v1_a2, UVec2(11, 12)))3074return ERROR;3075if (!IsEqual(i1_v0_a2, UVec2(9, 10)))3076return ERROR;3077if (!IsEqual(i1_v1_a2, UVec2(11, 12)))3078return ERROR;3079// attrib33080float i0_v0_a3 = *reinterpret_cast<float *>(&ptr[96]);3081float i0_v1_a3 = *reinterpret_cast<float *>(&ptr[100]);3082float i1_v0_a3 = *reinterpret_cast<float *>(&ptr[104]);3083float i1_v1_a3 = *reinterpret_cast<float *>(&ptr[108]);3084if (i0_v0_a3 != 13.0f)3085return ERROR;3086if (i0_v1_a3 != 14.0f)3087return ERROR;3088if (i1_v0_a3 != 13.0f)3089return ERROR;3090if (i1_v1_a3 != 14.0f)3091return ERROR;3092glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);3093}3094return NO_ERROR;3095}30963097public:3098AdvancedLargeStrideAndOffsetsNewAndLegacyAPI() : pipeline(true) {}3099};3100//=============================================================================3101// 4.1 NegativeBindVertexBuffer3102//-----------------------------------------------------------------------------3103class NegativeBindVertexBuffer : public VertexAttribBindingBase3104{31053106GLuint m_vao, m_vbo;31073108virtual long Setup()3109{3110glGenVertexArrays(1, &m_vao);3111glGenBuffers(1, &m_vbo);3112return NO_ERROR;3113}31143115virtual long Cleanup()3116{3117glDeleteVertexArrays(1, &m_vao);3118glDeleteBuffers(1, &m_vbo);3119return NO_ERROR;3120}31213122virtual long Run()3123{3124/*3125Errors3126An INVALID_OPERATION error is generated if buffer is not zero or a name3127returned from a previous call to GenBuffers, or if such a name has since been3128deleted with DeleteBuffers.3129An INVALID_VALUE error is generated if bindingindex is greater than or3130equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.3131OpenGL 4.4 (Core Profile) - July 21, 2013313210.3. VERTEX ARRAYS 3153133An INVALID_VALUE error is generated if stride or offset is negative, or if3134stride is greater than the value of MAX_VERTEX_ATTRIB_STRIDE.3135An INVALID_OPERATION error is generated if no vertex array object is3136bound.3137*/3138glBindBuffer(GL_ARRAY_BUFFER, m_vbo);3139glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_STATIC_DRAW);3140glBindBuffer(GL_ARRAY_BUFFER, 0);31413142glBindVertexArray(m_vao);31433144glBindVertexBuffer(0, 1234, 0, 12);3145if (glGetError() != GL_INVALID_OPERATION)3146{3147m_context.getTestContext().getLog()3148<< tcu::TestLog::Message3149<< "INVALID_OPERATION should be generated (buffer name not genned)."3150<< tcu::TestLog::EndMessage;3151return ERROR;3152}31533154GLint p;3155glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);3156glBindVertexBuffer(p + 1, m_vbo, 0, 12);3157if (glGetError() != GL_INVALID_VALUE)3158{3159m_context.getTestContext().getLog()3160<< tcu::TestLog::Message3161<< "INVALID_VALUE should be generated (bindingIndex greater than "3162"GL_MAX_VERTEX_ATTRIB_BINDINGS)."3163<< tcu::TestLog::EndMessage;3164return ERROR;3165}31663167glBindVertexBuffer(0, m_vbo, -10, 12);3168if (glGetError() != GL_INVALID_VALUE)3169{3170m_context.getTestContext().getLog()3171<< tcu::TestLog::Message << "INVALID_VALUE should be generated (negative offset)."3172<< tcu::TestLog::EndMessage;3173return ERROR;3174}3175glBindVertexBuffer(0, m_vbo, 0, -12);3176if (glGetError() != GL_INVALID_VALUE)3177{3178m_context.getTestContext().getLog()3179<< tcu::TestLog::Message << "INVALID_VALUE should be generated (negative stride)."3180<< tcu::TestLog::EndMessage;3181return ERROR;3182}31833184glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &p);3185glBindVertexBuffer(0, m_vbo, 0, p + 4);3186if (glGetError() != GL_INVALID_VALUE)3187{3188m_context.getTestContext().getLog() << tcu::TestLog::Message3189<< "INVALID_VALUE should be generated (stride "3190"greater than GL_MAX_VERTEX_ATTRIB_STRIDE)."3191<< tcu::TestLog::EndMessage;3192return ERROR;3193}31943195glBindVertexArray(0);3196glBindVertexBuffer(0, m_vbo, 0, 12);3197if (glGetError() != GL_INVALID_OPERATION)3198{3199m_context.getTestContext().getLog()3200<< tcu::TestLog::Message << "INVALID_OPERATION should be generated (default VAO)."3201<< tcu::TestLog::EndMessage;3202return ERROR;3203}32043205return NO_ERROR;3206}3207};3208//=============================================================================3209// 4.2 NegativeVertexAttribFormat3210//-----------------------------------------------------------------------------3211class NegativeVertexAttribFormat : public VertexAttribBindingBase3212{32133214GLuint m_vao, m_vbo;32153216virtual long Setup()3217{3218glGenVertexArrays(1, &m_vao);3219glGenBuffers(1, &m_vbo);3220return NO_ERROR;3221}32223223virtual long Cleanup()3224{3225glDeleteVertexArrays(1, &m_vao);3226glDeleteBuffers(1, &m_vbo);3227return NO_ERROR;3228}32293230virtual long Run()3231{3232/*3233Errors3234An INVALID_VALUE error is generated if attribindex is greater than or3235equal to the value of MAX_VERTEX_ATTRIBS.3236An INVALID_VALUE error is generated if size is not one of the values3237shown in table 10.2 for the corresponding command.3238An INVALID_ENUM error is generated if type is not one of the parameter3239token names from table 8.2 corresponding to one of the allowed GL data types3240for that command as shown in table 10.2.3241An INVALID_OPERATION error is generated under any of the following3242conditions:3243- if no vertex array object is currently bound (see section 10.4);3244- type is INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_-3245REV, and size is not 4;3246An INVALID_VALUE error is generated if relativeoffset is larger than the3247value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.3248*/3249glBindBuffer(GL_ARRAY_BUFFER, m_vbo);3250glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_STATIC_DRAW);3251glBindBuffer(GL_ARRAY_BUFFER, 0);32523253glBindVertexArray(m_vao);32543255GLint p;3256glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &p);3257glVertexAttribFormat(p + 1, 4, GL_FLOAT, GL_FALSE, 0);3258if (glGetError() != GL_INVALID_VALUE)3259{3260m_context.getTestContext().getLog() << tcu::TestLog::Message3261<< "INVALID_VALUE should be generated (attribindex "3262"greater than GL_MAX_VERTEX_ATTRIBS)."3263<< tcu::TestLog::EndMessage;3264return ERROR;3265}3266glVertexAttribIFormat(p + 2, 4, GL_INT, 0);3267if (glGetError() != GL_INVALID_VALUE)3268{3269m_context.getTestContext().getLog() << tcu::TestLog::Message3270<< "INVALID_VALUE should be generated (attribindex "3271"greater than GL_MAX_VERTEX_ATTRIBS)."3272<< tcu::TestLog::EndMessage;3273return ERROR;3274}3275glVertexAttribFormat(0, 0, GL_FLOAT, GL_FALSE, 0);3276if (glGetError() != GL_INVALID_VALUE)3277{3278m_context.getTestContext().getLog()3279<< tcu::TestLog::Message3280<< "INVALID_VALUE should be generated (invalid number of components)."3281<< tcu::TestLog::EndMessage;3282return ERROR;3283}3284glVertexAttribFormat(0, 5, GL_FLOAT, GL_FALSE, 0);3285if (glGetError() != GL_INVALID_VALUE)3286{3287m_context.getTestContext().getLog()3288<< tcu::TestLog::Message3289<< "INVALID_VALUE should be generated (invalid number of components)."3290<< tcu::TestLog::EndMessage;3291return ERROR;3292}3293glVertexAttribIFormat(0, 5, GL_INT, 0);3294if (glGetError() != GL_INVALID_VALUE)3295{3296m_context.getTestContext().getLog()3297<< tcu::TestLog::Message3298<< "INVALID_VALUE should be generated (invalid number of components)."3299<< tcu::TestLog::EndMessage;3300return ERROR;3301}3302glVertexAttribFormat(0, 4, GL_R32F, GL_FALSE, 0);3303if (glGetError() != GL_INVALID_ENUM)3304{3305m_context.getTestContext().getLog()3306<< tcu::TestLog::Message << "INVALID_ENUM should be generated (invalid type)."3307<< tcu::TestLog::EndMessage;3308return ERROR;3309}3310glVertexAttribIFormat(0, 4, GL_FLOAT, 0);3311if (glGetError() != GL_INVALID_ENUM)3312{3313m_context.getTestContext().getLog()3314<< tcu::TestLog::Message << "INVALID_ENUM should be generated (invalid type)."3315<< tcu::TestLog::EndMessage;3316return ERROR;3317}3318glVertexAttribFormat(0, 3, GL_INT_2_10_10_10_REV, GL_FALSE, 0);3319if (glGetError() != GL_INVALID_OPERATION)3320{3321m_context.getTestContext().getLog() << tcu::TestLog::Message3322<< "INVALID_OPERATION should be generated (invalid "3323"number of components for packed type)."3324<< tcu::TestLog::EndMessage;3325return ERROR;3326}3327glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);3328glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, p + 10);3329if (glGetError() != GL_INVALID_VALUE)3330{3331m_context.getTestContext().getLog()3332<< tcu::TestLog::Message3333<< "INVALID_VALUE should be generated (relativeoffset greater than "3334"GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)."3335<< tcu::TestLog::EndMessage;3336return ERROR;3337}3338glVertexAttribIFormat(0, 4, GL_INT, p + 10);3339if (glGetError() != GL_INVALID_VALUE)3340{3341m_context.getTestContext().getLog()3342<< tcu::TestLog::Message3343<< "INVALID_VALUE should be generated (relativeoffset greater than "3344"GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)."3345<< tcu::TestLog::EndMessage;3346return ERROR;3347}3348glBindVertexArray(0);3349glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);3350if (glGetError() != GL_INVALID_OPERATION)3351{3352m_context.getTestContext().getLog()3353<< tcu::TestLog::Message << "INVALID_OPERATION should be generated (default VAO)."3354<< tcu::TestLog::EndMessage;3355return ERROR;3356}3357glVertexAttribIFormat(0, 4, GL_INT, 0);3358if (glGetError() != GL_INVALID_OPERATION)3359{3360m_context.getTestContext().getLog()3361<< tcu::TestLog::Message << "INVALID_OPERATION should be generated (default VAO)."3362<< tcu::TestLog::EndMessage;3363return ERROR;3364}3365return NO_ERROR;3366}3367};33683369//=============================================================================3370// 4.3 NegativeVertexAttribBinding3371//-----------------------------------------------------------------------------3372class NegativeVertexAttribBinding : public VertexAttribBindingBase3373{3374GLuint m_vao;33753376virtual long Setup()3377{3378glGenVertexArrays(1, &m_vao);3379return NO_ERROR;3380}33813382virtual long Cleanup()3383{3384glDeleteVertexArrays(1, &m_vao);3385return NO_ERROR;3386}33873388virtual long Run()3389{3390/*3391Errors3392An INVALID_VALUE error is generated if attribindex is greater than or3393equal to the value of MAX_VERTEX_ATTRIBS.3394An INVALID_VALUE error is generated if bindingindex is greater than or3395equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.3396An INVALID_OPERATION error is generated if no vertex array object is3397bound.3398*/3399glBindVertexArray(m_vao);3400GLint p;3401glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &p);3402glVertexAttribBinding(p + 1, 0);3403if (glGetError() != GL_INVALID_VALUE)3404{3405m_context.getTestContext().getLog() << tcu::TestLog::Message3406<< "INVALID_VALUE should be generated (attribindex "3407"greater than GL_MAX_VERTEX_ATTRIBS)."3408<< tcu::TestLog::EndMessage;3409return ERROR;3410}3411glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);3412glVertexAttribBinding(0, p + 1);3413if (glGetError() != GL_INVALID_VALUE)3414{3415m_context.getTestContext().getLog()3416<< tcu::TestLog::Message3417<< "INVALID_VALUE should be generated (bindingIndex greater than "3418"GL_MAX_VERTEX_ATTRIB_BINDINGS)."3419<< tcu::TestLog::EndMessage;3420return ERROR;3421}3422glBindVertexArray(0);3423glVertexAttribBinding(0, 0);3424if (glGetError() != GL_INVALID_OPERATION)3425{3426m_context.getTestContext().getLog()3427<< tcu::TestLog::Message << "INVALID_OPERATION should be generated (default VAO)."3428<< tcu::TestLog::EndMessage;3429return ERROR;3430}3431return NO_ERROR;3432}3433};3434//=============================================================================3435// 4.4 NegativeVertexAttribDivisor3436//-----------------------------------------------------------------------------3437class NegativeVertexAttribDivisor : public VertexAttribBindingBase3438{34393440GLuint m_vao;34413442virtual long Setup()3443{3444glGenVertexArrays(1, &m_vao);3445return NO_ERROR;3446}34473448virtual long Cleanup()3449{3450glDeleteVertexArrays(1, &m_vao);3451return NO_ERROR;3452}34533454virtual long Run()3455{3456/*3457Errors3458An INVALID_VALUE error is generated if index is greater than or equal to3459the value of MAX_VERTEX_ATTRIBS.3460An INVALID_OPERATION error is generated if no vertex array object is3461bound.3462*/3463glBindVertexArray(m_vao);3464GLint p;3465glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &p);3466glVertexBindingDivisor(p + 1, 1);3467if (glGetError() != GL_INVALID_VALUE)3468{3469m_context.getTestContext().getLog()3470<< tcu::TestLog::Message3471<< "INVALID_VALUE should be generated (bindingIndex greater than "3472"GL_MAX_VERTEX_ATTRIBS)."3473<< tcu::TestLog::EndMessage;3474return ERROR;3475}3476glBindVertexArray(0);3477glVertexBindingDivisor(0, 1);3478if (glGetError() != GL_INVALID_OPERATION)3479{3480m_context.getTestContext().getLog()3481<< tcu::TestLog::Message << "INVALID_OPERATION should be generated (default VAO)."3482<< tcu::TestLog::EndMessage;3483return ERROR;3484}3485return NO_ERROR;3486}3487};3488//=============================================================================34893490} // namespace3491VertexAttribBindingTests::VertexAttribBindingTests(glcts::Context &context)3492: TestCaseGroup(context, "vertex_attrib_binding", "")3493{}34943495VertexAttribBindingTests::~VertexAttribBindingTests(void) {}34963497void VertexAttribBindingTests::init()3498{3499using namespace glcts;3500addChild(new TestSubcase(m_context, "basic-usage", TestSubcase::Create<BasicUsage>));3501addChild(new TestSubcase(m_context, "basic-input-case1", TestSubcase::Create<BasicInputCase1>));3502addChild(new TestSubcase(m_context, "basic-input-case2", TestSubcase::Create<BasicInputCase2>));3503addChild(new TestSubcase(m_context, "basic-input-case3", TestSubcase::Create<BasicInputCase3>));3504addChild(new TestSubcase(m_context, "basic-input-case4", TestSubcase::Create<BasicInputCase4>));3505addChild(new TestSubcase(m_context, "basic-input-case5", TestSubcase::Create<BasicInputCase5>));3506addChild(new TestSubcase(m_context, "basic-input-case6", TestSubcase::Create<BasicInputCase6>));3507addChild(new TestSubcase(m_context, "basic-input-case8", TestSubcase::Create<BasicInputCase8>));3508addChild(new TestSubcase(m_context, "basic-input-case9", TestSubcase::Create<BasicInputCase9>));3509addChild(3510new TestSubcase(m_context, "basic-input-case11", TestSubcase::Create<BasicInputCase11>));3511addChild(3512new TestSubcase(m_context, "basic-input-case12", TestSubcase::Create<BasicInputCase12>));3513addChild(3514new TestSubcase(m_context, "basic-inputI-case1", TestSubcase::Create<BasicInputICase1>));3515addChild(3516new TestSubcase(m_context, "basic-inputI-case2", TestSubcase::Create<BasicInputICase2>));3517addChild(3518new TestSubcase(m_context, "basic-inputI-case3", TestSubcase::Create<BasicInputICase3>));3519addChild(new TestSubcase(m_context, "basic-state1", TestSubcase::Create<BasicState1>));3520addChild(new TestSubcase(m_context, "basic-state2", TestSubcase::Create<BasicState2>));3521addChild(new TestSubcase(m_context, "advanced-bindingUpdate",3522TestSubcase::Create<AdvancedBindingUpdate>));3523addChild(3524new TestSubcase(m_context, "advanced-iterations", TestSubcase::Create<AdvancedIterations>));3525addChild(new TestSubcase(m_context, "advanced-largeStrideAndOffsetsNewAndLegacyAPI",3526TestSubcase::Create<AdvancedLargeStrideAndOffsetsNewAndLegacyAPI>));3527addChild(new TestSubcase(m_context, "negative-bindVertexBuffer",3528TestSubcase::Create<NegativeBindVertexBuffer>));3529addChild(new TestSubcase(m_context, "negative-vertexAttribFormat",3530TestSubcase::Create<NegativeVertexAttribFormat>));3531addChild(new TestSubcase(m_context, "negative-vertexAttribBinding",3532TestSubcase::Create<NegativeVertexAttribBinding>));3533addChild(new TestSubcase(m_context, "negative-vertexAttribDivisor",3534TestSubcase::Create<NegativeVertexAttribDivisor>));3535}3536} // namespace glcts353735383539