1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite 3e5c31af7Sopenharmony_ci * ----------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2015-2016 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci */ /*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief 22e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci/** 25e5c31af7Sopenharmony_ci * \file gl4cMultiBindTests.cpp 26e5c31af7Sopenharmony_ci * \brief Implements conformance tests for "Multi Bind" functionality. 27e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ci#include "gl4cMultiBindTests.hpp" 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_ci#include "gluDefs.hpp" 32e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp" 33e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 34e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 35e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_ci#include <string> 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_ci#define DEBUG_ENBALE_MESSAGE_CALLBACK 0 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 42e5c31af7Sopenharmony_ci#include <iomanip> 43e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ciusing namespace glw; 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_cinamespace gl4cts 48e5c31af7Sopenharmony_ci{ 49e5c31af7Sopenharmony_cinamespace MultiBind 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 53e5c31af7Sopenharmony_ci/** Debuging procedure. Logs parameters. 54e5c31af7Sopenharmony_ci * 55e5c31af7Sopenharmony_ci * @param source As specified in GL spec. 56e5c31af7Sopenharmony_ci * @param type As specified in GL spec. 57e5c31af7Sopenharmony_ci * @param id As specified in GL spec. 58e5c31af7Sopenharmony_ci * @param severity As specified in GL spec. 59e5c31af7Sopenharmony_ci * @param ignored 60e5c31af7Sopenharmony_ci * @param message As specified in GL spec. 61e5c31af7Sopenharmony_ci * @param info Pointer to instance of deqp::Context used by test. 62e5c31af7Sopenharmony_ci */ 63e5c31af7Sopenharmony_civoid GLW_APIENTRY debug_proc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /* length */, 64e5c31af7Sopenharmony_ci const GLchar* message, void* info) 65e5c31af7Sopenharmony_ci{ 66e5c31af7Sopenharmony_ci deqp::Context* ctx = (deqp::Context*)info; 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_ci const GLchar* source_str = "Unknown"; 69e5c31af7Sopenharmony_ci const GLchar* type_str = "Unknown"; 70e5c31af7Sopenharmony_ci const GLchar* severity_str = "Unknown"; 71e5c31af7Sopenharmony_ci 72e5c31af7Sopenharmony_ci switch (source) 73e5c31af7Sopenharmony_ci { 74e5c31af7Sopenharmony_ci case GL_DEBUG_SOURCE_API: 75e5c31af7Sopenharmony_ci source_str = "API"; 76e5c31af7Sopenharmony_ci break; 77e5c31af7Sopenharmony_ci case GL_DEBUG_SOURCE_APPLICATION: 78e5c31af7Sopenharmony_ci source_str = "APP"; 79e5c31af7Sopenharmony_ci break; 80e5c31af7Sopenharmony_ci case GL_DEBUG_SOURCE_OTHER: 81e5c31af7Sopenharmony_ci source_str = "OTR"; 82e5c31af7Sopenharmony_ci break; 83e5c31af7Sopenharmony_ci case GL_DEBUG_SOURCE_SHADER_COMPILER: 84e5c31af7Sopenharmony_ci source_str = "COM"; 85e5c31af7Sopenharmony_ci break; 86e5c31af7Sopenharmony_ci case GL_DEBUG_SOURCE_THIRD_PARTY: 87e5c31af7Sopenharmony_ci source_str = "3RD"; 88e5c31af7Sopenharmony_ci break; 89e5c31af7Sopenharmony_ci case GL_DEBUG_SOURCE_WINDOW_SYSTEM: 90e5c31af7Sopenharmony_ci source_str = "WS"; 91e5c31af7Sopenharmony_ci break; 92e5c31af7Sopenharmony_ci default: 93e5c31af7Sopenharmony_ci break; 94e5c31af7Sopenharmony_ci } 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_ci switch (type) 97e5c31af7Sopenharmony_ci { 98e5c31af7Sopenharmony_ci case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: 99e5c31af7Sopenharmony_ci type_str = "DEPRECATED_BEHAVIOR"; 100e5c31af7Sopenharmony_ci break; 101e5c31af7Sopenharmony_ci case GL_DEBUG_TYPE_ERROR: 102e5c31af7Sopenharmony_ci type_str = "ERROR"; 103e5c31af7Sopenharmony_ci break; 104e5c31af7Sopenharmony_ci case GL_DEBUG_TYPE_MARKER: 105e5c31af7Sopenharmony_ci type_str = "MARKER"; 106e5c31af7Sopenharmony_ci break; 107e5c31af7Sopenharmony_ci case GL_DEBUG_TYPE_OTHER: 108e5c31af7Sopenharmony_ci type_str = "OTHER"; 109e5c31af7Sopenharmony_ci break; 110e5c31af7Sopenharmony_ci case GL_DEBUG_TYPE_PERFORMANCE: 111e5c31af7Sopenharmony_ci type_str = "PERFORMANCE"; 112e5c31af7Sopenharmony_ci break; 113e5c31af7Sopenharmony_ci case GL_DEBUG_TYPE_POP_GROUP: 114e5c31af7Sopenharmony_ci type_str = "POP_GROUP"; 115e5c31af7Sopenharmony_ci break; 116e5c31af7Sopenharmony_ci case GL_DEBUG_TYPE_PORTABILITY: 117e5c31af7Sopenharmony_ci type_str = "PORTABILITY"; 118e5c31af7Sopenharmony_ci break; 119e5c31af7Sopenharmony_ci case GL_DEBUG_TYPE_PUSH_GROUP: 120e5c31af7Sopenharmony_ci type_str = "PUSH_GROUP"; 121e5c31af7Sopenharmony_ci break; 122e5c31af7Sopenharmony_ci case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: 123e5c31af7Sopenharmony_ci type_str = "UNDEFINED_BEHAVIOR"; 124e5c31af7Sopenharmony_ci break; 125e5c31af7Sopenharmony_ci default: 126e5c31af7Sopenharmony_ci break; 127e5c31af7Sopenharmony_ci } 128e5c31af7Sopenharmony_ci 129e5c31af7Sopenharmony_ci switch (severity) 130e5c31af7Sopenharmony_ci { 131e5c31af7Sopenharmony_ci case GL_DEBUG_SEVERITY_HIGH: 132e5c31af7Sopenharmony_ci severity_str = "H"; 133e5c31af7Sopenharmony_ci break; 134e5c31af7Sopenharmony_ci case GL_DEBUG_SEVERITY_LOW: 135e5c31af7Sopenharmony_ci severity_str = "L"; 136e5c31af7Sopenharmony_ci break; 137e5c31af7Sopenharmony_ci case GL_DEBUG_SEVERITY_MEDIUM: 138e5c31af7Sopenharmony_ci severity_str = "M"; 139e5c31af7Sopenharmony_ci break; 140e5c31af7Sopenharmony_ci case GL_DEBUG_SEVERITY_NOTIFICATION: 141e5c31af7Sopenharmony_ci severity_str = "N"; 142e5c31af7Sopenharmony_ci break; 143e5c31af7Sopenharmony_ci default: 144e5c31af7Sopenharmony_ci break; 145e5c31af7Sopenharmony_ci } 146e5c31af7Sopenharmony_ci 147e5c31af7Sopenharmony_ci ctx->getTestContext().getLog() << tcu::TestLog::Message << "DEBUG_INFO: " << std::setw(3) << source_str << "|" 148e5c31af7Sopenharmony_ci << severity_str << "|" << std::setw(18) << type_str << "|" << std::setw(12) << id 149e5c31af7Sopenharmony_ci << ": " << message << tcu::TestLog::EndMessage; 150e5c31af7Sopenharmony_ci} 151e5c31af7Sopenharmony_ci 152e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_ci/** Represents buffer instance 155e5c31af7Sopenharmony_ci * Provides basic buffer functionality 156e5c31af7Sopenharmony_ci **/ 157e5c31af7Sopenharmony_ciclass Buffer 158e5c31af7Sopenharmony_ci{ 159e5c31af7Sopenharmony_cipublic: 160e5c31af7Sopenharmony_ci /* Public methods */ 161e5c31af7Sopenharmony_ci /* Ctr & Dtr */ 162e5c31af7Sopenharmony_ci Buffer(); 163e5c31af7Sopenharmony_ci ~Buffer(); 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci /* Init & Release */ 166e5c31af7Sopenharmony_ci void Init(deqp::Context& context); 167e5c31af7Sopenharmony_ci 168e5c31af7Sopenharmony_ci void InitData(deqp::Context& context, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size, 169e5c31af7Sopenharmony_ci const glw::GLvoid* data); 170e5c31af7Sopenharmony_ci 171e5c31af7Sopenharmony_ci void Release(); 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_ci /* Functionality */ 174e5c31af7Sopenharmony_ci void Bind() const; 175e5c31af7Sopenharmony_ci void BindBase(glw::GLuint index) const; 176e5c31af7Sopenharmony_ci 177e5c31af7Sopenharmony_ci /* Public static routines */ 178e5c31af7Sopenharmony_ci /* Functionality */ 179e5c31af7Sopenharmony_ci static void Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target); 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_ci static void BindBase(const glw::Functions& gl, glw::GLuint id, glw::GLenum target, glw::GLuint index); 182e5c31af7Sopenharmony_ci 183e5c31af7Sopenharmony_ci static void Data(const glw::Functions& gl, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size, 184e5c31af7Sopenharmony_ci const glw::GLvoid* data); 185e5c31af7Sopenharmony_ci 186e5c31af7Sopenharmony_ci static void Generate(const glw::Functions& gl, glw::GLuint& out_id); 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ci static void SubData(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr size, 189e5c31af7Sopenharmony_ci glw::GLvoid* data); 190e5c31af7Sopenharmony_ci 191e5c31af7Sopenharmony_ci /* Public fields */ 192e5c31af7Sopenharmony_ci glw::GLuint m_id; 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_ci /* Public constants */ 195e5c31af7Sopenharmony_ci static const glw::GLuint m_invalid_id; 196e5c31af7Sopenharmony_ci 197e5c31af7Sopenharmony_ciprivate: 198e5c31af7Sopenharmony_ci /* Private enums */ 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci /* Private fields */ 201e5c31af7Sopenharmony_ci deqp::Context* m_context; 202e5c31af7Sopenharmony_ci glw::GLenum m_target; 203e5c31af7Sopenharmony_ci}; 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_ci/** Represents framebuffer 206e5c31af7Sopenharmony_ci * Provides basic functionality 207e5c31af7Sopenharmony_ci **/ 208e5c31af7Sopenharmony_ciclass Framebuffer 209e5c31af7Sopenharmony_ci{ 210e5c31af7Sopenharmony_cipublic: 211e5c31af7Sopenharmony_ci /* Public methods */ 212e5c31af7Sopenharmony_ci /* Ctr & Dtr */ 213e5c31af7Sopenharmony_ci Framebuffer(deqp::Context& context); 214e5c31af7Sopenharmony_ci ~Framebuffer(); 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci /* Init & Release */ 217e5c31af7Sopenharmony_ci void Release(); 218e5c31af7Sopenharmony_ci 219e5c31af7Sopenharmony_ci /* Public static routines */ 220e5c31af7Sopenharmony_ci static void AttachTexture(const glw::Functions& gl, glw::GLenum target, glw::GLenum attachment, 221e5c31af7Sopenharmony_ci glw::GLuint texture_id, glw::GLint level, glw::GLuint width, glw::GLuint height); 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_ci static void Bind(const glw::Functions& gl, glw::GLenum target, glw::GLuint id); 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_ci static void Generate(const glw::Functions& gl, glw::GLuint& out_id); 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ci /* Public fields */ 228e5c31af7Sopenharmony_ci glw::GLuint m_id; 229e5c31af7Sopenharmony_ci 230e5c31af7Sopenharmony_ci /* Public constants */ 231e5c31af7Sopenharmony_ci static const glw::GLuint m_invalid_id; 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_ciprivate: 234e5c31af7Sopenharmony_ci /* Private fields */ 235e5c31af7Sopenharmony_ci deqp::Context& m_context; 236e5c31af7Sopenharmony_ci}; 237e5c31af7Sopenharmony_ci 238e5c31af7Sopenharmony_ci/** Represents shader instance. 239e5c31af7Sopenharmony_ci * Provides basic functionality for shaders. 240e5c31af7Sopenharmony_ci **/ 241e5c31af7Sopenharmony_ciclass Shader 242e5c31af7Sopenharmony_ci{ 243e5c31af7Sopenharmony_cipublic: 244e5c31af7Sopenharmony_ci /* Public methods */ 245e5c31af7Sopenharmony_ci /* Ctr & Dtr */ 246e5c31af7Sopenharmony_ci Shader(deqp::Context& context); 247e5c31af7Sopenharmony_ci ~Shader(); 248e5c31af7Sopenharmony_ci 249e5c31af7Sopenharmony_ci /* Init & Realese */ 250e5c31af7Sopenharmony_ci void Init(glw::GLenum stage, const std::string& source); 251e5c31af7Sopenharmony_ci void Release(); 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci /* Public static routines */ 254e5c31af7Sopenharmony_ci /* Functionality */ 255e5c31af7Sopenharmony_ci static void Compile(const glw::Functions& gl, glw::GLuint id); 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_ci static void Create(const glw::Functions& gl, glw::GLenum stage, glw::GLuint& out_id); 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_ci static void Source(const glw::Functions& gl, glw::GLuint id, const std::string& source); 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ci /* Public fields */ 262e5c31af7Sopenharmony_ci glw::GLuint m_id; 263e5c31af7Sopenharmony_ci 264e5c31af7Sopenharmony_ci /* Public constants */ 265e5c31af7Sopenharmony_ci static const glw::GLuint m_invalid_id; 266e5c31af7Sopenharmony_ci 267e5c31af7Sopenharmony_ciprivate: 268e5c31af7Sopenharmony_ci /* Private fields */ 269e5c31af7Sopenharmony_ci deqp::Context& m_context; 270e5c31af7Sopenharmony_ci}; 271e5c31af7Sopenharmony_ci 272e5c31af7Sopenharmony_ci/** Represents program instance. 273e5c31af7Sopenharmony_ci * Provides basic functionality 274e5c31af7Sopenharmony_ci **/ 275e5c31af7Sopenharmony_ciclass Program 276e5c31af7Sopenharmony_ci{ 277e5c31af7Sopenharmony_cipublic: 278e5c31af7Sopenharmony_ci /* Public methods */ 279e5c31af7Sopenharmony_ci /* Ctr & Dtr */ 280e5c31af7Sopenharmony_ci Program(deqp::Context& context); 281e5c31af7Sopenharmony_ci ~Program(); 282e5c31af7Sopenharmony_ci 283e5c31af7Sopenharmony_ci /* Init & Release */ 284e5c31af7Sopenharmony_ci void Init(const std::string& compute_shader, const std::string& fragment_shader, const std::string& geometry_shader, 285e5c31af7Sopenharmony_ci const std::string& tesselation_control_shader, const std::string& tesselation_evaluation_shader, 286e5c31af7Sopenharmony_ci const std::string& vertex_shader); 287e5c31af7Sopenharmony_ci void Release(); 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ci /* Functionality */ 290e5c31af7Sopenharmony_ci void Use() const; 291e5c31af7Sopenharmony_ci 292e5c31af7Sopenharmony_ci /* Public static routines */ 293e5c31af7Sopenharmony_ci /* Functionality */ 294e5c31af7Sopenharmony_ci static void Attach(const glw::Functions& gl, glw::GLuint program_id, glw::GLuint shader_id); 295e5c31af7Sopenharmony_ci 296e5c31af7Sopenharmony_ci static void Create(const glw::Functions& gl, glw::GLuint& out_id); 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_ci static void Link(const glw::Functions& gl, glw::GLuint id); 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_ci static void Use(const glw::Functions& gl, glw::GLuint id); 301e5c31af7Sopenharmony_ci 302e5c31af7Sopenharmony_ci /* Public fields */ 303e5c31af7Sopenharmony_ci glw::GLuint m_id; 304e5c31af7Sopenharmony_ci 305e5c31af7Sopenharmony_ci Shader m_compute; 306e5c31af7Sopenharmony_ci Shader m_fragment; 307e5c31af7Sopenharmony_ci Shader m_geometry; 308e5c31af7Sopenharmony_ci Shader m_tess_ctrl; 309e5c31af7Sopenharmony_ci Shader m_tess_eval; 310e5c31af7Sopenharmony_ci Shader m_vertex; 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci /* Public constants */ 313e5c31af7Sopenharmony_ci static const glw::GLuint m_invalid_id; 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_ciprivate: 316e5c31af7Sopenharmony_ci /* Private fields */ 317e5c31af7Sopenharmony_ci deqp::Context& m_context; 318e5c31af7Sopenharmony_ci}; 319e5c31af7Sopenharmony_ci 320e5c31af7Sopenharmony_ci/** Represents texture instance 321e5c31af7Sopenharmony_ci **/ 322e5c31af7Sopenharmony_ciclass Texture 323e5c31af7Sopenharmony_ci{ 324e5c31af7Sopenharmony_cipublic: 325e5c31af7Sopenharmony_ci /* Public methods */ 326e5c31af7Sopenharmony_ci /* Ctr & Dtr */ 327e5c31af7Sopenharmony_ci Texture(); 328e5c31af7Sopenharmony_ci ~Texture(); 329e5c31af7Sopenharmony_ci 330e5c31af7Sopenharmony_ci /* Init & Release */ 331e5c31af7Sopenharmony_ci void Init(deqp::Context& context); 332e5c31af7Sopenharmony_ci 333e5c31af7Sopenharmony_ci void InitBuffer(deqp::Context& context, glw::GLenum internal_format, glw::GLuint buffer_id); 334e5c31af7Sopenharmony_ci 335e5c31af7Sopenharmony_ci void InitStorage(deqp::Context& context, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format, 336e5c31af7Sopenharmony_ci glw::GLuint width, glw::GLuint height, glw::GLuint depth, bool allow_error = false); 337e5c31af7Sopenharmony_ci 338e5c31af7Sopenharmony_ci void Release(); 339e5c31af7Sopenharmony_ci 340e5c31af7Sopenharmony_ci /* Public static routines */ 341e5c31af7Sopenharmony_ci /* Functionality */ 342e5c31af7Sopenharmony_ci static void Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target); 343e5c31af7Sopenharmony_ci 344e5c31af7Sopenharmony_ci static void CompressedImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, 345e5c31af7Sopenharmony_ci glw::GLenum internal_format, glw::GLuint width, glw::GLuint height, glw::GLuint depth, 346e5c31af7Sopenharmony_ci glw::GLsizei image_size, const glw::GLvoid* data); 347e5c31af7Sopenharmony_ci 348e5c31af7Sopenharmony_ci static void Generate(const glw::Functions& gl, glw::GLuint& out_id); 349e5c31af7Sopenharmony_ci 350e5c31af7Sopenharmony_ci static void GetData(const glw::Functions& gl, glw::GLint level, glw::GLenum target, glw::GLenum format, 351e5c31af7Sopenharmony_ci glw::GLenum type, glw::GLvoid* out_data); 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci static void GetLevelParameter(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum pname, 354e5c31af7Sopenharmony_ci glw::GLint* param); 355e5c31af7Sopenharmony_ci 356e5c31af7Sopenharmony_ci static void Image(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum internal_format, 357e5c31af7Sopenharmony_ci glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format, glw::GLenum type, 358e5c31af7Sopenharmony_ci const glw::GLvoid* data); 359e5c31af7Sopenharmony_ci 360e5c31af7Sopenharmony_ci static void Storage(const glw::Functions& gl, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format, 361e5c31af7Sopenharmony_ci glw::GLuint width, glw::GLuint height, glw::GLuint depth, bool allow_error); 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci static void SubImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLint x, glw::GLint y, 364e5c31af7Sopenharmony_ci glw::GLint z, glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth, glw::GLenum format, 365e5c31af7Sopenharmony_ci glw::GLenum type, const glw::GLvoid* pixels); 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ci /* Public fields */ 368e5c31af7Sopenharmony_ci glw::GLuint m_id; 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ci /* Public constants */ 371e5c31af7Sopenharmony_ci static const glw::GLuint m_invalid_id; 372e5c31af7Sopenharmony_ci 373e5c31af7Sopenharmony_ciprivate: 374e5c31af7Sopenharmony_ci /* Private fields */ 375e5c31af7Sopenharmony_ci deqp::Context* m_context; 376e5c31af7Sopenharmony_ci}; 377e5c31af7Sopenharmony_ci 378e5c31af7Sopenharmony_ci/* Buffer constants */ 379e5c31af7Sopenharmony_ciconst GLuint Buffer::m_invalid_id = -1; 380e5c31af7Sopenharmony_ci 381e5c31af7Sopenharmony_ci/** Constructor. 382e5c31af7Sopenharmony_ci * 383e5c31af7Sopenharmony_ci **/ 384e5c31af7Sopenharmony_ciBuffer::Buffer() : m_id(m_invalid_id), m_context(0), m_target(GL_ARRAY_BUFFER) 385e5c31af7Sopenharmony_ci{ 386e5c31af7Sopenharmony_ci} 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci/** Destructor 389e5c31af7Sopenharmony_ci * 390e5c31af7Sopenharmony_ci **/ 391e5c31af7Sopenharmony_ciBuffer::~Buffer() 392e5c31af7Sopenharmony_ci{ 393e5c31af7Sopenharmony_ci Release(); 394e5c31af7Sopenharmony_ci 395e5c31af7Sopenharmony_ci m_context = 0; 396e5c31af7Sopenharmony_ci} 397e5c31af7Sopenharmony_ci 398e5c31af7Sopenharmony_ci/** Initialize buffer instance 399e5c31af7Sopenharmony_ci * 400e5c31af7Sopenharmony_ci * @param context CTS context. 401e5c31af7Sopenharmony_ci **/ 402e5c31af7Sopenharmony_civoid Buffer::Init(deqp::Context& context) 403e5c31af7Sopenharmony_ci{ 404e5c31af7Sopenharmony_ci Release(); 405e5c31af7Sopenharmony_ci 406e5c31af7Sopenharmony_ci m_context = &context; 407e5c31af7Sopenharmony_ci} 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_ci/** Initialize buffer instance with some data 410e5c31af7Sopenharmony_ci * 411e5c31af7Sopenharmony_ci * @param context CTS context. 412e5c31af7Sopenharmony_ci * @param target Buffer target 413e5c31af7Sopenharmony_ci * @param usage Buffer usage enum 414e5c31af7Sopenharmony_ci * @param size <size> parameter 415e5c31af7Sopenharmony_ci * @param data <data> parameter 416e5c31af7Sopenharmony_ci **/ 417e5c31af7Sopenharmony_civoid Buffer::InitData(deqp::Context& context, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size, 418e5c31af7Sopenharmony_ci const glw::GLvoid* data) 419e5c31af7Sopenharmony_ci{ 420e5c31af7Sopenharmony_ci Init(context); 421e5c31af7Sopenharmony_ci 422e5c31af7Sopenharmony_ci m_target = target; 423e5c31af7Sopenharmony_ci 424e5c31af7Sopenharmony_ci const Functions& gl = m_context->getRenderContext().getFunctions(); 425e5c31af7Sopenharmony_ci 426e5c31af7Sopenharmony_ci Generate(gl, m_id); 427e5c31af7Sopenharmony_ci Bind(gl, m_id, m_target); 428e5c31af7Sopenharmony_ci Data(gl, m_target, usage, size, data); 429e5c31af7Sopenharmony_ci} 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci/** Release buffer instance 432e5c31af7Sopenharmony_ci * 433e5c31af7Sopenharmony_ci **/ 434e5c31af7Sopenharmony_civoid Buffer::Release() 435e5c31af7Sopenharmony_ci{ 436e5c31af7Sopenharmony_ci if (m_invalid_id != m_id) 437e5c31af7Sopenharmony_ci { 438e5c31af7Sopenharmony_ci const Functions& gl = m_context->getRenderContext().getFunctions(); 439e5c31af7Sopenharmony_ci 440e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_id); 441e5c31af7Sopenharmony_ci m_id = m_invalid_id; 442e5c31af7Sopenharmony_ci } 443e5c31af7Sopenharmony_ci} 444e5c31af7Sopenharmony_ci 445e5c31af7Sopenharmony_ci/** Binds buffer to its target 446e5c31af7Sopenharmony_ci * 447e5c31af7Sopenharmony_ci **/ 448e5c31af7Sopenharmony_civoid Buffer::Bind() const 449e5c31af7Sopenharmony_ci{ 450e5c31af7Sopenharmony_ci if (m_invalid_id == m_id) 451e5c31af7Sopenharmony_ci { 452e5c31af7Sopenharmony_ci return; 453e5c31af7Sopenharmony_ci } 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci const Functions& gl = m_context->getRenderContext().getFunctions(); 456e5c31af7Sopenharmony_ci 457e5c31af7Sopenharmony_ci Bind(gl, m_id, m_target); 458e5c31af7Sopenharmony_ci} 459e5c31af7Sopenharmony_ci 460e5c31af7Sopenharmony_ci/** Binds indexed buffer 461e5c31af7Sopenharmony_ci * 462e5c31af7Sopenharmony_ci * @param index <index> parameter 463e5c31af7Sopenharmony_ci **/ 464e5c31af7Sopenharmony_civoid Buffer::BindBase(glw::GLuint index) const 465e5c31af7Sopenharmony_ci{ 466e5c31af7Sopenharmony_ci if (m_invalid_id == m_id) 467e5c31af7Sopenharmony_ci { 468e5c31af7Sopenharmony_ci return; 469e5c31af7Sopenharmony_ci } 470e5c31af7Sopenharmony_ci 471e5c31af7Sopenharmony_ci const Functions& gl = m_context->getRenderContext().getFunctions(); 472e5c31af7Sopenharmony_ci 473e5c31af7Sopenharmony_ci BindBase(gl, m_id, m_target, index); 474e5c31af7Sopenharmony_ci} 475e5c31af7Sopenharmony_ci 476e5c31af7Sopenharmony_ci/** Bind buffer to given target 477e5c31af7Sopenharmony_ci * 478e5c31af7Sopenharmony_ci * @param gl GL functions 479e5c31af7Sopenharmony_ci * @param id Id of buffer 480e5c31af7Sopenharmony_ci * @param target Buffer target 481e5c31af7Sopenharmony_ci **/ 482e5c31af7Sopenharmony_civoid Buffer::Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target) 483e5c31af7Sopenharmony_ci{ 484e5c31af7Sopenharmony_ci gl.bindBuffer(target, id); 485e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer"); 486e5c31af7Sopenharmony_ci} 487e5c31af7Sopenharmony_ci 488e5c31af7Sopenharmony_ci/** Binds indexed buffer 489e5c31af7Sopenharmony_ci * 490e5c31af7Sopenharmony_ci * @param gl GL functions 491e5c31af7Sopenharmony_ci * @param id Id of buffer 492e5c31af7Sopenharmony_ci * @param target Buffer target 493e5c31af7Sopenharmony_ci * @param index <index> parameter 494e5c31af7Sopenharmony_ci **/ 495e5c31af7Sopenharmony_civoid Buffer::BindBase(const glw::Functions& gl, glw::GLuint id, glw::GLenum target, glw::GLuint index) 496e5c31af7Sopenharmony_ci{ 497e5c31af7Sopenharmony_ci gl.bindBufferBase(target, index, id); 498e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase"); 499e5c31af7Sopenharmony_ci} 500e5c31af7Sopenharmony_ci 501e5c31af7Sopenharmony_ci/** Allocate memory for buffer and sends initial content 502e5c31af7Sopenharmony_ci * 503e5c31af7Sopenharmony_ci * @param gl GL functions 504e5c31af7Sopenharmony_ci * @param target Buffer target 505e5c31af7Sopenharmony_ci * @param usage Buffer usage enum 506e5c31af7Sopenharmony_ci * @param size <size> parameter 507e5c31af7Sopenharmony_ci * @param data <data> parameter 508e5c31af7Sopenharmony_ci **/ 509e5c31af7Sopenharmony_civoid Buffer::Data(const glw::Functions& gl, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size, 510e5c31af7Sopenharmony_ci const glw::GLvoid* data) 511e5c31af7Sopenharmony_ci{ 512e5c31af7Sopenharmony_ci gl.bufferData(target, size, data, usage); 513e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData"); 514e5c31af7Sopenharmony_ci} 515e5c31af7Sopenharmony_ci 516e5c31af7Sopenharmony_ci/** Generate buffer 517e5c31af7Sopenharmony_ci * 518e5c31af7Sopenharmony_ci * @param gl GL functions 519e5c31af7Sopenharmony_ci * @param out_id Id of buffer 520e5c31af7Sopenharmony_ci **/ 521e5c31af7Sopenharmony_civoid Buffer::Generate(const glw::Functions& gl, glw::GLuint& out_id) 522e5c31af7Sopenharmony_ci{ 523e5c31af7Sopenharmony_ci GLuint id = m_invalid_id; 524e5c31af7Sopenharmony_ci 525e5c31af7Sopenharmony_ci gl.genBuffers(1, &id); 526e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers"); 527e5c31af7Sopenharmony_ci 528e5c31af7Sopenharmony_ci if (m_invalid_id == id) 529e5c31af7Sopenharmony_ci { 530e5c31af7Sopenharmony_ci TCU_FAIL("Got invalid id"); 531e5c31af7Sopenharmony_ci } 532e5c31af7Sopenharmony_ci 533e5c31af7Sopenharmony_ci out_id = id; 534e5c31af7Sopenharmony_ci} 535e5c31af7Sopenharmony_ci 536e5c31af7Sopenharmony_ci/** Update range of buffer 537e5c31af7Sopenharmony_ci * 538e5c31af7Sopenharmony_ci * @param gl GL functions 539e5c31af7Sopenharmony_ci * @param target Buffer target 540e5c31af7Sopenharmony_ci * @param offset Offset in buffer 541e5c31af7Sopenharmony_ci * @param size <size> parameter 542e5c31af7Sopenharmony_ci * @param data <data> parameter 543e5c31af7Sopenharmony_ci **/ 544e5c31af7Sopenharmony_civoid Buffer::SubData(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr size, 545e5c31af7Sopenharmony_ci glw::GLvoid* data) 546e5c31af7Sopenharmony_ci{ 547e5c31af7Sopenharmony_ci gl.bufferSubData(target, offset, size, data); 548e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData"); 549e5c31af7Sopenharmony_ci} 550e5c31af7Sopenharmony_ci 551e5c31af7Sopenharmony_ci/* Framebuffer constants */ 552e5c31af7Sopenharmony_ciconst GLuint Framebuffer::m_invalid_id = -1; 553e5c31af7Sopenharmony_ci 554e5c31af7Sopenharmony_ci/** Constructor. 555e5c31af7Sopenharmony_ci * 556e5c31af7Sopenharmony_ci * @param context CTS context. 557e5c31af7Sopenharmony_ci **/ 558e5c31af7Sopenharmony_ciFramebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 559e5c31af7Sopenharmony_ci{ 560e5c31af7Sopenharmony_ci /* Nothing to done here */ 561e5c31af7Sopenharmony_ci} 562e5c31af7Sopenharmony_ci 563e5c31af7Sopenharmony_ci/** Destructor 564e5c31af7Sopenharmony_ci * 565e5c31af7Sopenharmony_ci **/ 566e5c31af7Sopenharmony_ciFramebuffer::~Framebuffer() 567e5c31af7Sopenharmony_ci{ 568e5c31af7Sopenharmony_ci Release(); 569e5c31af7Sopenharmony_ci} 570e5c31af7Sopenharmony_ci 571e5c31af7Sopenharmony_ci/** Release texture instance 572e5c31af7Sopenharmony_ci * 573e5c31af7Sopenharmony_ci **/ 574e5c31af7Sopenharmony_civoid Framebuffer::Release() 575e5c31af7Sopenharmony_ci{ 576e5c31af7Sopenharmony_ci if (m_invalid_id != m_id) 577e5c31af7Sopenharmony_ci { 578e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 579e5c31af7Sopenharmony_ci 580e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &m_id); 581e5c31af7Sopenharmony_ci m_id = m_invalid_id; 582e5c31af7Sopenharmony_ci } 583e5c31af7Sopenharmony_ci} 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci/** Attach texture to specified attachment 586e5c31af7Sopenharmony_ci * 587e5c31af7Sopenharmony_ci * @param gl GL functions 588e5c31af7Sopenharmony_ci * @param target Framebuffer target 589e5c31af7Sopenharmony_ci * @param attachment Attachment 590e5c31af7Sopenharmony_ci * @param texture_id Texture id 591e5c31af7Sopenharmony_ci * @param level Level of mipmap 592e5c31af7Sopenharmony_ci * @param width Texture width 593e5c31af7Sopenharmony_ci * @param height Texture height 594e5c31af7Sopenharmony_ci **/ 595e5c31af7Sopenharmony_civoid Framebuffer::AttachTexture(const glw::Functions& gl, glw::GLenum target, glw::GLenum attachment, 596e5c31af7Sopenharmony_ci glw::GLuint texture_id, glw::GLint level, glw::GLuint width, glw::GLuint height) 597e5c31af7Sopenharmony_ci{ 598e5c31af7Sopenharmony_ci gl.framebufferTexture(target, attachment, texture_id, level); 599e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture"); 600e5c31af7Sopenharmony_ci 601e5c31af7Sopenharmony_ci gl.viewport(0 /* x */, 0 /* y */, width, height); 602e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport"); 603e5c31af7Sopenharmony_ci} 604e5c31af7Sopenharmony_ci 605e5c31af7Sopenharmony_ci/** Binds framebuffer to DRAW_FRAMEBUFFER 606e5c31af7Sopenharmony_ci * 607e5c31af7Sopenharmony_ci * @param gl GL functions 608e5c31af7Sopenharmony_ci * @param target Framebuffer target 609e5c31af7Sopenharmony_ci * @param id ID of framebuffer 610e5c31af7Sopenharmony_ci **/ 611e5c31af7Sopenharmony_civoid Framebuffer::Bind(const glw::Functions& gl, glw::GLenum target, glw::GLuint id) 612e5c31af7Sopenharmony_ci{ 613e5c31af7Sopenharmony_ci gl.bindFramebuffer(target, id); 614e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 615e5c31af7Sopenharmony_ci} 616e5c31af7Sopenharmony_ci 617e5c31af7Sopenharmony_ci/** Generate framebuffer 618e5c31af7Sopenharmony_ci * 619e5c31af7Sopenharmony_ci **/ 620e5c31af7Sopenharmony_civoid Framebuffer::Generate(const glw::Functions& gl, glw::GLuint& out_id) 621e5c31af7Sopenharmony_ci{ 622e5c31af7Sopenharmony_ci GLuint id = m_invalid_id; 623e5c31af7Sopenharmony_ci 624e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &id); 625e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers"); 626e5c31af7Sopenharmony_ci 627e5c31af7Sopenharmony_ci if (m_invalid_id == id) 628e5c31af7Sopenharmony_ci { 629e5c31af7Sopenharmony_ci TCU_FAIL("Invalid id"); 630e5c31af7Sopenharmony_ci } 631e5c31af7Sopenharmony_ci 632e5c31af7Sopenharmony_ci out_id = id; 633e5c31af7Sopenharmony_ci} 634e5c31af7Sopenharmony_ci 635e5c31af7Sopenharmony_ci/* Program constants */ 636e5c31af7Sopenharmony_ciconst GLuint Program::m_invalid_id = 0; 637e5c31af7Sopenharmony_ci 638e5c31af7Sopenharmony_ci/** Constructor. 639e5c31af7Sopenharmony_ci * 640e5c31af7Sopenharmony_ci * @param context CTS context. 641e5c31af7Sopenharmony_ci **/ 642e5c31af7Sopenharmony_ciProgram::Program(deqp::Context& context) 643e5c31af7Sopenharmony_ci : m_id(m_invalid_id) 644e5c31af7Sopenharmony_ci , m_compute(context) 645e5c31af7Sopenharmony_ci , m_fragment(context) 646e5c31af7Sopenharmony_ci , m_geometry(context) 647e5c31af7Sopenharmony_ci , m_tess_ctrl(context) 648e5c31af7Sopenharmony_ci , m_tess_eval(context) 649e5c31af7Sopenharmony_ci , m_vertex(context) 650e5c31af7Sopenharmony_ci , m_context(context) 651e5c31af7Sopenharmony_ci{ 652e5c31af7Sopenharmony_ci /* Nothing to be done here */ 653e5c31af7Sopenharmony_ci} 654e5c31af7Sopenharmony_ci 655e5c31af7Sopenharmony_ci/** Destructor 656e5c31af7Sopenharmony_ci * 657e5c31af7Sopenharmony_ci **/ 658e5c31af7Sopenharmony_ciProgram::~Program() 659e5c31af7Sopenharmony_ci{ 660e5c31af7Sopenharmony_ci Release(); 661e5c31af7Sopenharmony_ci} 662e5c31af7Sopenharmony_ci 663e5c31af7Sopenharmony_ci/** Initialize program instance 664e5c31af7Sopenharmony_ci * 665e5c31af7Sopenharmony_ci * @param compute_shader Compute shader source code 666e5c31af7Sopenharmony_ci * @param fragment_shader Fragment shader source code 667e5c31af7Sopenharmony_ci * @param geometry_shader Geometry shader source code 668e5c31af7Sopenharmony_ci * @param tesselation_control_shader Tesselation control shader source code 669e5c31af7Sopenharmony_ci * @param tesselation_evaluation_shader Tesselation evaluation shader source code 670e5c31af7Sopenharmony_ci * @param vertex_shader Vertex shader source code 671e5c31af7Sopenharmony_ci **/ 672e5c31af7Sopenharmony_civoid Program::Init(const std::string& compute_shader, const std::string& fragment_shader, 673e5c31af7Sopenharmony_ci const std::string& geometry_shader, const std::string& tesselation_control_shader, 674e5c31af7Sopenharmony_ci const std::string& tesselation_evaluation_shader, const std::string& vertex_shader) 675e5c31af7Sopenharmony_ci{ 676e5c31af7Sopenharmony_ci /* Delete previous program */ 677e5c31af7Sopenharmony_ci Release(); 678e5c31af7Sopenharmony_ci 679e5c31af7Sopenharmony_ci /* GL entry points */ 680e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 681e5c31af7Sopenharmony_ci 682e5c31af7Sopenharmony_ci /* Initialize shaders */ 683e5c31af7Sopenharmony_ci m_compute.Init(GL_COMPUTE_SHADER, compute_shader); 684e5c31af7Sopenharmony_ci m_fragment.Init(GL_FRAGMENT_SHADER, fragment_shader); 685e5c31af7Sopenharmony_ci m_geometry.Init(GL_GEOMETRY_SHADER, geometry_shader); 686e5c31af7Sopenharmony_ci m_tess_ctrl.Init(GL_TESS_CONTROL_SHADER, tesselation_control_shader); 687e5c31af7Sopenharmony_ci m_tess_eval.Init(GL_TESS_EVALUATION_SHADER, tesselation_evaluation_shader); 688e5c31af7Sopenharmony_ci m_vertex.Init(GL_VERTEX_SHADER, vertex_shader); 689e5c31af7Sopenharmony_ci 690e5c31af7Sopenharmony_ci /* Create program, set up transform feedback and attach shaders */ 691e5c31af7Sopenharmony_ci Create(gl, m_id); 692e5c31af7Sopenharmony_ci Attach(gl, m_id, m_compute.m_id); 693e5c31af7Sopenharmony_ci Attach(gl, m_id, m_fragment.m_id); 694e5c31af7Sopenharmony_ci Attach(gl, m_id, m_geometry.m_id); 695e5c31af7Sopenharmony_ci Attach(gl, m_id, m_tess_ctrl.m_id); 696e5c31af7Sopenharmony_ci Attach(gl, m_id, m_tess_eval.m_id); 697e5c31af7Sopenharmony_ci Attach(gl, m_id, m_vertex.m_id); 698e5c31af7Sopenharmony_ci 699e5c31af7Sopenharmony_ci /* Link program */ 700e5c31af7Sopenharmony_ci Link(gl, m_id); 701e5c31af7Sopenharmony_ci} 702e5c31af7Sopenharmony_ci 703e5c31af7Sopenharmony_ci/** Release program instance 704e5c31af7Sopenharmony_ci * 705e5c31af7Sopenharmony_ci **/ 706e5c31af7Sopenharmony_civoid Program::Release() 707e5c31af7Sopenharmony_ci{ 708e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 709e5c31af7Sopenharmony_ci 710e5c31af7Sopenharmony_ci if (m_invalid_id != m_id) 711e5c31af7Sopenharmony_ci { 712e5c31af7Sopenharmony_ci Use(gl, m_invalid_id); 713e5c31af7Sopenharmony_ci 714e5c31af7Sopenharmony_ci gl.deleteProgram(m_id); 715e5c31af7Sopenharmony_ci m_id = m_invalid_id; 716e5c31af7Sopenharmony_ci } 717e5c31af7Sopenharmony_ci 718e5c31af7Sopenharmony_ci m_compute.Release(); 719e5c31af7Sopenharmony_ci m_fragment.Release(); 720e5c31af7Sopenharmony_ci m_geometry.Release(); 721e5c31af7Sopenharmony_ci m_tess_ctrl.Release(); 722e5c31af7Sopenharmony_ci m_tess_eval.Release(); 723e5c31af7Sopenharmony_ci m_vertex.Release(); 724e5c31af7Sopenharmony_ci} 725e5c31af7Sopenharmony_ci 726e5c31af7Sopenharmony_ci/** Set program as active 727e5c31af7Sopenharmony_ci * 728e5c31af7Sopenharmony_ci **/ 729e5c31af7Sopenharmony_civoid Program::Use() const 730e5c31af7Sopenharmony_ci{ 731e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_ci Use(gl, m_id); 734e5c31af7Sopenharmony_ci} 735e5c31af7Sopenharmony_ci 736e5c31af7Sopenharmony_ci/** Attach shader to program 737e5c31af7Sopenharmony_ci * 738e5c31af7Sopenharmony_ci * @param gl GL functions 739e5c31af7Sopenharmony_ci * @param program_id Id of program 740e5c31af7Sopenharmony_ci * @param shader_id Id of shader 741e5c31af7Sopenharmony_ci **/ 742e5c31af7Sopenharmony_civoid Program::Attach(const glw::Functions& gl, glw::GLuint program_id, glw::GLuint shader_id) 743e5c31af7Sopenharmony_ci{ 744e5c31af7Sopenharmony_ci /* Quick checks */ 745e5c31af7Sopenharmony_ci if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id)) 746e5c31af7Sopenharmony_ci { 747e5c31af7Sopenharmony_ci return; 748e5c31af7Sopenharmony_ci } 749e5c31af7Sopenharmony_ci 750e5c31af7Sopenharmony_ci gl.attachShader(program_id, shader_id); 751e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 752e5c31af7Sopenharmony_ci} 753e5c31af7Sopenharmony_ci 754e5c31af7Sopenharmony_ci/** Create program instance 755e5c31af7Sopenharmony_ci * 756e5c31af7Sopenharmony_ci * @param gl GL functions 757e5c31af7Sopenharmony_ci * @param out_id Id of program 758e5c31af7Sopenharmony_ci **/ 759e5c31af7Sopenharmony_civoid Program::Create(const glw::Functions& gl, glw::GLuint& out_id) 760e5c31af7Sopenharmony_ci{ 761e5c31af7Sopenharmony_ci const GLuint id = gl.createProgram(); 762e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram"); 763e5c31af7Sopenharmony_ci 764e5c31af7Sopenharmony_ci if (m_invalid_id == id) 765e5c31af7Sopenharmony_ci { 766e5c31af7Sopenharmony_ci TCU_FAIL("Failed to create program"); 767e5c31af7Sopenharmony_ci } 768e5c31af7Sopenharmony_ci 769e5c31af7Sopenharmony_ci out_id = id; 770e5c31af7Sopenharmony_ci} 771e5c31af7Sopenharmony_ci 772e5c31af7Sopenharmony_ci/** Link program 773e5c31af7Sopenharmony_ci * 774e5c31af7Sopenharmony_ci * @param gl GL functions 775e5c31af7Sopenharmony_ci * @param id Id of program 776e5c31af7Sopenharmony_ci **/ 777e5c31af7Sopenharmony_civoid Program::Link(const glw::Functions& gl, glw::GLuint id) 778e5c31af7Sopenharmony_ci{ 779e5c31af7Sopenharmony_ci GLint status = GL_FALSE; 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ci gl.linkProgram(id); 782e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram"); 783e5c31af7Sopenharmony_ci 784e5c31af7Sopenharmony_ci /* Get link status */ 785e5c31af7Sopenharmony_ci gl.getProgramiv(id, GL_LINK_STATUS, &status); 786e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 787e5c31af7Sopenharmony_ci 788e5c31af7Sopenharmony_ci /* Log link error */ 789e5c31af7Sopenharmony_ci if (GL_TRUE != status) 790e5c31af7Sopenharmony_ci { 791e5c31af7Sopenharmony_ci glw::GLint length = 0; 792e5c31af7Sopenharmony_ci std::string message; 793e5c31af7Sopenharmony_ci 794e5c31af7Sopenharmony_ci /* Get error log length */ 795e5c31af7Sopenharmony_ci gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length); 796e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 797e5c31af7Sopenharmony_ci 798e5c31af7Sopenharmony_ci message.resize(length, 0); 799e5c31af7Sopenharmony_ci 800e5c31af7Sopenharmony_ci /* Get error log */ 801e5c31af7Sopenharmony_ci gl.getProgramInfoLog(id, length, 0, &message[0]); 802e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog"); 803e5c31af7Sopenharmony_ci 804e5c31af7Sopenharmony_ci TCU_FAIL(message.c_str()); 805e5c31af7Sopenharmony_ci } 806e5c31af7Sopenharmony_ci} 807e5c31af7Sopenharmony_ci 808e5c31af7Sopenharmony_ci/** Use program 809e5c31af7Sopenharmony_ci * 810e5c31af7Sopenharmony_ci * @param gl GL functions 811e5c31af7Sopenharmony_ci * @param id Id of program 812e5c31af7Sopenharmony_ci **/ 813e5c31af7Sopenharmony_civoid Program::Use(const glw::Functions& gl, glw::GLuint id) 814e5c31af7Sopenharmony_ci{ 815e5c31af7Sopenharmony_ci gl.useProgram(id); 816e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 817e5c31af7Sopenharmony_ci} 818e5c31af7Sopenharmony_ci 819e5c31af7Sopenharmony_ci/* Shader's constants */ 820e5c31af7Sopenharmony_ciconst GLuint Shader::m_invalid_id = 0; 821e5c31af7Sopenharmony_ci 822e5c31af7Sopenharmony_ci/** Constructor. 823e5c31af7Sopenharmony_ci * 824e5c31af7Sopenharmony_ci * @param context CTS context. 825e5c31af7Sopenharmony_ci **/ 826e5c31af7Sopenharmony_ciShader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 827e5c31af7Sopenharmony_ci{ 828e5c31af7Sopenharmony_ci /* Nothing to be done here */ 829e5c31af7Sopenharmony_ci} 830e5c31af7Sopenharmony_ci 831e5c31af7Sopenharmony_ci/** Destructor 832e5c31af7Sopenharmony_ci * 833e5c31af7Sopenharmony_ci **/ 834e5c31af7Sopenharmony_ciShader::~Shader() 835e5c31af7Sopenharmony_ci{ 836e5c31af7Sopenharmony_ci Release(); 837e5c31af7Sopenharmony_ci} 838e5c31af7Sopenharmony_ci 839e5c31af7Sopenharmony_ci/** Initialize shader instance 840e5c31af7Sopenharmony_ci * 841e5c31af7Sopenharmony_ci * @param stage Shader stage 842e5c31af7Sopenharmony_ci * @param source Source code 843e5c31af7Sopenharmony_ci **/ 844e5c31af7Sopenharmony_civoid Shader::Init(glw::GLenum stage, const std::string& source) 845e5c31af7Sopenharmony_ci{ 846e5c31af7Sopenharmony_ci if (true == source.empty()) 847e5c31af7Sopenharmony_ci { 848e5c31af7Sopenharmony_ci /* No source == no shader */ 849e5c31af7Sopenharmony_ci return; 850e5c31af7Sopenharmony_ci } 851e5c31af7Sopenharmony_ci 852e5c31af7Sopenharmony_ci /* Delete any previous shader */ 853e5c31af7Sopenharmony_ci Release(); 854e5c31af7Sopenharmony_ci 855e5c31af7Sopenharmony_ci /* Create, set source and compile */ 856e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 857e5c31af7Sopenharmony_ci 858e5c31af7Sopenharmony_ci Create(gl, stage, m_id); 859e5c31af7Sopenharmony_ci Source(gl, m_id, source); 860e5c31af7Sopenharmony_ci 861e5c31af7Sopenharmony_ci Compile(gl, m_id); 862e5c31af7Sopenharmony_ci} 863e5c31af7Sopenharmony_ci 864e5c31af7Sopenharmony_ci/** Release shader instance 865e5c31af7Sopenharmony_ci * 866e5c31af7Sopenharmony_ci **/ 867e5c31af7Sopenharmony_civoid Shader::Release() 868e5c31af7Sopenharmony_ci{ 869e5c31af7Sopenharmony_ci if (m_invalid_id != m_id) 870e5c31af7Sopenharmony_ci { 871e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 872e5c31af7Sopenharmony_ci 873e5c31af7Sopenharmony_ci gl.deleteShader(m_id); 874e5c31af7Sopenharmony_ci m_id = m_invalid_id; 875e5c31af7Sopenharmony_ci } 876e5c31af7Sopenharmony_ci} 877e5c31af7Sopenharmony_ci 878e5c31af7Sopenharmony_ci/** Compile shader 879e5c31af7Sopenharmony_ci * 880e5c31af7Sopenharmony_ci * @param gl GL functions 881e5c31af7Sopenharmony_ci * @param id Shader id 882e5c31af7Sopenharmony_ci **/ 883e5c31af7Sopenharmony_civoid Shader::Compile(const glw::Functions& gl, glw::GLuint id) 884e5c31af7Sopenharmony_ci{ 885e5c31af7Sopenharmony_ci GLint status = GL_FALSE; 886e5c31af7Sopenharmony_ci 887e5c31af7Sopenharmony_ci /* Compile */ 888e5c31af7Sopenharmony_ci gl.compileShader(id); 889e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader"); 890e5c31af7Sopenharmony_ci 891e5c31af7Sopenharmony_ci /* Get compilation status */ 892e5c31af7Sopenharmony_ci gl.getShaderiv(id, GL_COMPILE_STATUS, &status); 893e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 894e5c31af7Sopenharmony_ci 895e5c31af7Sopenharmony_ci /* Log compilation error */ 896e5c31af7Sopenharmony_ci if (GL_TRUE != status) 897e5c31af7Sopenharmony_ci { 898e5c31af7Sopenharmony_ci glw::GLint length = 0; 899e5c31af7Sopenharmony_ci std::string message; 900e5c31af7Sopenharmony_ci 901e5c31af7Sopenharmony_ci /* Error log length */ 902e5c31af7Sopenharmony_ci gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length); 903e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 904e5c31af7Sopenharmony_ci 905e5c31af7Sopenharmony_ci /* Prepare storage */ 906e5c31af7Sopenharmony_ci message.resize(length, 0); 907e5c31af7Sopenharmony_ci 908e5c31af7Sopenharmony_ci /* Get error log */ 909e5c31af7Sopenharmony_ci gl.getShaderInfoLog(id, length, 0, &message[0]); 910e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog"); 911e5c31af7Sopenharmony_ci 912e5c31af7Sopenharmony_ci TCU_FAIL(message.c_str()); 913e5c31af7Sopenharmony_ci } 914e5c31af7Sopenharmony_ci} 915e5c31af7Sopenharmony_ci 916e5c31af7Sopenharmony_ci/** Create shader 917e5c31af7Sopenharmony_ci * 918e5c31af7Sopenharmony_ci * @param gl GL functions 919e5c31af7Sopenharmony_ci * @param stage Shader stage 920e5c31af7Sopenharmony_ci * @param out_id Shader id 921e5c31af7Sopenharmony_ci **/ 922e5c31af7Sopenharmony_civoid Shader::Create(const glw::Functions& gl, glw::GLenum stage, glw::GLuint& out_id) 923e5c31af7Sopenharmony_ci{ 924e5c31af7Sopenharmony_ci const GLuint id = gl.createShader(stage); 925e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 926e5c31af7Sopenharmony_ci 927e5c31af7Sopenharmony_ci if (m_invalid_id == id) 928e5c31af7Sopenharmony_ci { 929e5c31af7Sopenharmony_ci TCU_FAIL("Failed to create shader"); 930e5c31af7Sopenharmony_ci } 931e5c31af7Sopenharmony_ci 932e5c31af7Sopenharmony_ci out_id = id; 933e5c31af7Sopenharmony_ci} 934e5c31af7Sopenharmony_ci 935e5c31af7Sopenharmony_ci/** Set shader's source code 936e5c31af7Sopenharmony_ci * 937e5c31af7Sopenharmony_ci * @param gl GL functions 938e5c31af7Sopenharmony_ci * @param id Shader id 939e5c31af7Sopenharmony_ci * @param source Shader source code 940e5c31af7Sopenharmony_ci **/ 941e5c31af7Sopenharmony_civoid Shader::Source(const glw::Functions& gl, glw::GLuint id, const std::string& source) 942e5c31af7Sopenharmony_ci{ 943e5c31af7Sopenharmony_ci const GLchar* code = source.c_str(); 944e5c31af7Sopenharmony_ci 945e5c31af7Sopenharmony_ci gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */); 946e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource"); 947e5c31af7Sopenharmony_ci} 948e5c31af7Sopenharmony_ci 949e5c31af7Sopenharmony_ci/* Texture static fields */ 950e5c31af7Sopenharmony_ciconst GLuint Texture::m_invalid_id = -1; 951e5c31af7Sopenharmony_ci 952e5c31af7Sopenharmony_ci/** Constructor. 953e5c31af7Sopenharmony_ci * 954e5c31af7Sopenharmony_ci **/ 955e5c31af7Sopenharmony_ciTexture::Texture() : m_id(m_invalid_id), m_context(0) 956e5c31af7Sopenharmony_ci{ 957e5c31af7Sopenharmony_ci /* Nothing to done here */ 958e5c31af7Sopenharmony_ci} 959e5c31af7Sopenharmony_ci 960e5c31af7Sopenharmony_ci/** Destructor 961e5c31af7Sopenharmony_ci * 962e5c31af7Sopenharmony_ci **/ 963e5c31af7Sopenharmony_ciTexture::~Texture() 964e5c31af7Sopenharmony_ci{ 965e5c31af7Sopenharmony_ci Release(); 966e5c31af7Sopenharmony_ci} 967e5c31af7Sopenharmony_ci 968e5c31af7Sopenharmony_ci/** Initialize texture instance 969e5c31af7Sopenharmony_ci * 970e5c31af7Sopenharmony_ci * @param context Test context 971e5c31af7Sopenharmony_ci **/ 972e5c31af7Sopenharmony_civoid Texture::Init(deqp::Context& context) 973e5c31af7Sopenharmony_ci{ 974e5c31af7Sopenharmony_ci Release(); 975e5c31af7Sopenharmony_ci 976e5c31af7Sopenharmony_ci m_context = &context; 977e5c31af7Sopenharmony_ci} 978e5c31af7Sopenharmony_ci 979e5c31af7Sopenharmony_ci/** Initialize texture instance as texture buffer 980e5c31af7Sopenharmony_ci * 981e5c31af7Sopenharmony_ci * @param context Test context 982e5c31af7Sopenharmony_ci * @param internal_format Internal format of texture 983e5c31af7Sopenharmony_ci * @param buufer_id ID of buffer that will be used as storage 984e5c31af7Sopenharmony_ci **/ 985e5c31af7Sopenharmony_civoid Texture::InitBuffer(deqp::Context& context, glw::GLenum internal_format, glw::GLuint buffer_id) 986e5c31af7Sopenharmony_ci{ 987e5c31af7Sopenharmony_ci Init(context); 988e5c31af7Sopenharmony_ci 989e5c31af7Sopenharmony_ci const Functions& gl = m_context->getRenderContext().getFunctions(); 990e5c31af7Sopenharmony_ci 991e5c31af7Sopenharmony_ci Generate(gl, m_id); 992e5c31af7Sopenharmony_ci Bind(gl, m_id, GL_TEXTURE_BUFFER); 993e5c31af7Sopenharmony_ci Buffer::Bind(gl, buffer_id, GL_TEXTURE_BUFFER); 994e5c31af7Sopenharmony_ci 995e5c31af7Sopenharmony_ci gl.texBuffer(GL_TEXTURE_BUFFER, internal_format, buffer_id); 996e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexBuffer"); 997e5c31af7Sopenharmony_ci} 998e5c31af7Sopenharmony_ci 999e5c31af7Sopenharmony_ci/** Initialize texture instance with storage 1000e5c31af7Sopenharmony_ci * 1001e5c31af7Sopenharmony_ci * @param context Test context 1002e5c31af7Sopenharmony_ci * @param target Texture target 1003e5c31af7Sopenharmony_ci * @param levels Number of levels 1004e5c31af7Sopenharmony_ci * @param internal_format Internal format of texture 1005e5c31af7Sopenharmony_ci * @param width Width of texture 1006e5c31af7Sopenharmony_ci * @param height Height of texture 1007e5c31af7Sopenharmony_ci * @param depth Depth of texture 1008e5c31af7Sopenharmony_ci **/ 1009e5c31af7Sopenharmony_civoid Texture::InitStorage(deqp::Context& context, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format, 1010e5c31af7Sopenharmony_ci glw::GLuint width, glw::GLuint height, glw::GLuint depth, bool allow_error) 1011e5c31af7Sopenharmony_ci{ 1012e5c31af7Sopenharmony_ci Init(context); 1013e5c31af7Sopenharmony_ci 1014e5c31af7Sopenharmony_ci const Functions& gl = m_context->getRenderContext().getFunctions(); 1015e5c31af7Sopenharmony_ci 1016e5c31af7Sopenharmony_ci Generate(gl, m_id); 1017e5c31af7Sopenharmony_ci Bind(gl, m_id, target); 1018e5c31af7Sopenharmony_ci Storage(gl, target, levels, internal_format, width, height, depth, allow_error); 1019e5c31af7Sopenharmony_ci} 1020e5c31af7Sopenharmony_ci 1021e5c31af7Sopenharmony_ci/** Release texture instance 1022e5c31af7Sopenharmony_ci * 1023e5c31af7Sopenharmony_ci * @param context CTS context. 1024e5c31af7Sopenharmony_ci **/ 1025e5c31af7Sopenharmony_civoid Texture::Release() 1026e5c31af7Sopenharmony_ci{ 1027e5c31af7Sopenharmony_ci if (m_invalid_id != m_id) 1028e5c31af7Sopenharmony_ci { 1029e5c31af7Sopenharmony_ci const Functions& gl = m_context->getRenderContext().getFunctions(); 1030e5c31af7Sopenharmony_ci 1031e5c31af7Sopenharmony_ci gl.deleteTextures(1, &m_id); 1032e5c31af7Sopenharmony_ci m_id = m_invalid_id; 1033e5c31af7Sopenharmony_ci } 1034e5c31af7Sopenharmony_ci} 1035e5c31af7Sopenharmony_ci 1036e5c31af7Sopenharmony_ci/** Bind texture to target 1037e5c31af7Sopenharmony_ci * 1038e5c31af7Sopenharmony_ci * @param gl GL functions 1039e5c31af7Sopenharmony_ci * @param id Id of texture 1040e5c31af7Sopenharmony_ci * @param tex_type Type of texture 1041e5c31af7Sopenharmony_ci **/ 1042e5c31af7Sopenharmony_civoid Texture::Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target) 1043e5c31af7Sopenharmony_ci{ 1044e5c31af7Sopenharmony_ci gl.bindTexture(target, id); 1045e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1046e5c31af7Sopenharmony_ci} 1047e5c31af7Sopenharmony_ci 1048e5c31af7Sopenharmony_ci/** Set contents of compressed texture 1049e5c31af7Sopenharmony_ci * 1050e5c31af7Sopenharmony_ci * @param gl GL functions 1051e5c31af7Sopenharmony_ci * @param target Texture target 1052e5c31af7Sopenharmony_ci * @param level Mipmap level 1053e5c31af7Sopenharmony_ci * @param internal_format Format of data 1054e5c31af7Sopenharmony_ci * @param width Width of texture 1055e5c31af7Sopenharmony_ci * @param height Height of texture 1056e5c31af7Sopenharmony_ci * @param depth Depth of texture 1057e5c31af7Sopenharmony_ci * @param image_size Size of data 1058e5c31af7Sopenharmony_ci * @param data Buffer with image data 1059e5c31af7Sopenharmony_ci **/ 1060e5c31af7Sopenharmony_civoid Texture::CompressedImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, 1061e5c31af7Sopenharmony_ci glw::GLenum internal_format, glw::GLuint width, glw::GLuint height, glw::GLuint depth, 1062e5c31af7Sopenharmony_ci glw::GLsizei image_size, const glw::GLvoid* data) 1063e5c31af7Sopenharmony_ci{ 1064e5c31af7Sopenharmony_ci switch (target) 1065e5c31af7Sopenharmony_ci { 1066e5c31af7Sopenharmony_ci case GL_TEXTURE_1D: 1067e5c31af7Sopenharmony_ci gl.compressedTexImage1D(target, level, internal_format, width, 0 /* border */, image_size, data); 1068e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage1D"); 1069e5c31af7Sopenharmony_ci break; 1070e5c31af7Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 1071e5c31af7Sopenharmony_ci case GL_TEXTURE_2D: 1072e5c31af7Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 1073e5c31af7Sopenharmony_ci gl.compressedTexImage2D(target, level, internal_format, width, height, 0 /* border */, image_size, data); 1074e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage2D"); 1075e5c31af7Sopenharmony_ci break; 1076e5c31af7Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1077e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, internal_format, width, height, 0 /* border */, 1078e5c31af7Sopenharmony_ci image_size, data); 1079e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, internal_format, width, height, 0 /* border */, 1080e5c31af7Sopenharmony_ci image_size, data); 1081e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, internal_format, width, height, 0 /* border */, 1082e5c31af7Sopenharmony_ci image_size, data); 1083e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internal_format, width, height, 0 /* border */, 1084e5c31af7Sopenharmony_ci image_size, data); 1085e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, internal_format, width, height, 0 /* border */, 1086e5c31af7Sopenharmony_ci image_size, data); 1087e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internal_format, width, height, 0 /* border */, 1088e5c31af7Sopenharmony_ci image_size, data); 1089e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage2D"); 1090e5c31af7Sopenharmony_ci break; 1091e5c31af7Sopenharmony_ci case GL_TEXTURE_3D: 1092e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 1093e5c31af7Sopenharmony_ci gl.compressedTexImage3D(target, level, internal_format, width, height, depth, 0 /* border */, image_size, data); 1094e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage3D"); 1095e5c31af7Sopenharmony_ci break; 1096e5c31af7Sopenharmony_ci default: 1097e5c31af7Sopenharmony_ci TCU_FAIL("Invliad enum"); 1098e5c31af7Sopenharmony_ci } 1099e5c31af7Sopenharmony_ci} 1100e5c31af7Sopenharmony_ci 1101e5c31af7Sopenharmony_ci/** Generate texture instance 1102e5c31af7Sopenharmony_ci * 1103e5c31af7Sopenharmony_ci * @param gl GL functions 1104e5c31af7Sopenharmony_ci * @param out_id Id of texture 1105e5c31af7Sopenharmony_ci **/ 1106e5c31af7Sopenharmony_civoid Texture::Generate(const glw::Functions& gl, glw::GLuint& out_id) 1107e5c31af7Sopenharmony_ci{ 1108e5c31af7Sopenharmony_ci GLuint id = m_invalid_id; 1109e5c31af7Sopenharmony_ci 1110e5c31af7Sopenharmony_ci gl.genTextures(1, &id); 1111e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 1112e5c31af7Sopenharmony_ci 1113e5c31af7Sopenharmony_ci if (m_invalid_id == id) 1114e5c31af7Sopenharmony_ci { 1115e5c31af7Sopenharmony_ci TCU_FAIL("Invalid id"); 1116e5c31af7Sopenharmony_ci } 1117e5c31af7Sopenharmony_ci 1118e5c31af7Sopenharmony_ci out_id = id; 1119e5c31af7Sopenharmony_ci} 1120e5c31af7Sopenharmony_ci 1121e5c31af7Sopenharmony_ci/** Get texture data 1122e5c31af7Sopenharmony_ci * 1123e5c31af7Sopenharmony_ci * @param gl GL functions 1124e5c31af7Sopenharmony_ci * @param target Texture target 1125e5c31af7Sopenharmony_ci * @param format Format of data 1126e5c31af7Sopenharmony_ci * @param type Type of data 1127e5c31af7Sopenharmony_ci * @param out_data Buffer for data 1128e5c31af7Sopenharmony_ci **/ 1129e5c31af7Sopenharmony_civoid Texture::GetData(const glw::Functions& gl, glw::GLint level, glw::GLenum target, glw::GLenum format, 1130e5c31af7Sopenharmony_ci glw::GLenum type, glw::GLvoid* out_data) 1131e5c31af7Sopenharmony_ci{ 1132e5c31af7Sopenharmony_ci gl.getTexImage(target, level, format, type, out_data); 1133e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage"); 1134e5c31af7Sopenharmony_ci} 1135e5c31af7Sopenharmony_ci 1136e5c31af7Sopenharmony_ci/** Generate texture instance 1137e5c31af7Sopenharmony_ci * 1138e5c31af7Sopenharmony_ci * @param gl GL functions 1139e5c31af7Sopenharmony_ci * @param target Texture target 1140e5c31af7Sopenharmony_ci * @param level Mipmap level 1141e5c31af7Sopenharmony_ci * @param pname Parameter to query 1142e5c31af7Sopenharmony_ci * @param param Result of query 1143e5c31af7Sopenharmony_ci **/ 1144e5c31af7Sopenharmony_civoid Texture::GetLevelParameter(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum pname, 1145e5c31af7Sopenharmony_ci glw::GLint* param) 1146e5c31af7Sopenharmony_ci{ 1147e5c31af7Sopenharmony_ci gl.getTexLevelParameteriv(target, level, pname, param); 1148e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 1149e5c31af7Sopenharmony_ci} 1150e5c31af7Sopenharmony_ci 1151e5c31af7Sopenharmony_ci/** Set contents of texture 1152e5c31af7Sopenharmony_ci * 1153e5c31af7Sopenharmony_ci * @param gl GL functions 1154e5c31af7Sopenharmony_ci * @param target Texture target 1155e5c31af7Sopenharmony_ci * @param level Mipmap level 1156e5c31af7Sopenharmony_ci * @param internal_format Format of data 1157e5c31af7Sopenharmony_ci * @param width Width of texture 1158e5c31af7Sopenharmony_ci * @param height Height of texture 1159e5c31af7Sopenharmony_ci * @param depth Depth of texture 1160e5c31af7Sopenharmony_ci * @param format Format of data 1161e5c31af7Sopenharmony_ci * @param type Type of data 1162e5c31af7Sopenharmony_ci * @param data Buffer with image data 1163e5c31af7Sopenharmony_ci **/ 1164e5c31af7Sopenharmony_civoid Texture::Image(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum internal_format, 1165e5c31af7Sopenharmony_ci glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format, glw::GLenum type, 1166e5c31af7Sopenharmony_ci const glw::GLvoid* data) 1167e5c31af7Sopenharmony_ci{ 1168e5c31af7Sopenharmony_ci switch (target) 1169e5c31af7Sopenharmony_ci { 1170e5c31af7Sopenharmony_ci case GL_TEXTURE_1D: 1171e5c31af7Sopenharmony_ci gl.texImage1D(target, level, internal_format, width, 0 /* border */, format, type, data); 1172e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage1D"); 1173e5c31af7Sopenharmony_ci break; 1174e5c31af7Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 1175e5c31af7Sopenharmony_ci case GL_TEXTURE_2D: 1176e5c31af7Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 1177e5c31af7Sopenharmony_ci gl.texImage2D(target, level, internal_format, width, height, 0 /* border */, format, type, data); 1178e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D"); 1179e5c31af7Sopenharmony_ci break; 1180e5c31af7Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1181e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, internal_format, width, height, 0 /* border */, format, 1182e5c31af7Sopenharmony_ci type, data); 1183e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, internal_format, width, height, 0 /* border */, format, 1184e5c31af7Sopenharmony_ci type, data); 1185e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, internal_format, width, height, 0 /* border */, format, 1186e5c31af7Sopenharmony_ci type, data); 1187e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internal_format, width, height, 0 /* border */, format, 1188e5c31af7Sopenharmony_ci type, data); 1189e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, internal_format, width, height, 0 /* border */, format, 1190e5c31af7Sopenharmony_ci type, data); 1191e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internal_format, width, height, 0 /* border */, format, 1192e5c31af7Sopenharmony_ci type, data); 1193e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D"); 1194e5c31af7Sopenharmony_ci break; 1195e5c31af7Sopenharmony_ci case GL_TEXTURE_3D: 1196e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 1197e5c31af7Sopenharmony_ci gl.texImage3D(target, level, internal_format, width, height, depth, 0 /* border */, format, type, data); 1198e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage3D"); 1199e5c31af7Sopenharmony_ci break; 1200e5c31af7Sopenharmony_ci default: 1201e5c31af7Sopenharmony_ci TCU_FAIL("Invliad enum"); 1202e5c31af7Sopenharmony_ci } 1203e5c31af7Sopenharmony_ci} 1204e5c31af7Sopenharmony_ci 1205e5c31af7Sopenharmony_ci/** Allocate storage for texture 1206e5c31af7Sopenharmony_ci * 1207e5c31af7Sopenharmony_ci * @param gl GL functions 1208e5c31af7Sopenharmony_ci * @param target Texture target 1209e5c31af7Sopenharmony_ci * @param levels Number of levels 1210e5c31af7Sopenharmony_ci * @param internal_format Internal format of texture 1211e5c31af7Sopenharmony_ci * @param width Width of texture 1212e5c31af7Sopenharmony_ci * @param height Height of texture 1213e5c31af7Sopenharmony_ci * @param depth Depth of texture 1214e5c31af7Sopenharmony_ci **/ 1215e5c31af7Sopenharmony_civoid Texture::Storage(const glw::Functions& gl, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format, 1216e5c31af7Sopenharmony_ci glw::GLuint width, glw::GLuint height, glw::GLuint depth, bool allow_error) 1217e5c31af7Sopenharmony_ci{ 1218e5c31af7Sopenharmony_ci switch (target) 1219e5c31af7Sopenharmony_ci { 1220e5c31af7Sopenharmony_ci case GL_TEXTURE_1D: 1221e5c31af7Sopenharmony_ci gl.texStorage1D(target, levels, internal_format, width); 1222e5c31af7Sopenharmony_ci if (!allow_error) 1223e5c31af7Sopenharmony_ci { 1224e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D"); 1225e5c31af7Sopenharmony_ci } 1226e5c31af7Sopenharmony_ci break; 1227e5c31af7Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 1228e5c31af7Sopenharmony_ci case GL_TEXTURE_2D: 1229e5c31af7Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 1230e5c31af7Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1231e5c31af7Sopenharmony_ci gl.texStorage2D(target, levels, internal_format, width, height); 1232e5c31af7Sopenharmony_ci if (!allow_error) 1233e5c31af7Sopenharmony_ci { 1234e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D"); 1235e5c31af7Sopenharmony_ci } 1236e5c31af7Sopenharmony_ci break; 1237e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 1238e5c31af7Sopenharmony_ci gl.texStorage2DMultisample(target, levels, internal_format, width, height, GL_FALSE); 1239e5c31af7Sopenharmony_ci if (!allow_error) 1240e5c31af7Sopenharmony_ci { 1241e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2DMultisample"); 1242e5c31af7Sopenharmony_ci } 1243e5c31af7Sopenharmony_ci break; 1244e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1245e5c31af7Sopenharmony_ci gl.texStorage3DMultisample(target, levels, internal_format, width, height, depth, GL_FALSE); 1246e5c31af7Sopenharmony_ci if (!allow_error) 1247e5c31af7Sopenharmony_ci { 1248e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3DMultisample"); 1249e5c31af7Sopenharmony_ci } 1250e5c31af7Sopenharmony_ci break; 1251e5c31af7Sopenharmony_ci case GL_TEXTURE_3D: 1252e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 1253e5c31af7Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 1254e5c31af7Sopenharmony_ci gl.texStorage3D(target, levels, internal_format, width, height, depth); 1255e5c31af7Sopenharmony_ci if (!allow_error) 1256e5c31af7Sopenharmony_ci { 1257e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D"); 1258e5c31af7Sopenharmony_ci } 1259e5c31af7Sopenharmony_ci break; 1260e5c31af7Sopenharmony_ci default: 1261e5c31af7Sopenharmony_ci TCU_FAIL("Invliad enum"); 1262e5c31af7Sopenharmony_ci } 1263e5c31af7Sopenharmony_ci} 1264e5c31af7Sopenharmony_ci 1265e5c31af7Sopenharmony_ci/** Set contents of texture 1266e5c31af7Sopenharmony_ci * 1267e5c31af7Sopenharmony_ci * @param gl GL functions 1268e5c31af7Sopenharmony_ci * @param target Texture target 1269e5c31af7Sopenharmony_ci * @param level Mipmap level 1270e5c31af7Sopenharmony_ci * @param x X offset 1271e5c31af7Sopenharmony_ci * @param y Y offset 1272e5c31af7Sopenharmony_ci * @param z Z offset 1273e5c31af7Sopenharmony_ci * @param width Width of texture 1274e5c31af7Sopenharmony_ci * @param height Height of texture 1275e5c31af7Sopenharmony_ci * @param depth Depth of texture 1276e5c31af7Sopenharmony_ci * @param format Format of data 1277e5c31af7Sopenharmony_ci * @param type Type of data 1278e5c31af7Sopenharmony_ci * @param pixels Buffer with image data 1279e5c31af7Sopenharmony_ci **/ 1280e5c31af7Sopenharmony_civoid Texture::SubImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLint x, glw::GLint y, 1281e5c31af7Sopenharmony_ci glw::GLint z, glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth, glw::GLenum format, 1282e5c31af7Sopenharmony_ci glw::GLenum type, const glw::GLvoid* pixels) 1283e5c31af7Sopenharmony_ci{ 1284e5c31af7Sopenharmony_ci switch (target) 1285e5c31af7Sopenharmony_ci { 1286e5c31af7Sopenharmony_ci case GL_TEXTURE_1D: 1287e5c31af7Sopenharmony_ci gl.texSubImage1D(target, level, x, width, format, type, pixels); 1288e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage1D"); 1289e5c31af7Sopenharmony_ci break; 1290e5c31af7Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 1291e5c31af7Sopenharmony_ci case GL_TEXTURE_2D: 1292e5c31af7Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 1293e5c31af7Sopenharmony_ci gl.texSubImage2D(target, level, x, y, width, height, format, type, pixels); 1294e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D"); 1295e5c31af7Sopenharmony_ci break; 1296e5c31af7Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1297e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, x, y, width, height, format, type, pixels); 1298e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, x, y, width, height, format, type, pixels); 1299e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, x, y, width, height, format, type, pixels); 1300e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, x, y, width, height, format, type, pixels); 1301e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, x, y, width, height, format, type, pixels); 1302e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, x, y, width, height, format, type, pixels); 1303e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D"); 1304e5c31af7Sopenharmony_ci break; 1305e5c31af7Sopenharmony_ci case GL_TEXTURE_3D: 1306e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 1307e5c31af7Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 1308e5c31af7Sopenharmony_ci gl.texSubImage3D(target, level, x, y, z, width, height, depth, format, type, pixels); 1309e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage3D"); 1310e5c31af7Sopenharmony_ci break; 1311e5c31af7Sopenharmony_ci default: 1312e5c31af7Sopenharmony_ci TCU_FAIL("Invliad enum"); 1313e5c31af7Sopenharmony_ci } 1314e5c31af7Sopenharmony_ci} 1315e5c31af7Sopenharmony_ci 1316e5c31af7Sopenharmony_ci/* Gather info about buffer target */ 1317e5c31af7Sopenharmony_cistruct bufferTargetInfo 1318e5c31af7Sopenharmony_ci{ 1319e5c31af7Sopenharmony_ci GLenum m_target; 1320e5c31af7Sopenharmony_ci GLenum m_pname_alignment; 1321e5c31af7Sopenharmony_ci GLenum m_pname_binding; 1322e5c31af7Sopenharmony_ci GLenum m_pname_max; 1323e5c31af7Sopenharmony_ci GLenum m_pname_max_size; 1324e5c31af7Sopenharmony_ci}; 1325e5c31af7Sopenharmony_ci 1326e5c31af7Sopenharmony_ci/* Gather info about texture target */ 1327e5c31af7Sopenharmony_cistruct textureTargetInfo 1328e5c31af7Sopenharmony_ci{ 1329e5c31af7Sopenharmony_ci GLenum m_target; 1330e5c31af7Sopenharmony_ci GLenum m_pname_binding; 1331e5c31af7Sopenharmony_ci const GLchar* m_name; 1332e5c31af7Sopenharmony_ci}; 1333e5c31af7Sopenharmony_ci 1334e5c31af7Sopenharmony_ci/* Collects information about buffers */ 1335e5c31af7Sopenharmony_cistatic const bufferTargetInfo s_buffer_infos[] = { 1336e5c31af7Sopenharmony_ci { GL_ATOMIC_COUNTER_BUFFER, 0, GL_ATOMIC_COUNTER_BUFFER_BINDING, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, 1337e5c31af7Sopenharmony_ci GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE }, 1338e5c31af7Sopenharmony_ci { 1339e5c31af7Sopenharmony_ci GL_TRANSFORM_FEEDBACK_BUFFER, 0, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, 1340e5c31af7Sopenharmony_ci GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, 1341e5c31af7Sopenharmony_ci }, 1342e5c31af7Sopenharmony_ci { GL_UNIFORM_BUFFER, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, GL_UNIFORM_BUFFER_BINDING, GL_MAX_UNIFORM_BUFFER_BINDINGS, 1343e5c31af7Sopenharmony_ci GL_MAX_UNIFORM_BLOCK_SIZE }, 1344e5c31af7Sopenharmony_ci { GL_SHADER_STORAGE_BUFFER, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, GL_SHADER_STORAGE_BUFFER_BINDING, 1345e5c31af7Sopenharmony_ci GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, GL_MAX_SHADER_STORAGE_BLOCK_SIZE }, 1346e5c31af7Sopenharmony_ci}; 1347e5c31af7Sopenharmony_ci 1348e5c31af7Sopenharmony_cistatic const size_t s_n_buffer_tragets = sizeof(s_buffer_infos) / sizeof(s_buffer_infos[0]); 1349e5c31af7Sopenharmony_ci 1350e5c31af7Sopenharmony_ci/* Collects information about textures */ 1351e5c31af7Sopenharmony_cistatic const textureTargetInfo s_texture_infos[] = { 1352e5c31af7Sopenharmony_ci { GL_TEXTURE_1D, GL_TEXTURE_BINDING_1D, "1D" }, 1353e5c31af7Sopenharmony_ci { GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BINDING_1D_ARRAY, "1D_ARRAY" }, 1354e5c31af7Sopenharmony_ci { GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D, "2D" }, 1355e5c31af7Sopenharmony_ci { GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BINDING_2D_ARRAY, "2D_ARRAY" }, 1356e5c31af7Sopenharmony_ci { GL_TEXTURE_3D, GL_TEXTURE_BINDING_3D, "3D" }, 1357e5c31af7Sopenharmony_ci { GL_TEXTURE_BUFFER, GL_TEXTURE_BINDING_BUFFER, "BUFFER" }, 1358e5c31af7Sopenharmony_ci { GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BINDING_CUBE_MAP, "CUBE" }, 1359e5c31af7Sopenharmony_ci { GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, "CUBE_ARRAY" }, 1360e5c31af7Sopenharmony_ci { GL_TEXTURE_RECTANGLE, GL_TEXTURE_BINDING_RECTANGLE, "RECTANGLE" }, 1361e5c31af7Sopenharmony_ci { GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BINDING_2D_MULTISAMPLE, "2D_MS" }, 1362e5c31af7Sopenharmony_ci { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY, "2D_MS_ARRAY" } 1363e5c31af7Sopenharmony_ci}; 1364e5c31af7Sopenharmony_ci 1365e5c31af7Sopenharmony_cistatic const size_t s_n_texture_tragets = sizeof(s_texture_infos) / sizeof(s_texture_infos[0]); 1366e5c31af7Sopenharmony_ci 1367e5c31af7Sopenharmony_ci/** Macro, verifies generated error, logs error message and throws failure 1368e5c31af7Sopenharmony_ci * 1369e5c31af7Sopenharmony_ci * @param expected_error Expected error value 1370e5c31af7Sopenharmony_ci * @param error_message Message logged if generated error is not the expected one 1371e5c31af7Sopenharmony_ci **/ 1372e5c31af7Sopenharmony_ci#define CHECK_ERROR(expected_error, error_message) \ 1373e5c31af7Sopenharmony_ci do { \ 1374e5c31af7Sopenharmony_ci GLenum generated_error = gl.getError(); \ 1375e5c31af7Sopenharmony_ci \ 1376e5c31af7Sopenharmony_ci if (expected_error != generated_error) \ 1377e5c31af7Sopenharmony_ci { \ 1378e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() \ 1379e5c31af7Sopenharmony_ci << tcu::TestLog::Message << "File: " << __FILE__ << ", line: " << __LINE__ \ 1380e5c31af7Sopenharmony_ci << ". Got wrong error: " << glu::getErrorStr(generated_error) \ 1381e5c31af7Sopenharmony_ci << ", expected: " << glu::getErrorStr(expected_error) << ", message: " << error_message \ 1382e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; \ 1383e5c31af7Sopenharmony_ci TCU_FAIL("Invalid error generated"); \ 1384e5c31af7Sopenharmony_ci } \ 1385e5c31af7Sopenharmony_ci } while (0) 1386e5c31af7Sopenharmony_ci 1387e5c31af7Sopenharmony_ci/* Prototypes */ 1388e5c31af7Sopenharmony_civoid replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string); 1389e5c31af7Sopenharmony_ci 1390e5c31af7Sopenharmony_ci/** Checks binding 1391e5c31af7Sopenharmony_ci * 1392e5c31af7Sopenharmony_ci * @param context Test contex 1393e5c31af7Sopenharmony_ci * @param pname Pname of binding 1394e5c31af7Sopenharmony_ci * @param index Index of binding 1395e5c31af7Sopenharmony_ci * @param target_name Name of target 1396e5c31af7Sopenharmony_ci * @param expected_value Expected value of binding 1397e5c31af7Sopenharmony_ci **/ 1398e5c31af7Sopenharmony_civoid checkBinding(deqp::Context& context, GLenum pname, GLuint index, const std::string& target_name, 1399e5c31af7Sopenharmony_ci GLint expected_value) 1400e5c31af7Sopenharmony_ci{ 1401e5c31af7Sopenharmony_ci const Functions& gl = context.getRenderContext().getFunctions(); 1402e5c31af7Sopenharmony_ci 1403e5c31af7Sopenharmony_ci GLint binding = -1; 1404e5c31af7Sopenharmony_ci 1405e5c31af7Sopenharmony_ci gl.getIntegeri_v(pname, index, &binding); 1406e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegeri_v"); 1407e5c31af7Sopenharmony_ci 1408e5c31af7Sopenharmony_ci if (binding != expected_value) 1409e5c31af7Sopenharmony_ci { 1410e5c31af7Sopenharmony_ci context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid binding: " << binding 1411e5c31af7Sopenharmony_ci << ", expected: " << expected_value << ". Target: " << target_name 1412e5c31af7Sopenharmony_ci << " at index: " << index << tcu::TestLog::EndMessage; 1413e5c31af7Sopenharmony_ci TCU_FAIL("Invalid binding"); 1414e5c31af7Sopenharmony_ci } 1415e5c31af7Sopenharmony_ci} 1416e5c31af7Sopenharmony_ci 1417e5c31af7Sopenharmony_ci/** Checks bindings for given texture unit 1418e5c31af7Sopenharmony_ci * 1419e5c31af7Sopenharmony_ci * @param context Test contex 1420e5c31af7Sopenharmony_ci * @param pname Binding pname of <expected_value> 1421e5c31af7Sopenharmony_ci * @param index Index of texture unit 1422e5c31af7Sopenharmony_ci * @param expected_value Expected value of binding at <pname> target 1423e5c31af7Sopenharmony_ci **/ 1424e5c31af7Sopenharmony_civoid checkTextureBinding(deqp::Context& context, GLenum pname, GLuint index, GLint expected_value) 1425e5c31af7Sopenharmony_ci{ 1426e5c31af7Sopenharmony_ci const Functions& gl = context.getRenderContext().getFunctions(); 1427e5c31af7Sopenharmony_ci 1428e5c31af7Sopenharmony_ci for (size_t i = 0; i < s_n_texture_tragets; ++i) 1429e5c31af7Sopenharmony_ci { 1430e5c31af7Sopenharmony_ci const GLenum pname_binding = s_texture_infos[i].m_pname_binding; 1431e5c31af7Sopenharmony_ci const GLchar* target_name = s_texture_infos[i].m_name; 1432e5c31af7Sopenharmony_ci 1433e5c31af7Sopenharmony_ci GLint binding = -1; 1434e5c31af7Sopenharmony_ci GLint value = 0; 1435e5c31af7Sopenharmony_ci 1436e5c31af7Sopenharmony_ci gl.getIntegeri_v(pname_binding, index, &binding); 1437e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegeri_v"); 1438e5c31af7Sopenharmony_ci 1439e5c31af7Sopenharmony_ci if (pname_binding == pname) 1440e5c31af7Sopenharmony_ci { 1441e5c31af7Sopenharmony_ci value = (GLint)expected_value; 1442e5c31af7Sopenharmony_ci } 1443e5c31af7Sopenharmony_ci 1444e5c31af7Sopenharmony_ci if (binding != value) 1445e5c31af7Sopenharmony_ci { 1446e5c31af7Sopenharmony_ci context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid binding: " << binding 1447e5c31af7Sopenharmony_ci << ", expected: " << expected_value << ". Target: " << target_name 1448e5c31af7Sopenharmony_ci << " at index: " << index << tcu::TestLog::EndMessage; 1449e5c31af7Sopenharmony_ci TCU_FAIL("Invalid binding"); 1450e5c31af7Sopenharmony_ci } 1451e5c31af7Sopenharmony_ci } 1452e5c31af7Sopenharmony_ci} 1453e5c31af7Sopenharmony_ci 1454e5c31af7Sopenharmony_ci/** Checks binding 1455e5c31af7Sopenharmony_ci * 1456e5c31af7Sopenharmony_ci * @param context Test context 1457e5c31af7Sopenharmony_ci * @param index Index of binding 1458e5c31af7Sopenharmony_ci * @param expected_value Expected value of binding 1459e5c31af7Sopenharmony_ci **/ 1460e5c31af7Sopenharmony_civoid checkVertexAttribBinding(deqp::Context& context, GLuint index, GLint expected_value) 1461e5c31af7Sopenharmony_ci{ 1462e5c31af7Sopenharmony_ci const Functions& gl = context.getRenderContext().getFunctions(); 1463e5c31af7Sopenharmony_ci 1464e5c31af7Sopenharmony_ci GLint binding = -1; 1465e5c31af7Sopenharmony_ci 1466e5c31af7Sopenharmony_ci gl.getVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &binding); 1467e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetVertexAttribiv"); 1468e5c31af7Sopenharmony_ci 1469e5c31af7Sopenharmony_ci if (binding != expected_value) 1470e5c31af7Sopenharmony_ci { 1471e5c31af7Sopenharmony_ci context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid binding: " << binding 1472e5c31af7Sopenharmony_ci << ", expected: " << expected_value << ". Target: Vertex attribute" 1473e5c31af7Sopenharmony_ci << " at index: " << index << tcu::TestLog::EndMessage; 1474e5c31af7Sopenharmony_ci TCU_FAIL("Invalid binding"); 1475e5c31af7Sopenharmony_ci } 1476e5c31af7Sopenharmony_ci} 1477e5c31af7Sopenharmony_ci 1478e5c31af7Sopenharmony_ci/** Fills MS texture with specified value 1479e5c31af7Sopenharmony_ci * 1480e5c31af7Sopenharmony_ci * @param context Test context 1481e5c31af7Sopenharmony_ci * @param texture_id Index of binding 1482e5c31af7Sopenharmony_ci * @param value Value for texture 1483e5c31af7Sopenharmony_ci * @param is_array Selects if array target should be used 1484e5c31af7Sopenharmony_ci **/ 1485e5c31af7Sopenharmony_civoid fillMSTexture(deqp::Context& context, GLuint texture_id, GLuint value, bool is_array) 1486e5c31af7Sopenharmony_ci{ 1487e5c31af7Sopenharmony_ci /* */ 1488e5c31af7Sopenharmony_ci static const GLchar* cs = "#version 430 core\n" 1489e5c31af7Sopenharmony_ci "\n" 1490e5c31af7Sopenharmony_ci "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 1491e5c31af7Sopenharmony_ci "\n" 1492e5c31af7Sopenharmony_ci "layout (location = 0) writeonly uniform IMAGE uni_image;\n" 1493e5c31af7Sopenharmony_ci "\n" 1494e5c31af7Sopenharmony_ci "layout (location = 1) uniform uint uni_value;\n" 1495e5c31af7Sopenharmony_ci "\n" 1496e5c31af7Sopenharmony_ci "void main()\n" 1497e5c31af7Sopenharmony_ci "{\n" 1498e5c31af7Sopenharmony_ci " const POINT;\n" 1499e5c31af7Sopenharmony_ci "\n" 1500e5c31af7Sopenharmony_ci " imageStore(uni_image, point, 0, uvec4(uni_value, 0, 0, 0));\n" 1501e5c31af7Sopenharmony_ci "}\n" 1502e5c31af7Sopenharmony_ci "\n"; 1503e5c31af7Sopenharmony_ci 1504e5c31af7Sopenharmony_ci static const GLchar* array_image = "uimage2DMSArray"; 1505e5c31af7Sopenharmony_ci static const GLchar* array_point = "ivec3 point = ivec3(gl_WorkGroupID.x, gl_WorkGroupID.y, 0)"; 1506e5c31af7Sopenharmony_ci static const GLchar* regular_image = "uimage2DMS"; 1507e5c31af7Sopenharmony_ci static const GLchar* regular_point = "ivec2 point = ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y)"; 1508e5c31af7Sopenharmony_ci 1509e5c31af7Sopenharmony_ci /* */ 1510e5c31af7Sopenharmony_ci const Functions& gl = context.getRenderContext().getFunctions(); 1511e5c31af7Sopenharmony_ci const GLchar* image = (true == is_array) ? array_image : regular_image; 1512e5c31af7Sopenharmony_ci const GLchar* point = (true == is_array) ? array_point : regular_point; 1513e5c31af7Sopenharmony_ci size_t position = 0; 1514e5c31af7Sopenharmony_ci std::string source = cs; 1515e5c31af7Sopenharmony_ci 1516e5c31af7Sopenharmony_ci /* */ 1517e5c31af7Sopenharmony_ci replaceToken("IMAGE", position, image, source); 1518e5c31af7Sopenharmony_ci replaceToken("POINT", position, point, source); 1519e5c31af7Sopenharmony_ci 1520e5c31af7Sopenharmony_ci /* */ 1521e5c31af7Sopenharmony_ci Program program(context); 1522e5c31af7Sopenharmony_ci program.Init(source.c_str(), "", "", "", "", ""); 1523e5c31af7Sopenharmony_ci program.Use(); 1524e5c31af7Sopenharmony_ci 1525e5c31af7Sopenharmony_ci /* */ 1526e5c31af7Sopenharmony_ci if (true == is_array) 1527e5c31af7Sopenharmony_ci { 1528e5c31af7Sopenharmony_ci gl.bindImageTexture(0 /* unit */, texture_id, 0 /* level */, GL_TRUE /* layered */, 0 /* layer */, 1529e5c31af7Sopenharmony_ci GL_WRITE_ONLY, GL_R32UI); 1530e5c31af7Sopenharmony_ci } 1531e5c31af7Sopenharmony_ci else 1532e5c31af7Sopenharmony_ci { 1533e5c31af7Sopenharmony_ci gl.bindImageTexture(0 /* unit */, texture_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */, 1534e5c31af7Sopenharmony_ci GL_WRITE_ONLY, GL_R32UI); 1535e5c31af7Sopenharmony_ci } 1536e5c31af7Sopenharmony_ci 1537e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTexture"); 1538e5c31af7Sopenharmony_ci 1539e5c31af7Sopenharmony_ci gl.uniform1i(0 /* location */, 0 /* image unit*/); 1540e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i"); 1541e5c31af7Sopenharmony_ci 1542e5c31af7Sopenharmony_ci gl.uniform1ui(1 /* location */, value /* uni_value */); 1543e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1ui"); 1544e5c31af7Sopenharmony_ci 1545e5c31af7Sopenharmony_ci /* */ 1546e5c31af7Sopenharmony_ci gl.dispatchCompute(6, 6, 1); 1547e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute"); 1548e5c31af7Sopenharmony_ci} 1549e5c31af7Sopenharmony_ci 1550e5c31af7Sopenharmony_ci/** Get texture binding pname for given index 1551e5c31af7Sopenharmony_ci * 1552e5c31af7Sopenharmony_ci * @param index Index of texture target 1553e5c31af7Sopenharmony_ci * 1554e5c31af7Sopenharmony_ci * @return Pname 1555e5c31af7Sopenharmony_ci **/ 1556e5c31af7Sopenharmony_ciGLenum getBinding(GLuint index) 1557e5c31af7Sopenharmony_ci{ 1558e5c31af7Sopenharmony_ci if (index < s_n_texture_tragets) 1559e5c31af7Sopenharmony_ci { 1560e5c31af7Sopenharmony_ci return s_texture_infos[index].m_pname_binding; 1561e5c31af7Sopenharmony_ci } 1562e5c31af7Sopenharmony_ci else 1563e5c31af7Sopenharmony_ci { 1564e5c31af7Sopenharmony_ci return GL_TEXTURE_BINDING_2D; 1565e5c31af7Sopenharmony_ci } 1566e5c31af7Sopenharmony_ci} 1567e5c31af7Sopenharmony_ci 1568e5c31af7Sopenharmony_ci/** Get texture target for given index 1569e5c31af7Sopenharmony_ci * 1570e5c31af7Sopenharmony_ci * @param index Index of texture target 1571e5c31af7Sopenharmony_ci * 1572e5c31af7Sopenharmony_ci * @return Target 1573e5c31af7Sopenharmony_ci **/ 1574e5c31af7Sopenharmony_ciGLenum getTarget(GLuint index) 1575e5c31af7Sopenharmony_ci{ 1576e5c31af7Sopenharmony_ci if (index < s_n_texture_tragets) 1577e5c31af7Sopenharmony_ci { 1578e5c31af7Sopenharmony_ci return s_texture_infos[index].m_target; 1579e5c31af7Sopenharmony_ci } 1580e5c31af7Sopenharmony_ci else 1581e5c31af7Sopenharmony_ci { 1582e5c31af7Sopenharmony_ci return GL_TEXTURE_2D; 1583e5c31af7Sopenharmony_ci } 1584e5c31af7Sopenharmony_ci} 1585e5c31af7Sopenharmony_ci 1586e5c31af7Sopenharmony_ci/** Replace first occurance of <token> with <text> in <string> starting at <search_posistion> 1587e5c31af7Sopenharmony_ci * 1588e5c31af7Sopenharmony_ci * @param token Token string 1589e5c31af7Sopenharmony_ci * @param search_position Position at which find will start, it is updated to position at which replaced text ends 1590e5c31af7Sopenharmony_ci * @param text String that will be used as replacement for <token> 1591e5c31af7Sopenharmony_ci * @param string String to work on 1592e5c31af7Sopenharmony_ci **/ 1593e5c31af7Sopenharmony_civoid replaceToken(const GLchar* token, size_t& search_position, const GLchar* text, std::string& string) 1594e5c31af7Sopenharmony_ci{ 1595e5c31af7Sopenharmony_ci const size_t text_length = strlen(text); 1596e5c31af7Sopenharmony_ci const size_t token_length = strlen(token); 1597e5c31af7Sopenharmony_ci const size_t token_position = string.find(token, search_position); 1598e5c31af7Sopenharmony_ci 1599e5c31af7Sopenharmony_ci string.replace(token_position, token_length, text, text_length); 1600e5c31af7Sopenharmony_ci 1601e5c31af7Sopenharmony_ci search_position = token_position + text_length; 1602e5c31af7Sopenharmony_ci} 1603e5c31af7Sopenharmony_ci 1604e5c31af7Sopenharmony_ci/** Constructor 1605e5c31af7Sopenharmony_ci * 1606e5c31af7Sopenharmony_ci * @param context Test context 1607e5c31af7Sopenharmony_ci **/ 1608e5c31af7Sopenharmony_ciErrorsBindBuffersTest::ErrorsBindBuffersTest(deqp::Context& context) 1609e5c31af7Sopenharmony_ci : TestCase(context, "errors_bind_buffers", "Verifies that proper errors are generated by buffer binding routines") 1610e5c31af7Sopenharmony_ci{ 1611e5c31af7Sopenharmony_ci /* Nothing to be done */ 1612e5c31af7Sopenharmony_ci} 1613e5c31af7Sopenharmony_ci 1614e5c31af7Sopenharmony_ci/** Execute test 1615e5c31af7Sopenharmony_ci * 1616e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 1617e5c31af7Sopenharmony_ci **/ 1618e5c31af7Sopenharmony_citcu::TestNode::IterateResult ErrorsBindBuffersTest::iterate() 1619e5c31af7Sopenharmony_ci{ 1620e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 1621e5c31af7Sopenharmony_ci 1622e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 1623e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 1624e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 1625e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 1626e5c31af7Sopenharmony_ci 1627e5c31af7Sopenharmony_ci /* - INVALID_ENUM when <target> is not valid; */ 1628e5c31af7Sopenharmony_ci { 1629e5c31af7Sopenharmony_ci static const GLintptr buffer_size = 16; 1630e5c31af7Sopenharmony_ci static const GLsizei count = 1; 1631e5c31af7Sopenharmony_ci static const GLuint first = 0; 1632e5c31af7Sopenharmony_ci static const GLintptr offset = 4; 1633e5c31af7Sopenharmony_ci static const GLintptr size = buffer_size - offset; 1634e5c31af7Sopenharmony_ci 1635e5c31af7Sopenharmony_ci Buffer buffer; 1636e5c31af7Sopenharmony_ci 1637e5c31af7Sopenharmony_ci buffer.InitData(m_context, GL_ARRAY_BUFFER, GL_DYNAMIC_COPY, buffer_size, 0 /* data */); 1638e5c31af7Sopenharmony_ci 1639e5c31af7Sopenharmony_ci gl.bindBuffersBase(GL_ARRAY_BUFFER, first, count, &buffer.m_id); 1640e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_ENUM, "BindBuffersBase with invalid <target>"); 1641e5c31af7Sopenharmony_ci 1642e5c31af7Sopenharmony_ci gl.bindBuffersRange(GL_ARRAY_BUFFER, first, count, &buffer.m_id, &offset, &size); 1643e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_ENUM, "BindBuffersRange with invalid <target>"); 1644e5c31af7Sopenharmony_ci } 1645e5c31af7Sopenharmony_ci 1646e5c31af7Sopenharmony_ci for (size_t i = 0; i < s_n_buffer_tragets; ++i) 1647e5c31af7Sopenharmony_ci { 1648e5c31af7Sopenharmony_ci static const GLsizei n_buffers = 4; 1649e5c31af7Sopenharmony_ci 1650e5c31af7Sopenharmony_ci const GLenum pname_alignment = s_buffer_infos[i].m_pname_alignment; 1651e5c31af7Sopenharmony_ci const GLenum pname_max = s_buffer_infos[i].m_pname_max; 1652e5c31af7Sopenharmony_ci const GLenum target = s_buffer_infos[i].m_target; 1653e5c31af7Sopenharmony_ci const std::string& target_name = glu::getBufferTargetStr(target).toString(); 1654e5c31af7Sopenharmony_ci 1655e5c31af7Sopenharmony_ci GLintptr buffer_size = 16; 1656e5c31af7Sopenharmony_ci GLsizei count = n_buffers; 1657e5c31af7Sopenharmony_ci GLuint first = 0; 1658e5c31af7Sopenharmony_ci GLuint invalid_id = 1; /* Start with 1, as 0 is not valid name */ 1659e5c31af7Sopenharmony_ci GLintptr offset = 4; /* ATOMIC and XFB require alignment of 4 */ 1660e5c31af7Sopenharmony_ci GLint offset_alignment = 1; 1661e5c31af7Sopenharmony_ci GLint max_buffers = 0; 1662e5c31af7Sopenharmony_ci GLintptr size = buffer_size - offset; 1663e5c31af7Sopenharmony_ci size_t validated_index = n_buffers - 1; 1664e5c31af7Sopenharmony_ci 1665e5c31af7Sopenharmony_ci /* Get alignment */ 1666e5c31af7Sopenharmony_ci if (0 != pname_alignment) 1667e5c31af7Sopenharmony_ci { 1668e5c31af7Sopenharmony_ci gl.getIntegerv(pname_alignment, &offset_alignment); 1669e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 1670e5c31af7Sopenharmony_ci 1671e5c31af7Sopenharmony_ci buffer_size += offset_alignment; 1672e5c31af7Sopenharmony_ci offset = offset_alignment; 1673e5c31af7Sopenharmony_ci size = buffer_size - offset; 1674e5c31af7Sopenharmony_ci } 1675e5c31af7Sopenharmony_ci 1676e5c31af7Sopenharmony_ci /* Get max */ 1677e5c31af7Sopenharmony_ci gl.getIntegerv(pname_max, &max_buffers); 1678e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 1679e5c31af7Sopenharmony_ci 1680e5c31af7Sopenharmony_ci /* Select count so <first + count> does not exceed max. 1681e5c31af7Sopenharmony_ci * Validated index shall be in the specified range. 1682e5c31af7Sopenharmony_ci */ 1683e5c31af7Sopenharmony_ci if (n_buffers > max_buffers) 1684e5c31af7Sopenharmony_ci { 1685e5c31af7Sopenharmony_ci count = max_buffers; 1686e5c31af7Sopenharmony_ci validated_index = max_buffers - 1; 1687e5c31af7Sopenharmony_ci } 1688e5c31af7Sopenharmony_ci 1689e5c31af7Sopenharmony_ci /* Storage */ 1690e5c31af7Sopenharmony_ci Buffer buffer[n_buffers]; 1691e5c31af7Sopenharmony_ci GLuint buffer_ids[n_buffers]; 1692e5c31af7Sopenharmony_ci GLintptr offsets[n_buffers]; 1693e5c31af7Sopenharmony_ci GLintptr sizes[n_buffers]; 1694e5c31af7Sopenharmony_ci 1695e5c31af7Sopenharmony_ci /* Prepare buffers */ 1696e5c31af7Sopenharmony_ci for (size_t j = 0; j < n_buffers; ++j) 1697e5c31af7Sopenharmony_ci { 1698e5c31af7Sopenharmony_ci buffer[j].InitData(m_context, target, GL_DYNAMIC_COPY, buffer_size, 0 /* data */); 1699e5c31af7Sopenharmony_ci 1700e5c31af7Sopenharmony_ci buffer_ids[j] = buffer[j].m_id; 1701e5c31af7Sopenharmony_ci offsets[j] = offset; 1702e5c31af7Sopenharmony_ci sizes[j] = size; 1703e5c31af7Sopenharmony_ci } 1704e5c31af7Sopenharmony_ci 1705e5c31af7Sopenharmony_ci /* - INVALID_OPERATION when <first> + <count> is greater than allowed limit; */ 1706e5c31af7Sopenharmony_ci { 1707e5c31af7Sopenharmony_ci GLsizei t_count = n_buffers; 1708e5c31af7Sopenharmony_ci GLuint t_first = 0; 1709e5c31af7Sopenharmony_ci 1710e5c31af7Sopenharmony_ci /* Select first so <first + count> exceeds max, avoid negative first */ 1711e5c31af7Sopenharmony_ci if (n_buffers <= max_buffers) 1712e5c31af7Sopenharmony_ci { 1713e5c31af7Sopenharmony_ci t_first = max_buffers - n_buffers + 1; 1714e5c31af7Sopenharmony_ci } 1715e5c31af7Sopenharmony_ci else 1716e5c31af7Sopenharmony_ci { 1717e5c31af7Sopenharmony_ci t_count = max_buffers + 1; 1718e5c31af7Sopenharmony_ci /* first = 0; */ 1719e5c31af7Sopenharmony_ci } 1720e5c31af7Sopenharmony_ci 1721e5c31af7Sopenharmony_ci /* Test */ 1722e5c31af7Sopenharmony_ci gl.bindBuffersBase(target, t_first, t_count, buffer_ids); 1723e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, 1724e5c31af7Sopenharmony_ci "BindBuffersBase with invalid <first> + <count>, target: " << target_name); 1725e5c31af7Sopenharmony_ci 1726e5c31af7Sopenharmony_ci gl.bindBuffersRange(target, t_first, t_count, buffer_ids, offsets, sizes); 1727e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, 1728e5c31af7Sopenharmony_ci "BindBuffersRange with invalid <first> + <count>, target: " << target_name); 1729e5c31af7Sopenharmony_ci } 1730e5c31af7Sopenharmony_ci 1731e5c31af7Sopenharmony_ci /* - INVALID_OPERATION if any value in <buffers> is not zero or the name of 1732e5c31af7Sopenharmony_ci * existing buffer; 1733e5c31af7Sopenharmony_ci */ 1734e5c31af7Sopenharmony_ci { 1735e5c31af7Sopenharmony_ci GLuint t_buffer_ids[n_buffers]; 1736e5c31af7Sopenharmony_ci 1737e5c31af7Sopenharmony_ci memcpy(t_buffer_ids, buffer_ids, sizeof(buffer_ids)); 1738e5c31af7Sopenharmony_ci 1739e5c31af7Sopenharmony_ci /* Find invalid id */ 1740e5c31af7Sopenharmony_ci while (1) 1741e5c31af7Sopenharmony_ci { 1742e5c31af7Sopenharmony_ci if (GL_TRUE != gl.isBuffer(invalid_id)) 1743e5c31af7Sopenharmony_ci { 1744e5c31af7Sopenharmony_ci break; 1745e5c31af7Sopenharmony_ci } 1746e5c31af7Sopenharmony_ci 1747e5c31af7Sopenharmony_ci invalid_id += 1; 1748e5c31af7Sopenharmony_ci } 1749e5c31af7Sopenharmony_ci 1750e5c31af7Sopenharmony_ci /* Invalidate the entry */ 1751e5c31af7Sopenharmony_ci t_buffer_ids[validated_index] = invalid_id; 1752e5c31af7Sopenharmony_ci 1753e5c31af7Sopenharmony_ci /* Test */ 1754e5c31af7Sopenharmony_ci gl.bindBuffersBase(target, first, count, t_buffer_ids); 1755e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindBuffersBase with invalid buffer id, target: " << target_name); 1756e5c31af7Sopenharmony_ci 1757e5c31af7Sopenharmony_ci gl.bindBuffersRange(target, first, count, t_buffer_ids, offsets, sizes); 1758e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindBuffersRange with invalid buffer id, target: " << target_name); 1759e5c31af7Sopenharmony_ci } 1760e5c31af7Sopenharmony_ci 1761e5c31af7Sopenharmony_ci /* - INVALID_VALUE if any value in <offsets> is less than zero; */ 1762e5c31af7Sopenharmony_ci { 1763e5c31af7Sopenharmony_ci GLintptr t_offsets[n_buffers]; 1764e5c31af7Sopenharmony_ci GLintptr t_sizes[n_buffers]; 1765e5c31af7Sopenharmony_ci 1766e5c31af7Sopenharmony_ci memcpy(t_offsets, offsets, sizeof(offsets)); 1767e5c31af7Sopenharmony_ci memcpy(t_sizes, sizes, sizeof(sizes)); 1768e5c31af7Sopenharmony_ci 1769e5c31af7Sopenharmony_ci /* Invalidate the entry */ 1770e5c31af7Sopenharmony_ci t_offsets[validated_index] = -1; 1771e5c31af7Sopenharmony_ci t_sizes[validated_index] = -1; 1772e5c31af7Sopenharmony_ci 1773e5c31af7Sopenharmony_ci /* Test */ 1774e5c31af7Sopenharmony_ci gl.bindBuffersRange(target, first, count, buffer_ids, t_offsets, sizes); 1775e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_VALUE, "BindBuffersRange with negative offset, target: " << target_name); 1776e5c31af7Sopenharmony_ci 1777e5c31af7Sopenharmony_ci /* Test */ 1778e5c31af7Sopenharmony_ci gl.bindBuffersRange(target, first, count, buffer_ids, offsets, t_sizes); 1779e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_VALUE, "BindBuffersRange with negative size, target: " << target_name); 1780e5c31af7Sopenharmony_ci } 1781e5c31af7Sopenharmony_ci 1782e5c31af7Sopenharmony_ci /* - INVALID_VALUE if any pair of <offsets> and <sizes> exceeds limits. */ 1783e5c31af7Sopenharmony_ci { 1784e5c31af7Sopenharmony_ci GLintptr t_offsets[n_buffers]; 1785e5c31af7Sopenharmony_ci GLintptr t_sizes[n_buffers]; 1786e5c31af7Sopenharmony_ci 1787e5c31af7Sopenharmony_ci memcpy(t_offsets, offsets, sizeof(offsets)); 1788e5c31af7Sopenharmony_ci memcpy(t_sizes, sizes, sizeof(sizes)); 1789e5c31af7Sopenharmony_ci 1790e5c31af7Sopenharmony_ci /* Invalidate the entry */ 1791e5c31af7Sopenharmony_ci t_offsets[validated_index] -= 1; /* Not aligned by required value */ 1792e5c31af7Sopenharmony_ci t_sizes[validated_index] = size - 1; /* Not aligned by required value */ 1793e5c31af7Sopenharmony_ci 1794e5c31af7Sopenharmony_ci /* Test */ 1795e5c31af7Sopenharmony_ci gl.bindBuffersRange(target, first, count, buffer_ids, t_offsets, sizes); 1796e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_VALUE, "BindBuffersRange with invalid <offset>, target: " << target_name); 1797e5c31af7Sopenharmony_ci 1798e5c31af7Sopenharmony_ci /* Test */ 1799e5c31af7Sopenharmony_ci if (GL_TRANSFORM_FEEDBACK_BUFFER == target) 1800e5c31af7Sopenharmony_ci { 1801e5c31af7Sopenharmony_ci gl.bindBuffersRange(target, first, count, buffer_ids, offsets, t_sizes); 1802e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_VALUE, "BindBuffersRange with invalid <size>, target: " << target_name); 1803e5c31af7Sopenharmony_ci } 1804e5c31af7Sopenharmony_ci } 1805e5c31af7Sopenharmony_ci } 1806e5c31af7Sopenharmony_ci 1807e5c31af7Sopenharmony_ci /* Set result */ 1808e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1809e5c31af7Sopenharmony_ci 1810e5c31af7Sopenharmony_ci /* Done */ 1811e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 1812e5c31af7Sopenharmony_ci} 1813e5c31af7Sopenharmony_ci 1814e5c31af7Sopenharmony_ci/** Constructor 1815e5c31af7Sopenharmony_ci * 1816e5c31af7Sopenharmony_ci * @param context Test context 1817e5c31af7Sopenharmony_ci **/ 1818e5c31af7Sopenharmony_ciErrorsBindTexturesTest::ErrorsBindTexturesTest(deqp::Context& context) 1819e5c31af7Sopenharmony_ci : TestCase(context, "errors_bind_textures", "Verifies that proper errors are generated by texture binding routines") 1820e5c31af7Sopenharmony_ci{ 1821e5c31af7Sopenharmony_ci /* Nothing to be done */ 1822e5c31af7Sopenharmony_ci} 1823e5c31af7Sopenharmony_ci 1824e5c31af7Sopenharmony_ci/** Execute test 1825e5c31af7Sopenharmony_ci * 1826e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 1827e5c31af7Sopenharmony_ci **/ 1828e5c31af7Sopenharmony_citcu::TestNode::IterateResult ErrorsBindTexturesTest::iterate() 1829e5c31af7Sopenharmony_ci{ 1830e5c31af7Sopenharmony_ci static const GLuint depth = 8; 1831e5c31af7Sopenharmony_ci static const GLuint height = 8; 1832e5c31af7Sopenharmony_ci static const GLsizei n_textures = 4; 1833e5c31af7Sopenharmony_ci static const GLuint width = 8; 1834e5c31af7Sopenharmony_ci 1835e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 1836e5c31af7Sopenharmony_ci 1837e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 1838e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 1839e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 1840e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 1841e5c31af7Sopenharmony_ci 1842e5c31af7Sopenharmony_ci GLsizei count = n_textures; 1843e5c31af7Sopenharmony_ci GLuint first = 0; 1844e5c31af7Sopenharmony_ci GLuint invalid_id = 1; /* Start with 1, as 0 is not valid name */ 1845e5c31af7Sopenharmony_ci GLint max_textures = 0; 1846e5c31af7Sopenharmony_ci size_t validated_index = n_textures - 1; 1847e5c31af7Sopenharmony_ci 1848e5c31af7Sopenharmony_ci /* Get max */ 1849e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_textures); 1850e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 1851e5c31af7Sopenharmony_ci 1852e5c31af7Sopenharmony_ci /* Select count so <first + count> does not exceed max. 1853e5c31af7Sopenharmony_ci * Validated index shall be in the specified range. 1854e5c31af7Sopenharmony_ci */ 1855e5c31af7Sopenharmony_ci if (n_textures > max_textures) 1856e5c31af7Sopenharmony_ci { 1857e5c31af7Sopenharmony_ci count = max_textures; 1858e5c31af7Sopenharmony_ci validated_index = max_textures - 1; 1859e5c31af7Sopenharmony_ci } 1860e5c31af7Sopenharmony_ci 1861e5c31af7Sopenharmony_ci /* Storage */ 1862e5c31af7Sopenharmony_ci Texture texture[n_textures]; 1863e5c31af7Sopenharmony_ci GLuint texture_ids[n_textures]; 1864e5c31af7Sopenharmony_ci 1865e5c31af7Sopenharmony_ci /* Prepare textures */ 1866e5c31af7Sopenharmony_ci texture[0].InitStorage(m_context, GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, width, height, depth); 1867e5c31af7Sopenharmony_ci texture[1].InitStorage(m_context, GL_TEXTURE_2D_ARRAY, 1 /* levels */, GL_RGBA8, width, height, depth); 1868e5c31af7Sopenharmony_ci texture[2].InitStorage(m_context, GL_TEXTURE_1D_ARRAY, 1 /* levels */, GL_RGBA8, width, height, depth); 1869e5c31af7Sopenharmony_ci texture[3].InitStorage(m_context, GL_TEXTURE_3D, 1 /* levels */, GL_RGBA8, width, height, depth); 1870e5c31af7Sopenharmony_ci 1871e5c31af7Sopenharmony_ci for (size_t i = 0; i < n_textures; ++i) 1872e5c31af7Sopenharmony_ci { 1873e5c31af7Sopenharmony_ci texture_ids[i] = texture[i].m_id; 1874e5c31af7Sopenharmony_ci } 1875e5c31af7Sopenharmony_ci 1876e5c31af7Sopenharmony_ci /* - INVALID_OPERATION when <first> + <count> exceed limits; */ 1877e5c31af7Sopenharmony_ci { 1878e5c31af7Sopenharmony_ci GLsizei t_count = n_textures; 1879e5c31af7Sopenharmony_ci GLuint t_first = 0; 1880e5c31af7Sopenharmony_ci 1881e5c31af7Sopenharmony_ci /* Select first so <first + count> exceeds max, avoid negative first */ 1882e5c31af7Sopenharmony_ci if (n_textures <= max_textures) 1883e5c31af7Sopenharmony_ci { 1884e5c31af7Sopenharmony_ci t_first = max_textures - n_textures + 1; 1885e5c31af7Sopenharmony_ci } 1886e5c31af7Sopenharmony_ci else 1887e5c31af7Sopenharmony_ci { 1888e5c31af7Sopenharmony_ci t_count = max_textures + 1; 1889e5c31af7Sopenharmony_ci /* first = 0; */ 1890e5c31af7Sopenharmony_ci } 1891e5c31af7Sopenharmony_ci 1892e5c31af7Sopenharmony_ci /* Test */ 1893e5c31af7Sopenharmony_ci gl.bindTextures(t_first, t_count, texture_ids); 1894e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindTextures with invalid <first> + <count>"); 1895e5c31af7Sopenharmony_ci } 1896e5c31af7Sopenharmony_ci 1897e5c31af7Sopenharmony_ci /* - INVALID_OPERATION if any value in <buffers> is not zero or the name of 1898e5c31af7Sopenharmony_ci * existing buffer; 1899e5c31af7Sopenharmony_ci */ 1900e5c31af7Sopenharmony_ci { 1901e5c31af7Sopenharmony_ci GLuint t_texture_ids[n_textures]; 1902e5c31af7Sopenharmony_ci 1903e5c31af7Sopenharmony_ci memcpy(t_texture_ids, texture_ids, sizeof(texture_ids)); 1904e5c31af7Sopenharmony_ci 1905e5c31af7Sopenharmony_ci /* Find invalid id */ 1906e5c31af7Sopenharmony_ci while (1) 1907e5c31af7Sopenharmony_ci { 1908e5c31af7Sopenharmony_ci if (GL_TRUE != gl.isTexture(invalid_id)) 1909e5c31af7Sopenharmony_ci { 1910e5c31af7Sopenharmony_ci break; 1911e5c31af7Sopenharmony_ci } 1912e5c31af7Sopenharmony_ci 1913e5c31af7Sopenharmony_ci invalid_id += 1; 1914e5c31af7Sopenharmony_ci } 1915e5c31af7Sopenharmony_ci 1916e5c31af7Sopenharmony_ci /* Invalidate the entry */ 1917e5c31af7Sopenharmony_ci t_texture_ids[validated_index] = invalid_id; 1918e5c31af7Sopenharmony_ci 1919e5c31af7Sopenharmony_ci /* Test */ 1920e5c31af7Sopenharmony_ci gl.bindTextures(first, count, t_texture_ids); 1921e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindTextures with invalid texture id"); 1922e5c31af7Sopenharmony_ci } 1923e5c31af7Sopenharmony_ci 1924e5c31af7Sopenharmony_ci /* Set result */ 1925e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1926e5c31af7Sopenharmony_ci 1927e5c31af7Sopenharmony_ci /* Done */ 1928e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 1929e5c31af7Sopenharmony_ci} 1930e5c31af7Sopenharmony_ci 1931e5c31af7Sopenharmony_ci/** Constructor 1932e5c31af7Sopenharmony_ci * 1933e5c31af7Sopenharmony_ci * @param context Test context 1934e5c31af7Sopenharmony_ci **/ 1935e5c31af7Sopenharmony_ciErrorsBindSamplersTest::ErrorsBindSamplersTest(deqp::Context& context) 1936e5c31af7Sopenharmony_ci : TestCase(context, "errors_bind_samplers", "Verifies that proper errors are generated by sampler binding routines") 1937e5c31af7Sopenharmony_ci{ 1938e5c31af7Sopenharmony_ci /* Nothing to be done */ 1939e5c31af7Sopenharmony_ci} 1940e5c31af7Sopenharmony_ci 1941e5c31af7Sopenharmony_ci/** Execute test 1942e5c31af7Sopenharmony_ci * 1943e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 1944e5c31af7Sopenharmony_ci **/ 1945e5c31af7Sopenharmony_citcu::TestNode::IterateResult ErrorsBindSamplersTest::iterate() 1946e5c31af7Sopenharmony_ci{ 1947e5c31af7Sopenharmony_ci static const GLsizei n_samplers = 4; 1948e5c31af7Sopenharmony_ci 1949e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 1950e5c31af7Sopenharmony_ci 1951e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 1952e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 1953e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 1954e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 1955e5c31af7Sopenharmony_ci 1956e5c31af7Sopenharmony_ci GLsizei count = n_samplers; 1957e5c31af7Sopenharmony_ci GLuint first = 0; 1958e5c31af7Sopenharmony_ci GLuint invalid_id = 1; /* Start with 1, as 0 is not valid name */ 1959e5c31af7Sopenharmony_ci GLint max_samplers = 0; 1960e5c31af7Sopenharmony_ci size_t validated_index = n_samplers - 1; 1961e5c31af7Sopenharmony_ci 1962e5c31af7Sopenharmony_ci /* Get max */ 1963e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_samplers); 1964e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 1965e5c31af7Sopenharmony_ci 1966e5c31af7Sopenharmony_ci /* Select count so <first + count> does not exceed max. 1967e5c31af7Sopenharmony_ci * Validated index shall be in the specified range. 1968e5c31af7Sopenharmony_ci */ 1969e5c31af7Sopenharmony_ci if (n_samplers > max_samplers) 1970e5c31af7Sopenharmony_ci { 1971e5c31af7Sopenharmony_ci count = max_samplers; 1972e5c31af7Sopenharmony_ci validated_index = max_samplers - 1; 1973e5c31af7Sopenharmony_ci } 1974e5c31af7Sopenharmony_ci 1975e5c31af7Sopenharmony_ci /* Storage */ 1976e5c31af7Sopenharmony_ci GLuint sampler_ids[n_samplers]; 1977e5c31af7Sopenharmony_ci 1978e5c31af7Sopenharmony_ci /* Prepare samplers */ 1979e5c31af7Sopenharmony_ci gl.genSamplers(n_samplers, sampler_ids); 1980e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenSamplers"); 1981e5c31af7Sopenharmony_ci 1982e5c31af7Sopenharmony_ci try 1983e5c31af7Sopenharmony_ci { 1984e5c31af7Sopenharmony_ci /* - INVALID_OPERATION when <first> + <count> exceed limits; */ 1985e5c31af7Sopenharmony_ci { 1986e5c31af7Sopenharmony_ci GLsizei t_count = n_samplers; 1987e5c31af7Sopenharmony_ci GLuint t_first = 0; 1988e5c31af7Sopenharmony_ci 1989e5c31af7Sopenharmony_ci /* Select first so <first + count> exceeds max, avoid negative first */ 1990e5c31af7Sopenharmony_ci if (n_samplers <= max_samplers) 1991e5c31af7Sopenharmony_ci { 1992e5c31af7Sopenharmony_ci t_first = max_samplers - n_samplers + 1; 1993e5c31af7Sopenharmony_ci } 1994e5c31af7Sopenharmony_ci else 1995e5c31af7Sopenharmony_ci { 1996e5c31af7Sopenharmony_ci t_count = max_samplers + 1; 1997e5c31af7Sopenharmony_ci /* first = 0; */ 1998e5c31af7Sopenharmony_ci } 1999e5c31af7Sopenharmony_ci 2000e5c31af7Sopenharmony_ci /* Test */ 2001e5c31af7Sopenharmony_ci gl.bindSamplers(t_first, t_count, sampler_ids); 2002e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindSamplers with invalid <first> + <count>"); 2003e5c31af7Sopenharmony_ci } 2004e5c31af7Sopenharmony_ci 2005e5c31af7Sopenharmony_ci /* - INVALID_OPERATION if any value in <buffers> is not zero or the name of 2006e5c31af7Sopenharmony_ci * existing buffer; 2007e5c31af7Sopenharmony_ci */ 2008e5c31af7Sopenharmony_ci { 2009e5c31af7Sopenharmony_ci GLuint t_sampler_ids[n_samplers]; 2010e5c31af7Sopenharmony_ci 2011e5c31af7Sopenharmony_ci memcpy(t_sampler_ids, sampler_ids, sizeof(sampler_ids)); 2012e5c31af7Sopenharmony_ci 2013e5c31af7Sopenharmony_ci /* Find invalid id */ 2014e5c31af7Sopenharmony_ci while (1) 2015e5c31af7Sopenharmony_ci { 2016e5c31af7Sopenharmony_ci if (GL_TRUE != gl.isTexture(invalid_id)) 2017e5c31af7Sopenharmony_ci { 2018e5c31af7Sopenharmony_ci break; 2019e5c31af7Sopenharmony_ci } 2020e5c31af7Sopenharmony_ci 2021e5c31af7Sopenharmony_ci invalid_id += 1; 2022e5c31af7Sopenharmony_ci } 2023e5c31af7Sopenharmony_ci 2024e5c31af7Sopenharmony_ci /* Invalidate the entry */ 2025e5c31af7Sopenharmony_ci t_sampler_ids[validated_index] = invalid_id; 2026e5c31af7Sopenharmony_ci 2027e5c31af7Sopenharmony_ci /* Test */ 2028e5c31af7Sopenharmony_ci gl.bindTextures(first, count, t_sampler_ids); 2029e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindSamplers with invalid sampler id"); 2030e5c31af7Sopenharmony_ci } 2031e5c31af7Sopenharmony_ci } 2032e5c31af7Sopenharmony_ci catch (const std::exception&) 2033e5c31af7Sopenharmony_ci { 2034e5c31af7Sopenharmony_ci gl.deleteSamplers(n_samplers, sampler_ids); 2035e5c31af7Sopenharmony_ci 2036e5c31af7Sopenharmony_ci TCU_FAIL("Invalid error generated"); 2037e5c31af7Sopenharmony_ci } 2038e5c31af7Sopenharmony_ci 2039e5c31af7Sopenharmony_ci /* Delete samplers */ 2040e5c31af7Sopenharmony_ci gl.deleteSamplers(n_samplers, sampler_ids); 2041e5c31af7Sopenharmony_ci 2042e5c31af7Sopenharmony_ci /* Set result */ 2043e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2044e5c31af7Sopenharmony_ci 2045e5c31af7Sopenharmony_ci /* Done */ 2046e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2047e5c31af7Sopenharmony_ci} 2048e5c31af7Sopenharmony_ci 2049e5c31af7Sopenharmony_ci/** Constructor 2050e5c31af7Sopenharmony_ci * 2051e5c31af7Sopenharmony_ci * @param context Test context 2052e5c31af7Sopenharmony_ci **/ 2053e5c31af7Sopenharmony_ciErrorsBindImageTexturesTest::ErrorsBindImageTexturesTest(deqp::Context& context) 2054e5c31af7Sopenharmony_ci : TestCase(context, "errors_bind_image_textures", 2055e5c31af7Sopenharmony_ci "Verifies that proper errors are generated by image binding routines") 2056e5c31af7Sopenharmony_ci{ 2057e5c31af7Sopenharmony_ci /* Nothing to be done */ 2058e5c31af7Sopenharmony_ci} 2059e5c31af7Sopenharmony_ci 2060e5c31af7Sopenharmony_ci/** Execute test 2061e5c31af7Sopenharmony_ci * 2062e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 2063e5c31af7Sopenharmony_ci **/ 2064e5c31af7Sopenharmony_citcu::TestNode::IterateResult ErrorsBindImageTexturesTest::iterate() 2065e5c31af7Sopenharmony_ci{ 2066e5c31af7Sopenharmony_ci static const GLuint depth = 8; 2067e5c31af7Sopenharmony_ci static const GLuint height = 8; 2068e5c31af7Sopenharmony_ci static const GLsizei n_textures = 4; 2069e5c31af7Sopenharmony_ci static const GLuint width = 8; 2070e5c31af7Sopenharmony_ci 2071e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2072e5c31af7Sopenharmony_ci 2073e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 2074e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 2075e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 2076e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 2077e5c31af7Sopenharmony_ci 2078e5c31af7Sopenharmony_ci GLsizei count = n_textures; 2079e5c31af7Sopenharmony_ci GLuint first = 0; 2080e5c31af7Sopenharmony_ci GLuint invalid_id = 1; /* Start with 1, as 0 is not valid name */ 2081e5c31af7Sopenharmony_ci GLint max_textures = 0; 2082e5c31af7Sopenharmony_ci size_t validated_index = n_textures - 1; 2083e5c31af7Sopenharmony_ci 2084e5c31af7Sopenharmony_ci /* Get max */ 2085e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_IMAGE_UNITS, &max_textures); 2086e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 2087e5c31af7Sopenharmony_ci 2088e5c31af7Sopenharmony_ci /* Select count so <first + count> does not exceed max. 2089e5c31af7Sopenharmony_ci * Validated index shall be in the specified range. 2090e5c31af7Sopenharmony_ci */ 2091e5c31af7Sopenharmony_ci if (n_textures > max_textures) 2092e5c31af7Sopenharmony_ci { 2093e5c31af7Sopenharmony_ci count = max_textures; 2094e5c31af7Sopenharmony_ci validated_index = max_textures - 1; 2095e5c31af7Sopenharmony_ci } 2096e5c31af7Sopenharmony_ci 2097e5c31af7Sopenharmony_ci /* Storage */ 2098e5c31af7Sopenharmony_ci Texture texture[n_textures]; 2099e5c31af7Sopenharmony_ci GLuint texture_ids[n_textures]; 2100e5c31af7Sopenharmony_ci 2101e5c31af7Sopenharmony_ci /* Prepare textures */ 2102e5c31af7Sopenharmony_ci texture[0].InitStorage(m_context, GL_TEXTURE_2D, 1, GL_RGBA8, width, height, depth); 2103e5c31af7Sopenharmony_ci texture[1].InitStorage(m_context, GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, width, height, depth); 2104e5c31af7Sopenharmony_ci texture[2].InitStorage(m_context, GL_TEXTURE_1D_ARRAY, 1, GL_RGBA8, width, height, depth); 2105e5c31af7Sopenharmony_ci texture[3].InitStorage(m_context, GL_TEXTURE_3D, 1, GL_RGBA8, width, height, depth); 2106e5c31af7Sopenharmony_ci 2107e5c31af7Sopenharmony_ci for (size_t i = 0; i < n_textures; ++i) 2108e5c31af7Sopenharmony_ci { 2109e5c31af7Sopenharmony_ci texture_ids[i] = texture[i].m_id; 2110e5c31af7Sopenharmony_ci } 2111e5c31af7Sopenharmony_ci 2112e5c31af7Sopenharmony_ci /* - INVALID_OPERATION when <first> + <count> exceed limits; */ 2113e5c31af7Sopenharmony_ci { 2114e5c31af7Sopenharmony_ci GLsizei t_count = n_textures; 2115e5c31af7Sopenharmony_ci GLuint t_first = 0; 2116e5c31af7Sopenharmony_ci 2117e5c31af7Sopenharmony_ci /* Select first so <first + count> exceeds max, avoid negative first */ 2118e5c31af7Sopenharmony_ci if (n_textures <= max_textures) 2119e5c31af7Sopenharmony_ci { 2120e5c31af7Sopenharmony_ci t_first = max_textures - n_textures + 1; 2121e5c31af7Sopenharmony_ci } 2122e5c31af7Sopenharmony_ci else 2123e5c31af7Sopenharmony_ci { 2124e5c31af7Sopenharmony_ci t_count = max_textures + 1; 2125e5c31af7Sopenharmony_ci /* first = 0; */ 2126e5c31af7Sopenharmony_ci } 2127e5c31af7Sopenharmony_ci 2128e5c31af7Sopenharmony_ci /* Test */ 2129e5c31af7Sopenharmony_ci gl.bindImageTextures(t_first, t_count, texture_ids); 2130e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindImageTextures with invalid <first> + <count>"); 2131e5c31af7Sopenharmony_ci } 2132e5c31af7Sopenharmony_ci 2133e5c31af7Sopenharmony_ci /* - INVALID_OPERATION if any value in <buffers> is not zero or the name of 2134e5c31af7Sopenharmony_ci * existing buffer; 2135e5c31af7Sopenharmony_ci */ 2136e5c31af7Sopenharmony_ci { 2137e5c31af7Sopenharmony_ci GLuint t_texture_ids[n_textures]; 2138e5c31af7Sopenharmony_ci 2139e5c31af7Sopenharmony_ci memcpy(t_texture_ids, texture_ids, sizeof(texture_ids)); 2140e5c31af7Sopenharmony_ci 2141e5c31af7Sopenharmony_ci /* Find invalid id */ 2142e5c31af7Sopenharmony_ci while (1) 2143e5c31af7Sopenharmony_ci { 2144e5c31af7Sopenharmony_ci if (GL_TRUE != gl.isTexture(invalid_id)) 2145e5c31af7Sopenharmony_ci { 2146e5c31af7Sopenharmony_ci break; 2147e5c31af7Sopenharmony_ci } 2148e5c31af7Sopenharmony_ci 2149e5c31af7Sopenharmony_ci invalid_id += 1; 2150e5c31af7Sopenharmony_ci } 2151e5c31af7Sopenharmony_ci 2152e5c31af7Sopenharmony_ci /* Invalidate the entry */ 2153e5c31af7Sopenharmony_ci t_texture_ids[validated_index] = invalid_id; 2154e5c31af7Sopenharmony_ci 2155e5c31af7Sopenharmony_ci /* Test */ 2156e5c31af7Sopenharmony_ci gl.bindImageTextures(first, count, t_texture_ids); 2157e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindImageTextures with invalid texture id"); 2158e5c31af7Sopenharmony_ci } 2159e5c31af7Sopenharmony_ci 2160e5c31af7Sopenharmony_ci /* - INVALID_OPERATION if any entry found in <textures> has invalid internal 2161e5c31af7Sopenharmony_ci * format at level 0; 2162e5c31af7Sopenharmony_ci */ 2163e5c31af7Sopenharmony_ci { 2164e5c31af7Sopenharmony_ci GLuint t_texture_ids[n_textures]; 2165e5c31af7Sopenharmony_ci 2166e5c31af7Sopenharmony_ci memcpy(t_texture_ids, texture_ids, sizeof(texture_ids)); 2167e5c31af7Sopenharmony_ci 2168e5c31af7Sopenharmony_ci /* Prepare texture with invalid format */ 2169e5c31af7Sopenharmony_ci Texture t_texture; 2170e5c31af7Sopenharmony_ci t_texture.Init(m_context); 2171e5c31af7Sopenharmony_ci t_texture.Generate(gl, t_texture.m_id); 2172e5c31af7Sopenharmony_ci t_texture.Bind(gl, t_texture.m_id, GL_TEXTURE_2D); 2173e5c31af7Sopenharmony_ci gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGB9_E5, width, 0); 2174e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_VALUE, "texStorage2D has height set to 0"); 2175e5c31af7Sopenharmony_ci 2176e5c31af7Sopenharmony_ci /* Invalidate the entry */ 2177e5c31af7Sopenharmony_ci t_texture_ids[validated_index] = t_texture.m_id; 2178e5c31af7Sopenharmony_ci 2179e5c31af7Sopenharmony_ci /* Test */ 2180e5c31af7Sopenharmony_ci gl.bindImageTextures(first, count, t_texture_ids); 2181e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindImageTextures with invalid internal format"); 2182e5c31af7Sopenharmony_ci } 2183e5c31af7Sopenharmony_ci 2184e5c31af7Sopenharmony_ci /* - INVALID_VALUE when any entry in <textures> has any of dimensions equal 2185e5c31af7Sopenharmony_ci * to 0 at level 0. 2186e5c31af7Sopenharmony_ci */ 2187e5c31af7Sopenharmony_ci { 2188e5c31af7Sopenharmony_ci GLuint t_texture_ids[n_textures]; 2189e5c31af7Sopenharmony_ci 2190e5c31af7Sopenharmony_ci memcpy(t_texture_ids, texture_ids, sizeof(texture_ids)); 2191e5c31af7Sopenharmony_ci 2192e5c31af7Sopenharmony_ci /* Prepare texture with invalid format */ 2193e5c31af7Sopenharmony_ci Texture t_texture; 2194e5c31af7Sopenharmony_ci t_texture.InitStorage(m_context, GL_TEXTURE_2D, 1, GL_RGB9_E5, width, 0, depth, true); 2195e5c31af7Sopenharmony_ci 2196e5c31af7Sopenharmony_ci /* Invalidate the entry */ 2197e5c31af7Sopenharmony_ci t_texture_ids[validated_index] = t_texture.m_id; 2198e5c31af7Sopenharmony_ci 2199e5c31af7Sopenharmony_ci /* Test */ 2200e5c31af7Sopenharmony_ci gl.bindImageTextures(first, count, t_texture_ids); 2201e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_VALUE, "BindImageTextures with 2D texture that has height set to 0"); 2202e5c31af7Sopenharmony_ci } 2203e5c31af7Sopenharmony_ci 2204e5c31af7Sopenharmony_ci /* Set result */ 2205e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2206e5c31af7Sopenharmony_ci 2207e5c31af7Sopenharmony_ci /* Done */ 2208e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2209e5c31af7Sopenharmony_ci} 2210e5c31af7Sopenharmony_ci 2211e5c31af7Sopenharmony_ci/** Constructor 2212e5c31af7Sopenharmony_ci * 2213e5c31af7Sopenharmony_ci * @param context Test context 2214e5c31af7Sopenharmony_ci **/ 2215e5c31af7Sopenharmony_ciErrorsBindVertexBuffersTest::ErrorsBindVertexBuffersTest(deqp::Context& context) 2216e5c31af7Sopenharmony_ci : TestCase(context, "errors_bind_vertex_buffers", 2217e5c31af7Sopenharmony_ci "Verifies that proper errors are generated by vertex buffer binding routines") 2218e5c31af7Sopenharmony_ci{ 2219e5c31af7Sopenharmony_ci /* Nothing to be done */ 2220e5c31af7Sopenharmony_ci} 2221e5c31af7Sopenharmony_ci 2222e5c31af7Sopenharmony_ci/** Execute test 2223e5c31af7Sopenharmony_ci * 2224e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 2225e5c31af7Sopenharmony_ci **/ 2226e5c31af7Sopenharmony_citcu::TestNode::IterateResult ErrorsBindVertexBuffersTest::iterate() 2227e5c31af7Sopenharmony_ci{ 2228e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2229e5c31af7Sopenharmony_ci 2230e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 2231e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 2232e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 2233e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 2234e5c31af7Sopenharmony_ci 2235e5c31af7Sopenharmony_ci static const GLsizei n_buffers = 4; 2236e5c31af7Sopenharmony_ci static const GLsizei stride = 4; 2237e5c31af7Sopenharmony_ci 2238e5c31af7Sopenharmony_ci GLintptr buffer_size = 16; 2239e5c31af7Sopenharmony_ci GLsizei count = n_buffers; 2240e5c31af7Sopenharmony_ci GLuint first = 0; 2241e5c31af7Sopenharmony_ci GLuint invalid_id = 1; /* Start with 1, as 0 is not valid name */ 2242e5c31af7Sopenharmony_ci GLintptr offset = 4; /* ATOMIC and XFB require alignment of 4 */ 2243e5c31af7Sopenharmony_ci GLint max_buffers = 0; 2244e5c31af7Sopenharmony_ci size_t validated_index = n_buffers - 1; 2245e5c31af7Sopenharmony_ci 2246e5c31af7Sopenharmony_ci /* Get max */ 2247e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_buffers); 2248e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 2249e5c31af7Sopenharmony_ci 2250e5c31af7Sopenharmony_ci /* Select count so <first + count> does not exceed max. 2251e5c31af7Sopenharmony_ci * Validated index shall be in the specified range. 2252e5c31af7Sopenharmony_ci */ 2253e5c31af7Sopenharmony_ci if (n_buffers > max_buffers) 2254e5c31af7Sopenharmony_ci { 2255e5c31af7Sopenharmony_ci count = max_buffers; 2256e5c31af7Sopenharmony_ci validated_index = max_buffers - 1; 2257e5c31af7Sopenharmony_ci } 2258e5c31af7Sopenharmony_ci 2259e5c31af7Sopenharmony_ci /* Storage */ 2260e5c31af7Sopenharmony_ci Buffer buffer[n_buffers]; 2261e5c31af7Sopenharmony_ci GLuint buffer_ids[n_buffers]; 2262e5c31af7Sopenharmony_ci GLintptr offsets[n_buffers]; 2263e5c31af7Sopenharmony_ci GLsizei strides[n_buffers]; 2264e5c31af7Sopenharmony_ci 2265e5c31af7Sopenharmony_ci /* Prepare buffers */ 2266e5c31af7Sopenharmony_ci for (size_t j = 0; j < n_buffers; ++j) 2267e5c31af7Sopenharmony_ci { 2268e5c31af7Sopenharmony_ci buffer[j].InitData(m_context, GL_ARRAY_BUFFER, GL_DYNAMIC_COPY, buffer_size, 0 /* data */); 2269e5c31af7Sopenharmony_ci 2270e5c31af7Sopenharmony_ci buffer_ids[j] = buffer[j].m_id; 2271e5c31af7Sopenharmony_ci offsets[j] = offset; 2272e5c31af7Sopenharmony_ci strides[j] = stride; 2273e5c31af7Sopenharmony_ci } 2274e5c31af7Sopenharmony_ci 2275e5c31af7Sopenharmony_ci /* Prepare VAO */ 2276e5c31af7Sopenharmony_ci GLuint vao = 0; 2277e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &vao); 2278e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays"); 2279e5c31af7Sopenharmony_ci try 2280e5c31af7Sopenharmony_ci { 2281e5c31af7Sopenharmony_ci gl.bindVertexArray(vao); 2282e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArrays"); 2283e5c31af7Sopenharmony_ci 2284e5c31af7Sopenharmony_ci /* - INVALID_OPERATION when <first> + <count> exceeds limits; */ 2285e5c31af7Sopenharmony_ci { 2286e5c31af7Sopenharmony_ci GLsizei t_count = n_buffers; 2287e5c31af7Sopenharmony_ci GLuint t_first = 0; 2288e5c31af7Sopenharmony_ci 2289e5c31af7Sopenharmony_ci /* Select first so <first + count> exceeds max, avoid negative first */ 2290e5c31af7Sopenharmony_ci if (n_buffers <= max_buffers) 2291e5c31af7Sopenharmony_ci { 2292e5c31af7Sopenharmony_ci t_first = max_buffers - n_buffers + 1; 2293e5c31af7Sopenharmony_ci } 2294e5c31af7Sopenharmony_ci else 2295e5c31af7Sopenharmony_ci { 2296e5c31af7Sopenharmony_ci t_count = max_buffers + 1; 2297e5c31af7Sopenharmony_ci /* first = 0; */ 2298e5c31af7Sopenharmony_ci } 2299e5c31af7Sopenharmony_ci 2300e5c31af7Sopenharmony_ci /* Test */ 2301e5c31af7Sopenharmony_ci gl.bindVertexBuffers(t_first, t_count, buffer_ids, offsets, strides); 2302e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindVertexBuffers with invalid <first> + <count>"); 2303e5c31af7Sopenharmony_ci } 2304e5c31af7Sopenharmony_ci 2305e5c31af7Sopenharmony_ci /* - INVALID_OPERATION if any value in <buffers> is not zero or the name of 2306e5c31af7Sopenharmony_ci * existing buffer; 2307e5c31af7Sopenharmony_ci */ 2308e5c31af7Sopenharmony_ci { 2309e5c31af7Sopenharmony_ci GLuint t_buffer_ids[n_buffers]; 2310e5c31af7Sopenharmony_ci 2311e5c31af7Sopenharmony_ci memcpy(t_buffer_ids, buffer_ids, sizeof(buffer_ids)); 2312e5c31af7Sopenharmony_ci 2313e5c31af7Sopenharmony_ci /* Find invalid id */ 2314e5c31af7Sopenharmony_ci while (1) 2315e5c31af7Sopenharmony_ci { 2316e5c31af7Sopenharmony_ci if (GL_TRUE != gl.isBuffer(invalid_id)) 2317e5c31af7Sopenharmony_ci { 2318e5c31af7Sopenharmony_ci break; 2319e5c31af7Sopenharmony_ci } 2320e5c31af7Sopenharmony_ci 2321e5c31af7Sopenharmony_ci invalid_id += 1; 2322e5c31af7Sopenharmony_ci } 2323e5c31af7Sopenharmony_ci 2324e5c31af7Sopenharmony_ci /* Invalidate the entry */ 2325e5c31af7Sopenharmony_ci t_buffer_ids[validated_index] = invalid_id; 2326e5c31af7Sopenharmony_ci 2327e5c31af7Sopenharmony_ci /* Test */ 2328e5c31af7Sopenharmony_ci gl.bindVertexBuffers(first, count, t_buffer_ids, offsets, strides); 2329e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindVertexBuffers with invalid buffer id"); 2330e5c31af7Sopenharmony_ci } 2331e5c31af7Sopenharmony_ci 2332e5c31af7Sopenharmony_ci /* - INVALID_VALUE if any value in <offsets> or <strides> is less than zero. */ 2333e5c31af7Sopenharmony_ci { 2334e5c31af7Sopenharmony_ci GLintptr t_offsets[n_buffers]; 2335e5c31af7Sopenharmony_ci GLsizei t_strides[n_buffers]; 2336e5c31af7Sopenharmony_ci 2337e5c31af7Sopenharmony_ci memcpy(t_offsets, offsets, sizeof(offsets)); 2338e5c31af7Sopenharmony_ci memcpy(t_strides, strides, sizeof(strides)); 2339e5c31af7Sopenharmony_ci 2340e5c31af7Sopenharmony_ci /* Invalidate the entry */ 2341e5c31af7Sopenharmony_ci t_offsets[validated_index] = -1; 2342e5c31af7Sopenharmony_ci t_strides[validated_index] = -1; 2343e5c31af7Sopenharmony_ci 2344e5c31af7Sopenharmony_ci /* Test */ 2345e5c31af7Sopenharmony_ci gl.bindVertexBuffers(first, count, buffer_ids, t_offsets, strides); 2346e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_VALUE, "BindVertexBuffers with negative offset"); 2347e5c31af7Sopenharmony_ci 2348e5c31af7Sopenharmony_ci gl.bindVertexBuffers(first, count, buffer_ids, offsets, t_strides); 2349e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_VALUE, "BindVertexBuffers with negative stride"); 2350e5c31af7Sopenharmony_ci } 2351e5c31af7Sopenharmony_ci } 2352e5c31af7Sopenharmony_ci catch (const std::exception&) 2353e5c31af7Sopenharmony_ci { 2354e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &vao); 2355e5c31af7Sopenharmony_ci TCU_FAIL("Unexpected error generated"); 2356e5c31af7Sopenharmony_ci } 2357e5c31af7Sopenharmony_ci 2358e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &vao); 2359e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteVertexArrays"); 2360e5c31af7Sopenharmony_ci 2361e5c31af7Sopenharmony_ci /* Set result */ 2362e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2363e5c31af7Sopenharmony_ci 2364e5c31af7Sopenharmony_ci /* Done */ 2365e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2366e5c31af7Sopenharmony_ci} 2367e5c31af7Sopenharmony_ci 2368e5c31af7Sopenharmony_ci/** Constructor 2369e5c31af7Sopenharmony_ci * 2370e5c31af7Sopenharmony_ci * @param context Test context 2371e5c31af7Sopenharmony_ci **/ 2372e5c31af7Sopenharmony_ciFunctionalBindBuffersBaseTest::FunctionalBindBuffersBaseTest(deqp::Context& context) 2373e5c31af7Sopenharmony_ci : TestCase(context, "functional_bind_buffers_base", "Verifies that BindBuffersBase works as expected") 2374e5c31af7Sopenharmony_ci{ 2375e5c31af7Sopenharmony_ci /* Nothing to be done */ 2376e5c31af7Sopenharmony_ci} 2377e5c31af7Sopenharmony_ci 2378e5c31af7Sopenharmony_ci/** Execute test 2379e5c31af7Sopenharmony_ci * 2380e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 2381e5c31af7Sopenharmony_ci **/ 2382e5c31af7Sopenharmony_citcu::TestNode::IterateResult FunctionalBindBuffersBaseTest::iterate() 2383e5c31af7Sopenharmony_ci{ 2384e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2385e5c31af7Sopenharmony_ci 2386e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 2387e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 2388e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 2389e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 2390e5c31af7Sopenharmony_ci 2391e5c31af7Sopenharmony_ci for (size_t i = 0; i < s_n_buffer_tragets; ++i) 2392e5c31af7Sopenharmony_ci { 2393e5c31af7Sopenharmony_ci const GLenum pname_binding = s_buffer_infos[i].m_pname_binding; 2394e5c31af7Sopenharmony_ci const GLenum pname_max = s_buffer_infos[i].m_pname_max; 2395e5c31af7Sopenharmony_ci const GLenum pname_max_size = s_buffer_infos[i].m_pname_max_size; 2396e5c31af7Sopenharmony_ci const GLenum target = s_buffer_infos[i].m_target; 2397e5c31af7Sopenharmony_ci const std::string& target_name = glu::getBufferTargetStr(target).toString(); 2398e5c31af7Sopenharmony_ci 2399e5c31af7Sopenharmony_ci GLint max_buffers = 0; 2400e5c31af7Sopenharmony_ci GLint max_size = 0; 2401e5c31af7Sopenharmony_ci 2402e5c31af7Sopenharmony_ci /* Get max */ 2403e5c31af7Sopenharmony_ci gl.getIntegerv(pname_max, &max_buffers); 2404e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 2405e5c31af7Sopenharmony_ci 2406e5c31af7Sopenharmony_ci /* Get max size */ 2407e5c31af7Sopenharmony_ci gl.getIntegerv(pname_max_size, &max_size); 2408e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 2409e5c31af7Sopenharmony_ci 2410e5c31af7Sopenharmony_ci GLintptr buffer_size = max_size / max_buffers; 2411e5c31af7Sopenharmony_ci 2412e5c31af7Sopenharmony_ci /* Storage */ 2413e5c31af7Sopenharmony_ci std::vector<Buffer> buffer; 2414e5c31af7Sopenharmony_ci std::vector<GLuint> buffer_ids; 2415e5c31af7Sopenharmony_ci 2416e5c31af7Sopenharmony_ci buffer.resize(max_buffers); 2417e5c31af7Sopenharmony_ci buffer_ids.resize(max_buffers); 2418e5c31af7Sopenharmony_ci 2419e5c31af7Sopenharmony_ci /* Prepare buffers */ 2420e5c31af7Sopenharmony_ci for (GLint j = 0; j < max_buffers; ++j) 2421e5c31af7Sopenharmony_ci { 2422e5c31af7Sopenharmony_ci buffer[j].InitData(m_context, target, GL_DYNAMIC_COPY, buffer_size, 0 /* data */); 2423e5c31af7Sopenharmony_ci 2424e5c31af7Sopenharmony_ci buffer_ids[j] = buffer[j].m_id; 2425e5c31af7Sopenharmony_ci } 2426e5c31af7Sopenharmony_ci 2427e5c31af7Sopenharmony_ci /* 2428e5c31af7Sopenharmony_ci * - execute BindBufferBase to bind all buffers to tested target; 2429e5c31af7Sopenharmony_ci * - inspect if bindings were modified; 2430e5c31af7Sopenharmony_ci */ 2431e5c31af7Sopenharmony_ci gl.bindBuffersBase(target, 0 /* first */, max_buffers /* count */, &buffer_ids[0]); 2432e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersBase"); 2433e5c31af7Sopenharmony_ci 2434e5c31af7Sopenharmony_ci for (GLint j = 0; j < max_buffers; ++j) 2435e5c31af7Sopenharmony_ci { 2436e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]); 2437e5c31af7Sopenharmony_ci } 2438e5c31af7Sopenharmony_ci 2439e5c31af7Sopenharmony_ci /* 2440e5c31af7Sopenharmony_ci * 2441e5c31af7Sopenharmony_ci * - execute BindBufferBase for first half of bindings with NULL as <buffers> 2442e5c31af7Sopenharmony_ci * to unbind first half of bindings for tested target; 2443e5c31af7Sopenharmony_ci * - inspect if bindings were modified; 2444e5c31af7Sopenharmony_ci * - execute BindBufferBase for second half of bindings with NULL as <buffers> 2445e5c31af7Sopenharmony_ci * to unbind rest of bindings; 2446e5c31af7Sopenharmony_ci * - inspect if bindings were modified; 2447e5c31af7Sopenharmony_ci */ 2448e5c31af7Sopenharmony_ci GLint half_index = max_buffers / 2; 2449e5c31af7Sopenharmony_ci gl.bindBuffersBase(target, 0 /* first */, half_index /* count */, 0); 2450e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersBase"); 2451e5c31af7Sopenharmony_ci 2452e5c31af7Sopenharmony_ci for (GLint j = 0; j < half_index; ++j) 2453e5c31af7Sopenharmony_ci { 2454e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, 0); 2455e5c31af7Sopenharmony_ci } 2456e5c31af7Sopenharmony_ci 2457e5c31af7Sopenharmony_ci for (GLint j = half_index; j < max_buffers; ++j) 2458e5c31af7Sopenharmony_ci { 2459e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]); 2460e5c31af7Sopenharmony_ci } 2461e5c31af7Sopenharmony_ci 2462e5c31af7Sopenharmony_ci gl.bindBuffersBase(target, half_index /* first */, max_buffers - half_index /* count */, 0); 2463e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersBase"); 2464e5c31af7Sopenharmony_ci 2465e5c31af7Sopenharmony_ci for (GLint j = 0; j < max_buffers; ++j) 2466e5c31af7Sopenharmony_ci { 2467e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, 0); 2468e5c31af7Sopenharmony_ci } 2469e5c31af7Sopenharmony_ci 2470e5c31af7Sopenharmony_ci /* 2471e5c31af7Sopenharmony_ci * - change <buffers> so first entry is invalid; 2472e5c31af7Sopenharmony_ci * - execute BindBufferBase to bind all buffers to tested target; It is 2473e5c31af7Sopenharmony_ci * expected that INVALID_OPERATION will be generated; 2474e5c31af7Sopenharmony_ci * - inspect if all bindings but first were modified; 2475e5c31af7Sopenharmony_ci */ 2476e5c31af7Sopenharmony_ci 2477e5c31af7Sopenharmony_ci /* Find invalid id */ 2478e5c31af7Sopenharmony_ci GLuint invalid_id = 1; 2479e5c31af7Sopenharmony_ci while (1) 2480e5c31af7Sopenharmony_ci { 2481e5c31af7Sopenharmony_ci if (GL_TRUE != gl.isBuffer(invalid_id)) 2482e5c31af7Sopenharmony_ci { 2483e5c31af7Sopenharmony_ci break; 2484e5c31af7Sopenharmony_ci } 2485e5c31af7Sopenharmony_ci 2486e5c31af7Sopenharmony_ci invalid_id += 1; 2487e5c31af7Sopenharmony_ci } 2488e5c31af7Sopenharmony_ci 2489e5c31af7Sopenharmony_ci buffer_ids[0] = invalid_id; 2490e5c31af7Sopenharmony_ci 2491e5c31af7Sopenharmony_ci gl.bindBuffersBase(target, 0 /* first */, max_buffers /* count */, &buffer_ids[0]); 2492e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindBufferBase with invalid buffer id"); 2493e5c31af7Sopenharmony_ci 2494e5c31af7Sopenharmony_ci /* Update buffer_ids */ 2495e5c31af7Sopenharmony_ci buffer_ids[0] = 0; /* 0 means unbound */ 2496e5c31af7Sopenharmony_ci 2497e5c31af7Sopenharmony_ci for (GLint j = 0; j < max_buffers; ++j) 2498e5c31af7Sopenharmony_ci { 2499e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]); 2500e5c31af7Sopenharmony_ci } 2501e5c31af7Sopenharmony_ci 2502e5c31af7Sopenharmony_ci /* 2503e5c31af7Sopenharmony_ci * - bind any buffer to first binding; 2504e5c31af7Sopenharmony_ci * - execute BindBufferBase for 0 as <first>, 1 as <count> and <buffers> filled 2505e5c31af7Sopenharmony_ci * with zeros to unbind 1st binding for tested target; 2506e5c31af7Sopenharmony_ci * - inspect if bindings were modified; 2507e5c31af7Sopenharmony_ci */ 2508e5c31af7Sopenharmony_ci gl.bindBufferBase(target, 0, buffer[0].m_id); 2509e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase"); 2510e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, 0, target_name, buffer[0].m_id); 2511e5c31af7Sopenharmony_ci 2512e5c31af7Sopenharmony_ci std::vector<GLuint> t_buffer_ids; 2513e5c31af7Sopenharmony_ci t_buffer_ids.resize(max_buffers); 2514e5c31af7Sopenharmony_ci 2515e5c31af7Sopenharmony_ci gl.bindBuffersBase(target, 0 /* first */, 1 /* count */, &t_buffer_ids[0]); 2516e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersBase"); 2517e5c31af7Sopenharmony_ci 2518e5c31af7Sopenharmony_ci for (GLint j = 0; j < max_buffers; ++j) 2519e5c31af7Sopenharmony_ci { 2520e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]); 2521e5c31af7Sopenharmony_ci } 2522e5c31af7Sopenharmony_ci 2523e5c31af7Sopenharmony_ci /* - unbind all buffers. */ 2524e5c31af7Sopenharmony_ci gl.bindBuffersBase(target, 0 /* first */, max_buffers /* count */, 0); 2525e5c31af7Sopenharmony_ci } 2526e5c31af7Sopenharmony_ci 2527e5c31af7Sopenharmony_ci /* Set result */ 2528e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2529e5c31af7Sopenharmony_ci 2530e5c31af7Sopenharmony_ci /* Done */ 2531e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2532e5c31af7Sopenharmony_ci} 2533e5c31af7Sopenharmony_ci 2534e5c31af7Sopenharmony_ci/** Constructor 2535e5c31af7Sopenharmony_ci * 2536e5c31af7Sopenharmony_ci * @param context Test context 2537e5c31af7Sopenharmony_ci **/ 2538e5c31af7Sopenharmony_ciFunctionalBindBuffersRangeTest::FunctionalBindBuffersRangeTest(deqp::Context& context) 2539e5c31af7Sopenharmony_ci : TestCase(context, "functional_bind_buffers_range", "Verifies that BindBuffersRange works as expected") 2540e5c31af7Sopenharmony_ci{ 2541e5c31af7Sopenharmony_ci /* Nothing to be done */ 2542e5c31af7Sopenharmony_ci} 2543e5c31af7Sopenharmony_ci 2544e5c31af7Sopenharmony_ci/** Execute test 2545e5c31af7Sopenharmony_ci * 2546e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 2547e5c31af7Sopenharmony_ci **/ 2548e5c31af7Sopenharmony_citcu::TestNode::IterateResult FunctionalBindBuffersRangeTest::iterate() 2549e5c31af7Sopenharmony_ci{ 2550e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2551e5c31af7Sopenharmony_ci 2552e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 2553e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 2554e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 2555e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 2556e5c31af7Sopenharmony_ci 2557e5c31af7Sopenharmony_ci for (size_t i = 0; i < s_n_buffer_tragets; ++i) 2558e5c31af7Sopenharmony_ci { 2559e5c31af7Sopenharmony_ci const GLenum pname_binding = s_buffer_infos[i].m_pname_binding; 2560e5c31af7Sopenharmony_ci const GLenum pname_max = s_buffer_infos[i].m_pname_max; 2561e5c31af7Sopenharmony_ci const GLenum pname_max_size = s_buffer_infos[i].m_pname_max_size; 2562e5c31af7Sopenharmony_ci const GLenum target = s_buffer_infos[i].m_target; 2563e5c31af7Sopenharmony_ci const std::string& target_name = glu::getBufferTargetStr(target).toString(); 2564e5c31af7Sopenharmony_ci 2565e5c31af7Sopenharmony_ci GLint max_buffers = 0; 2566e5c31af7Sopenharmony_ci GLint max_size = 0; 2567e5c31af7Sopenharmony_ci 2568e5c31af7Sopenharmony_ci /* Get max */ 2569e5c31af7Sopenharmony_ci gl.getIntegerv(pname_max, &max_buffers); 2570e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 2571e5c31af7Sopenharmony_ci 2572e5c31af7Sopenharmony_ci /* Get max size */ 2573e5c31af7Sopenharmony_ci gl.getIntegerv(pname_max_size, &max_size); 2574e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 2575e5c31af7Sopenharmony_ci 2576e5c31af7Sopenharmony_ci GLintptr buffer_size = max_size / max_buffers; 2577e5c31af7Sopenharmony_ci 2578e5c31af7Sopenharmony_ci /* Storage */ 2579e5c31af7Sopenharmony_ci std::vector<Buffer> buffer; 2580e5c31af7Sopenharmony_ci std::vector<GLuint> buffer_ids; 2581e5c31af7Sopenharmony_ci std::vector<GLintptr> offsets; 2582e5c31af7Sopenharmony_ci std::vector<GLsizeiptr> sizes; 2583e5c31af7Sopenharmony_ci 2584e5c31af7Sopenharmony_ci buffer.resize(max_buffers); 2585e5c31af7Sopenharmony_ci buffer_ids.resize(max_buffers); 2586e5c31af7Sopenharmony_ci offsets.resize(max_buffers); 2587e5c31af7Sopenharmony_ci sizes.resize(max_buffers); 2588e5c31af7Sopenharmony_ci 2589e5c31af7Sopenharmony_ci /* Prepare buffers */ 2590e5c31af7Sopenharmony_ci for (GLint j = 0; j < max_buffers; ++j) 2591e5c31af7Sopenharmony_ci { 2592e5c31af7Sopenharmony_ci buffer[j].InitData(m_context, target, GL_DYNAMIC_COPY, buffer_size, 0 /* data */); 2593e5c31af7Sopenharmony_ci 2594e5c31af7Sopenharmony_ci buffer_ids[j] = buffer[j].m_id; 2595e5c31af7Sopenharmony_ci offsets[j] = 0; 2596e5c31af7Sopenharmony_ci sizes[j] = buffer_size; 2597e5c31af7Sopenharmony_ci } 2598e5c31af7Sopenharmony_ci 2599e5c31af7Sopenharmony_ci /* 2600e5c31af7Sopenharmony_ci * - execute BindBufferBase to bind all buffers to tested target; 2601e5c31af7Sopenharmony_ci * - inspect if bindings were modified; 2602e5c31af7Sopenharmony_ci */ 2603e5c31af7Sopenharmony_ci gl.bindBuffersRange(target, 0 /* first */, max_buffers /* count */, &buffer_ids[0], &offsets[0], &sizes[0]); 2604e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersRange"); 2605e5c31af7Sopenharmony_ci 2606e5c31af7Sopenharmony_ci for (GLint j = 0; j < max_buffers; ++j) 2607e5c31af7Sopenharmony_ci { 2608e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]); 2609e5c31af7Sopenharmony_ci } 2610e5c31af7Sopenharmony_ci 2611e5c31af7Sopenharmony_ci /* 2612e5c31af7Sopenharmony_ci * 2613e5c31af7Sopenharmony_ci * - execute BindBufferBase for first half of bindings with NULL as <buffers> 2614e5c31af7Sopenharmony_ci * to unbind first half of bindings for tested target; 2615e5c31af7Sopenharmony_ci * - inspect if bindings were modified; 2616e5c31af7Sopenharmony_ci * - execute BindBufferBase for second half of bindings with NULL as <buffers> 2617e5c31af7Sopenharmony_ci * to unbind rest of bindings; 2618e5c31af7Sopenharmony_ci * - inspect if bindings were modified; 2619e5c31af7Sopenharmony_ci */ 2620e5c31af7Sopenharmony_ci GLint half_index = max_buffers / 2; 2621e5c31af7Sopenharmony_ci gl.bindBuffersRange(target, 0 /* first */, half_index /* count */, 0, &offsets[0], &sizes[0]); 2622e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersRange"); 2623e5c31af7Sopenharmony_ci 2624e5c31af7Sopenharmony_ci for (GLint j = 0; j < half_index; ++j) 2625e5c31af7Sopenharmony_ci { 2626e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, 0); 2627e5c31af7Sopenharmony_ci } 2628e5c31af7Sopenharmony_ci 2629e5c31af7Sopenharmony_ci for (GLint j = half_index; j < max_buffers; ++j) 2630e5c31af7Sopenharmony_ci { 2631e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]); 2632e5c31af7Sopenharmony_ci } 2633e5c31af7Sopenharmony_ci 2634e5c31af7Sopenharmony_ci gl.bindBuffersRange(target, half_index /* first */, max_buffers - half_index /* count */, 0, &offsets[0], 2635e5c31af7Sopenharmony_ci &sizes[0]); 2636e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersRange"); 2637e5c31af7Sopenharmony_ci 2638e5c31af7Sopenharmony_ci for (GLint j = 0; j < max_buffers; ++j) 2639e5c31af7Sopenharmony_ci { 2640e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, 0); 2641e5c31af7Sopenharmony_ci } 2642e5c31af7Sopenharmony_ci 2643e5c31af7Sopenharmony_ci /* 2644e5c31af7Sopenharmony_ci * - change <buffers> so first entry is invalid; 2645e5c31af7Sopenharmony_ci * - execute BindBufferBase to bind all buffers to tested target; It is 2646e5c31af7Sopenharmony_ci * expected that INVALID_OPERATION will be generated; 2647e5c31af7Sopenharmony_ci * - inspect if all bindings but first were modified; 2648e5c31af7Sopenharmony_ci */ 2649e5c31af7Sopenharmony_ci 2650e5c31af7Sopenharmony_ci /* Find invalid id */ 2651e5c31af7Sopenharmony_ci GLuint invalid_id = 1; 2652e5c31af7Sopenharmony_ci while (1) 2653e5c31af7Sopenharmony_ci { 2654e5c31af7Sopenharmony_ci if (GL_TRUE != gl.isBuffer(invalid_id)) 2655e5c31af7Sopenharmony_ci { 2656e5c31af7Sopenharmony_ci break; 2657e5c31af7Sopenharmony_ci } 2658e5c31af7Sopenharmony_ci 2659e5c31af7Sopenharmony_ci invalid_id += 1; 2660e5c31af7Sopenharmony_ci } 2661e5c31af7Sopenharmony_ci 2662e5c31af7Sopenharmony_ci buffer_ids[0] = invalid_id; 2663e5c31af7Sopenharmony_ci 2664e5c31af7Sopenharmony_ci gl.bindBuffersRange(target, 0 /* first */, max_buffers /* count */, &buffer_ids[0], &offsets[0], &sizes[0]); 2665e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindBuffersRange with invalid buffer id"); 2666e5c31af7Sopenharmony_ci 2667e5c31af7Sopenharmony_ci /* Update buffer_ids */ 2668e5c31af7Sopenharmony_ci buffer_ids[0] = 0; /* 0 means unbound */ 2669e5c31af7Sopenharmony_ci 2670e5c31af7Sopenharmony_ci for (GLint j = 0; j < max_buffers; ++j) 2671e5c31af7Sopenharmony_ci { 2672e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]); 2673e5c31af7Sopenharmony_ci } 2674e5c31af7Sopenharmony_ci 2675e5c31af7Sopenharmony_ci /* 2676e5c31af7Sopenharmony_ci * - bind any buffer to first binding; 2677e5c31af7Sopenharmony_ci * - execute BindBufferBase for 0 as <first>, 1 as <count> and <buffers> filled 2678e5c31af7Sopenharmony_ci * with zeros to unbind 1st binding for tested target; 2679e5c31af7Sopenharmony_ci * - inspect if bindings were modified; 2680e5c31af7Sopenharmony_ci */ 2681e5c31af7Sopenharmony_ci gl.bindBufferBase(target, 0, buffer[0].m_id); 2682e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase"); 2683e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, 0, target_name, buffer[0].m_id); 2684e5c31af7Sopenharmony_ci 2685e5c31af7Sopenharmony_ci std::vector<GLuint> t_buffer_ids; 2686e5c31af7Sopenharmony_ci t_buffer_ids.resize(max_buffers); 2687e5c31af7Sopenharmony_ci 2688e5c31af7Sopenharmony_ci gl.bindBuffersRange(target, 0 /* first */, 1 /* count */, &t_buffer_ids[0], &offsets[0], &sizes[0]); 2689e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersRange"); 2690e5c31af7Sopenharmony_ci 2691e5c31af7Sopenharmony_ci for (GLint j = 0; j < max_buffers; ++j) 2692e5c31af7Sopenharmony_ci { 2693e5c31af7Sopenharmony_ci checkBinding(m_context, pname_binding, j, target_name, buffer_ids[j]); 2694e5c31af7Sopenharmony_ci } 2695e5c31af7Sopenharmony_ci 2696e5c31af7Sopenharmony_ci /* - unbind all buffers. */ 2697e5c31af7Sopenharmony_ci gl.bindBuffersBase(target, 0 /* first */, max_buffers /* count */, 0); 2698e5c31af7Sopenharmony_ci } 2699e5c31af7Sopenharmony_ci 2700e5c31af7Sopenharmony_ci /* Set result */ 2701e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2702e5c31af7Sopenharmony_ci 2703e5c31af7Sopenharmony_ci /* Done */ 2704e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2705e5c31af7Sopenharmony_ci} 2706e5c31af7Sopenharmony_ci 2707e5c31af7Sopenharmony_ci/** Constructor 2708e5c31af7Sopenharmony_ci * 2709e5c31af7Sopenharmony_ci * @param context Test context 2710e5c31af7Sopenharmony_ci **/ 2711e5c31af7Sopenharmony_ciFunctionalBindTexturesTest::FunctionalBindTexturesTest(deqp::Context& context) 2712e5c31af7Sopenharmony_ci : TestCase(context, "functional_bind_textures", "Verifies that BindTextures works as expected") 2713e5c31af7Sopenharmony_ci{ 2714e5c31af7Sopenharmony_ci /* Nothing to be done */ 2715e5c31af7Sopenharmony_ci} 2716e5c31af7Sopenharmony_ci 2717e5c31af7Sopenharmony_ci/** Execute test 2718e5c31af7Sopenharmony_ci * 2719e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 2720e5c31af7Sopenharmony_ci **/ 2721e5c31af7Sopenharmony_citcu::TestNode::IterateResult FunctionalBindTexturesTest::iterate() 2722e5c31af7Sopenharmony_ci{ 2723e5c31af7Sopenharmony_ci static const GLuint depth = 6; 2724e5c31af7Sopenharmony_ci static const GLuint height = 6; 2725e5c31af7Sopenharmony_ci static const GLuint width = 6; 2726e5c31af7Sopenharmony_ci 2727e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2728e5c31af7Sopenharmony_ci 2729e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 2730e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 2731e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 2732e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 2733e5c31af7Sopenharmony_ci 2734e5c31af7Sopenharmony_ci GLuint invalid_id = 1; /* Start with 1, as 0 is not valid name */ 2735e5c31af7Sopenharmony_ci GLint max_textures = 0; 2736e5c31af7Sopenharmony_ci 2737e5c31af7Sopenharmony_ci /* Get max */ 2738e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_textures); 2739e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 2740e5c31af7Sopenharmony_ci 2741e5c31af7Sopenharmony_ci /* Storage */ 2742e5c31af7Sopenharmony_ci Buffer buffer; 2743e5c31af7Sopenharmony_ci std::vector<Texture> texture; 2744e5c31af7Sopenharmony_ci std::vector<GLuint> texture_ids; 2745e5c31af7Sopenharmony_ci std::vector<GLuint> t_texture_ids; 2746e5c31af7Sopenharmony_ci 2747e5c31af7Sopenharmony_ci texture.resize(max_textures); 2748e5c31af7Sopenharmony_ci texture_ids.resize(max_textures); 2749e5c31af7Sopenharmony_ci t_texture_ids.resize(max_textures); 2750e5c31af7Sopenharmony_ci 2751e5c31af7Sopenharmony_ci /* Prepare buffer */ 2752e5c31af7Sopenharmony_ci buffer.InitData(m_context, GL_TEXTURE_BUFFER, GL_DYNAMIC_COPY, 16 /* size */, 0 /* data */); 2753e5c31af7Sopenharmony_ci 2754e5c31af7Sopenharmony_ci /* Prepare textures */ 2755e5c31af7Sopenharmony_ci for (size_t i = 0; i < s_n_texture_tragets; ++i) 2756e5c31af7Sopenharmony_ci { 2757e5c31af7Sopenharmony_ci const GLenum target = s_texture_infos[i].m_target; 2758e5c31af7Sopenharmony_ci 2759e5c31af7Sopenharmony_ci if (GL_TEXTURE_BUFFER != target) 2760e5c31af7Sopenharmony_ci { 2761e5c31af7Sopenharmony_ci texture[i].InitStorage(m_context, target, 1, GL_RGBA8, width, height, depth); 2762e5c31af7Sopenharmony_ci } 2763e5c31af7Sopenharmony_ci else 2764e5c31af7Sopenharmony_ci { 2765e5c31af7Sopenharmony_ci texture[i].InitBuffer(m_context, GL_RGBA8, buffer.m_id); 2766e5c31af7Sopenharmony_ci } 2767e5c31af7Sopenharmony_ci 2768e5c31af7Sopenharmony_ci /* Unbind */ 2769e5c31af7Sopenharmony_ci Texture::Bind(gl, 0, target); 2770e5c31af7Sopenharmony_ci } 2771e5c31af7Sopenharmony_ci 2772e5c31af7Sopenharmony_ci for (GLint i = s_n_texture_tragets; i < max_textures; ++i) 2773e5c31af7Sopenharmony_ci { 2774e5c31af7Sopenharmony_ci texture[i].InitStorage(m_context, GL_TEXTURE_2D, 1, GL_RGBA8, width, height, depth); 2775e5c31af7Sopenharmony_ci } 2776e5c31af7Sopenharmony_ci 2777e5c31af7Sopenharmony_ci /* Unbind */ 2778e5c31af7Sopenharmony_ci Texture::Bind(gl, 0, GL_TEXTURE_2D); 2779e5c31af7Sopenharmony_ci 2780e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 2781e5c31af7Sopenharmony_ci { 2782e5c31af7Sopenharmony_ci texture_ids[i] = texture[i].m_id; 2783e5c31af7Sopenharmony_ci } 2784e5c31af7Sopenharmony_ci 2785e5c31af7Sopenharmony_ci /* 2786e5c31af7Sopenharmony_ci * - execute BindTextures to bind all textures; 2787e5c31af7Sopenharmony_ci * - inspect bindings of all texture units to verify that proper bindings were 2788e5c31af7Sopenharmony_ci * set; 2789e5c31af7Sopenharmony_ci */ 2790e5c31af7Sopenharmony_ci gl.bindTextures(0, max_textures, &texture_ids[0]); 2791e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures"); 2792e5c31af7Sopenharmony_ci 2793e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 2794e5c31af7Sopenharmony_ci { 2795e5c31af7Sopenharmony_ci checkTextureBinding(m_context, getBinding(i), i, texture_ids[i]); 2796e5c31af7Sopenharmony_ci } 2797e5c31af7Sopenharmony_ci 2798e5c31af7Sopenharmony_ci /* 2799e5c31af7Sopenharmony_ci * - execute BindTextures for the first half of units with <textures> filled 2800e5c31af7Sopenharmony_ci * with zeros, to unbind those units; 2801e5c31af7Sopenharmony_ci * - inspect bindings of all texture units to verify that proper bindings were 2802e5c31af7Sopenharmony_ci * unbound; 2803e5c31af7Sopenharmony_ci */ 2804e5c31af7Sopenharmony_ci GLint half_index = max_textures / 2; 2805e5c31af7Sopenharmony_ci 2806e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 2807e5c31af7Sopenharmony_ci { 2808e5c31af7Sopenharmony_ci t_texture_ids[i] = 0; 2809e5c31af7Sopenharmony_ci } 2810e5c31af7Sopenharmony_ci 2811e5c31af7Sopenharmony_ci gl.bindTextures(0, half_index, &t_texture_ids[0]); 2812e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures"); 2813e5c31af7Sopenharmony_ci 2814e5c31af7Sopenharmony_ci for (GLint i = 0; i < half_index; ++i) 2815e5c31af7Sopenharmony_ci { 2816e5c31af7Sopenharmony_ci checkTextureBinding(m_context, getBinding(i), i, 0); 2817e5c31af7Sopenharmony_ci } 2818e5c31af7Sopenharmony_ci 2819e5c31af7Sopenharmony_ci for (GLint i = half_index; i < max_textures; ++i) 2820e5c31af7Sopenharmony_ci { 2821e5c31af7Sopenharmony_ci checkTextureBinding(m_context, getBinding(i), i, texture_ids[i]); 2822e5c31af7Sopenharmony_ci } 2823e5c31af7Sopenharmony_ci 2824e5c31af7Sopenharmony_ci /* 2825e5c31af7Sopenharmony_ci * - execute BindTextures for the second half of units with NULL as<textures>, 2826e5c31af7Sopenharmony_ci * to unbind those units; 2827e5c31af7Sopenharmony_ci * - inspect bindings of all texture units to verify that proper bindings were 2828e5c31af7Sopenharmony_ci * unbound; 2829e5c31af7Sopenharmony_ci */ 2830e5c31af7Sopenharmony_ci gl.bindTextures(half_index, max_textures - half_index, 0); 2831e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures"); 2832e5c31af7Sopenharmony_ci 2833e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 2834e5c31af7Sopenharmony_ci { 2835e5c31af7Sopenharmony_ci checkTextureBinding(m_context, getBinding(i), i, 0); 2836e5c31af7Sopenharmony_ci } 2837e5c31af7Sopenharmony_ci 2838e5c31af7Sopenharmony_ci /* 2839e5c31af7Sopenharmony_ci * - modify <textures> so first entry is invalid; 2840e5c31af7Sopenharmony_ci * - execute BindTextures to bind all textures; It is expected that 2841e5c31af7Sopenharmony_ci * INVALID_OPERATION will be generated; 2842e5c31af7Sopenharmony_ci * - inspect bindings of all texture units to verify that proper bindings were 2843e5c31af7Sopenharmony_ci * set; 2844e5c31af7Sopenharmony_ci */ 2845e5c31af7Sopenharmony_ci 2846e5c31af7Sopenharmony_ci /* Find invalid id */ 2847e5c31af7Sopenharmony_ci while (1) 2848e5c31af7Sopenharmony_ci { 2849e5c31af7Sopenharmony_ci if (GL_TRUE != gl.isTexture(invalid_id)) 2850e5c31af7Sopenharmony_ci { 2851e5c31af7Sopenharmony_ci break; 2852e5c31af7Sopenharmony_ci } 2853e5c31af7Sopenharmony_ci 2854e5c31af7Sopenharmony_ci invalid_id += 1; 2855e5c31af7Sopenharmony_ci } 2856e5c31af7Sopenharmony_ci 2857e5c31af7Sopenharmony_ci /* Set invalid id */ 2858e5c31af7Sopenharmony_ci texture_ids[0] = invalid_id; 2859e5c31af7Sopenharmony_ci 2860e5c31af7Sopenharmony_ci gl.bindTextures(0, max_textures, &texture_ids[0]); 2861e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindTextures with invalid texture id"); 2862e5c31af7Sopenharmony_ci 2863e5c31af7Sopenharmony_ci checkTextureBinding(m_context, getBinding(0), 0, 0); 2864e5c31af7Sopenharmony_ci for (GLint i = 1; i < max_textures; ++i) 2865e5c31af7Sopenharmony_ci { 2866e5c31af7Sopenharmony_ci checkTextureBinding(m_context, getBinding(i), i, texture_ids[i]); 2867e5c31af7Sopenharmony_ci } 2868e5c31af7Sopenharmony_ci 2869e5c31af7Sopenharmony_ci /* - unbind all textures. */ 2870e5c31af7Sopenharmony_ci gl.bindTextures(0, max_textures, 0); 2871e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures"); 2872e5c31af7Sopenharmony_ci 2873e5c31af7Sopenharmony_ci /* Set result */ 2874e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2875e5c31af7Sopenharmony_ci 2876e5c31af7Sopenharmony_ci /* Done */ 2877e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2878e5c31af7Sopenharmony_ci} 2879e5c31af7Sopenharmony_ci 2880e5c31af7Sopenharmony_ci/** Constructor 2881e5c31af7Sopenharmony_ci * 2882e5c31af7Sopenharmony_ci * @param context Test context 2883e5c31af7Sopenharmony_ci **/ 2884e5c31af7Sopenharmony_ciFunctionalBindSamplersTest::FunctionalBindSamplersTest(deqp::Context& context) 2885e5c31af7Sopenharmony_ci : TestCase(context, "functional_bind_samplers", "Verifies that BindSamplers works as expected") 2886e5c31af7Sopenharmony_ci{ 2887e5c31af7Sopenharmony_ci /* Nothing to be done */ 2888e5c31af7Sopenharmony_ci} 2889e5c31af7Sopenharmony_ci 2890e5c31af7Sopenharmony_ci/** Execute test 2891e5c31af7Sopenharmony_ci * 2892e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 2893e5c31af7Sopenharmony_ci **/ 2894e5c31af7Sopenharmony_citcu::TestNode::IterateResult FunctionalBindSamplersTest::iterate() 2895e5c31af7Sopenharmony_ci{ 2896e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2897e5c31af7Sopenharmony_ci 2898e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 2899e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 2900e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 2901e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 2902e5c31af7Sopenharmony_ci 2903e5c31af7Sopenharmony_ci GLuint invalid_id = 1; /* Start with 1, as 0 is not valid name */ 2904e5c31af7Sopenharmony_ci GLint max_samplers = 0; 2905e5c31af7Sopenharmony_ci 2906e5c31af7Sopenharmony_ci /* Get max */ 2907e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_samplers); 2908e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 2909e5c31af7Sopenharmony_ci 2910e5c31af7Sopenharmony_ci /* Storage */ 2911e5c31af7Sopenharmony_ci std::vector<GLuint> sampler_ids; 2912e5c31af7Sopenharmony_ci std::vector<GLuint> t_sampler_ids; 2913e5c31af7Sopenharmony_ci 2914e5c31af7Sopenharmony_ci sampler_ids.resize(max_samplers); 2915e5c31af7Sopenharmony_ci t_sampler_ids.resize(max_samplers); 2916e5c31af7Sopenharmony_ci 2917e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_samplers; ++i) 2918e5c31af7Sopenharmony_ci { 2919e5c31af7Sopenharmony_ci t_sampler_ids[i] = 0; 2920e5c31af7Sopenharmony_ci } 2921e5c31af7Sopenharmony_ci 2922e5c31af7Sopenharmony_ci /* Prepare samplers */ 2923e5c31af7Sopenharmony_ci gl.genSamplers(max_samplers, &sampler_ids[0]); 2924e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenSamplers"); 2925e5c31af7Sopenharmony_ci 2926e5c31af7Sopenharmony_ci try 2927e5c31af7Sopenharmony_ci { 2928e5c31af7Sopenharmony_ci /* - execute BindSamplers to bind all samplers; 2929e5c31af7Sopenharmony_ci * - inspect bindings to verify that proper samplers were set; 2930e5c31af7Sopenharmony_ci */ 2931e5c31af7Sopenharmony_ci gl.bindSamplers(0 /* first */, max_samplers /* count */, &sampler_ids[0]); 2932e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindSamplers"); 2933e5c31af7Sopenharmony_ci 2934e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_samplers; ++i) 2935e5c31af7Sopenharmony_ci { 2936e5c31af7Sopenharmony_ci checkBinding(m_context, GL_SAMPLER_BINDING, i, "Sampler", sampler_ids[i]); 2937e5c31af7Sopenharmony_ci } 2938e5c31af7Sopenharmony_ci 2939e5c31af7Sopenharmony_ci /* - execute BindSamplers for first half of bindings with <samplers> filled 2940e5c31af7Sopenharmony_ci * with zeros, to unbind those samplers; 2941e5c31af7Sopenharmony_ci * - inspect bindings to verify that proper samplers were unbound; 2942e5c31af7Sopenharmony_ci */ 2943e5c31af7Sopenharmony_ci GLint half_index = max_samplers / 2; 2944e5c31af7Sopenharmony_ci 2945e5c31af7Sopenharmony_ci gl.bindSamplers(0, half_index, &t_sampler_ids[0]); 2946e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindSamplers"); 2947e5c31af7Sopenharmony_ci 2948e5c31af7Sopenharmony_ci for (GLint i = 0; i < half_index; ++i) 2949e5c31af7Sopenharmony_ci { 2950e5c31af7Sopenharmony_ci checkBinding(m_context, GL_SAMPLER_BINDING, i, "Sampler", 0); 2951e5c31af7Sopenharmony_ci } 2952e5c31af7Sopenharmony_ci 2953e5c31af7Sopenharmony_ci for (GLint i = half_index; i < max_samplers; ++i) 2954e5c31af7Sopenharmony_ci { 2955e5c31af7Sopenharmony_ci checkBinding(m_context, GL_SAMPLER_BINDING, i, "Sampler", sampler_ids[i]); 2956e5c31af7Sopenharmony_ci } 2957e5c31af7Sopenharmony_ci 2958e5c31af7Sopenharmony_ci /* - execute BindSamplers for second half of bindings with NULL as <samplers>, 2959e5c31af7Sopenharmony_ci * to unbind those samplers; 2960e5c31af7Sopenharmony_ci * - inspect bindings to verify that proper samplers were unbound; 2961e5c31af7Sopenharmony_ci */ 2962e5c31af7Sopenharmony_ci gl.bindSamplers(half_index, max_samplers - half_index, 0); 2963e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindSamplers"); 2964e5c31af7Sopenharmony_ci 2965e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_samplers; ++i) 2966e5c31af7Sopenharmony_ci { 2967e5c31af7Sopenharmony_ci checkBinding(m_context, GL_SAMPLER_BINDING, i, "Sampler", 0); 2968e5c31af7Sopenharmony_ci } 2969e5c31af7Sopenharmony_ci 2970e5c31af7Sopenharmony_ci /* - modify <samplers> so first entry is invalid; 2971e5c31af7Sopenharmony_ci * - execute BindSamplers to bind all samplers; It is expected that 2972e5c31af7Sopenharmony_ci * INVALID_OPERATION will be generated; 2973e5c31af7Sopenharmony_ci * - inspect bindings to verify that proper samplers were set; 2974e5c31af7Sopenharmony_ci */ 2975e5c31af7Sopenharmony_ci 2976e5c31af7Sopenharmony_ci /* Find invalid id */ 2977e5c31af7Sopenharmony_ci while (1) 2978e5c31af7Sopenharmony_ci { 2979e5c31af7Sopenharmony_ci if (GL_TRUE != gl.isSampler(invalid_id)) 2980e5c31af7Sopenharmony_ci { 2981e5c31af7Sopenharmony_ci break; 2982e5c31af7Sopenharmony_ci } 2983e5c31af7Sopenharmony_ci 2984e5c31af7Sopenharmony_ci invalid_id += 1; 2985e5c31af7Sopenharmony_ci } 2986e5c31af7Sopenharmony_ci 2987e5c31af7Sopenharmony_ci /* Prepare ids */ 2988e5c31af7Sopenharmony_ci t_sampler_ids[0] = invalid_id; 2989e5c31af7Sopenharmony_ci 2990e5c31af7Sopenharmony_ci for (GLint i = 1; i < max_samplers; ++i) 2991e5c31af7Sopenharmony_ci { 2992e5c31af7Sopenharmony_ci t_sampler_ids[i] = sampler_ids[i]; 2993e5c31af7Sopenharmony_ci } 2994e5c31af7Sopenharmony_ci 2995e5c31af7Sopenharmony_ci /* Bind */ 2996e5c31af7Sopenharmony_ci gl.bindSamplers(0, max_samplers, &t_sampler_ids[0]); 2997e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindSamplers with invalid sampler id"); 2998e5c31af7Sopenharmony_ci 2999e5c31af7Sopenharmony_ci /* Set 0 for invalid entry */ 3000e5c31af7Sopenharmony_ci t_sampler_ids[0] = 0; 3001e5c31af7Sopenharmony_ci 3002e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_samplers; ++i) 3003e5c31af7Sopenharmony_ci { 3004e5c31af7Sopenharmony_ci checkBinding(m_context, GL_SAMPLER_BINDING, i, "Sampler", t_sampler_ids[i]); 3005e5c31af7Sopenharmony_ci } 3006e5c31af7Sopenharmony_ci 3007e5c31af7Sopenharmony_ci /* - unbind all samplers. */ 3008e5c31af7Sopenharmony_ci gl.bindSamplers(0, max_samplers, 0); 3009e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindSamplers"); 3010e5c31af7Sopenharmony_ci } 3011e5c31af7Sopenharmony_ci catch (const std::exception&) 3012e5c31af7Sopenharmony_ci { 3013e5c31af7Sopenharmony_ci gl.deleteSamplers(max_samplers, &sampler_ids[0]); 3014e5c31af7Sopenharmony_ci 3015e5c31af7Sopenharmony_ci TCU_FAIL("Invalid error generated"); 3016e5c31af7Sopenharmony_ci } 3017e5c31af7Sopenharmony_ci 3018e5c31af7Sopenharmony_ci /* Delete samplers */ 3019e5c31af7Sopenharmony_ci gl.deleteSamplers(max_samplers, &sampler_ids[0]); 3020e5c31af7Sopenharmony_ci 3021e5c31af7Sopenharmony_ci /* Set result */ 3022e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3023e5c31af7Sopenharmony_ci 3024e5c31af7Sopenharmony_ci /* Done */ 3025e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 3026e5c31af7Sopenharmony_ci} 3027e5c31af7Sopenharmony_ci 3028e5c31af7Sopenharmony_ci/** Constructor 3029e5c31af7Sopenharmony_ci * 3030e5c31af7Sopenharmony_ci * @param context Test context 3031e5c31af7Sopenharmony_ci **/ 3032e5c31af7Sopenharmony_ciFunctionalBindImageTexturesTest::FunctionalBindImageTexturesTest(deqp::Context& context) 3033e5c31af7Sopenharmony_ci : TestCase(context, "functional_bind_image_textures", "Verifies that BindImageTextures works as expected") 3034e5c31af7Sopenharmony_ci{ 3035e5c31af7Sopenharmony_ci /* Nothing to be done */ 3036e5c31af7Sopenharmony_ci} 3037e5c31af7Sopenharmony_ci 3038e5c31af7Sopenharmony_ci/** Execute test 3039e5c31af7Sopenharmony_ci * 3040e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 3041e5c31af7Sopenharmony_ci **/ 3042e5c31af7Sopenharmony_citcu::TestNode::IterateResult FunctionalBindImageTexturesTest::iterate() 3043e5c31af7Sopenharmony_ci{ 3044e5c31af7Sopenharmony_ci static const GLuint depth = 6; 3045e5c31af7Sopenharmony_ci static const GLuint height = 6; 3046e5c31af7Sopenharmony_ci static const GLuint width = 6; 3047e5c31af7Sopenharmony_ci 3048e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 3049e5c31af7Sopenharmony_ci 3050e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 3051e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 3052e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 3053e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 3054e5c31af7Sopenharmony_ci 3055e5c31af7Sopenharmony_ci GLuint invalid_id = 1; /* Start with 1, as 0 is not valid name */ 3056e5c31af7Sopenharmony_ci GLint max_textures = 0; 3057e5c31af7Sopenharmony_ci 3058e5c31af7Sopenharmony_ci /* Get max */ 3059e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_IMAGE_UNITS, &max_textures); 3060e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3061e5c31af7Sopenharmony_ci 3062e5c31af7Sopenharmony_ci /* Storage */ 3063e5c31af7Sopenharmony_ci Buffer buffer; 3064e5c31af7Sopenharmony_ci std::vector<Texture> texture; 3065e5c31af7Sopenharmony_ci std::vector<GLuint> texture_ids; 3066e5c31af7Sopenharmony_ci std::vector<GLuint> t_texture_ids; 3067e5c31af7Sopenharmony_ci 3068e5c31af7Sopenharmony_ci texture.resize(max_textures); 3069e5c31af7Sopenharmony_ci texture_ids.resize(max_textures); 3070e5c31af7Sopenharmony_ci t_texture_ids.resize(max_textures); 3071e5c31af7Sopenharmony_ci 3072e5c31af7Sopenharmony_ci /* Prepare buffer */ 3073e5c31af7Sopenharmony_ci buffer.InitData(m_context, GL_TEXTURE_BUFFER, GL_DYNAMIC_COPY, 16 /* size */, 0 /* data */); 3074e5c31af7Sopenharmony_ci 3075e5c31af7Sopenharmony_ci /* Prepare textures */ 3076e5c31af7Sopenharmony_ci for (GLint i = 0; i < (GLint)s_n_texture_tragets; ++i) 3077e5c31af7Sopenharmony_ci { 3078e5c31af7Sopenharmony_ci const GLenum target = s_texture_infos[i].m_target; 3079e5c31af7Sopenharmony_ci 3080e5c31af7Sopenharmony_ci if (i >= max_textures) 3081e5c31af7Sopenharmony_ci { 3082e5c31af7Sopenharmony_ci break; 3083e5c31af7Sopenharmony_ci } 3084e5c31af7Sopenharmony_ci 3085e5c31af7Sopenharmony_ci if (GL_TEXTURE_BUFFER != target) 3086e5c31af7Sopenharmony_ci { 3087e5c31af7Sopenharmony_ci texture[i].InitStorage(m_context, target, 1, GL_RGBA8, width, height, depth); 3088e5c31af7Sopenharmony_ci } 3089e5c31af7Sopenharmony_ci else 3090e5c31af7Sopenharmony_ci { 3091e5c31af7Sopenharmony_ci texture[i].InitBuffer(m_context, GL_RGBA8, buffer.m_id); 3092e5c31af7Sopenharmony_ci } 3093e5c31af7Sopenharmony_ci 3094e5c31af7Sopenharmony_ci /* Unbind */ 3095e5c31af7Sopenharmony_ci Texture::Bind(gl, 0, target); 3096e5c31af7Sopenharmony_ci } 3097e5c31af7Sopenharmony_ci 3098e5c31af7Sopenharmony_ci for (GLint i = (GLint)s_n_texture_tragets; i < max_textures; ++i) 3099e5c31af7Sopenharmony_ci { 3100e5c31af7Sopenharmony_ci texture[i].InitStorage(m_context, GL_TEXTURE_2D, 1, GL_RGBA8, width, height, depth); 3101e5c31af7Sopenharmony_ci } 3102e5c31af7Sopenharmony_ci 3103e5c31af7Sopenharmony_ci /* Unbind */ 3104e5c31af7Sopenharmony_ci Texture::Bind(gl, 0, GL_TEXTURE_2D); 3105e5c31af7Sopenharmony_ci 3106e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 3107e5c31af7Sopenharmony_ci { 3108e5c31af7Sopenharmony_ci texture_ids[i] = texture[i].m_id; 3109e5c31af7Sopenharmony_ci } 3110e5c31af7Sopenharmony_ci 3111e5c31af7Sopenharmony_ci /* 3112e5c31af7Sopenharmony_ci * - execute BindImageTextures to bind all images; 3113e5c31af7Sopenharmony_ci * - inspect bindings to verify that proper images were set; 3114e5c31af7Sopenharmony_ci */ 3115e5c31af7Sopenharmony_ci gl.bindImageTextures(0, max_textures, &texture_ids[0]); 3116e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTextures"); 3117e5c31af7Sopenharmony_ci 3118e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 3119e5c31af7Sopenharmony_ci { 3120e5c31af7Sopenharmony_ci checkBinding(m_context, GL_IMAGE_BINDING_NAME, i, "Image unit", texture_ids[i]); 3121e5c31af7Sopenharmony_ci } 3122e5c31af7Sopenharmony_ci 3123e5c31af7Sopenharmony_ci /* 3124e5c31af7Sopenharmony_ci * - execute BindTextures for the first half of units with <textures> filled 3125e5c31af7Sopenharmony_ci * with zeros, to unbind those units; 3126e5c31af7Sopenharmony_ci * - inspect bindings of all texture units to verify that proper bindings were 3127e5c31af7Sopenharmony_ci * unbound; 3128e5c31af7Sopenharmony_ci */ 3129e5c31af7Sopenharmony_ci GLint half_index = max_textures / 2; 3130e5c31af7Sopenharmony_ci 3131e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 3132e5c31af7Sopenharmony_ci { 3133e5c31af7Sopenharmony_ci t_texture_ids[i] = 0; 3134e5c31af7Sopenharmony_ci } 3135e5c31af7Sopenharmony_ci 3136e5c31af7Sopenharmony_ci gl.bindImageTextures(0, half_index, &t_texture_ids[0]); 3137e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTextures"); 3138e5c31af7Sopenharmony_ci 3139e5c31af7Sopenharmony_ci for (GLint i = 0; i < half_index; ++i) 3140e5c31af7Sopenharmony_ci { 3141e5c31af7Sopenharmony_ci checkBinding(m_context, GL_IMAGE_BINDING_NAME, i, "Image unit", 0); 3142e5c31af7Sopenharmony_ci } 3143e5c31af7Sopenharmony_ci 3144e5c31af7Sopenharmony_ci for (GLint i = half_index; i < max_textures; ++i) 3145e5c31af7Sopenharmony_ci { 3146e5c31af7Sopenharmony_ci checkBinding(m_context, GL_IMAGE_BINDING_NAME, i, "Image unit", texture_ids[i]); 3147e5c31af7Sopenharmony_ci } 3148e5c31af7Sopenharmony_ci 3149e5c31af7Sopenharmony_ci /* 3150e5c31af7Sopenharmony_ci * - execute BindTextures for the second half of units with NULL as<textures>, 3151e5c31af7Sopenharmony_ci * to unbind those units; 3152e5c31af7Sopenharmony_ci * - inspect bindings of all texture units to verify that proper bindings were 3153e5c31af7Sopenharmony_ci * unbound; 3154e5c31af7Sopenharmony_ci */ 3155e5c31af7Sopenharmony_ci gl.bindImageTextures(half_index, max_textures - half_index, 0); 3156e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTextures"); 3157e5c31af7Sopenharmony_ci 3158e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 3159e5c31af7Sopenharmony_ci { 3160e5c31af7Sopenharmony_ci checkBinding(m_context, GL_IMAGE_BINDING_NAME, i, "Image unit", 0); 3161e5c31af7Sopenharmony_ci } 3162e5c31af7Sopenharmony_ci 3163e5c31af7Sopenharmony_ci /* 3164e5c31af7Sopenharmony_ci * - modify <textures> so first entry is invalid; 3165e5c31af7Sopenharmony_ci * - execute BindTextures to bind all textures; It is expected that 3166e5c31af7Sopenharmony_ci * INVALID_OPERATION will be generated; 3167e5c31af7Sopenharmony_ci * - inspect bindings of all texture units to verify that proper bindings were 3168e5c31af7Sopenharmony_ci * set; 3169e5c31af7Sopenharmony_ci */ 3170e5c31af7Sopenharmony_ci 3171e5c31af7Sopenharmony_ci /* Find invalid id */ 3172e5c31af7Sopenharmony_ci while (1) 3173e5c31af7Sopenharmony_ci { 3174e5c31af7Sopenharmony_ci if (GL_TRUE != gl.isTexture(invalid_id)) 3175e5c31af7Sopenharmony_ci { 3176e5c31af7Sopenharmony_ci break; 3177e5c31af7Sopenharmony_ci } 3178e5c31af7Sopenharmony_ci 3179e5c31af7Sopenharmony_ci invalid_id += 1; 3180e5c31af7Sopenharmony_ci } 3181e5c31af7Sopenharmony_ci 3182e5c31af7Sopenharmony_ci /* Set invalid id */ 3183e5c31af7Sopenharmony_ci texture_ids[0] = invalid_id; 3184e5c31af7Sopenharmony_ci 3185e5c31af7Sopenharmony_ci gl.bindImageTextures(0, max_textures, &texture_ids[0]); 3186e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindImageTextures with invalid texture id"); 3187e5c31af7Sopenharmony_ci 3188e5c31af7Sopenharmony_ci checkBinding(m_context, GL_IMAGE_BINDING_NAME, 0, "Image unit", 0); 3189e5c31af7Sopenharmony_ci for (GLint i = 1; i < max_textures; ++i) 3190e5c31af7Sopenharmony_ci { 3191e5c31af7Sopenharmony_ci checkBinding(m_context, GL_IMAGE_BINDING_NAME, i, "Image unit", texture_ids[i]); 3192e5c31af7Sopenharmony_ci } 3193e5c31af7Sopenharmony_ci 3194e5c31af7Sopenharmony_ci /* - unbind all textures. */ 3195e5c31af7Sopenharmony_ci gl.bindImageTextures(0, max_textures, 0); 3196e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTextures"); 3197e5c31af7Sopenharmony_ci 3198e5c31af7Sopenharmony_ci /* Set result */ 3199e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3200e5c31af7Sopenharmony_ci 3201e5c31af7Sopenharmony_ci /* Done */ 3202e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 3203e5c31af7Sopenharmony_ci} 3204e5c31af7Sopenharmony_ci 3205e5c31af7Sopenharmony_ci/** Constructor 3206e5c31af7Sopenharmony_ci * 3207e5c31af7Sopenharmony_ci * @param context Test context 3208e5c31af7Sopenharmony_ci **/ 3209e5c31af7Sopenharmony_ciFunctionalBindVertexBuffersTest::FunctionalBindVertexBuffersTest(deqp::Context& context) 3210e5c31af7Sopenharmony_ci : TestCase(context, "functional_bind_vertex_buffers", "Verifies that BindVertexBuffers works as expected") 3211e5c31af7Sopenharmony_ci{ 3212e5c31af7Sopenharmony_ci /* Nothing to be done */ 3213e5c31af7Sopenharmony_ci} 3214e5c31af7Sopenharmony_ci 3215e5c31af7Sopenharmony_ci/** Execute test 3216e5c31af7Sopenharmony_ci * 3217e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 3218e5c31af7Sopenharmony_ci **/ 3219e5c31af7Sopenharmony_citcu::TestNode::IterateResult FunctionalBindVertexBuffersTest::iterate() 3220e5c31af7Sopenharmony_ci{ 3221e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 3222e5c31af7Sopenharmony_ci 3223e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 3224e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 3225e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 3226e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 3227e5c31af7Sopenharmony_ci 3228e5c31af7Sopenharmony_ci static const GLintptr buffer_size = 16; 3229e5c31af7Sopenharmony_ci static const GLintptr offset = 4; 3230e5c31af7Sopenharmony_ci static const GLsizei stride = 4; 3231e5c31af7Sopenharmony_ci 3232e5c31af7Sopenharmony_ci GLuint invalid_id = 1; /* Start with 1, as 0 is not valid name */ 3233e5c31af7Sopenharmony_ci GLint max_buffers = 0; 3234e5c31af7Sopenharmony_ci 3235e5c31af7Sopenharmony_ci /* Get max */ 3236e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_buffers); 3237e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3238e5c31af7Sopenharmony_ci 3239e5c31af7Sopenharmony_ci /* Storage */ 3240e5c31af7Sopenharmony_ci std::vector<Buffer> buffer; 3241e5c31af7Sopenharmony_ci std::vector<GLuint> buffer_ids; 3242e5c31af7Sopenharmony_ci std::vector<GLintptr> offsets; 3243e5c31af7Sopenharmony_ci std::vector<GLsizei> strides; 3244e5c31af7Sopenharmony_ci std::vector<GLuint> t_buffer_ids; 3245e5c31af7Sopenharmony_ci 3246e5c31af7Sopenharmony_ci buffer.resize(max_buffers); 3247e5c31af7Sopenharmony_ci buffer_ids.resize(max_buffers); 3248e5c31af7Sopenharmony_ci offsets.resize(max_buffers); 3249e5c31af7Sopenharmony_ci strides.resize(max_buffers); 3250e5c31af7Sopenharmony_ci t_buffer_ids.resize(max_buffers); 3251e5c31af7Sopenharmony_ci 3252e5c31af7Sopenharmony_ci /* Prepare buffers */ 3253e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_buffers; ++i) 3254e5c31af7Sopenharmony_ci { 3255e5c31af7Sopenharmony_ci buffer[i].InitData(m_context, GL_ARRAY_BUFFER, GL_DYNAMIC_COPY, buffer_size, 0 /* data */); 3256e5c31af7Sopenharmony_ci 3257e5c31af7Sopenharmony_ci buffer_ids[i] = buffer[i].m_id; 3258e5c31af7Sopenharmony_ci offsets[i] = offset; 3259e5c31af7Sopenharmony_ci strides[i] = stride; 3260e5c31af7Sopenharmony_ci t_buffer_ids[i] = 0; 3261e5c31af7Sopenharmony_ci } 3262e5c31af7Sopenharmony_ci 3263e5c31af7Sopenharmony_ci GLuint vao = 0; 3264e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &vao); 3265e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays"); 3266e5c31af7Sopenharmony_ci try 3267e5c31af7Sopenharmony_ci { 3268e5c31af7Sopenharmony_ci gl.bindVertexArray(vao); 3269e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArrays"); 3270e5c31af7Sopenharmony_ci 3271e5c31af7Sopenharmony_ci /* - execute BindVertexBuffers to bind all buffer; 3272e5c31af7Sopenharmony_ci * - inspect bindings to verify that proper buffers were set; 3273e5c31af7Sopenharmony_ci */ 3274e5c31af7Sopenharmony_ci gl.bindVertexBuffers(0, max_buffers, &buffer_ids[0], &offsets[0], &strides[0]); 3275e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexBuffers"); 3276e5c31af7Sopenharmony_ci 3277e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_buffers; ++i) 3278e5c31af7Sopenharmony_ci { 3279e5c31af7Sopenharmony_ci checkVertexAttribBinding(m_context, i, buffer_ids[i]); 3280e5c31af7Sopenharmony_ci } 3281e5c31af7Sopenharmony_ci 3282e5c31af7Sopenharmony_ci /* - execute BindVertexBuffers for first half of bindings with <buffers> filled 3283e5c31af7Sopenharmony_ci * with zeros, to unbind those buffers; 3284e5c31af7Sopenharmony_ci * - inspect bindings to verify that proper buffers were unbound; 3285e5c31af7Sopenharmony_ci */ 3286e5c31af7Sopenharmony_ci GLint half_index = max_buffers / 2; 3287e5c31af7Sopenharmony_ci 3288e5c31af7Sopenharmony_ci gl.bindVertexBuffers(0, half_index, &t_buffer_ids[0], &offsets[0], &strides[0]); 3289e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexBuffers"); 3290e5c31af7Sopenharmony_ci 3291e5c31af7Sopenharmony_ci for (GLint i = 0; i < half_index; ++i) 3292e5c31af7Sopenharmony_ci { 3293e5c31af7Sopenharmony_ci checkVertexAttribBinding(m_context, i, 0); 3294e5c31af7Sopenharmony_ci } 3295e5c31af7Sopenharmony_ci 3296e5c31af7Sopenharmony_ci for (GLint i = half_index; i < max_buffers; ++i) 3297e5c31af7Sopenharmony_ci { 3298e5c31af7Sopenharmony_ci checkVertexAttribBinding(m_context, i, buffer_ids[i]); 3299e5c31af7Sopenharmony_ci } 3300e5c31af7Sopenharmony_ci 3301e5c31af7Sopenharmony_ci /* - execute BindVertexBuffers for second half of bindings with NULL as 3302e5c31af7Sopenharmony_ci * <buffers>, to unbind those buffers; 3303e5c31af7Sopenharmony_ci * - inspect bindings to verify that proper buffers were unbound; 3304e5c31af7Sopenharmony_ci */ 3305e5c31af7Sopenharmony_ci gl.bindVertexBuffers(half_index, max_buffers - half_index, 0, &offsets[0], &strides[0]); 3306e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexBuffers"); 3307e5c31af7Sopenharmony_ci 3308e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_buffers; ++i) 3309e5c31af7Sopenharmony_ci { 3310e5c31af7Sopenharmony_ci checkVertexAttribBinding(m_context, i, 0); 3311e5c31af7Sopenharmony_ci } 3312e5c31af7Sopenharmony_ci 3313e5c31af7Sopenharmony_ci /* - modify <buffers> so first entry is invalid; 3314e5c31af7Sopenharmony_ci * - execute BindVertexBuffers to bind all buffers; It is expected that 3315e5c31af7Sopenharmony_ci * INVALID_OPERATION will be generated; 3316e5c31af7Sopenharmony_ci * - inspect bindings to verify that proper buffers were set; 3317e5c31af7Sopenharmony_ci */ 3318e5c31af7Sopenharmony_ci 3319e5c31af7Sopenharmony_ci /* Find invalid id */ 3320e5c31af7Sopenharmony_ci while (1) 3321e5c31af7Sopenharmony_ci { 3322e5c31af7Sopenharmony_ci if (GL_TRUE != gl.isBuffer(invalid_id)) 3323e5c31af7Sopenharmony_ci { 3324e5c31af7Sopenharmony_ci break; 3325e5c31af7Sopenharmony_ci } 3326e5c31af7Sopenharmony_ci 3327e5c31af7Sopenharmony_ci invalid_id += 1; 3328e5c31af7Sopenharmony_ci } 3329e5c31af7Sopenharmony_ci 3330e5c31af7Sopenharmony_ci buffer_ids[0] = invalid_id; 3331e5c31af7Sopenharmony_ci gl.bindVertexBuffers(0, max_buffers, &buffer_ids[0], &offsets[0], &strides[0]); 3332e5c31af7Sopenharmony_ci CHECK_ERROR(GL_INVALID_OPERATION, "BindVertexBuffers with invalid id"); 3333e5c31af7Sopenharmony_ci 3334e5c31af7Sopenharmony_ci checkVertexAttribBinding(m_context, 0, 0); 3335e5c31af7Sopenharmony_ci for (GLint i = 1; i < max_buffers; ++i) 3336e5c31af7Sopenharmony_ci { 3337e5c31af7Sopenharmony_ci checkVertexAttribBinding(m_context, i, buffer_ids[i]); 3338e5c31af7Sopenharmony_ci } 3339e5c31af7Sopenharmony_ci 3340e5c31af7Sopenharmony_ci /* - unbind all buffers. */ 3341e5c31af7Sopenharmony_ci gl.bindVertexBuffers(0, max_buffers, 0, &offsets[0], &strides[0]); 3342e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexBuffers"); 3343e5c31af7Sopenharmony_ci } 3344e5c31af7Sopenharmony_ci catch (const std::exception&) 3345e5c31af7Sopenharmony_ci { 3346e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &vao); 3347e5c31af7Sopenharmony_ci 3348e5c31af7Sopenharmony_ci TCU_FAIL("Unexpected error generated"); 3349e5c31af7Sopenharmony_ci } 3350e5c31af7Sopenharmony_ci 3351e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &vao); 3352e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteVertexArrays"); 3353e5c31af7Sopenharmony_ci 3354e5c31af7Sopenharmony_ci /* Set result */ 3355e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3356e5c31af7Sopenharmony_ci 3357e5c31af7Sopenharmony_ci /* Done */ 3358e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 3359e5c31af7Sopenharmony_ci} 3360e5c31af7Sopenharmony_ci 3361e5c31af7Sopenharmony_ci/** Constructor 3362e5c31af7Sopenharmony_ci * 3363e5c31af7Sopenharmony_ci * @param context Test context 3364e5c31af7Sopenharmony_ci **/ 3365e5c31af7Sopenharmony_ciDispatchBindBuffersBaseTest::DispatchBindBuffersBaseTest(deqp::Context& context) 3366e5c31af7Sopenharmony_ci : TestCase(context, "dispatch_bind_buffers_base", "Tests BindBuffersBase with dispatch command") 3367e5c31af7Sopenharmony_ci{ 3368e5c31af7Sopenharmony_ci /* Nothing to be done */ 3369e5c31af7Sopenharmony_ci} 3370e5c31af7Sopenharmony_ci 3371e5c31af7Sopenharmony_ci/** Execute test 3372e5c31af7Sopenharmony_ci * 3373e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 3374e5c31af7Sopenharmony_ci **/ 3375e5c31af7Sopenharmony_citcu::TestNode::IterateResult DispatchBindBuffersBaseTest::iterate() 3376e5c31af7Sopenharmony_ci{ 3377e5c31af7Sopenharmony_ci static const GLchar* cs = "#version 440 core\n" 3378e5c31af7Sopenharmony_ci "\n" 3379e5c31af7Sopenharmony_ci "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 3380e5c31af7Sopenharmony_ci "\n" 3381e5c31af7Sopenharmony_ci "UBO_LIST\n" 3382e5c31af7Sopenharmony_ci "layout (std140, binding = 0) buffer SSB {\n" 3383e5c31af7Sopenharmony_ci " vec4 sum;\n" 3384e5c31af7Sopenharmony_ci "} ssb;\n" 3385e5c31af7Sopenharmony_ci "\n" 3386e5c31af7Sopenharmony_ci "void main()\n" 3387e5c31af7Sopenharmony_ci "{\n" 3388e5c31af7Sopenharmony_ci " ssb.sum = SUM_LIST;\n" 3389e5c31af7Sopenharmony_ci "}\n" 3390e5c31af7Sopenharmony_ci "\n"; 3391e5c31af7Sopenharmony_ci 3392e5c31af7Sopenharmony_ci static const GLchar* ubo = "layout (std140, binding = XXX) uniform BXXX { vec4 data; } bXXX;"; 3393e5c31af7Sopenharmony_ci 3394e5c31af7Sopenharmony_ci static const GLintptr buffer_size = 4 * sizeof(GLfloat); 3395e5c31af7Sopenharmony_ci 3396e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 3397e5c31af7Sopenharmony_ci 3398e5c31af7Sopenharmony_ci bool test_result = true; 3399e5c31af7Sopenharmony_ci 3400e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 3401e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 3402e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 3403e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 3404e5c31af7Sopenharmony_ci 3405e5c31af7Sopenharmony_ci GLint max_buffers = 0; 3406e5c31af7Sopenharmony_ci GLfloat sum[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; 3407e5c31af7Sopenharmony_ci 3408e5c31af7Sopenharmony_ci /* Get max */ 3409e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_COMPUTE_UNIFORM_BLOCKS, &max_buffers); 3410e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3411e5c31af7Sopenharmony_ci 3412e5c31af7Sopenharmony_ci /* UBO */ 3413e5c31af7Sopenharmony_ci /* Storage */ 3414e5c31af7Sopenharmony_ci std::vector<Buffer> uni_buffer; 3415e5c31af7Sopenharmony_ci std::vector<GLuint> uni_buffer_ids; 3416e5c31af7Sopenharmony_ci 3417e5c31af7Sopenharmony_ci uni_buffer.resize(max_buffers); 3418e5c31af7Sopenharmony_ci uni_buffer_ids.resize(max_buffers); 3419e5c31af7Sopenharmony_ci 3420e5c31af7Sopenharmony_ci /* Prepare buffers */ 3421e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_buffers; ++i) 3422e5c31af7Sopenharmony_ci { 3423e5c31af7Sopenharmony_ci const GLfloat data[4] = { 3424e5c31af7Sopenharmony_ci (GLfloat)(i * 4 + 0), (GLfloat)(i * 4 + 1), (GLfloat)(i * 4 + 2), (GLfloat)(i * 4 + 3), 3425e5c31af7Sopenharmony_ci }; 3426e5c31af7Sopenharmony_ci 3427e5c31af7Sopenharmony_ci sum[0] += data[0]; 3428e5c31af7Sopenharmony_ci sum[1] += data[1]; 3429e5c31af7Sopenharmony_ci sum[2] += data[2]; 3430e5c31af7Sopenharmony_ci sum[3] += data[3]; 3431e5c31af7Sopenharmony_ci 3432e5c31af7Sopenharmony_ci uni_buffer[i].InitData(m_context, GL_UNIFORM_BUFFER, GL_DYNAMIC_COPY, buffer_size, data); 3433e5c31af7Sopenharmony_ci 3434e5c31af7Sopenharmony_ci uni_buffer_ids[i] = uni_buffer[i].m_id; 3435e5c31af7Sopenharmony_ci } 3436e5c31af7Sopenharmony_ci 3437e5c31af7Sopenharmony_ci gl.bindBuffersBase(GL_UNIFORM_BUFFER, 0 /* first */, max_buffers /* count */, &uni_buffer_ids[0]); 3438e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersBase"); 3439e5c31af7Sopenharmony_ci 3440e5c31af7Sopenharmony_ci /* SSBO */ 3441e5c31af7Sopenharmony_ci Buffer ssb_buffer; 3442e5c31af7Sopenharmony_ci ssb_buffer.InitData(m_context, GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, buffer_size, 0 /* data */); 3443e5c31af7Sopenharmony_ci 3444e5c31af7Sopenharmony_ci ssb_buffer.BindBase(0); 3445e5c31af7Sopenharmony_ci 3446e5c31af7Sopenharmony_ci /* Prepare program */ 3447e5c31af7Sopenharmony_ci size_t ubo_position = 0; 3448e5c31af7Sopenharmony_ci size_t sum_position = 0; 3449e5c31af7Sopenharmony_ci std::string cs_source = cs; 3450e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_buffers; ++i) 3451e5c31af7Sopenharmony_ci { 3452e5c31af7Sopenharmony_ci size_t ubo_start_position = ubo_position; 3453e5c31af7Sopenharmony_ci size_t sum_start_position = sum_position; 3454e5c31af7Sopenharmony_ci 3455e5c31af7Sopenharmony_ci GLchar index[16]; 3456e5c31af7Sopenharmony_ci 3457e5c31af7Sopenharmony_ci sprintf(index, "%d", i); 3458e5c31af7Sopenharmony_ci 3459e5c31af7Sopenharmony_ci /* Add entry to ubo list */ 3460e5c31af7Sopenharmony_ci replaceToken("UBO_LIST", ubo_position, "UBO\nUBO_LIST", cs_source); 3461e5c31af7Sopenharmony_ci ubo_position = ubo_start_position; 3462e5c31af7Sopenharmony_ci 3463e5c31af7Sopenharmony_ci replaceToken("UBO", ubo_position, ubo, cs_source); 3464e5c31af7Sopenharmony_ci ubo_position = ubo_start_position; 3465e5c31af7Sopenharmony_ci 3466e5c31af7Sopenharmony_ci replaceToken("XXX", ubo_position, index, cs_source); 3467e5c31af7Sopenharmony_ci replaceToken("XXX", ubo_position, index, cs_source); 3468e5c31af7Sopenharmony_ci replaceToken("XXX", ubo_position, index, cs_source); 3469e5c31af7Sopenharmony_ci 3470e5c31af7Sopenharmony_ci /* Add entry to sum list */ 3471e5c31af7Sopenharmony_ci replaceToken("SUM_LIST", sum_position, "bXXX.data + SUM_LIST", cs_source); 3472e5c31af7Sopenharmony_ci sum_position = sum_start_position; 3473e5c31af7Sopenharmony_ci 3474e5c31af7Sopenharmony_ci replaceToken("XXX", sum_position, index, cs_source); 3475e5c31af7Sopenharmony_ci } 3476e5c31af7Sopenharmony_ci 3477e5c31af7Sopenharmony_ci /* Remove token for lists */ 3478e5c31af7Sopenharmony_ci replaceToken(" + SUM_LIST", sum_position, "", cs_source); 3479e5c31af7Sopenharmony_ci replaceToken("UBO_LIST", ubo_position, "", cs_source); 3480e5c31af7Sopenharmony_ci 3481e5c31af7Sopenharmony_ci Program program(m_context); 3482e5c31af7Sopenharmony_ci program.Init(cs_source.c_str(), "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */); 3483e5c31af7Sopenharmony_ci 3484e5c31af7Sopenharmony_ci program.Use(); 3485e5c31af7Sopenharmony_ci 3486e5c31af7Sopenharmony_ci gl.dispatchCompute(1, 1, 1); 3487e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute"); 3488e5c31af7Sopenharmony_ci 3489e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_ALL_BARRIER_BITS); 3490e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier"); 3491e5c31af7Sopenharmony_ci 3492e5c31af7Sopenharmony_ci GLfloat* result = (GLfloat*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); 3493e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 3494e5c31af7Sopenharmony_ci 3495e5c31af7Sopenharmony_ci if (0 != memcmp(result, sum, 4 * sizeof(GLfloat))) 3496e5c31af7Sopenharmony_ci { 3497e5c31af7Sopenharmony_ci test_result = false; 3498e5c31af7Sopenharmony_ci } 3499e5c31af7Sopenharmony_ci 3500e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 3501e5c31af7Sopenharmony_ci gl.getError(); /* Ignore error */ 3502e5c31af7Sopenharmony_ci 3503e5c31af7Sopenharmony_ci /* Set result */ 3504e5c31af7Sopenharmony_ci if (true == test_result) 3505e5c31af7Sopenharmony_ci { 3506e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3507e5c31af7Sopenharmony_ci } 3508e5c31af7Sopenharmony_ci else 3509e5c31af7Sopenharmony_ci { 3510e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3511e5c31af7Sopenharmony_ci } 3512e5c31af7Sopenharmony_ci 3513e5c31af7Sopenharmony_ci /* Done */ 3514e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 3515e5c31af7Sopenharmony_ci} 3516e5c31af7Sopenharmony_ci 3517e5c31af7Sopenharmony_ci/** Constructor 3518e5c31af7Sopenharmony_ci * 3519e5c31af7Sopenharmony_ci * @param context Test context 3520e5c31af7Sopenharmony_ci **/ 3521e5c31af7Sopenharmony_ciDispatchBindBuffersRangeTest::DispatchBindBuffersRangeTest(deqp::Context& context) 3522e5c31af7Sopenharmony_ci : TestCase(context, "dispatch_bind_buffers_range", "Tests BindBuffersRange with dispatch command") 3523e5c31af7Sopenharmony_ci{ 3524e5c31af7Sopenharmony_ci /* Nothing to be done */ 3525e5c31af7Sopenharmony_ci} 3526e5c31af7Sopenharmony_ci 3527e5c31af7Sopenharmony_ci/** Execute test 3528e5c31af7Sopenharmony_ci * 3529e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 3530e5c31af7Sopenharmony_ci **/ 3531e5c31af7Sopenharmony_citcu::TestNode::IterateResult DispatchBindBuffersRangeTest::iterate() 3532e5c31af7Sopenharmony_ci{ 3533e5c31af7Sopenharmony_ci static const GLchar* cs = "#version 440 core\n" 3534e5c31af7Sopenharmony_ci "\n" 3535e5c31af7Sopenharmony_ci "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 3536e5c31af7Sopenharmony_ci "\n" 3537e5c31af7Sopenharmony_ci "layout (std140, binding = 0) uniform B0 { int data; } b0;" 3538e5c31af7Sopenharmony_ci "layout (std140, binding = 1) uniform B1 { int data; } b1;" 3539e5c31af7Sopenharmony_ci "layout (std140, binding = 2) uniform B2 { int data; } b2;" 3540e5c31af7Sopenharmony_ci "layout (std140, binding = 3) uniform B3 { int data; } b3;" 3541e5c31af7Sopenharmony_ci "\n" 3542e5c31af7Sopenharmony_ci "layout (std140, binding = 0) buffer SSB {\n" 3543e5c31af7Sopenharmony_ci " int sum;\n" 3544e5c31af7Sopenharmony_ci "} ssb;\n" 3545e5c31af7Sopenharmony_ci "\n" 3546e5c31af7Sopenharmony_ci "void main()\n" 3547e5c31af7Sopenharmony_ci "{\n" 3548e5c31af7Sopenharmony_ci " //ssb.sum = b1.data;// + b1.data + b2.data + b3.data;\n" 3549e5c31af7Sopenharmony_ci " ssb.sum = b0.data + b1.data + b2.data + b3.data;\n" 3550e5c31af7Sopenharmony_ci "}\n" 3551e5c31af7Sopenharmony_ci "\n"; 3552e5c31af7Sopenharmony_ci 3553e5c31af7Sopenharmony_ci static const GLint data[] = { 0x00010001, 0x01000100 }; 3554e5c31af7Sopenharmony_ci static const size_t n_buffers = 4; 3555e5c31af7Sopenharmony_ci static const GLint sum = 0x02020202; 3556e5c31af7Sopenharmony_ci 3557e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 3558e5c31af7Sopenharmony_ci 3559e5c31af7Sopenharmony_ci bool test_result = true; 3560e5c31af7Sopenharmony_ci 3561e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 3562e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 3563e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 3564e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 3565e5c31af7Sopenharmony_ci 3566e5c31af7Sopenharmony_ci /* UBO */ 3567e5c31af7Sopenharmony_ci GLint offset_alignment = 0; 3568e5c31af7Sopenharmony_ci 3569e5c31af7Sopenharmony_ci gl.getIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &offset_alignment); 3570e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3571e5c31af7Sopenharmony_ci 3572e5c31af7Sopenharmony_ci /* Storage */ 3573e5c31af7Sopenharmony_ci Buffer uni_buffer; 3574e5c31af7Sopenharmony_ci GLuint uni_buffer_ids[n_buffers]; 3575e5c31af7Sopenharmony_ci std::vector<GLubyte> uni_data; 3576e5c31af7Sopenharmony_ci GLintptr uni_offsets[n_buffers]; 3577e5c31af7Sopenharmony_ci GLintptr uni_sizes[n_buffers]; 3578e5c31af7Sopenharmony_ci 3579e5c31af7Sopenharmony_ci const size_t buffer_size = (n_buffers - 1) * offset_alignment + sizeof(GLint); 3580e5c31af7Sopenharmony_ci uni_data.resize(buffer_size); 3581e5c31af7Sopenharmony_ci 3582e5c31af7Sopenharmony_ci for (size_t i = 0; i < buffer_size; ++i) 3583e5c31af7Sopenharmony_ci { 3584e5c31af7Sopenharmony_ci uni_data[i] = 0xaa; 3585e5c31af7Sopenharmony_ci } 3586e5c31af7Sopenharmony_ci 3587e5c31af7Sopenharmony_ci for (size_t i = 0; i < n_buffers; ++i) 3588e5c31af7Sopenharmony_ci { 3589e5c31af7Sopenharmony_ci void* dst = &uni_data[i * offset_alignment]; 3590e5c31af7Sopenharmony_ci const void* src = &data[(i % 2)]; 3591e5c31af7Sopenharmony_ci 3592e5c31af7Sopenharmony_ci memcpy(dst, src, sizeof(GLint)); 3593e5c31af7Sopenharmony_ci } 3594e5c31af7Sopenharmony_ci 3595e5c31af7Sopenharmony_ci uni_buffer.InitData(m_context, GL_UNIFORM_BUFFER, GL_DYNAMIC_COPY, buffer_size, &uni_data[0]); 3596e5c31af7Sopenharmony_ci 3597e5c31af7Sopenharmony_ci for (size_t i = 0; i < n_buffers; ++i) 3598e5c31af7Sopenharmony_ci { 3599e5c31af7Sopenharmony_ci uni_buffer_ids[i] = uni_buffer.m_id; 3600e5c31af7Sopenharmony_ci uni_offsets[i] = i * offset_alignment; 3601e5c31af7Sopenharmony_ci uni_sizes[i] = sizeof(GLint); 3602e5c31af7Sopenharmony_ci } 3603e5c31af7Sopenharmony_ci 3604e5c31af7Sopenharmony_ci gl.bindBuffersRange(GL_UNIFORM_BUFFER, 0 /* first */, n_buffers /* count */, &uni_buffer_ids[0], &uni_offsets[0], 3605e5c31af7Sopenharmony_ci &uni_sizes[0]); 3606e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffersRange"); 3607e5c31af7Sopenharmony_ci 3608e5c31af7Sopenharmony_ci /* SSBO */ 3609e5c31af7Sopenharmony_ci Buffer ssb_buffer; 3610e5c31af7Sopenharmony_ci ssb_buffer.InitData(m_context, GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, sizeof(GLint), 0 /* data */); 3611e5c31af7Sopenharmony_ci 3612e5c31af7Sopenharmony_ci ssb_buffer.BindBase(0); 3613e5c31af7Sopenharmony_ci 3614e5c31af7Sopenharmony_ci /* Prepare program */ 3615e5c31af7Sopenharmony_ci Program program(m_context); 3616e5c31af7Sopenharmony_ci program.Init(cs, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */); 3617e5c31af7Sopenharmony_ci 3618e5c31af7Sopenharmony_ci program.Use(); 3619e5c31af7Sopenharmony_ci 3620e5c31af7Sopenharmony_ci gl.dispatchCompute(1, 1, 1); 3621e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute"); 3622e5c31af7Sopenharmony_ci 3623e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_ALL_BARRIER_BITS); 3624e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier"); 3625e5c31af7Sopenharmony_ci 3626e5c31af7Sopenharmony_ci GLint* result = (GLint*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); 3627e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 3628e5c31af7Sopenharmony_ci 3629e5c31af7Sopenharmony_ci if (0 != memcmp(result, &sum, sizeof(sum))) 3630e5c31af7Sopenharmony_ci { 3631e5c31af7Sopenharmony_ci test_result = false; 3632e5c31af7Sopenharmony_ci } 3633e5c31af7Sopenharmony_ci 3634e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 3635e5c31af7Sopenharmony_ci gl.getError(); /* Ignore error */ 3636e5c31af7Sopenharmony_ci 3637e5c31af7Sopenharmony_ci /* Set result */ 3638e5c31af7Sopenharmony_ci if (true == test_result) 3639e5c31af7Sopenharmony_ci { 3640e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3641e5c31af7Sopenharmony_ci } 3642e5c31af7Sopenharmony_ci else 3643e5c31af7Sopenharmony_ci { 3644e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3645e5c31af7Sopenharmony_ci } 3646e5c31af7Sopenharmony_ci 3647e5c31af7Sopenharmony_ci /* Done */ 3648e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 3649e5c31af7Sopenharmony_ci} 3650e5c31af7Sopenharmony_ci 3651e5c31af7Sopenharmony_ci/** Constructor 3652e5c31af7Sopenharmony_ci * 3653e5c31af7Sopenharmony_ci * @param context Test context 3654e5c31af7Sopenharmony_ci **/ 3655e5c31af7Sopenharmony_ciDispatchBindTexturesTest::DispatchBindTexturesTest(deqp::Context& context) 3656e5c31af7Sopenharmony_ci : TestCase(context, "dispatch_bind_textures", "Tests BindTextures with dispatch command") 3657e5c31af7Sopenharmony_ci{ 3658e5c31af7Sopenharmony_ci /* Nothing to be done */ 3659e5c31af7Sopenharmony_ci} 3660e5c31af7Sopenharmony_ci 3661e5c31af7Sopenharmony_ci/** Execute test 3662e5c31af7Sopenharmony_ci * 3663e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 3664e5c31af7Sopenharmony_ci **/ 3665e5c31af7Sopenharmony_citcu::TestNode::IterateResult DispatchBindTexturesTest::iterate() 3666e5c31af7Sopenharmony_ci{ 3667e5c31af7Sopenharmony_ci static const GLchar* cs = "#version 440 core\n" 3668e5c31af7Sopenharmony_ci "\n" 3669e5c31af7Sopenharmony_ci "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 3670e5c31af7Sopenharmony_ci "\n" 3671e5c31af7Sopenharmony_ci "SAMPLER_LIST\n" 3672e5c31af7Sopenharmony_ci "layout (std140, binding = 0) buffer SSB {\n" 3673e5c31af7Sopenharmony_ci " uint sum;\n" 3674e5c31af7Sopenharmony_ci "} ssb;\n" 3675e5c31af7Sopenharmony_ci "\n" 3676e5c31af7Sopenharmony_ci "void main()\n" 3677e5c31af7Sopenharmony_ci "{\n" 3678e5c31af7Sopenharmony_ci " uvec4 sum = SUM_LIST;\n" 3679e5c31af7Sopenharmony_ci " ssb.sum = sum.r\n;" 3680e5c31af7Sopenharmony_ci "}\n" 3681e5c31af7Sopenharmony_ci "\n"; 3682e5c31af7Sopenharmony_ci 3683e5c31af7Sopenharmony_ci static const GLchar* sampler = "layout (location = XXX) uniform SAMPLER sXXX;"; 3684e5c31af7Sopenharmony_ci 3685e5c31af7Sopenharmony_ci static const GLchar* sampling[] = { 3686e5c31af7Sopenharmony_ci "texture(sXXX, COORDS)", "texture(sXXX, COORDS)", "texture(sXXX, COORDS)", "texture(sXXX, COORDS)", 3687e5c31af7Sopenharmony_ci "texture(sXXX, COORDS)", "texelFetch(sXXX, COORDS)", "texture(sXXX, COORDS)", "texture(sXXX, COORDS)", 3688e5c31af7Sopenharmony_ci "texture(sXXX, COORDS)", "texelFetch(sXXX, COORDS, 0)", "texelFetch(sXXX, COORDS, 0)" 3689e5c31af7Sopenharmony_ci }; 3690e5c31af7Sopenharmony_ci 3691e5c31af7Sopenharmony_ci static const GLchar* samplers[] = { "usampler1D", "usampler1DArray", "usampler2D", "usampler2DArray", 3692e5c31af7Sopenharmony_ci "usampler3D", "usamplerBuffer", "usamplerCube", "usamplerCubeArray", 3693e5c31af7Sopenharmony_ci "usampler2DRect", "usampler2DMS", "usampler2DMSArray" }; 3694e5c31af7Sopenharmony_ci 3695e5c31af7Sopenharmony_ci static const GLchar* coordinates[] = { 3696e5c31af7Sopenharmony_ci "0.5f", 3697e5c31af7Sopenharmony_ci "vec2(0.5f, 0.0f)", 3698e5c31af7Sopenharmony_ci "vec2(0.5f, 0.5f)", 3699e5c31af7Sopenharmony_ci "vec3(0.5f, 0.5f, 0.0f)", 3700e5c31af7Sopenharmony_ci "vec3(0.5f, 0.5f, 0.5f)", 3701e5c31af7Sopenharmony_ci "0", 3702e5c31af7Sopenharmony_ci "vec3(0.5f, 0.5f, 0.5f)", 3703e5c31af7Sopenharmony_ci "vec4(0.5f, 0.5f, 0.5f, 0.0f)", 3704e5c31af7Sopenharmony_ci "vec2(0.5f, 0.5f)", 3705e5c31af7Sopenharmony_ci "ivec2(0, 0)", 3706e5c31af7Sopenharmony_ci "ivec3(0, 0, 0)", 3707e5c31af7Sopenharmony_ci }; 3708e5c31af7Sopenharmony_ci 3709e5c31af7Sopenharmony_ci static const GLuint depth = 6; 3710e5c31af7Sopenharmony_ci static const GLuint height = 6; 3711e5c31af7Sopenharmony_ci static const GLuint width = 6; 3712e5c31af7Sopenharmony_ci 3713e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 3714e5c31af7Sopenharmony_ci 3715e5c31af7Sopenharmony_ci bool test_result = true; 3716e5c31af7Sopenharmony_ci 3717e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 3718e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 3719e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 3720e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 3721e5c31af7Sopenharmony_ci 3722e5c31af7Sopenharmony_ci bool cs_filled_textures = false; 3723e5c31af7Sopenharmony_ci 3724e5c31af7Sopenharmony_ci GLint max_textures = 0; 3725e5c31af7Sopenharmony_ci GLint max_image_samples = 0; 3726e5c31af7Sopenharmony_ci GLuint sum = 0; 3727e5c31af7Sopenharmony_ci 3728e5c31af7Sopenharmony_ci /* Get max */ 3729e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &max_textures); 3730e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3731e5c31af7Sopenharmony_ci 3732e5c31af7Sopenharmony_ci /* Check if load/store from multisampled images is supported */ 3733e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_IMAGE_SAMPLES, &max_image_samples); 3734e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3735e5c31af7Sopenharmony_ci 3736e5c31af7Sopenharmony_ci /* Textures */ 3737e5c31af7Sopenharmony_ci /* Storage */ 3738e5c31af7Sopenharmony_ci std::vector<Texture> texture; 3739e5c31af7Sopenharmony_ci std::vector<GLuint> texture_ids; 3740e5c31af7Sopenharmony_ci Buffer texture_buffer; 3741e5c31af7Sopenharmony_ci 3742e5c31af7Sopenharmony_ci texture.resize(max_textures); 3743e5c31af7Sopenharmony_ci texture_ids.resize(max_textures); 3744e5c31af7Sopenharmony_ci 3745e5c31af7Sopenharmony_ci /* Prepare */ 3746e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 3747e5c31af7Sopenharmony_ci { 3748e5c31af7Sopenharmony_ci GLenum target = getTarget(i); 3749e5c31af7Sopenharmony_ci if (target >= GL_TEXTURE_2D_MULTISAMPLE && max_image_samples < 2) 3750e5c31af7Sopenharmony_ci target = GL_TEXTURE_2D; 3751e5c31af7Sopenharmony_ci 3752e5c31af7Sopenharmony_ci GLuint data[width * height * depth]; 3753e5c31af7Sopenharmony_ci 3754e5c31af7Sopenharmony_ci for (GLuint j = 0; j < width * height * depth; ++j) 3755e5c31af7Sopenharmony_ci { 3756e5c31af7Sopenharmony_ci data[j] = i; 3757e5c31af7Sopenharmony_ci } 3758e5c31af7Sopenharmony_ci 3759e5c31af7Sopenharmony_ci sum += i; 3760e5c31af7Sopenharmony_ci 3761e5c31af7Sopenharmony_ci bool is_array = false; 3762e5c31af7Sopenharmony_ci 3763e5c31af7Sopenharmony_ci switch (target) 3764e5c31af7Sopenharmony_ci { 3765e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 3766e5c31af7Sopenharmony_ci is_array = true; 3767e5c31af7Sopenharmony_ci /* Intentional fallthrough */ 3768e5c31af7Sopenharmony_ci 3769e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 3770e5c31af7Sopenharmony_ci texture[i].InitStorage(m_context, target, 1, GL_R32UI, width, height, depth); 3771e5c31af7Sopenharmony_ci fillMSTexture(m_context, texture[i].m_id, i, is_array); 3772e5c31af7Sopenharmony_ci cs_filled_textures = true; 3773e5c31af7Sopenharmony_ci break; 3774e5c31af7Sopenharmony_ci 3775e5c31af7Sopenharmony_ci case GL_TEXTURE_BUFFER: 3776e5c31af7Sopenharmony_ci texture_buffer.InitData(m_context, GL_TEXTURE_BUFFER, GL_DYNAMIC_COPY, sizeof(data), data); 3777e5c31af7Sopenharmony_ci texture[i].InitBuffer(m_context, GL_R32UI, texture_buffer.m_id); 3778e5c31af7Sopenharmony_ci break; 3779e5c31af7Sopenharmony_ci 3780e5c31af7Sopenharmony_ci default: 3781e5c31af7Sopenharmony_ci texture[i].InitStorage(m_context, target, 1, GL_R32UI, width, height, depth); 3782e5c31af7Sopenharmony_ci Texture::Bind(gl, texture[i].m_id, target); 3783e5c31af7Sopenharmony_ci Texture::SubImage(gl, target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, 3784e5c31af7Sopenharmony_ci GL_RED_INTEGER, GL_UNSIGNED_INT, &data); 3785e5c31af7Sopenharmony_ci gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 3786e5c31af7Sopenharmony_ci gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 3787e5c31af7Sopenharmony_ci break; 3788e5c31af7Sopenharmony_ci } 3789e5c31af7Sopenharmony_ci 3790e5c31af7Sopenharmony_ci /* Clean */ 3791e5c31af7Sopenharmony_ci Texture::Bind(gl, 0, target); 3792e5c31af7Sopenharmony_ci 3793e5c31af7Sopenharmony_ci texture_ids[i] = texture[i].m_id; 3794e5c31af7Sopenharmony_ci } 3795e5c31af7Sopenharmony_ci 3796e5c31af7Sopenharmony_ci /* Make sure fillMSTexture affects are seen in next compute dispatch */ 3797e5c31af7Sopenharmony_ci if (cs_filled_textures) 3798e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 3799e5c31af7Sopenharmony_ci 3800e5c31af7Sopenharmony_ci gl.bindTextures(0 /* first */, max_textures /* count */, &texture_ids[0]); 3801e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures"); 3802e5c31af7Sopenharmony_ci 3803e5c31af7Sopenharmony_ci /* SSBO */ 3804e5c31af7Sopenharmony_ci Buffer ssb_buffer; 3805e5c31af7Sopenharmony_ci ssb_buffer.InitData(m_context, GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, sizeof(GLuint), 0 /* data */); 3806e5c31af7Sopenharmony_ci 3807e5c31af7Sopenharmony_ci ssb_buffer.BindBase(0); 3808e5c31af7Sopenharmony_ci 3809e5c31af7Sopenharmony_ci /* Prepare program */ 3810e5c31af7Sopenharmony_ci size_t sam_position = 0; 3811e5c31af7Sopenharmony_ci size_t sum_position = 0; 3812e5c31af7Sopenharmony_ci std::string cs_source = cs; 3813e5c31af7Sopenharmony_ci GLint max_target_index = (GLint)(max_image_samples >= 2 ? s_n_texture_tragets : s_n_texture_tragets - 2); 3814e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 3815e5c31af7Sopenharmony_ci { 3816e5c31af7Sopenharmony_ci size_t sam_start_position = sam_position; 3817e5c31af7Sopenharmony_ci size_t sum_start_position = sum_position; 3818e5c31af7Sopenharmony_ci 3819e5c31af7Sopenharmony_ci GLchar index[16]; 3820e5c31af7Sopenharmony_ci 3821e5c31af7Sopenharmony_ci sprintf(index, "%d", i); 3822e5c31af7Sopenharmony_ci 3823e5c31af7Sopenharmony_ci const GLchar* coords = 0; 3824e5c31af7Sopenharmony_ci const GLchar* sampler_type = 0; 3825e5c31af7Sopenharmony_ci const GLchar* sampling_code = 0; 3826e5c31af7Sopenharmony_ci 3827e5c31af7Sopenharmony_ci if (i < max_target_index) 3828e5c31af7Sopenharmony_ci { 3829e5c31af7Sopenharmony_ci coords = coordinates[i]; 3830e5c31af7Sopenharmony_ci sampler_type = samplers[i]; 3831e5c31af7Sopenharmony_ci sampling_code = sampling[i]; 3832e5c31af7Sopenharmony_ci } 3833e5c31af7Sopenharmony_ci else 3834e5c31af7Sopenharmony_ci { 3835e5c31af7Sopenharmony_ci coords = coordinates[2]; /* vec2(0.5f, 0.5f) */ 3836e5c31af7Sopenharmony_ci sampler_type = samplers[2]; /* usampler2D */ 3837e5c31af7Sopenharmony_ci sampling_code = sampling[2]; /* texture(sXXX, COORDS) */ 3838e5c31af7Sopenharmony_ci } 3839e5c31af7Sopenharmony_ci 3840e5c31af7Sopenharmony_ci /* Add entry to ubo list */ 3841e5c31af7Sopenharmony_ci replaceToken("SAMPLER_LIST", sam_position, "SAMPLER\nSAMPLER_LIST", cs_source); 3842e5c31af7Sopenharmony_ci sam_position = sam_start_position; 3843e5c31af7Sopenharmony_ci 3844e5c31af7Sopenharmony_ci replaceToken("SAMPLER", sam_position, sampler, cs_source); 3845e5c31af7Sopenharmony_ci sam_position = sam_start_position; 3846e5c31af7Sopenharmony_ci 3847e5c31af7Sopenharmony_ci replaceToken("XXX", sam_position, index, cs_source); 3848e5c31af7Sopenharmony_ci replaceToken("SAMPLER", sam_position, sampler_type, cs_source); 3849e5c31af7Sopenharmony_ci replaceToken("XXX", sam_position, index, cs_source); 3850e5c31af7Sopenharmony_ci 3851e5c31af7Sopenharmony_ci /* Add entry to sum list */ 3852e5c31af7Sopenharmony_ci replaceToken("SUM_LIST", sum_position, "SAMPLING + SUM_LIST", cs_source); 3853e5c31af7Sopenharmony_ci sum_position = sum_start_position; 3854e5c31af7Sopenharmony_ci 3855e5c31af7Sopenharmony_ci replaceToken("SAMPLING", sum_position, sampling_code, cs_source); 3856e5c31af7Sopenharmony_ci sum_position = sum_start_position; 3857e5c31af7Sopenharmony_ci 3858e5c31af7Sopenharmony_ci replaceToken("XXX", sum_position, index, cs_source); 3859e5c31af7Sopenharmony_ci replaceToken("COORDS", sum_position, coords, cs_source); 3860e5c31af7Sopenharmony_ci } 3861e5c31af7Sopenharmony_ci 3862e5c31af7Sopenharmony_ci /* Remove token for lists */ 3863e5c31af7Sopenharmony_ci replaceToken(" + SUM_LIST", sum_position, "", cs_source); 3864e5c31af7Sopenharmony_ci replaceToken("SAMPLER_LIST", sam_position, "", cs_source); 3865e5c31af7Sopenharmony_ci 3866e5c31af7Sopenharmony_ci Program program(m_context); 3867e5c31af7Sopenharmony_ci program.Init(cs_source.c_str(), "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */); 3868e5c31af7Sopenharmony_ci 3869e5c31af7Sopenharmony_ci program.Use(); 3870e5c31af7Sopenharmony_ci 3871e5c31af7Sopenharmony_ci /* Set samplers */ 3872e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 3873e5c31af7Sopenharmony_ci { 3874e5c31af7Sopenharmony_ci gl.uniform1i(i, i); 3875e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i"); 3876e5c31af7Sopenharmony_ci } 3877e5c31af7Sopenharmony_ci 3878e5c31af7Sopenharmony_ci gl.dispatchCompute(1, 1, 1); 3879e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute"); 3880e5c31af7Sopenharmony_ci 3881e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_ALL_BARRIER_BITS); 3882e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier"); 3883e5c31af7Sopenharmony_ci 3884e5c31af7Sopenharmony_ci GLuint* result = (GLuint*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); 3885e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 3886e5c31af7Sopenharmony_ci 3887e5c31af7Sopenharmony_ci if (0 != memcmp(result, &sum, sizeof(sum))) 3888e5c31af7Sopenharmony_ci { 3889e5c31af7Sopenharmony_ci test_result = false; 3890e5c31af7Sopenharmony_ci } 3891e5c31af7Sopenharmony_ci 3892e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 3893e5c31af7Sopenharmony_ci gl.getError(); /* Ignore error */ 3894e5c31af7Sopenharmony_ci 3895e5c31af7Sopenharmony_ci /* Set result */ 3896e5c31af7Sopenharmony_ci if (true == test_result) 3897e5c31af7Sopenharmony_ci { 3898e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3899e5c31af7Sopenharmony_ci } 3900e5c31af7Sopenharmony_ci else 3901e5c31af7Sopenharmony_ci { 3902e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3903e5c31af7Sopenharmony_ci } 3904e5c31af7Sopenharmony_ci 3905e5c31af7Sopenharmony_ci /* Done */ 3906e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 3907e5c31af7Sopenharmony_ci} 3908e5c31af7Sopenharmony_ci 3909e5c31af7Sopenharmony_ci/** Constructor 3910e5c31af7Sopenharmony_ci * 3911e5c31af7Sopenharmony_ci * @param context Test context 3912e5c31af7Sopenharmony_ci **/ 3913e5c31af7Sopenharmony_ciDispatchBindImageTexturesTest::DispatchBindImageTexturesTest(deqp::Context& context) 3914e5c31af7Sopenharmony_ci : TestCase(context, "dispatch_bind_image_textures", "Tests BindImageTextures with dispatch command") 3915e5c31af7Sopenharmony_ci{ 3916e5c31af7Sopenharmony_ci /* Nothing to be done */ 3917e5c31af7Sopenharmony_ci} 3918e5c31af7Sopenharmony_ci 3919e5c31af7Sopenharmony_ci/** Execute test 3920e5c31af7Sopenharmony_ci * 3921e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 3922e5c31af7Sopenharmony_ci **/ 3923e5c31af7Sopenharmony_citcu::TestNode::IterateResult DispatchBindImageTexturesTest::iterate() 3924e5c31af7Sopenharmony_ci{ 3925e5c31af7Sopenharmony_ci static const GLchar* cs = "#version 440 core\n" 3926e5c31af7Sopenharmony_ci "\n" 3927e5c31af7Sopenharmony_ci "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 3928e5c31af7Sopenharmony_ci "\n" 3929e5c31af7Sopenharmony_ci "IMAGE_LIST\n" 3930e5c31af7Sopenharmony_ci "layout (std140, binding = 0) buffer SSB {\n" 3931e5c31af7Sopenharmony_ci " uint sum;\n" 3932e5c31af7Sopenharmony_ci "} ssb;\n" 3933e5c31af7Sopenharmony_ci "\n" 3934e5c31af7Sopenharmony_ci "void main()\n" 3935e5c31af7Sopenharmony_ci "{\n" 3936e5c31af7Sopenharmony_ci " uvec4 sum = SUM_LIST;\n" 3937e5c31af7Sopenharmony_ci " ssb.sum = sum.r\n;" 3938e5c31af7Sopenharmony_ci "}\n" 3939e5c31af7Sopenharmony_ci "\n"; 3940e5c31af7Sopenharmony_ci 3941e5c31af7Sopenharmony_ci static const GLchar* image = "layout (location = XXX, r32ui) readonly uniform IMAGE iXXX;"; 3942e5c31af7Sopenharmony_ci 3943e5c31af7Sopenharmony_ci static const GLchar* loading[] = { 3944e5c31af7Sopenharmony_ci "imageLoad(iXXX, COORDS)", "imageLoad(iXXX, COORDS)", "imageLoad(iXXX, COORDS)", "imageLoad(iXXX, COORDS)", 3945e5c31af7Sopenharmony_ci "imageLoad(iXXX, COORDS)", "imageLoad(iXXX, COORDS)", "imageLoad(iXXX, COORDS)", "imageLoad(iXXX, COORDS)", 3946e5c31af7Sopenharmony_ci "imageLoad(iXXX, COORDS)", "imageLoad(iXXX, COORDS, 0)", "imageLoad(iXXX, COORDS, 0)" 3947e5c31af7Sopenharmony_ci }; 3948e5c31af7Sopenharmony_ci 3949e5c31af7Sopenharmony_ci static const GLchar* images[] = { "uimage1D", "uimage1DArray", "uimage2D", "uimage2DArray", 3950e5c31af7Sopenharmony_ci "uimage3D", "uimageBuffer", "uimageCube", "uimageCubeArray", 3951e5c31af7Sopenharmony_ci "uimage2DRect", "uimage2DMS", "uimage2DMSArray" }; 3952e5c31af7Sopenharmony_ci 3953e5c31af7Sopenharmony_ci static const GLchar* coordinates[] = { 3954e5c31af7Sopenharmony_ci "0", 3955e5c31af7Sopenharmony_ci "ivec2(0, 0)", 3956e5c31af7Sopenharmony_ci "ivec2(0, 0)", 3957e5c31af7Sopenharmony_ci "ivec3(0, 0, 0)", 3958e5c31af7Sopenharmony_ci "ivec3(0, 0, 0)", 3959e5c31af7Sopenharmony_ci "0", 3960e5c31af7Sopenharmony_ci "ivec3(0, 0, 0)", 3961e5c31af7Sopenharmony_ci "ivec3(0, 0, 0)", 3962e5c31af7Sopenharmony_ci "ivec2(0, 0)", 3963e5c31af7Sopenharmony_ci "ivec2(0, 0)", 3964e5c31af7Sopenharmony_ci "ivec3(0, 0, 0)", 3965e5c31af7Sopenharmony_ci }; 3966e5c31af7Sopenharmony_ci 3967e5c31af7Sopenharmony_ci static const GLuint depth = 6; 3968e5c31af7Sopenharmony_ci static const GLuint height = 6; 3969e5c31af7Sopenharmony_ci static const GLuint width = 6; 3970e5c31af7Sopenharmony_ci 3971e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 3972e5c31af7Sopenharmony_ci 3973e5c31af7Sopenharmony_ci bool test_result = true; 3974e5c31af7Sopenharmony_ci 3975e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 3976e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 3977e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 3978e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 3979e5c31af7Sopenharmony_ci 3980e5c31af7Sopenharmony_ci bool cs_filled_textures = false; 3981e5c31af7Sopenharmony_ci 3982e5c31af7Sopenharmony_ci GLint max_textures = 0; 3983e5c31af7Sopenharmony_ci GLint max_image_samples = 0; 3984e5c31af7Sopenharmony_ci GLuint sum = 0; 3985e5c31af7Sopenharmony_ci 3986e5c31af7Sopenharmony_ci /* Get max */ 3987e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_COMPUTE_IMAGE_UNIFORMS, &max_textures); 3988e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3989e5c31af7Sopenharmony_ci 3990e5c31af7Sopenharmony_ci /* Check if load/store from multisampled images is supported */ 3991e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_IMAGE_SAMPLES, &max_image_samples); 3992e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 3993e5c31af7Sopenharmony_ci 3994e5c31af7Sopenharmony_ci /* Textures */ 3995e5c31af7Sopenharmony_ci /* Storage */ 3996e5c31af7Sopenharmony_ci std::vector<Texture> texture; 3997e5c31af7Sopenharmony_ci std::vector<GLuint> texture_ids; 3998e5c31af7Sopenharmony_ci Buffer texture_buffer; 3999e5c31af7Sopenharmony_ci 4000e5c31af7Sopenharmony_ci texture.resize(max_textures); 4001e5c31af7Sopenharmony_ci texture_ids.resize(max_textures); 4002e5c31af7Sopenharmony_ci 4003e5c31af7Sopenharmony_ci /* Prepare */ 4004e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 4005e5c31af7Sopenharmony_ci { 4006e5c31af7Sopenharmony_ci GLenum target = getTarget(i); 4007e5c31af7Sopenharmony_ci if (target >= GL_TEXTURE_2D_MULTISAMPLE && max_image_samples == 0) 4008e5c31af7Sopenharmony_ci target = GL_TEXTURE_2D; 4009e5c31af7Sopenharmony_ci 4010e5c31af7Sopenharmony_ci GLuint data[width * height * depth]; 4011e5c31af7Sopenharmony_ci 4012e5c31af7Sopenharmony_ci for (GLuint j = 0; j < width * height * depth; ++j) 4013e5c31af7Sopenharmony_ci { 4014e5c31af7Sopenharmony_ci data[j] = i; 4015e5c31af7Sopenharmony_ci } 4016e5c31af7Sopenharmony_ci 4017e5c31af7Sopenharmony_ci sum += i; 4018e5c31af7Sopenharmony_ci 4019e5c31af7Sopenharmony_ci bool is_array = false; 4020e5c31af7Sopenharmony_ci 4021e5c31af7Sopenharmony_ci switch (target) 4022e5c31af7Sopenharmony_ci { 4023e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 4024e5c31af7Sopenharmony_ci is_array = true; 4025e5c31af7Sopenharmony_ci /* Intentional fallthrough */ 4026e5c31af7Sopenharmony_ci 4027e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 4028e5c31af7Sopenharmony_ci texture[i].InitStorage(m_context, target, 1, GL_R32UI, width, height, depth); 4029e5c31af7Sopenharmony_ci fillMSTexture(m_context, texture[i].m_id, i, is_array); 4030e5c31af7Sopenharmony_ci cs_filled_textures = true; 4031e5c31af7Sopenharmony_ci break; 4032e5c31af7Sopenharmony_ci 4033e5c31af7Sopenharmony_ci case GL_TEXTURE_BUFFER: 4034e5c31af7Sopenharmony_ci texture_buffer.InitData(m_context, GL_TEXTURE_BUFFER, GL_DYNAMIC_COPY, sizeof(data), data); 4035e5c31af7Sopenharmony_ci texture[i].InitBuffer(m_context, GL_R32UI, texture_buffer.m_id); 4036e5c31af7Sopenharmony_ci break; 4037e5c31af7Sopenharmony_ci 4038e5c31af7Sopenharmony_ci default: 4039e5c31af7Sopenharmony_ci texture[i].InitStorage(m_context, target, 1, GL_R32UI, width, height, depth); 4040e5c31af7Sopenharmony_ci Texture::Bind(gl, texture[i].m_id, target); 4041e5c31af7Sopenharmony_ci Texture::SubImage(gl, target, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, 4042e5c31af7Sopenharmony_ci GL_RED_INTEGER, GL_UNSIGNED_INT, &data); 4043e5c31af7Sopenharmony_ci break; 4044e5c31af7Sopenharmony_ci } 4045e5c31af7Sopenharmony_ci 4046e5c31af7Sopenharmony_ci /* Clean */ 4047e5c31af7Sopenharmony_ci Texture::Bind(gl, 0, target); 4048e5c31af7Sopenharmony_ci 4049e5c31af7Sopenharmony_ci texture_ids[i] = texture[i].m_id; 4050e5c31af7Sopenharmony_ci } 4051e5c31af7Sopenharmony_ci 4052e5c31af7Sopenharmony_ci /* Make sure fillMSTexture affects are seen in next compute dispatch */ 4053e5c31af7Sopenharmony_ci if (cs_filled_textures) 4054e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); 4055e5c31af7Sopenharmony_ci 4056e5c31af7Sopenharmony_ci gl.bindImageTextures(0 /* first */, max_textures /* count */, &texture_ids[0]); 4057e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindImageTextures"); 4058e5c31af7Sopenharmony_ci 4059e5c31af7Sopenharmony_ci /* SSBO */ 4060e5c31af7Sopenharmony_ci Buffer ssb_buffer; 4061e5c31af7Sopenharmony_ci ssb_buffer.InitData(m_context, GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, sizeof(GLuint), 0 /* data */); 4062e5c31af7Sopenharmony_ci 4063e5c31af7Sopenharmony_ci ssb_buffer.BindBase(0); 4064e5c31af7Sopenharmony_ci 4065e5c31af7Sopenharmony_ci /* Prepare program */ 4066e5c31af7Sopenharmony_ci size_t load_position = 0; 4067e5c31af7Sopenharmony_ci size_t sum_position = 0; 4068e5c31af7Sopenharmony_ci std::string cs_source = cs; 4069e5c31af7Sopenharmony_ci GLint max_target_index = (GLint)(max_image_samples > 0 ? s_n_texture_tragets : s_n_texture_tragets - 2); 4070e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 4071e5c31af7Sopenharmony_ci { 4072e5c31af7Sopenharmony_ci size_t load_start_position = load_position; 4073e5c31af7Sopenharmony_ci size_t sum_start_position = sum_position; 4074e5c31af7Sopenharmony_ci 4075e5c31af7Sopenharmony_ci GLchar index[16]; 4076e5c31af7Sopenharmony_ci 4077e5c31af7Sopenharmony_ci sprintf(index, "%d", i); 4078e5c31af7Sopenharmony_ci 4079e5c31af7Sopenharmony_ci const GLchar* coords = 0; 4080e5c31af7Sopenharmony_ci const GLchar* image_type = 0; 4081e5c31af7Sopenharmony_ci const GLchar* loading_code = 0; 4082e5c31af7Sopenharmony_ci 4083e5c31af7Sopenharmony_ci if (i < max_target_index) 4084e5c31af7Sopenharmony_ci { 4085e5c31af7Sopenharmony_ci coords = coordinates[i]; 4086e5c31af7Sopenharmony_ci image_type = images[i]; 4087e5c31af7Sopenharmony_ci loading_code = loading[i]; 4088e5c31af7Sopenharmony_ci } 4089e5c31af7Sopenharmony_ci else 4090e5c31af7Sopenharmony_ci { 4091e5c31af7Sopenharmony_ci coords = coordinates[2]; /* vec2(0.5f, 0.5f) */ 4092e5c31af7Sopenharmony_ci image_type = images[2]; /* usampler2D */ 4093e5c31af7Sopenharmony_ci loading_code = loading[2]; /* texture(sXXX, COORDS) */ 4094e5c31af7Sopenharmony_ci } 4095e5c31af7Sopenharmony_ci 4096e5c31af7Sopenharmony_ci /* Add entry to ubo list */ 4097e5c31af7Sopenharmony_ci replaceToken("IMAGE_LIST", load_position, "IMAGE\nIMAGE_LIST", cs_source); 4098e5c31af7Sopenharmony_ci load_position = load_start_position; 4099e5c31af7Sopenharmony_ci 4100e5c31af7Sopenharmony_ci replaceToken("IMAGE", load_position, image, cs_source); 4101e5c31af7Sopenharmony_ci load_position = load_start_position; 4102e5c31af7Sopenharmony_ci 4103e5c31af7Sopenharmony_ci replaceToken("XXX", load_position, index, cs_source); 4104e5c31af7Sopenharmony_ci replaceToken("IMAGE", load_position, image_type, cs_source); 4105e5c31af7Sopenharmony_ci replaceToken("XXX", load_position, index, cs_source); 4106e5c31af7Sopenharmony_ci 4107e5c31af7Sopenharmony_ci /* Add entry to sum list */ 4108e5c31af7Sopenharmony_ci replaceToken("SUM_LIST", sum_position, "LOADING + SUM_LIST", cs_source); 4109e5c31af7Sopenharmony_ci sum_position = sum_start_position; 4110e5c31af7Sopenharmony_ci 4111e5c31af7Sopenharmony_ci replaceToken("LOADING", sum_position, loading_code, cs_source); 4112e5c31af7Sopenharmony_ci sum_position = sum_start_position; 4113e5c31af7Sopenharmony_ci 4114e5c31af7Sopenharmony_ci replaceToken("XXX", sum_position, index, cs_source); 4115e5c31af7Sopenharmony_ci replaceToken("COORDS", sum_position, coords, cs_source); 4116e5c31af7Sopenharmony_ci } 4117e5c31af7Sopenharmony_ci 4118e5c31af7Sopenharmony_ci /* Remove token for lists */ 4119e5c31af7Sopenharmony_ci replaceToken(" + SUM_LIST", sum_position, "", cs_source); 4120e5c31af7Sopenharmony_ci replaceToken("IMAGE_LIST", load_position, "", cs_source); 4121e5c31af7Sopenharmony_ci 4122e5c31af7Sopenharmony_ci Program program(m_context); 4123e5c31af7Sopenharmony_ci program.Init(cs_source.c_str(), "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */); 4124e5c31af7Sopenharmony_ci 4125e5c31af7Sopenharmony_ci program.Use(); 4126e5c31af7Sopenharmony_ci 4127e5c31af7Sopenharmony_ci /* Set images */ 4128e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 4129e5c31af7Sopenharmony_ci { 4130e5c31af7Sopenharmony_ci gl.uniform1i(i, i); 4131e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i"); 4132e5c31af7Sopenharmony_ci } 4133e5c31af7Sopenharmony_ci 4134e5c31af7Sopenharmony_ci gl.dispatchCompute(1, 1, 1); 4135e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute"); 4136e5c31af7Sopenharmony_ci 4137e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_ALL_BARRIER_BITS); 4138e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier"); 4139e5c31af7Sopenharmony_ci 4140e5c31af7Sopenharmony_ci GLuint* result = (GLuint*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); 4141e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 4142e5c31af7Sopenharmony_ci 4143e5c31af7Sopenharmony_ci if (0 != memcmp(result, &sum, sizeof(sum))) 4144e5c31af7Sopenharmony_ci { 4145e5c31af7Sopenharmony_ci test_result = false; 4146e5c31af7Sopenharmony_ci } 4147e5c31af7Sopenharmony_ci 4148e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 4149e5c31af7Sopenharmony_ci gl.getError(); /* Ignore error */ 4150e5c31af7Sopenharmony_ci 4151e5c31af7Sopenharmony_ci /* Set result */ 4152e5c31af7Sopenharmony_ci if (true == test_result) 4153e5c31af7Sopenharmony_ci { 4154e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4155e5c31af7Sopenharmony_ci } 4156e5c31af7Sopenharmony_ci else 4157e5c31af7Sopenharmony_ci { 4158e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4159e5c31af7Sopenharmony_ci } 4160e5c31af7Sopenharmony_ci 4161e5c31af7Sopenharmony_ci /* Done */ 4162e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 4163e5c31af7Sopenharmony_ci} 4164e5c31af7Sopenharmony_ci 4165e5c31af7Sopenharmony_ci/** Constructor 4166e5c31af7Sopenharmony_ci * 4167e5c31af7Sopenharmony_ci * @param context Test context 4168e5c31af7Sopenharmony_ci **/ 4169e5c31af7Sopenharmony_ciDispatchBindSamplersTest::DispatchBindSamplersTest(deqp::Context& context) 4170e5c31af7Sopenharmony_ci : TestCase(context, "dispatch_bind_samplers", "Tests BindSamplers with dispatch command") 4171e5c31af7Sopenharmony_ci{ 4172e5c31af7Sopenharmony_ci /* Nothing to be done */ 4173e5c31af7Sopenharmony_ci} 4174e5c31af7Sopenharmony_ci 4175e5c31af7Sopenharmony_ci/** Execute test 4176e5c31af7Sopenharmony_ci * 4177e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 4178e5c31af7Sopenharmony_ci **/ 4179e5c31af7Sopenharmony_citcu::TestNode::IterateResult DispatchBindSamplersTest::iterate() 4180e5c31af7Sopenharmony_ci{ 4181e5c31af7Sopenharmony_ci static const GLchar* cs = "#version 440 core\n" 4182e5c31af7Sopenharmony_ci "\n" 4183e5c31af7Sopenharmony_ci "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 4184e5c31af7Sopenharmony_ci "\n" 4185e5c31af7Sopenharmony_ci "SAMPLER_LIST\n" 4186e5c31af7Sopenharmony_ci "layout (std140, binding = 0) buffer SSB {\n" 4187e5c31af7Sopenharmony_ci " uint sum;\n" 4188e5c31af7Sopenharmony_ci "} ssb;\n" 4189e5c31af7Sopenharmony_ci "\n" 4190e5c31af7Sopenharmony_ci "void main()\n" 4191e5c31af7Sopenharmony_ci "{\n" 4192e5c31af7Sopenharmony_ci " uvec4 sum = SUM_LIST;\n" 4193e5c31af7Sopenharmony_ci " ssb.sum = sum.r\n;" 4194e5c31af7Sopenharmony_ci "}\n" 4195e5c31af7Sopenharmony_ci "\n"; 4196e5c31af7Sopenharmony_ci 4197e5c31af7Sopenharmony_ci static const GLchar* sampler = "layout (location = XXX) uniform usampler2D sXXX;"; 4198e5c31af7Sopenharmony_ci 4199e5c31af7Sopenharmony_ci static const GLchar* sampling = "texture(sXXX, vec2(1.5f, 0.5f))"; 4200e5c31af7Sopenharmony_ci 4201e5c31af7Sopenharmony_ci static const GLuint depth = 1; 4202e5c31af7Sopenharmony_ci static const GLuint height = 8; 4203e5c31af7Sopenharmony_ci static const GLuint width = 8; 4204e5c31af7Sopenharmony_ci 4205e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 4206e5c31af7Sopenharmony_ci 4207e5c31af7Sopenharmony_ci bool test_result = true; 4208e5c31af7Sopenharmony_ci 4209e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 4210e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 4211e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 4212e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 4213e5c31af7Sopenharmony_ci 4214e5c31af7Sopenharmony_ci GLint max_textures = 0; 4215e5c31af7Sopenharmony_ci 4216e5c31af7Sopenharmony_ci /* Get max */ 4217e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &max_textures); 4218e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 4219e5c31af7Sopenharmony_ci 4220e5c31af7Sopenharmony_ci /* Textures */ 4221e5c31af7Sopenharmony_ci /* Storage */ 4222e5c31af7Sopenharmony_ci std::vector<GLuint> sampler_ids; 4223e5c31af7Sopenharmony_ci std::vector<Texture> texture; 4224e5c31af7Sopenharmony_ci std::vector<GLuint> texture_ids; 4225e5c31af7Sopenharmony_ci 4226e5c31af7Sopenharmony_ci sampler_ids.resize(max_textures); 4227e5c31af7Sopenharmony_ci texture.resize(max_textures); 4228e5c31af7Sopenharmony_ci texture_ids.resize(max_textures); 4229e5c31af7Sopenharmony_ci 4230e5c31af7Sopenharmony_ci GLuint data[width * height * depth]; 4231e5c31af7Sopenharmony_ci 4232e5c31af7Sopenharmony_ci for (GLuint j = 0; j < width * height; ++j) 4233e5c31af7Sopenharmony_ci { 4234e5c31af7Sopenharmony_ci data[j] = 0; 4235e5c31af7Sopenharmony_ci } 4236e5c31af7Sopenharmony_ci 4237e5c31af7Sopenharmony_ci { 4238e5c31af7Sopenharmony_ci const size_t last_line_offset = (height - 1) * width; 4239e5c31af7Sopenharmony_ci const size_t last_pixel_in_line_offset = width - 1; 4240e5c31af7Sopenharmony_ci 4241e5c31af7Sopenharmony_ci for (GLuint j = 0; j < width; ++j) 4242e5c31af7Sopenharmony_ci { 4243e5c31af7Sopenharmony_ci data[j] = 1; 4244e5c31af7Sopenharmony_ci data[j + last_line_offset] = 1; 4245e5c31af7Sopenharmony_ci } 4246e5c31af7Sopenharmony_ci 4247e5c31af7Sopenharmony_ci for (GLuint j = 0; j < height; ++j) 4248e5c31af7Sopenharmony_ci { 4249e5c31af7Sopenharmony_ci const size_t line_offset = j * width; 4250e5c31af7Sopenharmony_ci 4251e5c31af7Sopenharmony_ci data[line_offset] = 1; 4252e5c31af7Sopenharmony_ci data[line_offset + last_pixel_in_line_offset] = 1; 4253e5c31af7Sopenharmony_ci } 4254e5c31af7Sopenharmony_ci } 4255e5c31af7Sopenharmony_ci 4256e5c31af7Sopenharmony_ci /* Prepare */ 4257e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 4258e5c31af7Sopenharmony_ci { 4259e5c31af7Sopenharmony_ci texture[i].InitStorage(m_context, GL_TEXTURE_2D, 1, GL_R32UI, width, height, depth); 4260e5c31af7Sopenharmony_ci Texture::Bind(gl, texture[i].m_id, GL_TEXTURE_2D); 4261e5c31af7Sopenharmony_ci Texture::SubImage(gl, GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height, depth, 4262e5c31af7Sopenharmony_ci GL_RED_INTEGER, GL_UNSIGNED_INT, &data); 4263e5c31af7Sopenharmony_ci 4264e5c31af7Sopenharmony_ci texture_ids[i] = texture[i].m_id; 4265e5c31af7Sopenharmony_ci } 4266e5c31af7Sopenharmony_ci 4267e5c31af7Sopenharmony_ci /* Clean */ 4268e5c31af7Sopenharmony_ci Texture::Bind(gl, 0, GL_TEXTURE_2D); 4269e5c31af7Sopenharmony_ci 4270e5c31af7Sopenharmony_ci /* Execute the test */ 4271e5c31af7Sopenharmony_ci gl.bindTextures(0 /* first */, max_textures /* count */, &texture_ids[0]); 4272e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindTextures"); 4273e5c31af7Sopenharmony_ci 4274e5c31af7Sopenharmony_ci /* SSBO */ 4275e5c31af7Sopenharmony_ci Buffer ssb_buffer; 4276e5c31af7Sopenharmony_ci ssb_buffer.InitData(m_context, GL_SHADER_STORAGE_BUFFER, GL_DYNAMIC_COPY, sizeof(GLuint), 0 /* data */); 4277e5c31af7Sopenharmony_ci 4278e5c31af7Sopenharmony_ci ssb_buffer.BindBase(0); 4279e5c31af7Sopenharmony_ci 4280e5c31af7Sopenharmony_ci /* Prepare program */ 4281e5c31af7Sopenharmony_ci size_t sam_position = 0; 4282e5c31af7Sopenharmony_ci size_t sum_position = 0; 4283e5c31af7Sopenharmony_ci std::string cs_source = cs; 4284e5c31af7Sopenharmony_ci 4285e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 4286e5c31af7Sopenharmony_ci { 4287e5c31af7Sopenharmony_ci size_t sam_start_position = sam_position; 4288e5c31af7Sopenharmony_ci size_t sum_start_position = sum_position; 4289e5c31af7Sopenharmony_ci 4290e5c31af7Sopenharmony_ci GLchar index[16]; 4291e5c31af7Sopenharmony_ci 4292e5c31af7Sopenharmony_ci sprintf(index, "%d", i); 4293e5c31af7Sopenharmony_ci 4294e5c31af7Sopenharmony_ci /* Add entry to ubo list */ 4295e5c31af7Sopenharmony_ci replaceToken("SAMPLER_LIST", sam_position, "SAMPLER\nSAMPLER_LIST", cs_source); 4296e5c31af7Sopenharmony_ci sam_position = sam_start_position; 4297e5c31af7Sopenharmony_ci 4298e5c31af7Sopenharmony_ci replaceToken("SAMPLER", sam_position, sampler, cs_source); 4299e5c31af7Sopenharmony_ci sam_position = sam_start_position; 4300e5c31af7Sopenharmony_ci 4301e5c31af7Sopenharmony_ci replaceToken("XXX", sam_position, index, cs_source); 4302e5c31af7Sopenharmony_ci replaceToken("XXX", sam_position, index, cs_source); 4303e5c31af7Sopenharmony_ci 4304e5c31af7Sopenharmony_ci /* Add entry to sum list */ 4305e5c31af7Sopenharmony_ci replaceToken("SUM_LIST", sum_position, "SAMPLING + SUM_LIST", cs_source); 4306e5c31af7Sopenharmony_ci sum_position = sum_start_position; 4307e5c31af7Sopenharmony_ci 4308e5c31af7Sopenharmony_ci replaceToken("SAMPLING", sum_position, sampling, cs_source); 4309e5c31af7Sopenharmony_ci sum_position = sum_start_position; 4310e5c31af7Sopenharmony_ci 4311e5c31af7Sopenharmony_ci replaceToken("XXX", sum_position, index, cs_source); 4312e5c31af7Sopenharmony_ci } 4313e5c31af7Sopenharmony_ci 4314e5c31af7Sopenharmony_ci /* Remove token for lists */ 4315e5c31af7Sopenharmony_ci replaceToken(" + SUM_LIST", sum_position, "", cs_source); 4316e5c31af7Sopenharmony_ci replaceToken("SAMPLER_LIST", sam_position, "", cs_source); 4317e5c31af7Sopenharmony_ci 4318e5c31af7Sopenharmony_ci Program program(m_context); 4319e5c31af7Sopenharmony_ci program.Init(cs_source.c_str(), "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */); 4320e5c31af7Sopenharmony_ci 4321e5c31af7Sopenharmony_ci program.Use(); 4322e5c31af7Sopenharmony_ci 4323e5c31af7Sopenharmony_ci /* Set texture units */ 4324e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 4325e5c31af7Sopenharmony_ci { 4326e5c31af7Sopenharmony_ci gl.uniform1i(i, i); 4327e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform1i"); 4328e5c31af7Sopenharmony_ci } 4329e5c31af7Sopenharmony_ci 4330e5c31af7Sopenharmony_ci /* Prepare samplers */ 4331e5c31af7Sopenharmony_ci gl.genSamplers(max_textures, &sampler_ids[0]); 4332e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenSamplers"); 4333e5c31af7Sopenharmony_ci 4334e5c31af7Sopenharmony_ci try 4335e5c31af7Sopenharmony_ci { 4336e5c31af7Sopenharmony_ci gl.bindSamplers(0 /* first */, max_textures /* count */, &sampler_ids[0]); 4337e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindSamplers"); 4338e5c31af7Sopenharmony_ci 4339e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_textures; ++i) 4340e5c31af7Sopenharmony_ci { 4341e5c31af7Sopenharmony_ci gl.samplerParameteri(sampler_ids[i], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 4342e5c31af7Sopenharmony_ci gl.samplerParameteri(sampler_ids[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST); 4343e5c31af7Sopenharmony_ci gl.samplerParameteri(sampler_ids[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST); 4344e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "SamplerParameteri"); 4345e5c31af7Sopenharmony_ci } 4346e5c31af7Sopenharmony_ci 4347e5c31af7Sopenharmony_ci gl.dispatchCompute(1, 1, 1); 4348e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute"); 4349e5c31af7Sopenharmony_ci 4350e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_ALL_BARRIER_BITS); 4351e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier"); 4352e5c31af7Sopenharmony_ci } 4353e5c31af7Sopenharmony_ci catch (const std::exception&) 4354e5c31af7Sopenharmony_ci { 4355e5c31af7Sopenharmony_ci gl.deleteSamplers(max_textures, &sampler_ids[0]); 4356e5c31af7Sopenharmony_ci 4357e5c31af7Sopenharmony_ci TCU_FAIL("Unexpected error generated"); 4358e5c31af7Sopenharmony_ci } 4359e5c31af7Sopenharmony_ci 4360e5c31af7Sopenharmony_ci /* Remove samplers */ 4361e5c31af7Sopenharmony_ci gl.deleteSamplers(max_textures, &sampler_ids[0]); 4362e5c31af7Sopenharmony_ci 4363e5c31af7Sopenharmony_ci /* Verify results */ 4364e5c31af7Sopenharmony_ci GLuint* result = (GLuint*)gl.mapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY); 4365e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 4366e5c31af7Sopenharmony_ci 4367e5c31af7Sopenharmony_ci if (0 != memcmp(result, &max_textures, sizeof(max_textures))) 4368e5c31af7Sopenharmony_ci { 4369e5c31af7Sopenharmony_ci test_result = false; 4370e5c31af7Sopenharmony_ci } 4371e5c31af7Sopenharmony_ci 4372e5c31af7Sopenharmony_ci gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER); 4373e5c31af7Sopenharmony_ci gl.getError(); /* Ignore error */ 4374e5c31af7Sopenharmony_ci 4375e5c31af7Sopenharmony_ci /* Set result */ 4376e5c31af7Sopenharmony_ci if (true == test_result) 4377e5c31af7Sopenharmony_ci { 4378e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4379e5c31af7Sopenharmony_ci } 4380e5c31af7Sopenharmony_ci else 4381e5c31af7Sopenharmony_ci { 4382e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4383e5c31af7Sopenharmony_ci } 4384e5c31af7Sopenharmony_ci 4385e5c31af7Sopenharmony_ci /* Done */ 4386e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 4387e5c31af7Sopenharmony_ci} 4388e5c31af7Sopenharmony_ci 4389e5c31af7Sopenharmony_ci/** Constructor 4390e5c31af7Sopenharmony_ci * 4391e5c31af7Sopenharmony_ci * @param context Test context 4392e5c31af7Sopenharmony_ci **/ 4393e5c31af7Sopenharmony_ciDrawBindVertexBuffersTest::DrawBindVertexBuffersTest(deqp::Context& context) 4394e5c31af7Sopenharmony_ci : TestCase(context, "draw_bind_vertex_buffers", "Tests BindVertexBuffers command with drawArrays") 4395e5c31af7Sopenharmony_ci{ 4396e5c31af7Sopenharmony_ci /* Nothing to be done */ 4397e5c31af7Sopenharmony_ci} 4398e5c31af7Sopenharmony_ci 4399e5c31af7Sopenharmony_ci/** Execute test 4400e5c31af7Sopenharmony_ci * 4401e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP 4402e5c31af7Sopenharmony_ci **/ 4403e5c31af7Sopenharmony_citcu::TestNode::IterateResult DrawBindVertexBuffersTest::iterate() 4404e5c31af7Sopenharmony_ci{ 4405e5c31af7Sopenharmony_ci static const GLchar* vs = "#version 440 core\n" 4406e5c31af7Sopenharmony_ci "\n" 4407e5c31af7Sopenharmony_ci "ATTRIBUTE_LIST\n" 4408e5c31af7Sopenharmony_ci "\n" 4409e5c31af7Sopenharmony_ci "out vec4 vs_gs_sum;\n" 4410e5c31af7Sopenharmony_ci "\n" 4411e5c31af7Sopenharmony_ci "void main()\n" 4412e5c31af7Sopenharmony_ci "{\n" 4413e5c31af7Sopenharmony_ci " vs_gs_sum = SUM_LIST;\n" 4414e5c31af7Sopenharmony_ci "}\n" 4415e5c31af7Sopenharmony_ci "\n"; 4416e5c31af7Sopenharmony_ci 4417e5c31af7Sopenharmony_ci static const GLchar* gs = "#version 440 core\n" 4418e5c31af7Sopenharmony_ci "\n" 4419e5c31af7Sopenharmony_ci "layout(points) in;\n" 4420e5c31af7Sopenharmony_ci "layout(triangle_strip, max_vertices = 4) out;\n" 4421e5c31af7Sopenharmony_ci "\n" 4422e5c31af7Sopenharmony_ci "in vec4 vs_gs_sum[];\n" 4423e5c31af7Sopenharmony_ci "out vec4 gs_fs_sum;\n" 4424e5c31af7Sopenharmony_ci "\n" 4425e5c31af7Sopenharmony_ci "void main()\n" 4426e5c31af7Sopenharmony_ci "{\n" 4427e5c31af7Sopenharmony_ci " gs_fs_sum = vs_gs_sum[0];\n" 4428e5c31af7Sopenharmony_ci " gl_Position = vec4(-1, -1, 0, 1);\n" 4429e5c31af7Sopenharmony_ci " EmitVertex();\n" 4430e5c31af7Sopenharmony_ci " gs_fs_sum = vs_gs_sum[0];\n" 4431e5c31af7Sopenharmony_ci " gl_Position = vec4(-1, 1, 0, 1);\n" 4432e5c31af7Sopenharmony_ci " EmitVertex();\n" 4433e5c31af7Sopenharmony_ci " gs_fs_sum = vs_gs_sum[0];\n" 4434e5c31af7Sopenharmony_ci " gl_Position = vec4(1, -1, 0, 1);\n" 4435e5c31af7Sopenharmony_ci " EmitVertex();\n" 4436e5c31af7Sopenharmony_ci " gs_fs_sum = vs_gs_sum[0];\n" 4437e5c31af7Sopenharmony_ci " gl_Position = vec4(1, 1, 0, 1);\n" 4438e5c31af7Sopenharmony_ci " EmitVertex();\n" 4439e5c31af7Sopenharmony_ci "}\n" 4440e5c31af7Sopenharmony_ci "\n"; 4441e5c31af7Sopenharmony_ci 4442e5c31af7Sopenharmony_ci static const GLchar* fs = "#version 440 core\n" 4443e5c31af7Sopenharmony_ci "\n" 4444e5c31af7Sopenharmony_ci "in vec4 gs_fs_sum;\n" 4445e5c31af7Sopenharmony_ci "out vec4 fs_out;\n" 4446e5c31af7Sopenharmony_ci "\n" 4447e5c31af7Sopenharmony_ci "void main()\n" 4448e5c31af7Sopenharmony_ci "{\n" 4449e5c31af7Sopenharmony_ci " fs_out = gs_fs_sum;\n" 4450e5c31af7Sopenharmony_ci "}\n" 4451e5c31af7Sopenharmony_ci "\n"; 4452e5c31af7Sopenharmony_ci 4453e5c31af7Sopenharmony_ci static const GLchar* attribute = "layout (location = XXX) in vec4 aXXX;"; 4454e5c31af7Sopenharmony_ci 4455e5c31af7Sopenharmony_ci static const GLuint height = 8; 4456e5c31af7Sopenharmony_ci static const GLuint width = 8; 4457e5c31af7Sopenharmony_ci 4458e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 4459e5c31af7Sopenharmony_ci 4460e5c31af7Sopenharmony_ci bool test_result = true; 4461e5c31af7Sopenharmony_ci 4462e5c31af7Sopenharmony_ci#if DEBUG_ENBALE_MESSAGE_CALLBACK 4463e5c31af7Sopenharmony_ci gl.debugMessageCallback(debug_proc, &m_context); 4464e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DebugMessageCallback"); 4465e5c31af7Sopenharmony_ci#endif /* DEBUG_ENBALE_MESSAGE_CALLBACK */ 4466e5c31af7Sopenharmony_ci 4467e5c31af7Sopenharmony_ci static const GLintptr attribute_size = 4 * sizeof(GLfloat); 4468e5c31af7Sopenharmony_ci 4469e5c31af7Sopenharmony_ci GLint max_buffers = 0; 4470e5c31af7Sopenharmony_ci GLuint vao = 0; 4471e5c31af7Sopenharmony_ci 4472e5c31af7Sopenharmony_ci /* Get max */ 4473e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_buffers); 4474e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 4475e5c31af7Sopenharmony_ci 4476e5c31af7Sopenharmony_ci /* Storage */ 4477e5c31af7Sopenharmony_ci Buffer buffer; 4478e5c31af7Sopenharmony_ci std::vector<GLuint> buffer_ids; 4479e5c31af7Sopenharmony_ci std::vector<GLfloat> data; 4480e5c31af7Sopenharmony_ci std::vector<GLintptr> offsets; 4481e5c31af7Sopenharmony_ci std::vector<GLsizei> strides; 4482e5c31af7Sopenharmony_ci 4483e5c31af7Sopenharmony_ci buffer_ids.resize(max_buffers); 4484e5c31af7Sopenharmony_ci data.resize(max_buffers * 4); 4485e5c31af7Sopenharmony_ci offsets.resize(max_buffers); 4486e5c31af7Sopenharmony_ci strides.resize(max_buffers); 4487e5c31af7Sopenharmony_ci 4488e5c31af7Sopenharmony_ci /* Prepare data */ 4489e5c31af7Sopenharmony_ci const GLfloat value = 1.0f / (GLfloat)max_buffers; 4490e5c31af7Sopenharmony_ci 4491e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_buffers; ++i) 4492e5c31af7Sopenharmony_ci { 4493e5c31af7Sopenharmony_ci data[i * 4 + 0] = value; 4494e5c31af7Sopenharmony_ci data[i * 4 + 1] = value; 4495e5c31af7Sopenharmony_ci data[i * 4 + 2] = value; 4496e5c31af7Sopenharmony_ci data[i * 4 + 3] = value; 4497e5c31af7Sopenharmony_ci } 4498e5c31af7Sopenharmony_ci 4499e5c31af7Sopenharmony_ci /* Prepare buffer */ 4500e5c31af7Sopenharmony_ci buffer.InitData(m_context, GL_ARRAY_BUFFER, GL_DYNAMIC_COPY, data.size() * sizeof(GLfloat), &data[0]); 4501e5c31af7Sopenharmony_ci 4502e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_buffers; ++i) 4503e5c31af7Sopenharmony_ci { 4504e5c31af7Sopenharmony_ci buffer_ids[i] = buffer.m_id; 4505e5c31af7Sopenharmony_ci offsets[i] = i * attribute_size; 4506e5c31af7Sopenharmony_ci strides[i] = attribute_size; 4507e5c31af7Sopenharmony_ci } 4508e5c31af7Sopenharmony_ci 4509e5c31af7Sopenharmony_ci /* Prepare FBO */ 4510e5c31af7Sopenharmony_ci Framebuffer framebuffer(m_context); 4511e5c31af7Sopenharmony_ci Texture texture; 4512e5c31af7Sopenharmony_ci 4513e5c31af7Sopenharmony_ci texture.InitStorage(m_context, GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, width, height, 1 /* depth */); 4514e5c31af7Sopenharmony_ci 4515e5c31af7Sopenharmony_ci /* */ 4516e5c31af7Sopenharmony_ci Framebuffer::Generate(gl, framebuffer.m_id); 4517e5c31af7Sopenharmony_ci Framebuffer::Bind(gl, GL_DRAW_FRAMEBUFFER, framebuffer.m_id); 4518e5c31af7Sopenharmony_ci Framebuffer::AttachTexture(gl, GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture.m_id, 0 /* level */, width, 4519e5c31af7Sopenharmony_ci height); 4520e5c31af7Sopenharmony_ci 4521e5c31af7Sopenharmony_ci /* Prepare program */ 4522e5c31af7Sopenharmony_ci size_t attr_position = 0; 4523e5c31af7Sopenharmony_ci size_t sum_position = 0; 4524e5c31af7Sopenharmony_ci std::string vs_source = vs; 4525e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_buffers; ++i) 4526e5c31af7Sopenharmony_ci { 4527e5c31af7Sopenharmony_ci size_t attr_start_position = attr_position; 4528e5c31af7Sopenharmony_ci size_t sum_start_position = sum_position; 4529e5c31af7Sopenharmony_ci 4530e5c31af7Sopenharmony_ci GLchar index[16]; 4531e5c31af7Sopenharmony_ci 4532e5c31af7Sopenharmony_ci sprintf(index, "%d", i); 4533e5c31af7Sopenharmony_ci 4534e5c31af7Sopenharmony_ci /* Add entry to ubo list */ 4535e5c31af7Sopenharmony_ci replaceToken("ATTRIBUTE_LIST", attr_position, "ATTRIBUTE\nATTRIBUTE_LIST", vs_source); 4536e5c31af7Sopenharmony_ci attr_position = attr_start_position; 4537e5c31af7Sopenharmony_ci 4538e5c31af7Sopenharmony_ci replaceToken("ATTRIBUTE", attr_position, attribute, vs_source); 4539e5c31af7Sopenharmony_ci attr_position = attr_start_position; 4540e5c31af7Sopenharmony_ci 4541e5c31af7Sopenharmony_ci replaceToken("XXX", attr_position, index, vs_source); 4542e5c31af7Sopenharmony_ci replaceToken("XXX", attr_position, index, vs_source); 4543e5c31af7Sopenharmony_ci 4544e5c31af7Sopenharmony_ci /* Add entry to sum list */ 4545e5c31af7Sopenharmony_ci replaceToken("SUM_LIST", sum_position, "aXXX + SUM_LIST", vs_source); 4546e5c31af7Sopenharmony_ci sum_position = sum_start_position; 4547e5c31af7Sopenharmony_ci 4548e5c31af7Sopenharmony_ci replaceToken("XXX", sum_position, index, vs_source); 4549e5c31af7Sopenharmony_ci } 4550e5c31af7Sopenharmony_ci 4551e5c31af7Sopenharmony_ci /* Remove token for lists */ 4552e5c31af7Sopenharmony_ci replaceToken(" + SUM_LIST", sum_position, "", vs_source); 4553e5c31af7Sopenharmony_ci replaceToken("ATTRIBUTE_LIST", attr_position, "", vs_source); 4554e5c31af7Sopenharmony_ci 4555e5c31af7Sopenharmony_ci Program program(m_context); 4556e5c31af7Sopenharmony_ci program.Init("" /* cs */, fs, gs, "" /* tcs */, "" /* tes */, vs_source.c_str()); 4557e5c31af7Sopenharmony_ci 4558e5c31af7Sopenharmony_ci program.Use(); 4559e5c31af7Sopenharmony_ci 4560e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &vao); 4561e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays"); 4562e5c31af7Sopenharmony_ci 4563e5c31af7Sopenharmony_ci try 4564e5c31af7Sopenharmony_ci { 4565e5c31af7Sopenharmony_ci gl.bindVertexArray(vao); 4566e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArrays"); 4567e5c31af7Sopenharmony_ci 4568e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_buffers; ++i) 4569e5c31af7Sopenharmony_ci { 4570e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(i); 4571e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "EnableVertexAttribArray"); 4572e5c31af7Sopenharmony_ci } 4573e5c31af7Sopenharmony_ci 4574e5c31af7Sopenharmony_ci /* */ 4575e5c31af7Sopenharmony_ci gl.bindVertexBuffers(0, max_buffers, &buffer_ids[0], &offsets[0], &strides[0]); 4576e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexBuffers"); 4577e5c31af7Sopenharmony_ci 4578e5c31af7Sopenharmony_ci /* */ 4579e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */); 4580e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays"); 4581e5c31af7Sopenharmony_ci 4582e5c31af7Sopenharmony_ci for (GLint i = 0; i < max_buffers; ++i) 4583e5c31af7Sopenharmony_ci { 4584e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(i); 4585e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DisableVertexAttribArray"); 4586e5c31af7Sopenharmony_ci } 4587e5c31af7Sopenharmony_ci } 4588e5c31af7Sopenharmony_ci catch (const std::exception&) 4589e5c31af7Sopenharmony_ci { 4590e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &vao); 4591e5c31af7Sopenharmony_ci 4592e5c31af7Sopenharmony_ci TCU_FAIL("Unexpected error generated"); 4593e5c31af7Sopenharmony_ci } 4594e5c31af7Sopenharmony_ci 4595e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &vao); 4596e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteVertexArrays"); 4597e5c31af7Sopenharmony_ci 4598e5c31af7Sopenharmony_ci /* Verify results */ 4599e5c31af7Sopenharmony_ci GLuint pixels[width * height]; 4600e5c31af7Sopenharmony_ci for (GLuint i = 0; i < width * height; ++i) 4601e5c31af7Sopenharmony_ci { 4602e5c31af7Sopenharmony_ci pixels[i] = 0; 4603e5c31af7Sopenharmony_ci } 4604e5c31af7Sopenharmony_ci 4605e5c31af7Sopenharmony_ci Texture::Bind(gl, texture.m_id, GL_TEXTURE_2D); 4606e5c31af7Sopenharmony_ci 4607e5c31af7Sopenharmony_ci Texture::GetData(gl, 0 /* level */, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 4608e5c31af7Sopenharmony_ci 4609e5c31af7Sopenharmony_ci /* Unbind */ 4610e5c31af7Sopenharmony_ci Texture::Bind(gl, 0, GL_TEXTURE_2D); 4611e5c31af7Sopenharmony_ci 4612e5c31af7Sopenharmony_ci /* Verify */ 4613e5c31af7Sopenharmony_ci for (GLuint i = 0; i < width * height; ++i) 4614e5c31af7Sopenharmony_ci { 4615e5c31af7Sopenharmony_ci if (0xffffffff != pixels[i]) 4616e5c31af7Sopenharmony_ci { 4617e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message << "Invalid value: " << (GLuint)pixels[i] 4618e5c31af7Sopenharmony_ci << " at offset: " << i << tcu::TestLog::EndMessage; 4619e5c31af7Sopenharmony_ci 4620e5c31af7Sopenharmony_ci test_result = false; 4621e5c31af7Sopenharmony_ci 4622e5c31af7Sopenharmony_ci break; 4623e5c31af7Sopenharmony_ci } 4624e5c31af7Sopenharmony_ci } 4625e5c31af7Sopenharmony_ci 4626e5c31af7Sopenharmony_ci /* Set result */ 4627e5c31af7Sopenharmony_ci if (true == test_result) 4628e5c31af7Sopenharmony_ci { 4629e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 4630e5c31af7Sopenharmony_ci } 4631e5c31af7Sopenharmony_ci else 4632e5c31af7Sopenharmony_ci { 4633e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 4634e5c31af7Sopenharmony_ci } 4635e5c31af7Sopenharmony_ci 4636e5c31af7Sopenharmony_ci /* Done */ 4637e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 4638e5c31af7Sopenharmony_ci} 4639e5c31af7Sopenharmony_ci} /* MultiBind */ 4640e5c31af7Sopenharmony_ci 4641e5c31af7Sopenharmony_ci/** Constructor. 4642e5c31af7Sopenharmony_ci * 4643e5c31af7Sopenharmony_ci * @param context Rendering context. 4644e5c31af7Sopenharmony_ci **/ 4645e5c31af7Sopenharmony_ciMultiBindTests::MultiBindTests(deqp::Context& context) 4646e5c31af7Sopenharmony_ci : TestCaseGroup(context, "multi_bind", "Verifies \"multi bind\" functionality") 4647e5c31af7Sopenharmony_ci{ 4648e5c31af7Sopenharmony_ci /* Left blank on purpose */ 4649e5c31af7Sopenharmony_ci} 4650e5c31af7Sopenharmony_ci 4651e5c31af7Sopenharmony_ci/** Initializes a multi_bind test group. 4652e5c31af7Sopenharmony_ci * 4653e5c31af7Sopenharmony_ci **/ 4654e5c31af7Sopenharmony_civoid MultiBindTests::init(void) 4655e5c31af7Sopenharmony_ci{ 4656e5c31af7Sopenharmony_ci addChild(new MultiBind::DispatchBindTexturesTest(m_context)); 4657e5c31af7Sopenharmony_ci 4658e5c31af7Sopenharmony_ci addChild(new MultiBind::ErrorsBindBuffersTest(m_context)); 4659e5c31af7Sopenharmony_ci addChild(new MultiBind::ErrorsBindTexturesTest(m_context)); 4660e5c31af7Sopenharmony_ci addChild(new MultiBind::ErrorsBindSamplersTest(m_context)); 4661e5c31af7Sopenharmony_ci addChild(new MultiBind::ErrorsBindImageTexturesTest(m_context)); 4662e5c31af7Sopenharmony_ci addChild(new MultiBind::ErrorsBindVertexBuffersTest(m_context)); 4663e5c31af7Sopenharmony_ci addChild(new MultiBind::FunctionalBindBuffersBaseTest(m_context)); 4664e5c31af7Sopenharmony_ci addChild(new MultiBind::FunctionalBindBuffersRangeTest(m_context)); 4665e5c31af7Sopenharmony_ci addChild(new MultiBind::FunctionalBindTexturesTest(m_context)); 4666e5c31af7Sopenharmony_ci addChild(new MultiBind::FunctionalBindSamplersTest(m_context)); 4667e5c31af7Sopenharmony_ci addChild(new MultiBind::FunctionalBindImageTexturesTest(m_context)); 4668e5c31af7Sopenharmony_ci addChild(new MultiBind::FunctionalBindVertexBuffersTest(m_context)); 4669e5c31af7Sopenharmony_ci addChild(new MultiBind::DispatchBindBuffersBaseTest(m_context)); 4670e5c31af7Sopenharmony_ci addChild(new MultiBind::DispatchBindBuffersRangeTest(m_context)); 4671e5c31af7Sopenharmony_ci 4672e5c31af7Sopenharmony_ci addChild(new MultiBind::DispatchBindImageTexturesTest(m_context)); 4673e5c31af7Sopenharmony_ci addChild(new MultiBind::DispatchBindSamplersTest(m_context)); 4674e5c31af7Sopenharmony_ci addChild(new MultiBind::DrawBindVertexBuffersTest(m_context)); 4675e5c31af7Sopenharmony_ci} 4676e5c31af7Sopenharmony_ci 4677e5c31af7Sopenharmony_ci} /* gl4cts namespace */ 4678