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 gl4cBufferStorageTests.cpp 26e5c31af7Sopenharmony_ci * \brief Implements conformance tests for "Buffer storage" functionality. 27e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/ 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ci#include "gl4cBufferStorageTests.hpp" 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp" 32e5c31af7Sopenharmony_ci#include "gluDefs.hpp" 33e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp" 34e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 35e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 36e5c31af7Sopenharmony_ci#include "tcuImageIO.hpp" 37e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 38e5c31af7Sopenharmony_ci#include "tcuTexture.hpp" 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ci#include <iomanip> 41e5c31af7Sopenharmony_ci#include <string> 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_ciusing namespace glw; 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_cinamespace gl4cts 46e5c31af7Sopenharmony_ci{ 47e5c31af7Sopenharmony_cinamespace BufferStorage 48e5c31af7Sopenharmony_ci{ 49e5c31af7Sopenharmony_ci/* Enums */ 50e5c31af7Sopenharmony_ci 51e5c31af7Sopenharmony_ci/* Represents how functionality is supported */ 52e5c31af7Sopenharmony_cienum FUNCTIONALITY_SUPPORT 53e5c31af7Sopenharmony_ci{ 54e5c31af7Sopenharmony_ci FUNCTIONALITY_SUPPORT_NONE = 0, 55e5c31af7Sopenharmony_ci FUNCTIONALITY_SUPPORT_EXTENSION, 56e5c31af7Sopenharmony_ci FUNCTIONALITY_SUPPORT_CORE, 57e5c31af7Sopenharmony_ci FUNCTIONALITY_SUPPORT_NOT_DETERMINED, 58e5c31af7Sopenharmony_ci}; 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_ci/* Prototypes of functions */ 61e5c31af7Sopenharmony_ciFUNCTIONALITY_SUPPORT getDirectStateAccessSupport(deqp::Context& context); 62e5c31af7Sopenharmony_cibool isGLVersionAtLeast(const glw::Functions& gl, glw::GLint required_major, glw::GLint required_minor); 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_ci/* Classes */ 65e5c31af7Sopenharmony_ci 66e5c31af7Sopenharmony_ci/** Represents buffer instance 67e5c31af7Sopenharmony_ci * Provides basic buffer functionality 68e5c31af7Sopenharmony_ci **/ 69e5c31af7Sopenharmony_ciclass Buffer 70e5c31af7Sopenharmony_ci{ 71e5c31af7Sopenharmony_cipublic: 72e5c31af7Sopenharmony_ci // I don't quite understand how the old code *ever* worked... 73e5c31af7Sopenharmony_ci // This is uglyish hack to make it actually compile on any sane 74e5c31af7Sopenharmony_ci // compiler, and not crash. 75e5c31af7Sopenharmony_ci struct MoveMapOwner 76e5c31af7Sopenharmony_ci { 77e5c31af7Sopenharmony_ci MoveMapOwner(Buffer* buffer_, glw::GLvoid* data_) : buffer(buffer_), data(data_) 78e5c31af7Sopenharmony_ci { 79e5c31af7Sopenharmony_ci } 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_ci Buffer* buffer; 82e5c31af7Sopenharmony_ci glw::GLvoid* data; 83e5c31af7Sopenharmony_ci }; 84e5c31af7Sopenharmony_ci 85e5c31af7Sopenharmony_ci /* Public classes */ 86e5c31af7Sopenharmony_ci class MapOwner 87e5c31af7Sopenharmony_ci { 88e5c31af7Sopenharmony_ci friend class Buffer; 89e5c31af7Sopenharmony_ci 90e5c31af7Sopenharmony_ci public: 91e5c31af7Sopenharmony_ci MapOwner(MapOwner& map_owner); 92e5c31af7Sopenharmony_ci MapOwner(const MoveMapOwner& moveOwner); 93e5c31af7Sopenharmony_ci ~MapOwner(); 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_ci glw::GLvoid* m_data; 96e5c31af7Sopenharmony_ci 97e5c31af7Sopenharmony_ci private: 98e5c31af7Sopenharmony_ci MapOwner(Buffer& buffer, glw::GLvoid* data); 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_ci Buffer* m_buffer; 101e5c31af7Sopenharmony_ci }; 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_ci /* Public methods */ 104e5c31af7Sopenharmony_ci /* Ctr & Dtr */ 105e5c31af7Sopenharmony_ci Buffer(deqp::Context& context); 106e5c31af7Sopenharmony_ci ~Buffer(); 107e5c31af7Sopenharmony_ci 108e5c31af7Sopenharmony_ci /* Init & Release */ 109e5c31af7Sopenharmony_ci void InitData(glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size, const glw::GLvoid* data); 110e5c31af7Sopenharmony_ci 111e5c31af7Sopenharmony_ci void InitStorage(glw::GLenum target, glw::GLenum flags, glw::GLsizeiptr size, const glw::GLvoid* data); 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci void Release(); 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_ci /* Functionality */ 116e5c31af7Sopenharmony_ci void Bind() const; 117e5c31af7Sopenharmony_ci void BindBase(glw::GLuint index) const; 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci void BindRange(glw::GLuint index, glw::GLintptr offset, glw::GLsizeiptr size) const; 120e5c31af7Sopenharmony_ci 121e5c31af7Sopenharmony_ci MoveMapOwner MapRange(glw::GLintptr offset, glw::GLsizeiptr length, glw::GLenum access); 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ci void UnMap(); 124e5c31af7Sopenharmony_ci 125e5c31af7Sopenharmony_ci /* Public static routines */ 126e5c31af7Sopenharmony_ci /* Extensions */ 127e5c31af7Sopenharmony_ci static void LoadExtDirectStateAccess(deqp::Context& context); 128e5c31af7Sopenharmony_ci 129e5c31af7Sopenharmony_ci /* Functionality */ 130e5c31af7Sopenharmony_ci static void Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target); 131e5c31af7Sopenharmony_ci 132e5c31af7Sopenharmony_ci static void BindBase(const glw::Functions& gl, glw::GLuint id, glw::GLenum target, glw::GLuint index); 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci static void BindRange(const glw::Functions& gl, glw::GLuint id, glw::GLenum target, glw::GLuint index, 135e5c31af7Sopenharmony_ci glw::GLintptr offset, glw::GLsizeiptr size); 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ci static void Data(const glw::Functions& gl, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size, 138e5c31af7Sopenharmony_ci const glw::GLvoid* data); 139e5c31af7Sopenharmony_ci 140e5c31af7Sopenharmony_ci static void Generate(const glw::Functions& gl, glw::GLuint& out_id); 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci static void GetNamedParameter(const glw::Functions& gl, glw::GLuint buffer, glw::GLenum pname, glw::GLint* data); 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ci static void GetParameter(const glw::Functions& gl, glw::GLenum target, glw::GLenum value, glw::GLint* data); 145e5c31af7Sopenharmony_ci 146e5c31af7Sopenharmony_ci static void GetSubData(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr size, 147e5c31af7Sopenharmony_ci glw::GLvoid* data); 148e5c31af7Sopenharmony_ci 149e5c31af7Sopenharmony_ci static void* Map(const glw::Functions& gl, glw::GLenum target, glw::GLenum access); 150e5c31af7Sopenharmony_ci 151e5c31af7Sopenharmony_ci static void* MapRange(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr length, 152e5c31af7Sopenharmony_ci glw::GLenum access); 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_ci static void Storage(const glw::Functions& gl, glw::GLenum target, glw::GLenum flags, glw::GLsizeiptr size, 155e5c31af7Sopenharmony_ci const glw::GLvoid* data); 156e5c31af7Sopenharmony_ci 157e5c31af7Sopenharmony_ci static void SubData(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr size, 158e5c31af7Sopenharmony_ci glw::GLvoid* data); 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_ci static void UnMap(const glw::Functions& gl, glw::GLenum target); 161e5c31af7Sopenharmony_ci 162e5c31af7Sopenharmony_ci /* Public fields */ 163e5c31af7Sopenharmony_ci glw::GLuint m_id; 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci /* Public constants */ 166e5c31af7Sopenharmony_ci static const glw::GLuint m_invalid_id; 167e5c31af7Sopenharmony_ci static const glw::GLuint m_n_targets = 13; 168e5c31af7Sopenharmony_ci static const glw::GLenum m_targets[m_n_targets]; 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ciprivate: 171e5c31af7Sopenharmony_ci /* Private enums */ 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_ci /* Private fields */ 174e5c31af7Sopenharmony_ci deqp::Context& m_context; 175e5c31af7Sopenharmony_ci glw::GLenum m_target; 176e5c31af7Sopenharmony_ci}; 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci/** Represents framebuffer 179e5c31af7Sopenharmony_ci * Provides basic functionality 180e5c31af7Sopenharmony_ci **/ 181e5c31af7Sopenharmony_ciclass Framebuffer 182e5c31af7Sopenharmony_ci{ 183e5c31af7Sopenharmony_cipublic: 184e5c31af7Sopenharmony_ci /* Public methods */ 185e5c31af7Sopenharmony_ci /* Ctr & Dtr */ 186e5c31af7Sopenharmony_ci Framebuffer(deqp::Context& context); 187e5c31af7Sopenharmony_ci ~Framebuffer(); 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ci /* Init & Release */ 190e5c31af7Sopenharmony_ci void Release(); 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ci /* Public static routines */ 193e5c31af7Sopenharmony_ci static void AttachTexture(const glw::Functions& gl, glw::GLenum target, glw::GLenum attachment, 194e5c31af7Sopenharmony_ci glw::GLuint texture_id, glw::GLuint width, glw::GLuint height); 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci static void Bind(const glw::Functions& gl, glw::GLenum target, glw::GLuint id); 197e5c31af7Sopenharmony_ci 198e5c31af7Sopenharmony_ci static void Generate(const glw::Functions& gl, glw::GLuint& out_id); 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci /* Public fields */ 201e5c31af7Sopenharmony_ci glw::GLuint m_id; 202e5c31af7Sopenharmony_ci 203e5c31af7Sopenharmony_ci /* Public constants */ 204e5c31af7Sopenharmony_ci static const glw::GLuint m_invalid_id; 205e5c31af7Sopenharmony_ci 206e5c31af7Sopenharmony_ciprivate: 207e5c31af7Sopenharmony_ci /* Private fields */ 208e5c31af7Sopenharmony_ci deqp::Context& m_context; 209e5c31af7Sopenharmony_ci}; 210e5c31af7Sopenharmony_ci 211e5c31af7Sopenharmony_ci/** Represents shader instance. 212e5c31af7Sopenharmony_ci * Provides basic functionality for shaders. 213e5c31af7Sopenharmony_ci **/ 214e5c31af7Sopenharmony_ciclass Shader 215e5c31af7Sopenharmony_ci{ 216e5c31af7Sopenharmony_cipublic: 217e5c31af7Sopenharmony_ci /* Public methods */ 218e5c31af7Sopenharmony_ci /* Ctr & Dtr */ 219e5c31af7Sopenharmony_ci Shader(deqp::Context& context); 220e5c31af7Sopenharmony_ci ~Shader(); 221e5c31af7Sopenharmony_ci 222e5c31af7Sopenharmony_ci /* Init & Realese */ 223e5c31af7Sopenharmony_ci void Init(glw::GLenum stage, const std::string& source); 224e5c31af7Sopenharmony_ci void Release(); 225e5c31af7Sopenharmony_ci 226e5c31af7Sopenharmony_ci /* Public static routines */ 227e5c31af7Sopenharmony_ci /* Functionality */ 228e5c31af7Sopenharmony_ci static void Compile(const glw::Functions& gl, glw::GLuint id); 229e5c31af7Sopenharmony_ci 230e5c31af7Sopenharmony_ci static void Create(const glw::Functions& gl, glw::GLenum stage, glw::GLuint& out_id); 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ci static void Source(const glw::Functions& gl, glw::GLuint id, const std::string& source); 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ci /* Public fields */ 235e5c31af7Sopenharmony_ci glw::GLuint m_id; 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ci /* Public constants */ 238e5c31af7Sopenharmony_ci static const glw::GLuint m_invalid_id; 239e5c31af7Sopenharmony_ci 240e5c31af7Sopenharmony_ciprivate: 241e5c31af7Sopenharmony_ci /* Private fields */ 242e5c31af7Sopenharmony_ci deqp::Context& m_context; 243e5c31af7Sopenharmony_ci}; 244e5c31af7Sopenharmony_ci 245e5c31af7Sopenharmony_ci/** Represents program instance. 246e5c31af7Sopenharmony_ci * Provides basic functionality 247e5c31af7Sopenharmony_ci **/ 248e5c31af7Sopenharmony_ciclass Program 249e5c31af7Sopenharmony_ci{ 250e5c31af7Sopenharmony_cipublic: 251e5c31af7Sopenharmony_ci /* Public methods */ 252e5c31af7Sopenharmony_ci /* Ctr & Dtr */ 253e5c31af7Sopenharmony_ci Program(deqp::Context& context); 254e5c31af7Sopenharmony_ci ~Program(); 255e5c31af7Sopenharmony_ci 256e5c31af7Sopenharmony_ci /* Init & Release */ 257e5c31af7Sopenharmony_ci void Init(const std::string& compute_shader, const std::string& fragment_shader, const std::string& geometry_shader, 258e5c31af7Sopenharmony_ci const std::string& tesselation_control_shader, const std::string& tesselation_evaluation_shader, 259e5c31af7Sopenharmony_ci const std::string& vertex_shader); 260e5c31af7Sopenharmony_ci 261e5c31af7Sopenharmony_ci void Release(); 262e5c31af7Sopenharmony_ci 263e5c31af7Sopenharmony_ci /* Public static routines */ 264e5c31af7Sopenharmony_ci /* Functionality */ 265e5c31af7Sopenharmony_ci static void Attach(const glw::Functions& gl, glw::GLuint program_id, glw::GLuint shader_id); 266e5c31af7Sopenharmony_ci 267e5c31af7Sopenharmony_ci static void Create(const glw::Functions& gl, glw::GLuint& out_id); 268e5c31af7Sopenharmony_ci 269e5c31af7Sopenharmony_ci static void Link(const glw::Functions& gl, glw::GLuint id); 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_ci static void Use(const glw::Functions& gl, glw::GLuint id); 272e5c31af7Sopenharmony_ci 273e5c31af7Sopenharmony_ci /* Public fields */ 274e5c31af7Sopenharmony_ci glw::GLuint m_id; 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ci Shader m_compute; 277e5c31af7Sopenharmony_ci Shader m_fragment; 278e5c31af7Sopenharmony_ci Shader m_geometry; 279e5c31af7Sopenharmony_ci Shader m_tess_ctrl; 280e5c31af7Sopenharmony_ci Shader m_tess_eval; 281e5c31af7Sopenharmony_ci Shader m_vertex; 282e5c31af7Sopenharmony_ci 283e5c31af7Sopenharmony_ci /* Public constants */ 284e5c31af7Sopenharmony_ci static const glw::GLuint m_invalid_id; 285e5c31af7Sopenharmony_ci 286e5c31af7Sopenharmony_ciprivate: 287e5c31af7Sopenharmony_ci /* Private fields */ 288e5c31af7Sopenharmony_ci deqp::Context& m_context; 289e5c31af7Sopenharmony_ci}; 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ci/** Represents texture instance 292e5c31af7Sopenharmony_ci **/ 293e5c31af7Sopenharmony_ciclass Texture 294e5c31af7Sopenharmony_ci{ 295e5c31af7Sopenharmony_cipublic: 296e5c31af7Sopenharmony_ci /* Public types */ 297e5c31af7Sopenharmony_ci /* Public methods */ 298e5c31af7Sopenharmony_ci /* Ctr & Dtr */ 299e5c31af7Sopenharmony_ci Texture(deqp::Context& context); 300e5c31af7Sopenharmony_ci ~Texture(); 301e5c31af7Sopenharmony_ci 302e5c31af7Sopenharmony_ci /* Init & Release */ 303e5c31af7Sopenharmony_ci void Release(); 304e5c31af7Sopenharmony_ci 305e5c31af7Sopenharmony_ci /* Public static routines */ 306e5c31af7Sopenharmony_ci /* Extensions */ 307e5c31af7Sopenharmony_ci static void LoadExtDirectStateAccess(deqp::Context& context); 308e5c31af7Sopenharmony_ci 309e5c31af7Sopenharmony_ci /* Functionality */ 310e5c31af7Sopenharmony_ci static void Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target); 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci static void CompressedImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, 313e5c31af7Sopenharmony_ci glw::GLenum internal_format, glw::GLuint width, glw::GLuint height, glw::GLuint depth, 314e5c31af7Sopenharmony_ci glw::GLsizei image_size, const glw::GLvoid* data); 315e5c31af7Sopenharmony_ci 316e5c31af7Sopenharmony_ci static void Generate(const glw::Functions& gl, glw::GLuint& out_id); 317e5c31af7Sopenharmony_ci 318e5c31af7Sopenharmony_ci static void GetData(const glw::Functions& gl, glw::GLenum target, glw::GLenum format, glw::GLenum type, 319e5c31af7Sopenharmony_ci glw::GLvoid* out_data); 320e5c31af7Sopenharmony_ci 321e5c31af7Sopenharmony_ci static void GetLevelParameter(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum pname, 322e5c31af7Sopenharmony_ci glw::GLint* param); 323e5c31af7Sopenharmony_ci 324e5c31af7Sopenharmony_ci static void Image(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum internal_format, 325e5c31af7Sopenharmony_ci glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format, glw::GLenum type, 326e5c31af7Sopenharmony_ci const glw::GLvoid* data); 327e5c31af7Sopenharmony_ci 328e5c31af7Sopenharmony_ci static void Storage(const glw::Functions& gl, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format, 329e5c31af7Sopenharmony_ci glw::GLuint width, glw::GLuint height, glw::GLuint depth); 330e5c31af7Sopenharmony_ci 331e5c31af7Sopenharmony_ci static void SubImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLint x, glw::GLint y, 332e5c31af7Sopenharmony_ci glw::GLint z, glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth, glw::GLenum format, 333e5c31af7Sopenharmony_ci glw::GLenum type, const glw::GLvoid* pixels); 334e5c31af7Sopenharmony_ci 335e5c31af7Sopenharmony_ci /* Public fields */ 336e5c31af7Sopenharmony_ci glw::GLuint m_id; 337e5c31af7Sopenharmony_ci 338e5c31af7Sopenharmony_ci /* Public constants */ 339e5c31af7Sopenharmony_ci static const glw::GLuint m_invalid_id; 340e5c31af7Sopenharmony_ci 341e5c31af7Sopenharmony_ciprivate: 342e5c31af7Sopenharmony_ci /* Private fields */ 343e5c31af7Sopenharmony_ci deqp::Context& m_context; 344e5c31af7Sopenharmony_ci 345e5c31af7Sopenharmony_ci /* Private static fields */ 346e5c31af7Sopenharmony_ci static FUNCTIONALITY_SUPPORT m_direct_state_access_support; 347e5c31af7Sopenharmony_ci}; 348e5c31af7Sopenharmony_ci 349e5c31af7Sopenharmony_ci/** Represents Vertex array object 350e5c31af7Sopenharmony_ci * Provides basic functionality 351e5c31af7Sopenharmony_ci **/ 352e5c31af7Sopenharmony_ciclass VertexArray 353e5c31af7Sopenharmony_ci{ 354e5c31af7Sopenharmony_cipublic: 355e5c31af7Sopenharmony_ci /* Public methods */ 356e5c31af7Sopenharmony_ci /* Ctr & Dtr */ 357e5c31af7Sopenharmony_ci VertexArray(deqp::Context& Context); 358e5c31af7Sopenharmony_ci ~VertexArray(); 359e5c31af7Sopenharmony_ci 360e5c31af7Sopenharmony_ci /* Init & Release */ 361e5c31af7Sopenharmony_ci void Release(); 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci /* Public static methods */ 364e5c31af7Sopenharmony_ci static void Bind(const glw::Functions& gl, glw::GLuint id); 365e5c31af7Sopenharmony_ci static void Generate(const glw::Functions& gl, glw::GLuint& out_id); 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/* Global variables */ 379e5c31af7Sopenharmony_cistatic FUNCTIONALITY_SUPPORT m_direct_state_access_support = FUNCTIONALITY_SUPPORT_NOT_DETERMINED; 380e5c31af7Sopenharmony_ci 381e5c31af7Sopenharmony_ci/* Implementations of functions */ 382e5c31af7Sopenharmony_ci/** Get support for direct state access 383e5c31af7Sopenharmony_ci * 384e5c31af7Sopenharmony_ci * @param context CTS context 385e5c31af7Sopenharmony_ci **/ 386e5c31af7Sopenharmony_ciFUNCTIONALITY_SUPPORT getDirectStateAccessSupport(deqp::Context& context) 387e5c31af7Sopenharmony_ci{ 388e5c31af7Sopenharmony_ci if (FUNCTIONALITY_SUPPORT_NOT_DETERMINED == m_direct_state_access_support) 389e5c31af7Sopenharmony_ci { 390e5c31af7Sopenharmony_ci const Functions& gl = context.getRenderContext().getFunctions(); 391e5c31af7Sopenharmony_ci 392e5c31af7Sopenharmony_ci if (true == isGLVersionAtLeast(gl, 4, 5)) 393e5c31af7Sopenharmony_ci { 394e5c31af7Sopenharmony_ci m_direct_state_access_support = FUNCTIONALITY_SUPPORT_CORE; 395e5c31af7Sopenharmony_ci } 396e5c31af7Sopenharmony_ci else 397e5c31af7Sopenharmony_ci { 398e5c31af7Sopenharmony_ci bool is_supported = context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ci if (true == is_supported) 401e5c31af7Sopenharmony_ci { 402e5c31af7Sopenharmony_ci m_direct_state_access_support = FUNCTIONALITY_SUPPORT_EXTENSION; 403e5c31af7Sopenharmony_ci } 404e5c31af7Sopenharmony_ci else 405e5c31af7Sopenharmony_ci { 406e5c31af7Sopenharmony_ci m_direct_state_access_support = FUNCTIONALITY_SUPPORT_NONE; 407e5c31af7Sopenharmony_ci } 408e5c31af7Sopenharmony_ci } 409e5c31af7Sopenharmony_ci } 410e5c31af7Sopenharmony_ci 411e5c31af7Sopenharmony_ci return m_direct_state_access_support; 412e5c31af7Sopenharmony_ci} 413e5c31af7Sopenharmony_ci 414e5c31af7Sopenharmony_ci/** Check if GL context meets version requirements 415e5c31af7Sopenharmony_ci * 416e5c31af7Sopenharmony_ci * @param gl Functions 417e5c31af7Sopenharmony_ci * @param required_major Minimum required MAJOR_VERSION 418e5c31af7Sopenharmony_ci * @param required_minor Minimum required MINOR_VERSION 419e5c31af7Sopenharmony_ci * 420e5c31af7Sopenharmony_ci * @return true if GL context version is at least as requested, false otherwise 421e5c31af7Sopenharmony_ci **/ 422e5c31af7Sopenharmony_cibool isGLVersionAtLeast(const glw::Functions& gl, glw::GLint required_major, glw::GLint required_minor) 423e5c31af7Sopenharmony_ci{ 424e5c31af7Sopenharmony_ci glw::GLint major = 0; 425e5c31af7Sopenharmony_ci glw::GLint minor = 0; 426e5c31af7Sopenharmony_ci 427e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MAJOR_VERSION, &major); 428e5c31af7Sopenharmony_ci gl.getIntegerv(GL_MINOR_VERSION, &minor); 429e5c31af7Sopenharmony_ci 430e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); 431e5c31af7Sopenharmony_ci 432e5c31af7Sopenharmony_ci if (major > required_major) 433e5c31af7Sopenharmony_ci { 434e5c31af7Sopenharmony_ci /* Major is higher than required one */ 435e5c31af7Sopenharmony_ci return true; 436e5c31af7Sopenharmony_ci } 437e5c31af7Sopenharmony_ci else if (major == required_major) 438e5c31af7Sopenharmony_ci { 439e5c31af7Sopenharmony_ci if (minor >= required_minor) 440e5c31af7Sopenharmony_ci { 441e5c31af7Sopenharmony_ci /* Major is equal to required one */ 442e5c31af7Sopenharmony_ci /* Minor is higher than or equal to required one */ 443e5c31af7Sopenharmony_ci return true; 444e5c31af7Sopenharmony_ci } 445e5c31af7Sopenharmony_ci else 446e5c31af7Sopenharmony_ci { 447e5c31af7Sopenharmony_ci /* Major is equal to required one */ 448e5c31af7Sopenharmony_ci /* Minor is lower than required one */ 449e5c31af7Sopenharmony_ci return false; 450e5c31af7Sopenharmony_ci } 451e5c31af7Sopenharmony_ci } 452e5c31af7Sopenharmony_ci else 453e5c31af7Sopenharmony_ci { 454e5c31af7Sopenharmony_ci /* Major is lower than required one */ 455e5c31af7Sopenharmony_ci return false; 456e5c31af7Sopenharmony_ci } 457e5c31af7Sopenharmony_ci} 458e5c31af7Sopenharmony_ci 459e5c31af7Sopenharmony_ci/* Buffer constants */ 460e5c31af7Sopenharmony_ciconst GLuint Buffer::m_invalid_id = -1; 461e5c31af7Sopenharmony_ci 462e5c31af7Sopenharmony_ciconst GLenum Buffer::m_targets[Buffer::m_n_targets] = { 463e5c31af7Sopenharmony_ci GL_ARRAY_BUFFER, /* 0 */ 464e5c31af7Sopenharmony_ci GL_ATOMIC_COUNTER_BUFFER, /* 1 */ 465e5c31af7Sopenharmony_ci GL_COPY_READ_BUFFER, /* 2 */ 466e5c31af7Sopenharmony_ci GL_COPY_WRITE_BUFFER, /* 3 */ 467e5c31af7Sopenharmony_ci GL_DISPATCH_INDIRECT_BUFFER, /* 4 */ 468e5c31af7Sopenharmony_ci GL_DRAW_INDIRECT_BUFFER, /* 5 */ 469e5c31af7Sopenharmony_ci GL_ELEMENT_ARRAY_BUFFER, /* 6 */ 470e5c31af7Sopenharmony_ci GL_PIXEL_PACK_BUFFER, /* 7 */ 471e5c31af7Sopenharmony_ci GL_PIXEL_UNPACK_BUFFER, /* 8 */ 472e5c31af7Sopenharmony_ci GL_QUERY_BUFFER, /* 9 */ 473e5c31af7Sopenharmony_ci GL_SHADER_STORAGE_BUFFER, /* 10 */ 474e5c31af7Sopenharmony_ci GL_TRANSFORM_FEEDBACK_BUFFER, /* 11 */ 475e5c31af7Sopenharmony_ci GL_UNIFORM_BUFFER, /* 12 */ 476e5c31af7Sopenharmony_ci}; 477e5c31af7Sopenharmony_ci 478e5c31af7Sopenharmony_ci/** Constructor. 479e5c31af7Sopenharmony_ci * 480e5c31af7Sopenharmony_ci * @param context CTS context. 481e5c31af7Sopenharmony_ci **/ 482e5c31af7Sopenharmony_ciBuffer::Buffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context), m_target(GL_ARRAY_BUFFER) 483e5c31af7Sopenharmony_ci{ 484e5c31af7Sopenharmony_ci} 485e5c31af7Sopenharmony_ci 486e5c31af7Sopenharmony_ci/** Destructor 487e5c31af7Sopenharmony_ci * 488e5c31af7Sopenharmony_ci **/ 489e5c31af7Sopenharmony_ciBuffer::~Buffer() 490e5c31af7Sopenharmony_ci{ 491e5c31af7Sopenharmony_ci Release(); 492e5c31af7Sopenharmony_ci} 493e5c31af7Sopenharmony_ci 494e5c31af7Sopenharmony_ci/** Initialize buffer instance 495e5c31af7Sopenharmony_ci * 496e5c31af7Sopenharmony_ci * @param target Buffer target 497e5c31af7Sopenharmony_ci * @param usage Buffer usage enum 498e5c31af7Sopenharmony_ci * @param size <size> parameter 499e5c31af7Sopenharmony_ci * @param data <data> parameter 500e5c31af7Sopenharmony_ci **/ 501e5c31af7Sopenharmony_civoid Buffer::InitData(glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size, const glw::GLvoid* data) 502e5c31af7Sopenharmony_ci{ 503e5c31af7Sopenharmony_ci /* Delete previous buffer instance */ 504e5c31af7Sopenharmony_ci Release(); 505e5c31af7Sopenharmony_ci 506e5c31af7Sopenharmony_ci m_target = target; 507e5c31af7Sopenharmony_ci 508e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 509e5c31af7Sopenharmony_ci 510e5c31af7Sopenharmony_ci Generate(gl, m_id); 511e5c31af7Sopenharmony_ci Bind(gl, m_id, m_target); 512e5c31af7Sopenharmony_ci Data(gl, m_target, usage, size, data); 513e5c31af7Sopenharmony_ci} 514e5c31af7Sopenharmony_ci 515e5c31af7Sopenharmony_ci/** Initialize buffer instance 516e5c31af7Sopenharmony_ci * 517e5c31af7Sopenharmony_ci * @param target Buffer target 518e5c31af7Sopenharmony_ci * @param usage Buffer usage enum 519e5c31af7Sopenharmony_ci * @param size <size> parameter 520e5c31af7Sopenharmony_ci * @param data <data> parameter 521e5c31af7Sopenharmony_ci **/ 522e5c31af7Sopenharmony_civoid Buffer::InitStorage(glw::GLenum target, glw::GLenum flags, glw::GLsizeiptr size, const glw::GLvoid* data) 523e5c31af7Sopenharmony_ci{ 524e5c31af7Sopenharmony_ci /* Delete previous buffer instance */ 525e5c31af7Sopenharmony_ci Release(); 526e5c31af7Sopenharmony_ci 527e5c31af7Sopenharmony_ci m_target = target; 528e5c31af7Sopenharmony_ci 529e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_ci Generate(gl, m_id); 532e5c31af7Sopenharmony_ci Bind(gl, m_id, m_target); 533e5c31af7Sopenharmony_ci Storage(gl, m_target, flags, size, data); 534e5c31af7Sopenharmony_ci} 535e5c31af7Sopenharmony_ci 536e5c31af7Sopenharmony_ci/** Release buffer instance 537e5c31af7Sopenharmony_ci * 538e5c31af7Sopenharmony_ci **/ 539e5c31af7Sopenharmony_civoid Buffer::Release() 540e5c31af7Sopenharmony_ci{ 541e5c31af7Sopenharmony_ci if (m_invalid_id != m_id) 542e5c31af7Sopenharmony_ci { 543e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 544e5c31af7Sopenharmony_ci 545e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &m_id); 546e5c31af7Sopenharmony_ci m_id = m_invalid_id; 547e5c31af7Sopenharmony_ci } 548e5c31af7Sopenharmony_ci} 549e5c31af7Sopenharmony_ci 550e5c31af7Sopenharmony_ci/** Binds buffer to its target 551e5c31af7Sopenharmony_ci * 552e5c31af7Sopenharmony_ci **/ 553e5c31af7Sopenharmony_civoid Buffer::Bind() const 554e5c31af7Sopenharmony_ci{ 555e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 556e5c31af7Sopenharmony_ci 557e5c31af7Sopenharmony_ci Bind(gl, m_id, m_target); 558e5c31af7Sopenharmony_ci} 559e5c31af7Sopenharmony_ci 560e5c31af7Sopenharmony_ci/** Binds indexed buffer 561e5c31af7Sopenharmony_ci * 562e5c31af7Sopenharmony_ci * @param index <index> parameter 563e5c31af7Sopenharmony_ci **/ 564e5c31af7Sopenharmony_civoid Buffer::BindBase(glw::GLuint index) const 565e5c31af7Sopenharmony_ci{ 566e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 567e5c31af7Sopenharmony_ci 568e5c31af7Sopenharmony_ci BindBase(gl, m_id, m_target, index); 569e5c31af7Sopenharmony_ci} 570e5c31af7Sopenharmony_ci 571e5c31af7Sopenharmony_ci/** Binds range of buffer 572e5c31af7Sopenharmony_ci * 573e5c31af7Sopenharmony_ci * @param index <index> parameter 574e5c31af7Sopenharmony_ci * @param offset <offset> parameter 575e5c31af7Sopenharmony_ci * @param size <size> parameter 576e5c31af7Sopenharmony_ci **/ 577e5c31af7Sopenharmony_civoid Buffer::BindRange(glw::GLuint index, glw::GLintptr offset, glw::GLsizeiptr size) const 578e5c31af7Sopenharmony_ci{ 579e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 580e5c31af7Sopenharmony_ci 581e5c31af7Sopenharmony_ci BindRange(gl, m_id, m_target, index, offset, size); 582e5c31af7Sopenharmony_ci} 583e5c31af7Sopenharmony_ci 584e5c31af7Sopenharmony_ci/** Maps contents of buffer into CPU space 585e5c31af7Sopenharmony_ci * 586e5c31af7Sopenharmony_ci * @param access Requested access 587e5c31af7Sopenharmony_ci * 588e5c31af7Sopenharmony_ci * @return Pointer to memory region available for CPU 589e5c31af7Sopenharmony_ci **/ 590e5c31af7Sopenharmony_ciBuffer::MoveMapOwner Buffer::MapRange(glw::GLintptr offset, glw::GLsizeiptr length, glw::GLenum access) 591e5c31af7Sopenharmony_ci{ 592e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 593e5c31af7Sopenharmony_ci 594e5c31af7Sopenharmony_ci Bind(gl, m_id, m_target); 595e5c31af7Sopenharmony_ci 596e5c31af7Sopenharmony_ci void* data = MapRange(gl, m_target, offset, length, access); 597e5c31af7Sopenharmony_ci 598e5c31af7Sopenharmony_ci MoveMapOwner map(this, data); 599e5c31af7Sopenharmony_ci 600e5c31af7Sopenharmony_ci return map; 601e5c31af7Sopenharmony_ci} 602e5c31af7Sopenharmony_ci 603e5c31af7Sopenharmony_ci/** Unmaps contents of buffer 604e5c31af7Sopenharmony_ci * 605e5c31af7Sopenharmony_ci **/ 606e5c31af7Sopenharmony_civoid Buffer::UnMap() 607e5c31af7Sopenharmony_ci{ 608e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 609e5c31af7Sopenharmony_ci 610e5c31af7Sopenharmony_ci UnMap(gl, m_target); 611e5c31af7Sopenharmony_ci} 612e5c31af7Sopenharmony_ci 613e5c31af7Sopenharmony_ci/** Loads entry points for direct state access extension 614e5c31af7Sopenharmony_ci * 615e5c31af7Sopenharmony_ci * @param context CTS context 616e5c31af7Sopenharmony_ci **/ 617e5c31af7Sopenharmony_civoid Buffer::LoadExtDirectStateAccess(deqp::Context& context) 618e5c31af7Sopenharmony_ci{ 619e5c31af7Sopenharmony_ci FUNCTIONALITY_SUPPORT support = getDirectStateAccessSupport(context); 620e5c31af7Sopenharmony_ci 621e5c31af7Sopenharmony_ci switch (support) 622e5c31af7Sopenharmony_ci { 623e5c31af7Sopenharmony_ci case FUNCTIONALITY_SUPPORT_NONE: 624e5c31af7Sopenharmony_ci /* Nothing to be done */ 625e5c31af7Sopenharmony_ci break; 626e5c31af7Sopenharmony_ci case FUNCTIONALITY_SUPPORT_CORE: 627e5c31af7Sopenharmony_ci case FUNCTIONALITY_SUPPORT_EXTENSION: 628e5c31af7Sopenharmony_ci break; 629e5c31af7Sopenharmony_ci default: 630e5c31af7Sopenharmony_ci TCU_FAIL("Invalid enum"); 631e5c31af7Sopenharmony_ci } 632e5c31af7Sopenharmony_ci} 633e5c31af7Sopenharmony_ci 634e5c31af7Sopenharmony_ci/** Bind buffer to given target 635e5c31af7Sopenharmony_ci * 636e5c31af7Sopenharmony_ci * @param gl GL functions 637e5c31af7Sopenharmony_ci * @param id Id of buffer 638e5c31af7Sopenharmony_ci * @param target Buffer target 639e5c31af7Sopenharmony_ci **/ 640e5c31af7Sopenharmony_civoid Buffer::Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target) 641e5c31af7Sopenharmony_ci{ 642e5c31af7Sopenharmony_ci gl.bindBuffer(target, id); 643e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBuffer"); 644e5c31af7Sopenharmony_ci} 645e5c31af7Sopenharmony_ci 646e5c31af7Sopenharmony_ci/** Binds indexed buffer 647e5c31af7Sopenharmony_ci * 648e5c31af7Sopenharmony_ci * @param gl GL functions 649e5c31af7Sopenharmony_ci * @param id Id of buffer 650e5c31af7Sopenharmony_ci * @param target Buffer target 651e5c31af7Sopenharmony_ci * @param index <index> parameter 652e5c31af7Sopenharmony_ci **/ 653e5c31af7Sopenharmony_civoid Buffer::BindBase(const glw::Functions& gl, glw::GLuint id, glw::GLenum target, glw::GLuint index) 654e5c31af7Sopenharmony_ci{ 655e5c31af7Sopenharmony_ci gl.bindBufferBase(target, index, id); 656e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferBase"); 657e5c31af7Sopenharmony_ci} 658e5c31af7Sopenharmony_ci 659e5c31af7Sopenharmony_ci/** Binds buffer range 660e5c31af7Sopenharmony_ci * 661e5c31af7Sopenharmony_ci * @param gl GL functions 662e5c31af7Sopenharmony_ci * @param id Id of buffer 663e5c31af7Sopenharmony_ci * @param target Buffer target 664e5c31af7Sopenharmony_ci * @param index <index> parameter 665e5c31af7Sopenharmony_ci * @param offset <offset> parameter 666e5c31af7Sopenharmony_ci * @param size <size> parameter 667e5c31af7Sopenharmony_ci **/ 668e5c31af7Sopenharmony_civoid Buffer::BindRange(const glw::Functions& gl, glw::GLuint id, glw::GLenum target, glw::GLuint index, 669e5c31af7Sopenharmony_ci glw::GLintptr offset, glw::GLsizeiptr size) 670e5c31af7Sopenharmony_ci{ 671e5c31af7Sopenharmony_ci gl.bindBufferRange(target, index, id, offset, size); 672e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindBufferRange"); 673e5c31af7Sopenharmony_ci} 674e5c31af7Sopenharmony_ci 675e5c31af7Sopenharmony_ci/** Allocate memory for buffer and sends initial content 676e5c31af7Sopenharmony_ci * 677e5c31af7Sopenharmony_ci * @param gl GL functions 678e5c31af7Sopenharmony_ci * @param target Buffer target 679e5c31af7Sopenharmony_ci * @param usage Buffer usage enum 680e5c31af7Sopenharmony_ci * @param size <size> parameter 681e5c31af7Sopenharmony_ci * @param data <data> parameter 682e5c31af7Sopenharmony_ci **/ 683e5c31af7Sopenharmony_civoid Buffer::Data(const glw::Functions& gl, glw::GLenum target, glw::GLenum usage, glw::GLsizeiptr size, 684e5c31af7Sopenharmony_ci const glw::GLvoid* data) 685e5c31af7Sopenharmony_ci{ 686e5c31af7Sopenharmony_ci gl.bufferData(target, size, data, usage); 687e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BufferData"); 688e5c31af7Sopenharmony_ci} 689e5c31af7Sopenharmony_ci 690e5c31af7Sopenharmony_ci/** Generate buffer 691e5c31af7Sopenharmony_ci * 692e5c31af7Sopenharmony_ci * @param gl GL functions 693e5c31af7Sopenharmony_ci * @param out_id Id of buffer 694e5c31af7Sopenharmony_ci **/ 695e5c31af7Sopenharmony_civoid Buffer::Generate(const glw::Functions& gl, glw::GLuint& out_id) 696e5c31af7Sopenharmony_ci{ 697e5c31af7Sopenharmony_ci GLuint id = m_invalid_id; 698e5c31af7Sopenharmony_ci 699e5c31af7Sopenharmony_ci gl.genBuffers(1, &id); 700e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenBuffers"); 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_ci if (m_invalid_id == id) 703e5c31af7Sopenharmony_ci { 704e5c31af7Sopenharmony_ci TCU_FAIL("Got invalid id"); 705e5c31af7Sopenharmony_ci } 706e5c31af7Sopenharmony_ci 707e5c31af7Sopenharmony_ci out_id = id; 708e5c31af7Sopenharmony_ci} 709e5c31af7Sopenharmony_ci 710e5c31af7Sopenharmony_ci/** Query parameter of named buffer 711e5c31af7Sopenharmony_ci * 712e5c31af7Sopenharmony_ci * @param gl GL functions 713e5c31af7Sopenharmony_ci * @param buffer Buffer name 714e5c31af7Sopenharmony_ci * @param pname Parameter name 715e5c31af7Sopenharmony_ci * @param data Storage for queried results 716e5c31af7Sopenharmony_ci **/ 717e5c31af7Sopenharmony_civoid Buffer::GetNamedParameter(const glw::Functions& gl, glw::GLuint buffer, glw::GLenum pname, glw::GLint* data) 718e5c31af7Sopenharmony_ci{ 719e5c31af7Sopenharmony_ci gl.getNamedBufferParameteriv(buffer, pname, data); 720e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetNameBufferParameteriv"); 721e5c31af7Sopenharmony_ci} 722e5c31af7Sopenharmony_ci 723e5c31af7Sopenharmony_ci/** Query parameter of bound buffer 724e5c31af7Sopenharmony_ci * 725e5c31af7Sopenharmony_ci * @param gl GL functions 726e5c31af7Sopenharmony_ci * @param Target Buffer target 727e5c31af7Sopenharmony_ci * @param pname Parameter name 728e5c31af7Sopenharmony_ci * @param data Storage for queried results 729e5c31af7Sopenharmony_ci **/ 730e5c31af7Sopenharmony_civoid Buffer::GetParameter(const glw::Functions& gl, glw::GLenum target, glw::GLenum value, glw::GLint* data) 731e5c31af7Sopenharmony_ci{ 732e5c31af7Sopenharmony_ci gl.getBufferParameteriv(target, value, data); 733e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetBufferParameteriv"); 734e5c31af7Sopenharmony_ci} 735e5c31af7Sopenharmony_ci 736e5c31af7Sopenharmony_ci/** Get contents of buffer's region 737e5c31af7Sopenharmony_ci * 738e5c31af7Sopenharmony_ci * @param gl GL functions 739e5c31af7Sopenharmony_ci * @param target Buffer target 740e5c31af7Sopenharmony_ci * @param offset Offset in buffer 741e5c31af7Sopenharmony_ci * @param size <size> parameter 742e5c31af7Sopenharmony_ci * @param data <data> parameter 743e5c31af7Sopenharmony_ci **/ 744e5c31af7Sopenharmony_civoid Buffer::GetSubData(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr size, 745e5c31af7Sopenharmony_ci glw::GLvoid* data) 746e5c31af7Sopenharmony_ci{ 747e5c31af7Sopenharmony_ci gl.getBufferSubData(target, offset, size, data); 748e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetBufferSubData"); 749e5c31af7Sopenharmony_ci} 750e5c31af7Sopenharmony_ci 751e5c31af7Sopenharmony_ci/** Maps buffer content 752e5c31af7Sopenharmony_ci * 753e5c31af7Sopenharmony_ci * @param gl GL functions 754e5c31af7Sopenharmony_ci * @param target Buffer target 755e5c31af7Sopenharmony_ci * @param access Access rights for mapped region 756e5c31af7Sopenharmony_ci * 757e5c31af7Sopenharmony_ci * @return Mapped memory 758e5c31af7Sopenharmony_ci **/ 759e5c31af7Sopenharmony_civoid* Buffer::Map(const glw::Functions& gl, glw::GLenum target, glw::GLenum access) 760e5c31af7Sopenharmony_ci{ 761e5c31af7Sopenharmony_ci void* result = gl.mapBuffer(target, access); 762e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MapBuffer"); 763e5c31af7Sopenharmony_ci 764e5c31af7Sopenharmony_ci return result; 765e5c31af7Sopenharmony_ci} 766e5c31af7Sopenharmony_ci 767e5c31af7Sopenharmony_ci/** Maps buffer content 768e5c31af7Sopenharmony_ci * 769e5c31af7Sopenharmony_ci * @param gl GL functions 770e5c31af7Sopenharmony_ci * @param target Buffer target 771e5c31af7Sopenharmony_ci * @param access Access rights for mapped region 772e5c31af7Sopenharmony_ci * 773e5c31af7Sopenharmony_ci * @return Mapped memory 774e5c31af7Sopenharmony_ci **/ 775e5c31af7Sopenharmony_civoid* Buffer::MapRange(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr length, 776e5c31af7Sopenharmony_ci glw::GLenum access) 777e5c31af7Sopenharmony_ci{ 778e5c31af7Sopenharmony_ci void* result = gl.mapBufferRange(target, offset, length, access); 779e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MapBufferRange"); 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ci return result; 782e5c31af7Sopenharmony_ci} 783e5c31af7Sopenharmony_ci 784e5c31af7Sopenharmony_ci/** Allocate immutable memory for buffer and sends initial content 785e5c31af7Sopenharmony_ci * 786e5c31af7Sopenharmony_ci * @param gl GL functions 787e5c31af7Sopenharmony_ci * @param target Buffer target 788e5c31af7Sopenharmony_ci * @param flags Buffer flags 789e5c31af7Sopenharmony_ci * @param size <size> parameter 790e5c31af7Sopenharmony_ci * @param data <data> parameter 791e5c31af7Sopenharmony_ci **/ 792e5c31af7Sopenharmony_civoid Buffer::Storage(const glw::Functions& gl, glw::GLenum target, glw::GLenum flags, glw::GLsizeiptr size, 793e5c31af7Sopenharmony_ci const glw::GLvoid* data) 794e5c31af7Sopenharmony_ci{ 795e5c31af7Sopenharmony_ci gl.bufferStorage(target, size, data, flags); 796e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BufferStorage"); 797e5c31af7Sopenharmony_ci} 798e5c31af7Sopenharmony_ci 799e5c31af7Sopenharmony_ci/** Update range of buffer 800e5c31af7Sopenharmony_ci * 801e5c31af7Sopenharmony_ci * @param gl GL functions 802e5c31af7Sopenharmony_ci * @param target Buffer target 803e5c31af7Sopenharmony_ci * @param offset Offset in buffer 804e5c31af7Sopenharmony_ci * @param size <size> parameter 805e5c31af7Sopenharmony_ci * @param data <data> parameter 806e5c31af7Sopenharmony_ci **/ 807e5c31af7Sopenharmony_civoid Buffer::SubData(const glw::Functions& gl, glw::GLenum target, glw::GLintptr offset, glw::GLsizeiptr size, 808e5c31af7Sopenharmony_ci glw::GLvoid* data) 809e5c31af7Sopenharmony_ci{ 810e5c31af7Sopenharmony_ci gl.bufferSubData(target, offset, size, data); 811e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData"); 812e5c31af7Sopenharmony_ci} 813e5c31af7Sopenharmony_ci 814e5c31af7Sopenharmony_ci/** Unmaps buffer 815e5c31af7Sopenharmony_ci * 816e5c31af7Sopenharmony_ci * @param gl GL functions 817e5c31af7Sopenharmony_ci * @param target Buffer target 818e5c31af7Sopenharmony_ci **/ 819e5c31af7Sopenharmony_civoid Buffer::UnMap(const glw::Functions& gl, glw::GLenum target) 820e5c31af7Sopenharmony_ci{ 821e5c31af7Sopenharmony_ci gl.unmapBuffer(target); 822e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); 823e5c31af7Sopenharmony_ci} 824e5c31af7Sopenharmony_ci 825e5c31af7Sopenharmony_ci/** Constructor 826e5c31af7Sopenharmony_ci * Takes ownership of mapped region 827e5c31af7Sopenharmony_ci * 828e5c31af7Sopenharmony_ci * @param buffer Mapped buffer 829e5c31af7Sopenharmony_ci * @param data Mapped data 830e5c31af7Sopenharmony_ci **/ 831e5c31af7Sopenharmony_ciBuffer::MapOwner::MapOwner(Buffer& buffer, glw::GLvoid* data) : m_data(data), m_buffer(&buffer) 832e5c31af7Sopenharmony_ci{ 833e5c31af7Sopenharmony_ci /* Nothing to be done */ 834e5c31af7Sopenharmony_ci} 835e5c31af7Sopenharmony_ci 836e5c31af7Sopenharmony_ciBuffer::MapOwner::MapOwner(const Buffer::MoveMapOwner& moveOwner) : m_data(moveOwner.data), m_buffer(moveOwner.buffer) 837e5c31af7Sopenharmony_ci{ 838e5c31af7Sopenharmony_ci} 839e5c31af7Sopenharmony_ci 840e5c31af7Sopenharmony_ci/** Move constructor 841e5c31af7Sopenharmony_ci * Transfer ownership of mapped region. 842e5c31af7Sopenharmony_ci * 843e5c31af7Sopenharmony_ci * @param map_owner Map owner 844e5c31af7Sopenharmony_ci **/ 845e5c31af7Sopenharmony_ciBuffer::MapOwner::MapOwner(MapOwner& map_owner) : m_data(map_owner.m_data), m_buffer(map_owner.m_buffer) 846e5c31af7Sopenharmony_ci{ 847e5c31af7Sopenharmony_ci map_owner.m_data = 0; 848e5c31af7Sopenharmony_ci map_owner.m_buffer = 0; 849e5c31af7Sopenharmony_ci} 850e5c31af7Sopenharmony_ci 851e5c31af7Sopenharmony_ci/** Destructor 852e5c31af7Sopenharmony_ci * Unmaps buffer 853e5c31af7Sopenharmony_ci **/ 854e5c31af7Sopenharmony_ciBuffer::MapOwner::~MapOwner() 855e5c31af7Sopenharmony_ci{ 856e5c31af7Sopenharmony_ci m_data = 0; 857e5c31af7Sopenharmony_ci if (0 != m_buffer) 858e5c31af7Sopenharmony_ci { 859e5c31af7Sopenharmony_ci m_buffer->Bind(); 860e5c31af7Sopenharmony_ci m_buffer->UnMap(); 861e5c31af7Sopenharmony_ci m_buffer = 0; 862e5c31af7Sopenharmony_ci } 863e5c31af7Sopenharmony_ci} 864e5c31af7Sopenharmony_ci 865e5c31af7Sopenharmony_ci/* Framebuffer constants */ 866e5c31af7Sopenharmony_ciconst GLuint Framebuffer::m_invalid_id = -1; 867e5c31af7Sopenharmony_ci 868e5c31af7Sopenharmony_ci/** Constructor. 869e5c31af7Sopenharmony_ci * 870e5c31af7Sopenharmony_ci * @param context CTS context. 871e5c31af7Sopenharmony_ci **/ 872e5c31af7Sopenharmony_ciFramebuffer::Framebuffer(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 873e5c31af7Sopenharmony_ci{ 874e5c31af7Sopenharmony_ci /* Nothing to done here */ 875e5c31af7Sopenharmony_ci} 876e5c31af7Sopenharmony_ci 877e5c31af7Sopenharmony_ci/** Destructor 878e5c31af7Sopenharmony_ci * 879e5c31af7Sopenharmony_ci **/ 880e5c31af7Sopenharmony_ciFramebuffer::~Framebuffer() 881e5c31af7Sopenharmony_ci{ 882e5c31af7Sopenharmony_ci Release(); 883e5c31af7Sopenharmony_ci} 884e5c31af7Sopenharmony_ci 885e5c31af7Sopenharmony_ci/** Release texture instance 886e5c31af7Sopenharmony_ci * 887e5c31af7Sopenharmony_ci **/ 888e5c31af7Sopenharmony_civoid Framebuffer::Release() 889e5c31af7Sopenharmony_ci{ 890e5c31af7Sopenharmony_ci if (m_invalid_id != m_id) 891e5c31af7Sopenharmony_ci { 892e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 893e5c31af7Sopenharmony_ci 894e5c31af7Sopenharmony_ci gl.deleteFramebuffers(1, &m_id); 895e5c31af7Sopenharmony_ci m_id = m_invalid_id; 896e5c31af7Sopenharmony_ci } 897e5c31af7Sopenharmony_ci} 898e5c31af7Sopenharmony_ci 899e5c31af7Sopenharmony_ci/** Attach texture to specified attachment 900e5c31af7Sopenharmony_ci * 901e5c31af7Sopenharmony_ci * @param gl GL functions 902e5c31af7Sopenharmony_ci * @param target Framebuffer target 903e5c31af7Sopenharmony_ci * @param attachment Attachment 904e5c31af7Sopenharmony_ci * @param texture_id Texture id 905e5c31af7Sopenharmony_ci * @param width Texture width 906e5c31af7Sopenharmony_ci * @param height Texture height 907e5c31af7Sopenharmony_ci **/ 908e5c31af7Sopenharmony_civoid Framebuffer::AttachTexture(const glw::Functions& gl, glw::GLenum target, glw::GLenum attachment, 909e5c31af7Sopenharmony_ci glw::GLuint texture_id, glw::GLuint width, glw::GLuint height) 910e5c31af7Sopenharmony_ci{ 911e5c31af7Sopenharmony_ci gl.framebufferTexture(target, attachment, texture_id, 0 /* level */); 912e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture"); 913e5c31af7Sopenharmony_ci 914e5c31af7Sopenharmony_ci gl.viewport(0 /* x */, 0 /* y */, width, height); 915e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport"); 916e5c31af7Sopenharmony_ci} 917e5c31af7Sopenharmony_ci 918e5c31af7Sopenharmony_ci/** Binds framebuffer to DRAW_FRAMEBUFFER 919e5c31af7Sopenharmony_ci * 920e5c31af7Sopenharmony_ci * @param gl GL functions 921e5c31af7Sopenharmony_ci * @param target Framebuffer target 922e5c31af7Sopenharmony_ci * @param id ID of framebuffer 923e5c31af7Sopenharmony_ci **/ 924e5c31af7Sopenharmony_civoid Framebuffer::Bind(const glw::Functions& gl, glw::GLenum target, glw::GLuint id) 925e5c31af7Sopenharmony_ci{ 926e5c31af7Sopenharmony_ci gl.bindFramebuffer(target, id); 927e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer"); 928e5c31af7Sopenharmony_ci} 929e5c31af7Sopenharmony_ci 930e5c31af7Sopenharmony_ci/** Generate framebuffer 931e5c31af7Sopenharmony_ci * 932e5c31af7Sopenharmony_ci **/ 933e5c31af7Sopenharmony_civoid Framebuffer::Generate(const glw::Functions& gl, glw::GLuint& out_id) 934e5c31af7Sopenharmony_ci{ 935e5c31af7Sopenharmony_ci GLuint id = m_invalid_id; 936e5c31af7Sopenharmony_ci 937e5c31af7Sopenharmony_ci gl.genFramebuffers(1, &id); 938e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers"); 939e5c31af7Sopenharmony_ci 940e5c31af7Sopenharmony_ci if (m_invalid_id == id) 941e5c31af7Sopenharmony_ci { 942e5c31af7Sopenharmony_ci TCU_FAIL("Invalid id"); 943e5c31af7Sopenharmony_ci } 944e5c31af7Sopenharmony_ci 945e5c31af7Sopenharmony_ci out_id = id; 946e5c31af7Sopenharmony_ci} 947e5c31af7Sopenharmony_ci 948e5c31af7Sopenharmony_ci/* Program constants */ 949e5c31af7Sopenharmony_ciconst GLuint Program::m_invalid_id = 0; 950e5c31af7Sopenharmony_ci 951e5c31af7Sopenharmony_ci/** Constructor. 952e5c31af7Sopenharmony_ci * 953e5c31af7Sopenharmony_ci * @param context CTS context. 954e5c31af7Sopenharmony_ci **/ 955e5c31af7Sopenharmony_ciProgram::Program(deqp::Context& context) 956e5c31af7Sopenharmony_ci : m_id(m_invalid_id) 957e5c31af7Sopenharmony_ci , m_compute(context) 958e5c31af7Sopenharmony_ci , m_fragment(context) 959e5c31af7Sopenharmony_ci , m_geometry(context) 960e5c31af7Sopenharmony_ci , m_tess_ctrl(context) 961e5c31af7Sopenharmony_ci , m_tess_eval(context) 962e5c31af7Sopenharmony_ci , m_vertex(context) 963e5c31af7Sopenharmony_ci , m_context(context) 964e5c31af7Sopenharmony_ci{ 965e5c31af7Sopenharmony_ci /* Nothing to be done here */ 966e5c31af7Sopenharmony_ci} 967e5c31af7Sopenharmony_ci 968e5c31af7Sopenharmony_ci/** Destructor 969e5c31af7Sopenharmony_ci * 970e5c31af7Sopenharmony_ci **/ 971e5c31af7Sopenharmony_ciProgram::~Program() 972e5c31af7Sopenharmony_ci{ 973e5c31af7Sopenharmony_ci Release(); 974e5c31af7Sopenharmony_ci} 975e5c31af7Sopenharmony_ci 976e5c31af7Sopenharmony_ci/** Initialize program instance 977e5c31af7Sopenharmony_ci * 978e5c31af7Sopenharmony_ci * @param compute_shader Compute shader source code 979e5c31af7Sopenharmony_ci * @param fragment_shader Fragment shader source code 980e5c31af7Sopenharmony_ci * @param geometry_shader Geometry shader source code 981e5c31af7Sopenharmony_ci * @param tesselation_control_shader Tesselation control shader source code 982e5c31af7Sopenharmony_ci * @param tesselation_evaluation_shader Tesselation evaluation shader source code 983e5c31af7Sopenharmony_ci * @param vertex_shader Vertex shader source code 984e5c31af7Sopenharmony_ci **/ 985e5c31af7Sopenharmony_civoid Program::Init(const std::string& compute_shader, const std::string& fragment_shader, 986e5c31af7Sopenharmony_ci const std::string& geometry_shader, const std::string& tesselation_control_shader, 987e5c31af7Sopenharmony_ci const std::string& tesselation_evaluation_shader, const std::string& vertex_shader) 988e5c31af7Sopenharmony_ci{ 989e5c31af7Sopenharmony_ci /* Delete previous program */ 990e5c31af7Sopenharmony_ci Release(); 991e5c31af7Sopenharmony_ci 992e5c31af7Sopenharmony_ci /* GL entry points */ 993e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 994e5c31af7Sopenharmony_ci 995e5c31af7Sopenharmony_ci /* Initialize shaders */ 996e5c31af7Sopenharmony_ci m_compute.Init(GL_COMPUTE_SHADER, compute_shader); 997e5c31af7Sopenharmony_ci m_fragment.Init(GL_FRAGMENT_SHADER, fragment_shader); 998e5c31af7Sopenharmony_ci m_geometry.Init(GL_GEOMETRY_SHADER, geometry_shader); 999e5c31af7Sopenharmony_ci m_tess_ctrl.Init(GL_TESS_CONTROL_SHADER, tesselation_control_shader); 1000e5c31af7Sopenharmony_ci m_tess_eval.Init(GL_TESS_EVALUATION_SHADER, tesselation_evaluation_shader); 1001e5c31af7Sopenharmony_ci m_vertex.Init(GL_VERTEX_SHADER, vertex_shader); 1002e5c31af7Sopenharmony_ci 1003e5c31af7Sopenharmony_ci /* Create program, set up transform feedback and attach shaders */ 1004e5c31af7Sopenharmony_ci Create(gl, m_id); 1005e5c31af7Sopenharmony_ci Attach(gl, m_id, m_compute.m_id); 1006e5c31af7Sopenharmony_ci Attach(gl, m_id, m_fragment.m_id); 1007e5c31af7Sopenharmony_ci Attach(gl, m_id, m_geometry.m_id); 1008e5c31af7Sopenharmony_ci Attach(gl, m_id, m_tess_ctrl.m_id); 1009e5c31af7Sopenharmony_ci Attach(gl, m_id, m_tess_eval.m_id); 1010e5c31af7Sopenharmony_ci Attach(gl, m_id, m_vertex.m_id); 1011e5c31af7Sopenharmony_ci 1012e5c31af7Sopenharmony_ci /* Link program */ 1013e5c31af7Sopenharmony_ci Link(gl, m_id); 1014e5c31af7Sopenharmony_ci} 1015e5c31af7Sopenharmony_ci 1016e5c31af7Sopenharmony_ci/** Release program instance 1017e5c31af7Sopenharmony_ci * 1018e5c31af7Sopenharmony_ci **/ 1019e5c31af7Sopenharmony_civoid Program::Release() 1020e5c31af7Sopenharmony_ci{ 1021e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 1022e5c31af7Sopenharmony_ci 1023e5c31af7Sopenharmony_ci if (m_invalid_id != m_id) 1024e5c31af7Sopenharmony_ci { 1025e5c31af7Sopenharmony_ci Use(gl, m_invalid_id); 1026e5c31af7Sopenharmony_ci 1027e5c31af7Sopenharmony_ci gl.deleteProgram(m_id); 1028e5c31af7Sopenharmony_ci m_id = m_invalid_id; 1029e5c31af7Sopenharmony_ci } 1030e5c31af7Sopenharmony_ci 1031e5c31af7Sopenharmony_ci m_compute.Release(); 1032e5c31af7Sopenharmony_ci m_fragment.Release(); 1033e5c31af7Sopenharmony_ci m_geometry.Release(); 1034e5c31af7Sopenharmony_ci m_tess_ctrl.Release(); 1035e5c31af7Sopenharmony_ci m_tess_eval.Release(); 1036e5c31af7Sopenharmony_ci m_vertex.Release(); 1037e5c31af7Sopenharmony_ci} 1038e5c31af7Sopenharmony_ci 1039e5c31af7Sopenharmony_ci/** Attach shader to program 1040e5c31af7Sopenharmony_ci * 1041e5c31af7Sopenharmony_ci * @param gl GL functions 1042e5c31af7Sopenharmony_ci * @param program_id Id of program 1043e5c31af7Sopenharmony_ci * @param shader_id Id of shader 1044e5c31af7Sopenharmony_ci **/ 1045e5c31af7Sopenharmony_civoid Program::Attach(const glw::Functions& gl, glw::GLuint program_id, glw::GLuint shader_id) 1046e5c31af7Sopenharmony_ci{ 1047e5c31af7Sopenharmony_ci /* Quick checks */ 1048e5c31af7Sopenharmony_ci if ((m_invalid_id == program_id) || (Shader::m_invalid_id == shader_id)) 1049e5c31af7Sopenharmony_ci { 1050e5c31af7Sopenharmony_ci return; 1051e5c31af7Sopenharmony_ci } 1052e5c31af7Sopenharmony_ci 1053e5c31af7Sopenharmony_ci gl.attachShader(program_id, shader_id); 1054e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader"); 1055e5c31af7Sopenharmony_ci} 1056e5c31af7Sopenharmony_ci 1057e5c31af7Sopenharmony_ci/** Create program instance 1058e5c31af7Sopenharmony_ci * 1059e5c31af7Sopenharmony_ci * @param gl GL functions 1060e5c31af7Sopenharmony_ci * @param out_id Id of program 1061e5c31af7Sopenharmony_ci **/ 1062e5c31af7Sopenharmony_civoid Program::Create(const glw::Functions& gl, glw::GLuint& out_id) 1063e5c31af7Sopenharmony_ci{ 1064e5c31af7Sopenharmony_ci const GLuint id = gl.createProgram(); 1065e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram"); 1066e5c31af7Sopenharmony_ci 1067e5c31af7Sopenharmony_ci if (m_invalid_id == id) 1068e5c31af7Sopenharmony_ci { 1069e5c31af7Sopenharmony_ci TCU_FAIL("Failed to create program"); 1070e5c31af7Sopenharmony_ci } 1071e5c31af7Sopenharmony_ci 1072e5c31af7Sopenharmony_ci out_id = id; 1073e5c31af7Sopenharmony_ci} 1074e5c31af7Sopenharmony_ci 1075e5c31af7Sopenharmony_ci/** Link program 1076e5c31af7Sopenharmony_ci * 1077e5c31af7Sopenharmony_ci * @param gl GL functions 1078e5c31af7Sopenharmony_ci * @param id Id of program 1079e5c31af7Sopenharmony_ci **/ 1080e5c31af7Sopenharmony_civoid Program::Link(const glw::Functions& gl, glw::GLuint id) 1081e5c31af7Sopenharmony_ci{ 1082e5c31af7Sopenharmony_ci GLint status = GL_FALSE; 1083e5c31af7Sopenharmony_ci 1084e5c31af7Sopenharmony_ci gl.linkProgram(id); 1085e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram"); 1086e5c31af7Sopenharmony_ci 1087e5c31af7Sopenharmony_ci /* Get link status */ 1088e5c31af7Sopenharmony_ci gl.getProgramiv(id, GL_LINK_STATUS, &status); 1089e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 1090e5c31af7Sopenharmony_ci 1091e5c31af7Sopenharmony_ci /* Log link error */ 1092e5c31af7Sopenharmony_ci if (GL_TRUE != status) 1093e5c31af7Sopenharmony_ci { 1094e5c31af7Sopenharmony_ci glw::GLint length = 0; 1095e5c31af7Sopenharmony_ci std::string message; 1096e5c31af7Sopenharmony_ci 1097e5c31af7Sopenharmony_ci /* Get error log length */ 1098e5c31af7Sopenharmony_ci gl.getProgramiv(id, GL_INFO_LOG_LENGTH, &length); 1099e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); 1100e5c31af7Sopenharmony_ci 1101e5c31af7Sopenharmony_ci message.resize(length, 0); 1102e5c31af7Sopenharmony_ci 1103e5c31af7Sopenharmony_ci /* Get error log */ 1104e5c31af7Sopenharmony_ci gl.getProgramInfoLog(id, length, 0, &message[0]); 1105e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog"); 1106e5c31af7Sopenharmony_ci 1107e5c31af7Sopenharmony_ci TCU_FAIL(message.c_str()); 1108e5c31af7Sopenharmony_ci } 1109e5c31af7Sopenharmony_ci} 1110e5c31af7Sopenharmony_ci 1111e5c31af7Sopenharmony_ci/** Use program 1112e5c31af7Sopenharmony_ci * 1113e5c31af7Sopenharmony_ci * @param gl GL functions 1114e5c31af7Sopenharmony_ci * @param id Id of program 1115e5c31af7Sopenharmony_ci **/ 1116e5c31af7Sopenharmony_civoid Program::Use(const glw::Functions& gl, glw::GLuint id) 1117e5c31af7Sopenharmony_ci{ 1118e5c31af7Sopenharmony_ci gl.useProgram(id); 1119e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram"); 1120e5c31af7Sopenharmony_ci} 1121e5c31af7Sopenharmony_ci 1122e5c31af7Sopenharmony_ci/* Shader's constants */ 1123e5c31af7Sopenharmony_ciconst GLuint Shader::m_invalid_id = 0; 1124e5c31af7Sopenharmony_ci 1125e5c31af7Sopenharmony_ci/** Constructor. 1126e5c31af7Sopenharmony_ci * 1127e5c31af7Sopenharmony_ci * @param context CTS context. 1128e5c31af7Sopenharmony_ci **/ 1129e5c31af7Sopenharmony_ciShader::Shader(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 1130e5c31af7Sopenharmony_ci{ 1131e5c31af7Sopenharmony_ci /* Nothing to be done here */ 1132e5c31af7Sopenharmony_ci} 1133e5c31af7Sopenharmony_ci 1134e5c31af7Sopenharmony_ci/** Destructor 1135e5c31af7Sopenharmony_ci * 1136e5c31af7Sopenharmony_ci **/ 1137e5c31af7Sopenharmony_ciShader::~Shader() 1138e5c31af7Sopenharmony_ci{ 1139e5c31af7Sopenharmony_ci Release(); 1140e5c31af7Sopenharmony_ci} 1141e5c31af7Sopenharmony_ci 1142e5c31af7Sopenharmony_ci/** Initialize shader instance 1143e5c31af7Sopenharmony_ci * 1144e5c31af7Sopenharmony_ci * @param stage Shader stage 1145e5c31af7Sopenharmony_ci * @param source Source code 1146e5c31af7Sopenharmony_ci **/ 1147e5c31af7Sopenharmony_civoid Shader::Init(glw::GLenum stage, const std::string& source) 1148e5c31af7Sopenharmony_ci{ 1149e5c31af7Sopenharmony_ci if (true == source.empty()) 1150e5c31af7Sopenharmony_ci { 1151e5c31af7Sopenharmony_ci /* No source == no shader */ 1152e5c31af7Sopenharmony_ci return; 1153e5c31af7Sopenharmony_ci } 1154e5c31af7Sopenharmony_ci 1155e5c31af7Sopenharmony_ci /* Delete any previous shader */ 1156e5c31af7Sopenharmony_ci Release(); 1157e5c31af7Sopenharmony_ci 1158e5c31af7Sopenharmony_ci /* Create, set source and compile */ 1159e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 1160e5c31af7Sopenharmony_ci 1161e5c31af7Sopenharmony_ci Create(gl, stage, m_id); 1162e5c31af7Sopenharmony_ci Source(gl, m_id, source); 1163e5c31af7Sopenharmony_ci 1164e5c31af7Sopenharmony_ci Compile(gl, m_id); 1165e5c31af7Sopenharmony_ci} 1166e5c31af7Sopenharmony_ci 1167e5c31af7Sopenharmony_ci/** Release shader instance 1168e5c31af7Sopenharmony_ci * 1169e5c31af7Sopenharmony_ci **/ 1170e5c31af7Sopenharmony_civoid Shader::Release() 1171e5c31af7Sopenharmony_ci{ 1172e5c31af7Sopenharmony_ci if (m_invalid_id != m_id) 1173e5c31af7Sopenharmony_ci { 1174e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 1175e5c31af7Sopenharmony_ci 1176e5c31af7Sopenharmony_ci gl.deleteShader(m_id); 1177e5c31af7Sopenharmony_ci m_id = m_invalid_id; 1178e5c31af7Sopenharmony_ci } 1179e5c31af7Sopenharmony_ci} 1180e5c31af7Sopenharmony_ci 1181e5c31af7Sopenharmony_ci/** Compile shader 1182e5c31af7Sopenharmony_ci * 1183e5c31af7Sopenharmony_ci * @param gl GL functions 1184e5c31af7Sopenharmony_ci * @param id Shader id 1185e5c31af7Sopenharmony_ci **/ 1186e5c31af7Sopenharmony_civoid Shader::Compile(const glw::Functions& gl, glw::GLuint id) 1187e5c31af7Sopenharmony_ci{ 1188e5c31af7Sopenharmony_ci GLint status = GL_FALSE; 1189e5c31af7Sopenharmony_ci 1190e5c31af7Sopenharmony_ci /* Compile */ 1191e5c31af7Sopenharmony_ci gl.compileShader(id); 1192e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader"); 1193e5c31af7Sopenharmony_ci 1194e5c31af7Sopenharmony_ci /* Get compilation status */ 1195e5c31af7Sopenharmony_ci gl.getShaderiv(id, GL_COMPILE_STATUS, &status); 1196e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 1197e5c31af7Sopenharmony_ci 1198e5c31af7Sopenharmony_ci /* Log compilation error */ 1199e5c31af7Sopenharmony_ci if (GL_TRUE != status) 1200e5c31af7Sopenharmony_ci { 1201e5c31af7Sopenharmony_ci glw::GLint length = 0; 1202e5c31af7Sopenharmony_ci std::string message; 1203e5c31af7Sopenharmony_ci 1204e5c31af7Sopenharmony_ci /* Error log length */ 1205e5c31af7Sopenharmony_ci gl.getShaderiv(id, GL_INFO_LOG_LENGTH, &length); 1206e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); 1207e5c31af7Sopenharmony_ci 1208e5c31af7Sopenharmony_ci /* Prepare storage */ 1209e5c31af7Sopenharmony_ci message.resize(length, 0); 1210e5c31af7Sopenharmony_ci 1211e5c31af7Sopenharmony_ci /* Get error log */ 1212e5c31af7Sopenharmony_ci gl.getShaderInfoLog(id, length, 0, &message[0]); 1213e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog"); 1214e5c31af7Sopenharmony_ci 1215e5c31af7Sopenharmony_ci TCU_FAIL(message.c_str()); 1216e5c31af7Sopenharmony_ci } 1217e5c31af7Sopenharmony_ci} 1218e5c31af7Sopenharmony_ci 1219e5c31af7Sopenharmony_ci/** Create shader 1220e5c31af7Sopenharmony_ci * 1221e5c31af7Sopenharmony_ci * @param gl GL functions 1222e5c31af7Sopenharmony_ci * @param stage Shader stage 1223e5c31af7Sopenharmony_ci * @param out_id Shader id 1224e5c31af7Sopenharmony_ci **/ 1225e5c31af7Sopenharmony_civoid Shader::Create(const glw::Functions& gl, glw::GLenum stage, glw::GLuint& out_id) 1226e5c31af7Sopenharmony_ci{ 1227e5c31af7Sopenharmony_ci const GLuint id = gl.createShader(stage); 1228e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader"); 1229e5c31af7Sopenharmony_ci 1230e5c31af7Sopenharmony_ci if (m_invalid_id == id) 1231e5c31af7Sopenharmony_ci { 1232e5c31af7Sopenharmony_ci TCU_FAIL("Failed to create shader"); 1233e5c31af7Sopenharmony_ci } 1234e5c31af7Sopenharmony_ci 1235e5c31af7Sopenharmony_ci out_id = id; 1236e5c31af7Sopenharmony_ci} 1237e5c31af7Sopenharmony_ci 1238e5c31af7Sopenharmony_ci/** Set shader's source code 1239e5c31af7Sopenharmony_ci * 1240e5c31af7Sopenharmony_ci * @param gl GL functions 1241e5c31af7Sopenharmony_ci * @param id Shader id 1242e5c31af7Sopenharmony_ci * @param source Shader source code 1243e5c31af7Sopenharmony_ci **/ 1244e5c31af7Sopenharmony_civoid Shader::Source(const glw::Functions& gl, glw::GLuint id, const std::string& source) 1245e5c31af7Sopenharmony_ci{ 1246e5c31af7Sopenharmony_ci const GLchar* code = source.c_str(); 1247e5c31af7Sopenharmony_ci 1248e5c31af7Sopenharmony_ci gl.shaderSource(id, 1 /* count */, &code, 0 /* lengths */); 1249e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource"); 1250e5c31af7Sopenharmony_ci} 1251e5c31af7Sopenharmony_ci 1252e5c31af7Sopenharmony_ci/* Texture static fields */ 1253e5c31af7Sopenharmony_ci 1254e5c31af7Sopenharmony_ciFUNCTIONALITY_SUPPORT Texture::m_direct_state_access_support = FUNCTIONALITY_SUPPORT_NOT_DETERMINED; 1255e5c31af7Sopenharmony_ci 1256e5c31af7Sopenharmony_ci/* Texture constants */ 1257e5c31af7Sopenharmony_ciconst GLuint Texture::m_invalid_id = -1; 1258e5c31af7Sopenharmony_ci 1259e5c31af7Sopenharmony_ci/** Constructor. 1260e5c31af7Sopenharmony_ci * 1261e5c31af7Sopenharmony_ci * @param context CTS context. 1262e5c31af7Sopenharmony_ci **/ 1263e5c31af7Sopenharmony_ciTexture::Texture(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 1264e5c31af7Sopenharmony_ci{ 1265e5c31af7Sopenharmony_ci /* Nothing to done here */ 1266e5c31af7Sopenharmony_ci} 1267e5c31af7Sopenharmony_ci 1268e5c31af7Sopenharmony_ci/** Destructor 1269e5c31af7Sopenharmony_ci * 1270e5c31af7Sopenharmony_ci **/ 1271e5c31af7Sopenharmony_ciTexture::~Texture() 1272e5c31af7Sopenharmony_ci{ 1273e5c31af7Sopenharmony_ci Release(); 1274e5c31af7Sopenharmony_ci} 1275e5c31af7Sopenharmony_ci 1276e5c31af7Sopenharmony_ci/** Release texture instance 1277e5c31af7Sopenharmony_ci * 1278e5c31af7Sopenharmony_ci **/ 1279e5c31af7Sopenharmony_civoid Texture::Release() 1280e5c31af7Sopenharmony_ci{ 1281e5c31af7Sopenharmony_ci if (m_invalid_id != m_id) 1282e5c31af7Sopenharmony_ci { 1283e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 1284e5c31af7Sopenharmony_ci 1285e5c31af7Sopenharmony_ci gl.deleteTextures(1, &m_id); 1286e5c31af7Sopenharmony_ci m_id = m_invalid_id; 1287e5c31af7Sopenharmony_ci } 1288e5c31af7Sopenharmony_ci} 1289e5c31af7Sopenharmony_ci 1290e5c31af7Sopenharmony_ci/** Loads entry points for direct state access extension 1291e5c31af7Sopenharmony_ci * 1292e5c31af7Sopenharmony_ci * @param context CTS context 1293e5c31af7Sopenharmony_ci **/ 1294e5c31af7Sopenharmony_civoid Texture::LoadExtDirectStateAccess(deqp::Context& context) 1295e5c31af7Sopenharmony_ci{ 1296e5c31af7Sopenharmony_ci FUNCTIONALITY_SUPPORT support = getDirectStateAccessSupport(context); 1297e5c31af7Sopenharmony_ci 1298e5c31af7Sopenharmony_ci switch (support) 1299e5c31af7Sopenharmony_ci { 1300e5c31af7Sopenharmony_ci case FUNCTIONALITY_SUPPORT_NONE: 1301e5c31af7Sopenharmony_ci /* Nothing to be done */ 1302e5c31af7Sopenharmony_ci break; 1303e5c31af7Sopenharmony_ci case FUNCTIONALITY_SUPPORT_CORE: 1304e5c31af7Sopenharmony_ci case FUNCTIONALITY_SUPPORT_EXTENSION: 1305e5c31af7Sopenharmony_ci break; 1306e5c31af7Sopenharmony_ci default: 1307e5c31af7Sopenharmony_ci TCU_FAIL("Invalid enum"); 1308e5c31af7Sopenharmony_ci } 1309e5c31af7Sopenharmony_ci} 1310e5c31af7Sopenharmony_ci 1311e5c31af7Sopenharmony_ci/** Bind texture to target 1312e5c31af7Sopenharmony_ci * 1313e5c31af7Sopenharmony_ci * @param gl GL functions 1314e5c31af7Sopenharmony_ci * @param id Id of texture 1315e5c31af7Sopenharmony_ci * @param tex_type Type of texture 1316e5c31af7Sopenharmony_ci **/ 1317e5c31af7Sopenharmony_civoid Texture::Bind(const glw::Functions& gl, glw::GLuint id, glw::GLenum target) 1318e5c31af7Sopenharmony_ci{ 1319e5c31af7Sopenharmony_ci gl.bindTexture(target, id); 1320e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture"); 1321e5c31af7Sopenharmony_ci} 1322e5c31af7Sopenharmony_ci 1323e5c31af7Sopenharmony_ci/** Set contents of compressed texture 1324e5c31af7Sopenharmony_ci * 1325e5c31af7Sopenharmony_ci * @param gl GL functions 1326e5c31af7Sopenharmony_ci * @param target Texture target 1327e5c31af7Sopenharmony_ci * @param level Mipmap level 1328e5c31af7Sopenharmony_ci * @param internal_format Format of data 1329e5c31af7Sopenharmony_ci * @param width Width of texture 1330e5c31af7Sopenharmony_ci * @param height Height of texture 1331e5c31af7Sopenharmony_ci * @param depth Depth of texture 1332e5c31af7Sopenharmony_ci * @param image_size Size of data 1333e5c31af7Sopenharmony_ci * @param data Buffer with image data 1334e5c31af7Sopenharmony_ci **/ 1335e5c31af7Sopenharmony_civoid Texture::CompressedImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, 1336e5c31af7Sopenharmony_ci glw::GLenum internal_format, glw::GLuint width, glw::GLuint height, glw::GLuint depth, 1337e5c31af7Sopenharmony_ci glw::GLsizei image_size, const glw::GLvoid* data) 1338e5c31af7Sopenharmony_ci{ 1339e5c31af7Sopenharmony_ci switch (target) 1340e5c31af7Sopenharmony_ci { 1341e5c31af7Sopenharmony_ci case GL_TEXTURE_1D: 1342e5c31af7Sopenharmony_ci gl.compressedTexImage1D(target, level, internal_format, width, 0 /* border */, image_size, data); 1343e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage1D"); 1344e5c31af7Sopenharmony_ci break; 1345e5c31af7Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 1346e5c31af7Sopenharmony_ci case GL_TEXTURE_2D: 1347e5c31af7Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 1348e5c31af7Sopenharmony_ci gl.compressedTexImage2D(target, level, internal_format, width, height, 0 /* border */, image_size, data); 1349e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage2D"); 1350e5c31af7Sopenharmony_ci break; 1351e5c31af7Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1352e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, internal_format, width, height, 0 /* border */, 1353e5c31af7Sopenharmony_ci image_size, data); 1354e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, internal_format, width, height, 0 /* border */, 1355e5c31af7Sopenharmony_ci image_size, data); 1356e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, internal_format, width, height, 0 /* border */, 1357e5c31af7Sopenharmony_ci image_size, data); 1358e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internal_format, width, height, 0 /* border */, 1359e5c31af7Sopenharmony_ci image_size, data); 1360e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, internal_format, width, height, 0 /* border */, 1361e5c31af7Sopenharmony_ci image_size, data); 1362e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internal_format, width, height, 0 /* border */, 1363e5c31af7Sopenharmony_ci image_size, data); 1364e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage2D"); 1365e5c31af7Sopenharmony_ci break; 1366e5c31af7Sopenharmony_ci case GL_TEXTURE_3D: 1367e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 1368e5c31af7Sopenharmony_ci gl.compressedTexImage3D(target, level, internal_format, width, height, depth, 0 /* border */, image_size, data); 1369e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CompressedTexImage3D"); 1370e5c31af7Sopenharmony_ci break; 1371e5c31af7Sopenharmony_ci default: 1372e5c31af7Sopenharmony_ci TCU_FAIL("Invliad enum"); 1373e5c31af7Sopenharmony_ci } 1374e5c31af7Sopenharmony_ci} 1375e5c31af7Sopenharmony_ci 1376e5c31af7Sopenharmony_ci/** Generate texture instance 1377e5c31af7Sopenharmony_ci * 1378e5c31af7Sopenharmony_ci * @param gl GL functions 1379e5c31af7Sopenharmony_ci * @param out_id Id of texture 1380e5c31af7Sopenharmony_ci **/ 1381e5c31af7Sopenharmony_civoid Texture::Generate(const glw::Functions& gl, glw::GLuint& out_id) 1382e5c31af7Sopenharmony_ci{ 1383e5c31af7Sopenharmony_ci GLuint id = m_invalid_id; 1384e5c31af7Sopenharmony_ci 1385e5c31af7Sopenharmony_ci gl.genTextures(1, &id); 1386e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures"); 1387e5c31af7Sopenharmony_ci 1388e5c31af7Sopenharmony_ci if (m_invalid_id == id) 1389e5c31af7Sopenharmony_ci { 1390e5c31af7Sopenharmony_ci TCU_FAIL("Invalid id"); 1391e5c31af7Sopenharmony_ci } 1392e5c31af7Sopenharmony_ci 1393e5c31af7Sopenharmony_ci out_id = id; 1394e5c31af7Sopenharmony_ci} 1395e5c31af7Sopenharmony_ci 1396e5c31af7Sopenharmony_ci/** Get texture data 1397e5c31af7Sopenharmony_ci * 1398e5c31af7Sopenharmony_ci * @param gl GL functions 1399e5c31af7Sopenharmony_ci * @param target Texture target 1400e5c31af7Sopenharmony_ci * @param format Format of data 1401e5c31af7Sopenharmony_ci * @param type Type of data 1402e5c31af7Sopenharmony_ci * @param out_data Buffer for data 1403e5c31af7Sopenharmony_ci **/ 1404e5c31af7Sopenharmony_civoid Texture::GetData(const glw::Functions& gl, glw::GLenum target, glw::GLenum format, glw::GLenum type, 1405e5c31af7Sopenharmony_ci glw::GLvoid* out_data) 1406e5c31af7Sopenharmony_ci{ 1407e5c31af7Sopenharmony_ci gl.getTexImage(target, 0 /* level */, format, type, out_data); 1408e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexImage"); 1409e5c31af7Sopenharmony_ci} 1410e5c31af7Sopenharmony_ci 1411e5c31af7Sopenharmony_ci/** Generate texture instance 1412e5c31af7Sopenharmony_ci * 1413e5c31af7Sopenharmony_ci * @param gl GL functions 1414e5c31af7Sopenharmony_ci * @param target Texture target 1415e5c31af7Sopenharmony_ci * @param level Mipmap level 1416e5c31af7Sopenharmony_ci * @param pname Parameter to query 1417e5c31af7Sopenharmony_ci * @param param Result of query 1418e5c31af7Sopenharmony_ci **/ 1419e5c31af7Sopenharmony_civoid Texture::GetLevelParameter(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum pname, 1420e5c31af7Sopenharmony_ci glw::GLint* param) 1421e5c31af7Sopenharmony_ci{ 1422e5c31af7Sopenharmony_ci gl.getTexLevelParameteriv(target, level, pname, param); 1423e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetTexLevelParameteriv"); 1424e5c31af7Sopenharmony_ci} 1425e5c31af7Sopenharmony_ci 1426e5c31af7Sopenharmony_ci/** Set contents of texture 1427e5c31af7Sopenharmony_ci * 1428e5c31af7Sopenharmony_ci * @param gl GL functions 1429e5c31af7Sopenharmony_ci * @param target Texture target 1430e5c31af7Sopenharmony_ci * @param level Mipmap level 1431e5c31af7Sopenharmony_ci * @param internal_format Format of data 1432e5c31af7Sopenharmony_ci * @param width Width of texture 1433e5c31af7Sopenharmony_ci * @param height Height of texture 1434e5c31af7Sopenharmony_ci * @param depth Depth of texture 1435e5c31af7Sopenharmony_ci * @param format Format of data 1436e5c31af7Sopenharmony_ci * @param type Type of data 1437e5c31af7Sopenharmony_ci * @param data Buffer with image data 1438e5c31af7Sopenharmony_ci **/ 1439e5c31af7Sopenharmony_civoid Texture::Image(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLenum internal_format, 1440e5c31af7Sopenharmony_ci glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum format, glw::GLenum type, 1441e5c31af7Sopenharmony_ci const glw::GLvoid* data) 1442e5c31af7Sopenharmony_ci{ 1443e5c31af7Sopenharmony_ci switch (target) 1444e5c31af7Sopenharmony_ci { 1445e5c31af7Sopenharmony_ci case GL_TEXTURE_1D: 1446e5c31af7Sopenharmony_ci gl.texImage1D(target, level, internal_format, width, 0 /* border */, format, type, data); 1447e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage1D"); 1448e5c31af7Sopenharmony_ci break; 1449e5c31af7Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 1450e5c31af7Sopenharmony_ci case GL_TEXTURE_2D: 1451e5c31af7Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 1452e5c31af7Sopenharmony_ci gl.texImage2D(target, level, internal_format, width, height, 0 /* border */, format, type, data); 1453e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D"); 1454e5c31af7Sopenharmony_ci break; 1455e5c31af7Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1456e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, internal_format, width, height, 0 /* border */, format, 1457e5c31af7Sopenharmony_ci type, data); 1458e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, internal_format, width, height, 0 /* border */, format, 1459e5c31af7Sopenharmony_ci type, data); 1460e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, internal_format, width, height, 0 /* border */, format, 1461e5c31af7Sopenharmony_ci type, data); 1462e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, internal_format, width, height, 0 /* border */, format, 1463e5c31af7Sopenharmony_ci type, data); 1464e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, internal_format, width, height, 0 /* border */, format, 1465e5c31af7Sopenharmony_ci type, data); 1466e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, internal_format, width, height, 0 /* border */, format, 1467e5c31af7Sopenharmony_ci type, data); 1468e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage2D"); 1469e5c31af7Sopenharmony_ci break; 1470e5c31af7Sopenharmony_ci case GL_TEXTURE_3D: 1471e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 1472e5c31af7Sopenharmony_ci gl.texImage3D(target, level, internal_format, width, height, depth, 0 /* border */, format, type, data); 1473e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexImage3D"); 1474e5c31af7Sopenharmony_ci break; 1475e5c31af7Sopenharmony_ci default: 1476e5c31af7Sopenharmony_ci TCU_FAIL("Invliad enum"); 1477e5c31af7Sopenharmony_ci } 1478e5c31af7Sopenharmony_ci} 1479e5c31af7Sopenharmony_ci 1480e5c31af7Sopenharmony_ci/** Allocate storage for texture 1481e5c31af7Sopenharmony_ci * 1482e5c31af7Sopenharmony_ci * @param gl GL functions 1483e5c31af7Sopenharmony_ci * @param target Texture target 1484e5c31af7Sopenharmony_ci * @param levels Number of levels 1485e5c31af7Sopenharmony_ci * @param internal_format Internal format of texture 1486e5c31af7Sopenharmony_ci * @param width Width of texture 1487e5c31af7Sopenharmony_ci * @param height Height of texture 1488e5c31af7Sopenharmony_ci * @param depth Depth of texture 1489e5c31af7Sopenharmony_ci **/ 1490e5c31af7Sopenharmony_civoid Texture::Storage(const glw::Functions& gl, glw::GLenum target, glw::GLsizei levels, glw::GLenum internal_format, 1491e5c31af7Sopenharmony_ci glw::GLuint width, glw::GLuint height, glw::GLuint depth) 1492e5c31af7Sopenharmony_ci{ 1493e5c31af7Sopenharmony_ci switch (target) 1494e5c31af7Sopenharmony_ci { 1495e5c31af7Sopenharmony_ci case GL_TEXTURE_1D: 1496e5c31af7Sopenharmony_ci gl.texStorage1D(target, levels, internal_format, width); 1497e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage1D"); 1498e5c31af7Sopenharmony_ci break; 1499e5c31af7Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 1500e5c31af7Sopenharmony_ci case GL_TEXTURE_2D: 1501e5c31af7Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 1502e5c31af7Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1503e5c31af7Sopenharmony_ci gl.texStorage2D(target, levels, internal_format, width, height); 1504e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D"); 1505e5c31af7Sopenharmony_ci break; 1506e5c31af7Sopenharmony_ci case GL_TEXTURE_3D: 1507e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 1508e5c31af7Sopenharmony_ci gl.texStorage3D(target, levels, internal_format, width, height, depth); 1509e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage3D"); 1510e5c31af7Sopenharmony_ci break; 1511e5c31af7Sopenharmony_ci default: 1512e5c31af7Sopenharmony_ci TCU_FAIL("Invliad enum"); 1513e5c31af7Sopenharmony_ci } 1514e5c31af7Sopenharmony_ci} 1515e5c31af7Sopenharmony_ci 1516e5c31af7Sopenharmony_ci/** Set contents of texture 1517e5c31af7Sopenharmony_ci * 1518e5c31af7Sopenharmony_ci * @param gl GL functions 1519e5c31af7Sopenharmony_ci * @param target Texture target 1520e5c31af7Sopenharmony_ci * @param level Mipmap level 1521e5c31af7Sopenharmony_ci * @param x X offset 1522e5c31af7Sopenharmony_ci * @param y Y offset 1523e5c31af7Sopenharmony_ci * @param z Z offset 1524e5c31af7Sopenharmony_ci * @param width Width of texture 1525e5c31af7Sopenharmony_ci * @param height Height of texture 1526e5c31af7Sopenharmony_ci * @param depth Depth of texture 1527e5c31af7Sopenharmony_ci * @param format Format of data 1528e5c31af7Sopenharmony_ci * @param type Type of data 1529e5c31af7Sopenharmony_ci * @param pixels Buffer with image data 1530e5c31af7Sopenharmony_ci **/ 1531e5c31af7Sopenharmony_civoid Texture::SubImage(const glw::Functions& gl, glw::GLenum target, glw::GLint level, glw::GLint x, glw::GLint y, 1532e5c31af7Sopenharmony_ci glw::GLint z, glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth, glw::GLenum format, 1533e5c31af7Sopenharmony_ci glw::GLenum type, const glw::GLvoid* pixels) 1534e5c31af7Sopenharmony_ci{ 1535e5c31af7Sopenharmony_ci switch (target) 1536e5c31af7Sopenharmony_ci { 1537e5c31af7Sopenharmony_ci case GL_TEXTURE_1D: 1538e5c31af7Sopenharmony_ci gl.texSubImage1D(target, level, x, width, format, type, pixels); 1539e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage1D"); 1540e5c31af7Sopenharmony_ci break; 1541e5c31af7Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 1542e5c31af7Sopenharmony_ci case GL_TEXTURE_2D: 1543e5c31af7Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 1544e5c31af7Sopenharmony_ci gl.texSubImage2D(target, level, x, y, width, height, format, type, pixels); 1545e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D"); 1546e5c31af7Sopenharmony_ci break; 1547e5c31af7Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 1548e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level, x, y, width, height, format, type, pixels); 1549e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, level, x, y, width, height, format, type, pixels); 1550e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level, x, y, width, height, format, type, pixels); 1551e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, level, x, y, width, height, format, type, pixels); 1552e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, level, x, y, width, height, format, type, pixels); 1553e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, level, x, y, width, height, format, type, pixels); 1554e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage2D"); 1555e5c31af7Sopenharmony_ci break; 1556e5c31af7Sopenharmony_ci case GL_TEXTURE_3D: 1557e5c31af7Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 1558e5c31af7Sopenharmony_ci gl.texSubImage3D(target, level, x, y, z, width, height, depth, format, type, pixels); 1559e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "TexSubImage3D"); 1560e5c31af7Sopenharmony_ci break; 1561e5c31af7Sopenharmony_ci default: 1562e5c31af7Sopenharmony_ci TCU_FAIL("Invliad enum"); 1563e5c31af7Sopenharmony_ci } 1564e5c31af7Sopenharmony_ci} 1565e5c31af7Sopenharmony_ci 1566e5c31af7Sopenharmony_ci/* VertexArray constants */ 1567e5c31af7Sopenharmony_ciconst GLuint VertexArray::m_invalid_id = -1; 1568e5c31af7Sopenharmony_ci 1569e5c31af7Sopenharmony_ci/** Constructor. 1570e5c31af7Sopenharmony_ci * 1571e5c31af7Sopenharmony_ci * @param context CTS context. 1572e5c31af7Sopenharmony_ci **/ 1573e5c31af7Sopenharmony_ciVertexArray::VertexArray(deqp::Context& context) : m_id(m_invalid_id), m_context(context) 1574e5c31af7Sopenharmony_ci{ 1575e5c31af7Sopenharmony_ci} 1576e5c31af7Sopenharmony_ci 1577e5c31af7Sopenharmony_ci/** Destructor 1578e5c31af7Sopenharmony_ci * 1579e5c31af7Sopenharmony_ci **/ 1580e5c31af7Sopenharmony_ciVertexArray::~VertexArray() 1581e5c31af7Sopenharmony_ci{ 1582e5c31af7Sopenharmony_ci Release(); 1583e5c31af7Sopenharmony_ci} 1584e5c31af7Sopenharmony_ci 1585e5c31af7Sopenharmony_ci/** Release vertex array object instance 1586e5c31af7Sopenharmony_ci * 1587e5c31af7Sopenharmony_ci **/ 1588e5c31af7Sopenharmony_civoid VertexArray::Release() 1589e5c31af7Sopenharmony_ci{ 1590e5c31af7Sopenharmony_ci if (m_invalid_id != m_id) 1591e5c31af7Sopenharmony_ci { 1592e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 1593e5c31af7Sopenharmony_ci 1594e5c31af7Sopenharmony_ci Bind(gl, 0); 1595e5c31af7Sopenharmony_ci 1596e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &m_id); 1597e5c31af7Sopenharmony_ci 1598e5c31af7Sopenharmony_ci m_id = m_invalid_id; 1599e5c31af7Sopenharmony_ci } 1600e5c31af7Sopenharmony_ci} 1601e5c31af7Sopenharmony_ci 1602e5c31af7Sopenharmony_ci/** Binds Vertex array object 1603e5c31af7Sopenharmony_ci * 1604e5c31af7Sopenharmony_ci * @param gl GL functions 1605e5c31af7Sopenharmony_ci * @param id ID of vertex array object 1606e5c31af7Sopenharmony_ci **/ 1607e5c31af7Sopenharmony_civoid VertexArray::Bind(const glw::Functions& gl, glw::GLuint id) 1608e5c31af7Sopenharmony_ci{ 1609e5c31af7Sopenharmony_ci gl.bindVertexArray(id); 1610e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindVertexArray"); 1611e5c31af7Sopenharmony_ci} 1612e5c31af7Sopenharmony_ci 1613e5c31af7Sopenharmony_ci/** Generates Vertex array object 1614e5c31af7Sopenharmony_ci * 1615e5c31af7Sopenharmony_ci * @param gl GL functions 1616e5c31af7Sopenharmony_ci * @param out_id ID of vertex array object 1617e5c31af7Sopenharmony_ci **/ 1618e5c31af7Sopenharmony_civoid VertexArray::Generate(const glw::Functions& gl, glw::GLuint& out_id) 1619e5c31af7Sopenharmony_ci{ 1620e5c31af7Sopenharmony_ci GLuint id = m_invalid_id; 1621e5c31af7Sopenharmony_ci 1622e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &id); 1623e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GenVertexArrays"); 1624e5c31af7Sopenharmony_ci 1625e5c31af7Sopenharmony_ci if (m_invalid_id == id) 1626e5c31af7Sopenharmony_ci { 1627e5c31af7Sopenharmony_ci TCU_FAIL("Invalid id"); 1628e5c31af7Sopenharmony_ci } 1629e5c31af7Sopenharmony_ci 1630e5c31af7Sopenharmony_ci out_id = id; 1631e5c31af7Sopenharmony_ci} 1632e5c31af7Sopenharmony_ci 1633e5c31af7Sopenharmony_ci/** Constructor 1634e5c31af7Sopenharmony_ci * 1635e5c31af7Sopenharmony_ci * @param context Test context 1636e5c31af7Sopenharmony_ci **/ 1637e5c31af7Sopenharmony_ciErrorsTest::ErrorsTest(deqp::Context& context) 1638e5c31af7Sopenharmony_ci : TestCase(context, "errors", "Test if errors are generated as specified") 1639e5c31af7Sopenharmony_ci{ 1640e5c31af7Sopenharmony_ci /* Nothing to be done here */ 1641e5c31af7Sopenharmony_ci} 1642e5c31af7Sopenharmony_ci 1643e5c31af7Sopenharmony_ci/** Execute test 1644e5c31af7Sopenharmony_ci * 1645e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP otherwise 1646e5c31af7Sopenharmony_ci **/ 1647e5c31af7Sopenharmony_citcu::TestNode::IterateResult ErrorsTest::iterate() 1648e5c31af7Sopenharmony_ci{ 1649e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 1650e5c31af7Sopenharmony_ci 1651e5c31af7Sopenharmony_ci bool test_result = true; 1652e5c31af7Sopenharmony_ci 1653e5c31af7Sopenharmony_ci Buffer::LoadExtDirectStateAccess(m_context); 1654e5c31af7Sopenharmony_ci 1655e5c31af7Sopenharmony_ci // No GL45 or GL_ARB_direct_state_access support 1656e5c31af7Sopenharmony_ci if (m_direct_state_access_support == FUNCTIONALITY_SUPPORT_NONE) 1657e5c31af7Sopenharmony_ci { 1658e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Unsupported"); 1659e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 1660e5c31af7Sopenharmony_ci } 1661e5c31af7Sopenharmony_ci 1662e5c31af7Sopenharmony_ci /* 1663e5c31af7Sopenharmony_ci * - INVALID_OPERATION is generated by BufferStorage when 0 is bound to 1664e5c31af7Sopenharmony_ci * <target>; Check all targets; 1665e5c31af7Sopenharmony_ci */ 1666e5c31af7Sopenharmony_ci for (GLuint i = 0; i < Buffer::m_n_targets; ++i) 1667e5c31af7Sopenharmony_ci { 1668e5c31af7Sopenharmony_ci const GLenum target = Buffer::m_targets[i]; 1669e5c31af7Sopenharmony_ci std::string message = "BufferStorage was executed for id 0, target: "; 1670e5c31af7Sopenharmony_ci 1671e5c31af7Sopenharmony_ci message.append(glu::getBufferTargetStr(target).toString().c_str()); 1672e5c31af7Sopenharmony_ci 1673e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0 /* id */, target); 1674e5c31af7Sopenharmony_ci gl.bufferStorage(target, 0 /* size */, 0 /* data */, GL_DYNAMIC_STORAGE_BIT /* flags */); 1675e5c31af7Sopenharmony_ci 1676e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION, message.c_str(), test_result); 1677e5c31af7Sopenharmony_ci } 1678e5c31af7Sopenharmony_ci 1679e5c31af7Sopenharmony_ci /* 1680e5c31af7Sopenharmony_ci * - INVLIAD_OPERATION is generated by BufferStorage, NamedBufferStorage and 1681e5c31af7Sopenharmony_ci * BufferData if buffer already have immutable store; 1682e5c31af7Sopenharmony_ci */ 1683e5c31af7Sopenharmony_ci { 1684e5c31af7Sopenharmony_ci static const GLsizeiptr data_size = 32; 1685e5c31af7Sopenharmony_ci static GLubyte data[data_size]; 1686e5c31af7Sopenharmony_ci 1687e5c31af7Sopenharmony_ci Buffer buffer(m_context); 1688e5c31af7Sopenharmony_ci buffer.InitStorage(GL_ARRAY_BUFFER, GL_DYNAMIC_STORAGE_BIT, data_size, data); 1689e5c31af7Sopenharmony_ci 1690e5c31af7Sopenharmony_ci /* NamedBufferStorage */ 1691e5c31af7Sopenharmony_ci if (0 != gl.namedBufferStorage) 1692e5c31af7Sopenharmony_ci { 1693e5c31af7Sopenharmony_ci gl.namedBufferStorage(buffer.m_id, data_size, data, GL_DYNAMIC_STORAGE_BIT); 1694e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION, "NamedBufferStorage was executed for id with immutable storage", 1695e5c31af7Sopenharmony_ci test_result); 1696e5c31af7Sopenharmony_ci } 1697e5c31af7Sopenharmony_ci 1698e5c31af7Sopenharmony_ci /* BufferStorage */ 1699e5c31af7Sopenharmony_ci Buffer::Bind(gl, buffer.m_id, GL_ARRAY_BUFFER); 1700e5c31af7Sopenharmony_ci 1701e5c31af7Sopenharmony_ci gl.bufferStorage(GL_ARRAY_BUFFER, data_size, data, GL_DYNAMIC_STORAGE_BIT); 1702e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION, "BufferStorage was executed for target with immutable storage", test_result); 1703e5c31af7Sopenharmony_ci 1704e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0, GL_ARRAY_BUFFER); 1705e5c31af7Sopenharmony_ci } 1706e5c31af7Sopenharmony_ci 1707e5c31af7Sopenharmony_ci /* 1708e5c31af7Sopenharmony_ci * - INVALID_VALUE is generated by BufferStorage and NamedBufferStorage when 1709e5c31af7Sopenharmony_ci * <size> is less or equal to zero; 1710e5c31af7Sopenharmony_ci */ 1711e5c31af7Sopenharmony_ci { 1712e5c31af7Sopenharmony_ci static const GLsizeiptr data_size = 32; 1713e5c31af7Sopenharmony_ci static GLubyte data[data_size]; 1714e5c31af7Sopenharmony_ci 1715e5c31af7Sopenharmony_ci Buffer buffer(m_context); 1716e5c31af7Sopenharmony_ci gl.createBuffers(1, &buffer.m_id); 1717e5c31af7Sopenharmony_ci 1718e5c31af7Sopenharmony_ci /* NamedBufferStorage */ 1719e5c31af7Sopenharmony_ci if (0 != gl.namedBufferStorage) 1720e5c31af7Sopenharmony_ci { 1721e5c31af7Sopenharmony_ci gl.namedBufferStorage(buffer.m_id, 0 /* size */, data, GL_DYNAMIC_STORAGE_BIT); 1722e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE, "NamedBufferStorage was executed with size == 0", test_result); 1723e5c31af7Sopenharmony_ci 1724e5c31af7Sopenharmony_ci gl.namedBufferStorage(buffer.m_id, -16 /* size */, data, GL_DYNAMIC_STORAGE_BIT); 1725e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE, "NamedBufferStorage was executed with size == -16", test_result); 1726e5c31af7Sopenharmony_ci } 1727e5c31af7Sopenharmony_ci 1728e5c31af7Sopenharmony_ci /* BufferStorage */ 1729e5c31af7Sopenharmony_ci Buffer::Bind(gl, buffer.m_id, GL_ARRAY_BUFFER); 1730e5c31af7Sopenharmony_ci 1731e5c31af7Sopenharmony_ci gl.bufferStorage(GL_ARRAY_BUFFER, 0 /* size */, data, GL_DYNAMIC_STORAGE_BIT); 1732e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE, "BufferStorage was executed with size == 0", test_result); 1733e5c31af7Sopenharmony_ci 1734e5c31af7Sopenharmony_ci gl.bufferStorage(GL_ARRAY_BUFFER, -16 /* size */, data, GL_DYNAMIC_STORAGE_BIT); 1735e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE, "BufferStorage was executed with size == -16", test_result); 1736e5c31af7Sopenharmony_ci 1737e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0, GL_ARRAY_BUFFER); 1738e5c31af7Sopenharmony_ci } 1739e5c31af7Sopenharmony_ci 1740e5c31af7Sopenharmony_ci /* 1741e5c31af7Sopenharmony_ci * - INVLAID_VALUE is generated by BufferStorage and NamedBufferStorage when 1742e5c31af7Sopenharmony_ci * <flags> contains MAP_PERSISTENT_BIT and neither MAP_READ_BIT nor 1743e5c31af7Sopenharmony_ci * MAP_WRITE_BIT; 1744e5c31af7Sopenharmony_ci */ 1745e5c31af7Sopenharmony_ci { 1746e5c31af7Sopenharmony_ci static const GLsizeiptr data_size = 32; 1747e5c31af7Sopenharmony_ci static GLubyte data[data_size]; 1748e5c31af7Sopenharmony_ci 1749e5c31af7Sopenharmony_ci Buffer buffer(m_context); 1750e5c31af7Sopenharmony_ci gl.createBuffers(1, &buffer.m_id); 1751e5c31af7Sopenharmony_ci 1752e5c31af7Sopenharmony_ci /* NamedBufferStorage */ 1753e5c31af7Sopenharmony_ci if (0 != gl.namedBufferStorage) 1754e5c31af7Sopenharmony_ci { 1755e5c31af7Sopenharmony_ci gl.namedBufferStorage(buffer.m_id, data_size, data, GL_MAP_PERSISTENT_BIT); 1756e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE, "NamedBufferStorage was executed with flags == GL_MAP_PERSISTENT_BIT", 1757e5c31af7Sopenharmony_ci test_result); 1758e5c31af7Sopenharmony_ci } 1759e5c31af7Sopenharmony_ci 1760e5c31af7Sopenharmony_ci /* BufferStorage */ 1761e5c31af7Sopenharmony_ci Buffer::Bind(gl, buffer.m_id, GL_ARRAY_BUFFER); 1762e5c31af7Sopenharmony_ci 1763e5c31af7Sopenharmony_ci gl.bufferStorage(GL_ARRAY_BUFFER, data_size, data, GL_MAP_PERSISTENT_BIT); 1764e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE, "BufferStorage was executed with flags == GL_MAP_PERSISTENT_BIT", test_result); 1765e5c31af7Sopenharmony_ci 1766e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0, GL_ARRAY_BUFFER); 1767e5c31af7Sopenharmony_ci } 1768e5c31af7Sopenharmony_ci 1769e5c31af7Sopenharmony_ci /* 1770e5c31af7Sopenharmony_ci * - INVALID_VALUE is generated by BufferStorage and NamedBufferStorage when 1771e5c31af7Sopenharmony_ci * <flags> contains MAP_COHERENT_BIT and no MAP_PERSISTENT_BIT; 1772e5c31af7Sopenharmony_ci */ 1773e5c31af7Sopenharmony_ci { 1774e5c31af7Sopenharmony_ci static const GLsizeiptr data_size = 32; 1775e5c31af7Sopenharmony_ci static GLubyte data[data_size]; 1776e5c31af7Sopenharmony_ci 1777e5c31af7Sopenharmony_ci Buffer buffer(m_context); 1778e5c31af7Sopenharmony_ci gl.createBuffers(1, &buffer.m_id); 1779e5c31af7Sopenharmony_ci 1780e5c31af7Sopenharmony_ci /* NamedBufferStorage */ 1781e5c31af7Sopenharmony_ci if (0 != gl.namedBufferStorage) 1782e5c31af7Sopenharmony_ci { 1783e5c31af7Sopenharmony_ci gl.namedBufferStorage(buffer.m_id, data_size, data, GL_MAP_COHERENT_BIT); 1784e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE, "NamedBufferStorage was executed with flags == GL_MAP_COHERENT_BIT", 1785e5c31af7Sopenharmony_ci test_result); 1786e5c31af7Sopenharmony_ci } 1787e5c31af7Sopenharmony_ci 1788e5c31af7Sopenharmony_ci /* BufferStorage */ 1789e5c31af7Sopenharmony_ci Buffer::Bind(gl, buffer.m_id, GL_ARRAY_BUFFER); 1790e5c31af7Sopenharmony_ci 1791e5c31af7Sopenharmony_ci gl.bufferStorage(GL_ARRAY_BUFFER, data_size, data, GL_MAP_COHERENT_BIT); 1792e5c31af7Sopenharmony_ci verifyError(GL_INVALID_VALUE, "BufferStorage was executed with flags == GL_MAP_COHERENT_BIT", test_result); 1793e5c31af7Sopenharmony_ci 1794e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0, GL_ARRAY_BUFFER); 1795e5c31af7Sopenharmony_ci } 1796e5c31af7Sopenharmony_ci 1797e5c31af7Sopenharmony_ci /* 1798e5c31af7Sopenharmony_ci * - INVALID_OPERATION is generated by MapBufferRange if any of: 1799e5c31af7Sopenharmony_ci * * MAP_COHERENT_BIT, 1800e5c31af7Sopenharmony_ci * * MAP_PERSISTENT_BIT, 1801e5c31af7Sopenharmony_ci * * MAP_READ_BIT, 1802e5c31af7Sopenharmony_ci * * MAP_WRITE_BIT 1803e5c31af7Sopenharmony_ci * is included in <access> and not in buffer's storage flags; 1804e5c31af7Sopenharmony_ci */ 1805e5c31af7Sopenharmony_ci { 1806e5c31af7Sopenharmony_ci static const GLsizeiptr data_size = 32; 1807e5c31af7Sopenharmony_ci static GLubyte data[data_size]; 1808e5c31af7Sopenharmony_ci 1809e5c31af7Sopenharmony_ci Buffer buffer(m_context); 1810e5c31af7Sopenharmony_ci buffer.InitStorage(GL_ARRAY_BUFFER, GL_DYNAMIC_STORAGE_BIT, data_size, data); 1811e5c31af7Sopenharmony_ci 1812e5c31af7Sopenharmony_ci /* MapNamedBufferRange */ 1813e5c31af7Sopenharmony_ci if (0 != gl.mapNamedBufferRange) 1814e5c31af7Sopenharmony_ci { 1815e5c31af7Sopenharmony_ci gl.mapNamedBufferRange(buffer.m_id, 0 /* offset */, data_size, GL_MAP_READ_BIT); 1816e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION, "MapNamedBufferRange was executed with access == GL_MAP_READ_BIT, " 1817e5c31af7Sopenharmony_ci "storage flags == GL_DYNAMIC_STORAGE_BIT", 1818e5c31af7Sopenharmony_ci test_result); 1819e5c31af7Sopenharmony_ci 1820e5c31af7Sopenharmony_ci gl.mapNamedBufferRange(buffer.m_id, 0 /* offset */, data_size, GL_MAP_WRITE_BIT); 1821e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION, "MapNamedBufferRange was executed with access == GL_MAP_WRITE_BIT, " 1822e5c31af7Sopenharmony_ci "storage flags == GL_DYNAMIC_STORAGE_BIT", 1823e5c31af7Sopenharmony_ci test_result); 1824e5c31af7Sopenharmony_ci 1825e5c31af7Sopenharmony_ci gl.mapNamedBufferRange(buffer.m_id, 0 /* offset */, data_size, GL_MAP_PERSISTENT_BIT); 1826e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION, "MapNamedBufferRange was executed with access == GL_MAP_PERSISTENT_BIT, " 1827e5c31af7Sopenharmony_ci "storage flags == GL_DYNAMIC_STORAGE_BIT", 1828e5c31af7Sopenharmony_ci test_result); 1829e5c31af7Sopenharmony_ci 1830e5c31af7Sopenharmony_ci gl.mapNamedBufferRange(buffer.m_id, 0 /* offset */, data_size, GL_MAP_COHERENT_BIT); 1831e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION, "MapNamedBufferRange was executed with access == GL_MAP_COHERENT_BIT, " 1832e5c31af7Sopenharmony_ci "storage flags == GL_DYNAMIC_STORAGE_BIT", 1833e5c31af7Sopenharmony_ci test_result); 1834e5c31af7Sopenharmony_ci } 1835e5c31af7Sopenharmony_ci 1836e5c31af7Sopenharmony_ci /* BufferStorage */ 1837e5c31af7Sopenharmony_ci Buffer::Bind(gl, buffer.m_id, GL_ARRAY_BUFFER); 1838e5c31af7Sopenharmony_ci 1839e5c31af7Sopenharmony_ci gl.mapBufferRange(GL_ARRAY_BUFFER, 0 /* offset */, data_size, GL_MAP_READ_BIT); 1840e5c31af7Sopenharmony_ci verifyError( 1841e5c31af7Sopenharmony_ci GL_INVALID_OPERATION, 1842e5c31af7Sopenharmony_ci "MapBufferRange was executed with access == GL_MAP_READ_BIT, storage flags == GL_DYNAMIC_STORAGE_BIT", 1843e5c31af7Sopenharmony_ci test_result); 1844e5c31af7Sopenharmony_ci 1845e5c31af7Sopenharmony_ci gl.mapBufferRange(GL_ARRAY_BUFFER, 0 /* offset */, data_size, GL_MAP_WRITE_BIT); 1846e5c31af7Sopenharmony_ci verifyError( 1847e5c31af7Sopenharmony_ci GL_INVALID_OPERATION, 1848e5c31af7Sopenharmony_ci "MapBufferRange was executed with access == GL_MAP_WRITE_BIT, storage flags == GL_DYNAMIC_STORAGE_BIT", 1849e5c31af7Sopenharmony_ci test_result); 1850e5c31af7Sopenharmony_ci 1851e5c31af7Sopenharmony_ci gl.mapBufferRange(GL_ARRAY_BUFFER, 0 /* offset */, data_size, GL_MAP_PERSISTENT_BIT); 1852e5c31af7Sopenharmony_ci verifyError( 1853e5c31af7Sopenharmony_ci GL_INVALID_OPERATION, 1854e5c31af7Sopenharmony_ci "MapBufferRange was executed with access == GL_MAP_PERSISTENT_BIT, storage flags == GL_DYNAMIC_STORAGE_BIT", 1855e5c31af7Sopenharmony_ci test_result); 1856e5c31af7Sopenharmony_ci 1857e5c31af7Sopenharmony_ci gl.mapBufferRange(GL_ARRAY_BUFFER, 0 /* offset */, data_size, GL_MAP_COHERENT_BIT); 1858e5c31af7Sopenharmony_ci verifyError( 1859e5c31af7Sopenharmony_ci GL_INVALID_OPERATION, 1860e5c31af7Sopenharmony_ci "MapBufferRange was executed with access == GL_MAP_COHERENT_BIT, storage flags == GL_DYNAMIC_STORAGE_BIT", 1861e5c31af7Sopenharmony_ci test_result); 1862e5c31af7Sopenharmony_ci 1863e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0, GL_ARRAY_BUFFER); 1864e5c31af7Sopenharmony_ci } 1865e5c31af7Sopenharmony_ci 1866e5c31af7Sopenharmony_ci /* 1867e5c31af7Sopenharmony_ci * - INVALID_OPERATION is generated by BufferSubData and NamedBufferSubData 1868e5c31af7Sopenharmony_ci * when buffer has immutable store but its flags does not include 1869e5c31af7Sopenharmony_ci * DYNAMIC_STORAGE. 1870e5c31af7Sopenharmony_ci */ 1871e5c31af7Sopenharmony_ci { 1872e5c31af7Sopenharmony_ci static const GLsizeiptr data_size = 32; 1873e5c31af7Sopenharmony_ci static GLubyte data[data_size]; 1874e5c31af7Sopenharmony_ci 1875e5c31af7Sopenharmony_ci Buffer buffer(m_context); 1876e5c31af7Sopenharmony_ci buffer.InitStorage(GL_ARRAY_BUFFER, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT, data_size, 1877e5c31af7Sopenharmony_ci data); 1878e5c31af7Sopenharmony_ci 1879e5c31af7Sopenharmony_ci /* NamedBufferSubData */ 1880e5c31af7Sopenharmony_ci if (0 != gl.namedBufferSubData) 1881e5c31af7Sopenharmony_ci { 1882e5c31af7Sopenharmony_ci gl.namedBufferSubData(buffer.m_id, 0 /* offset */, data_size, data); 1883e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION, 1884e5c31af7Sopenharmony_ci "NamedBufferSubData was executed for storage without GL_DYNAMIC_STORAGE_BIT", test_result); 1885e5c31af7Sopenharmony_ci } 1886e5c31af7Sopenharmony_ci 1887e5c31af7Sopenharmony_ci /* BufferStorage */ 1888e5c31af7Sopenharmony_ci Buffer::Bind(gl, buffer.m_id, GL_ARRAY_BUFFER); 1889e5c31af7Sopenharmony_ci 1890e5c31af7Sopenharmony_ci gl.bufferSubData(GL_ARRAY_BUFFER, 0 /* offset */, data_size, data); 1891e5c31af7Sopenharmony_ci verifyError(GL_INVALID_OPERATION, "BufferSubData was executed for storage without GL_DYNAMIC_STORAGE_BIT", 1892e5c31af7Sopenharmony_ci test_result); 1893e5c31af7Sopenharmony_ci 1894e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0, GL_ARRAY_BUFFER); 1895e5c31af7Sopenharmony_ci } 1896e5c31af7Sopenharmony_ci 1897e5c31af7Sopenharmony_ci /* Set result */ 1898e5c31af7Sopenharmony_ci if (true == test_result) 1899e5c31af7Sopenharmony_ci { 1900e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1901e5c31af7Sopenharmony_ci } 1902e5c31af7Sopenharmony_ci else 1903e5c31af7Sopenharmony_ci { 1904e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1905e5c31af7Sopenharmony_ci } 1906e5c31af7Sopenharmony_ci 1907e5c31af7Sopenharmony_ci /* Done */ 1908e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 1909e5c31af7Sopenharmony_ci} 1910e5c31af7Sopenharmony_ci 1911e5c31af7Sopenharmony_ci/** Verifies that expected error was generated 1912e5c31af7Sopenharmony_ci * 1913e5c31af7Sopenharmony_ci * @param expected_error Expected error 1914e5c31af7Sopenharmony_ci * @param error_message Message that will be logged in case of wrong error 1915e5c31af7Sopenharmony_ci * @param out_test_result Set to false if worng error was generated, not modified otherwise 1916e5c31af7Sopenharmony_ci **/ 1917e5c31af7Sopenharmony_civoid ErrorsTest::verifyError(glw::GLenum expected_error, const glw::GLchar* error_message, bool& out_test_result) 1918e5c31af7Sopenharmony_ci{ 1919e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 1920e5c31af7Sopenharmony_ci 1921e5c31af7Sopenharmony_ci const GLenum error = gl.getError(); 1922e5c31af7Sopenharmony_ci 1923e5c31af7Sopenharmony_ci if (error != expected_error) 1924e5c31af7Sopenharmony_ci { 1925e5c31af7Sopenharmony_ci out_test_result = false; 1926e5c31af7Sopenharmony_ci 1927e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 1928e5c31af7Sopenharmony_ci << tcu::TestLog::Message << "Got invalid error: " << glu::getErrorName(error) 1929e5c31af7Sopenharmony_ci << ", expected: " << glu::getErrorName(expected_error) << ". Message: " << error_message 1930e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 1931e5c31af7Sopenharmony_ci } 1932e5c31af7Sopenharmony_ci} 1933e5c31af7Sopenharmony_ci 1934e5c31af7Sopenharmony_ci/** Constructor 1935e5c31af7Sopenharmony_ci * 1936e5c31af7Sopenharmony_ci * @param context Test context 1937e5c31af7Sopenharmony_ci **/ 1938e5c31af7Sopenharmony_ciGetBufferParameterTest::GetBufferParameterTest(deqp::Context& context) 1939e5c31af7Sopenharmony_ci : TestCase(context, "get_buffer_parameter", "Test queries for parameters of buffers") 1940e5c31af7Sopenharmony_ci{ 1941e5c31af7Sopenharmony_ci static const GLenum s_mapping_bits[] = { 0, GL_MAP_PERSISTENT_BIT, GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT }; 1942e5c31af7Sopenharmony_ci static const GLuint s_n_mapping_bits = sizeof(s_mapping_bits) / sizeof(s_mapping_bits[0]); 1943e5c31af7Sopenharmony_ci 1944e5c31af7Sopenharmony_ci GLenum flags = 0; 1945e5c31af7Sopenharmony_ci 1946e5c31af7Sopenharmony_ci for (GLuint dynamic = 0; dynamic < 2; ++dynamic) 1947e5c31af7Sopenharmony_ci { 1948e5c31af7Sopenharmony_ci flags = (0 == dynamic) ? 0 : GL_DYNAMIC_STORAGE_BIT; 1949e5c31af7Sopenharmony_ci 1950e5c31af7Sopenharmony_ci for (GLuint client = 0; client < 2; ++client) 1951e5c31af7Sopenharmony_ci { 1952e5c31af7Sopenharmony_ci flags |= (0 == client) ? 0 : GL_CLIENT_STORAGE_BIT; 1953e5c31af7Sopenharmony_ci 1954e5c31af7Sopenharmony_ci /* No "map" bits */ 1955e5c31af7Sopenharmony_ci if (0 != flags) 1956e5c31af7Sopenharmony_ci { 1957e5c31af7Sopenharmony_ci m_test_cases.push_back(testCase(flags, 0)); 1958e5c31af7Sopenharmony_ci } 1959e5c31af7Sopenharmony_ci 1960e5c31af7Sopenharmony_ci for (GLuint flag_idx = 0; flag_idx < s_n_mapping_bits; ++flag_idx) 1961e5c31af7Sopenharmony_ci { 1962e5c31af7Sopenharmony_ci const GLenum flag_mapping_bits = s_mapping_bits[flag_idx]; 1963e5c31af7Sopenharmony_ci const GLenum flags_with_mapping = flags | flag_mapping_bits; 1964e5c31af7Sopenharmony_ci 1965e5c31af7Sopenharmony_ci for (GLuint access_idx = 0; access_idx <= flag_idx; ++access_idx) 1966e5c31af7Sopenharmony_ci { 1967e5c31af7Sopenharmony_ci const GLenum access = s_mapping_bits[access_idx]; 1968e5c31af7Sopenharmony_ci 1969e5c31af7Sopenharmony_ci m_test_cases.push_back(testCase(flags_with_mapping | GL_MAP_READ_BIT, access | GL_MAP_READ_BIT)); 1970e5c31af7Sopenharmony_ci m_test_cases.push_back(testCase(flags_with_mapping | GL_MAP_WRITE_BIT, access | GL_MAP_WRITE_BIT)); 1971e5c31af7Sopenharmony_ci m_test_cases.push_back( 1972e5c31af7Sopenharmony_ci testCase(flags_with_mapping | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, access | GL_MAP_READ_BIT)); 1973e5c31af7Sopenharmony_ci m_test_cases.push_back( 1974e5c31af7Sopenharmony_ci testCase(flags_with_mapping | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, access | GL_MAP_WRITE_BIT)); 1975e5c31af7Sopenharmony_ci m_test_cases.push_back(testCase(flags_with_mapping | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, 1976e5c31af7Sopenharmony_ci access | GL_MAP_WRITE_BIT | GL_MAP_READ_BIT)); 1977e5c31af7Sopenharmony_ci } 1978e5c31af7Sopenharmony_ci } 1979e5c31af7Sopenharmony_ci } 1980e5c31af7Sopenharmony_ci } 1981e5c31af7Sopenharmony_ci} 1982e5c31af7Sopenharmony_ci 1983e5c31af7Sopenharmony_ci/** Execute test 1984e5c31af7Sopenharmony_ci * 1985e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP otherwise 1986e5c31af7Sopenharmony_ci **/ 1987e5c31af7Sopenharmony_citcu::TestNode::IterateResult GetBufferParameterTest::iterate() 1988e5c31af7Sopenharmony_ci{ 1989e5c31af7Sopenharmony_ci static const GLsizeiptr data_size = 32; 1990e5c31af7Sopenharmony_ci static GLubyte data[data_size]; 1991e5c31af7Sopenharmony_ci 1992e5c31af7Sopenharmony_ci Buffer::LoadExtDirectStateAccess(m_context); 1993e5c31af7Sopenharmony_ci 1994e5c31af7Sopenharmony_ci // No GL45 or GL_ARB_direct_state_access support 1995e5c31af7Sopenharmony_ci if (m_direct_state_access_support == FUNCTIONALITY_SUPPORT_NONE) 1996e5c31af7Sopenharmony_ci { 1997e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Unsupported"); 1998e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 1999e5c31af7Sopenharmony_ci } 2000e5c31af7Sopenharmony_ci 2001e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2002e5c31af7Sopenharmony_ci 2003e5c31af7Sopenharmony_ci bool test_result = true; 2004e5c31af7Sopenharmony_ci 2005e5c31af7Sopenharmony_ci for (GLuint i = 0; i < m_test_cases.size(); ++i) 2006e5c31af7Sopenharmony_ci { 2007e5c31af7Sopenharmony_ci const testCase& test_case = m_test_cases[i]; 2008e5c31af7Sopenharmony_ci const GLenum access = test_case.m_access; 2009e5c31af7Sopenharmony_ci const GLenum flags = test_case.m_flags; 2010e5c31af7Sopenharmony_ci 2011e5c31af7Sopenharmony_ci GLint queried_flags = -1; 2012e5c31af7Sopenharmony_ci GLint queried_immutable = -1; 2013e5c31af7Sopenharmony_ci GLint queried_size = -1; 2014e5c31af7Sopenharmony_ci 2015e5c31af7Sopenharmony_ci Buffer buffer(m_context); 2016e5c31af7Sopenharmony_ci 2017e5c31af7Sopenharmony_ci buffer.InitStorage(GL_ARRAY_BUFFER, flags, data_size, data); 2018e5c31af7Sopenharmony_ci Buffer::Bind(gl, buffer.m_id, GL_ARRAY_BUFFER); 2019e5c31af7Sopenharmony_ci 2020e5c31af7Sopenharmony_ci if (0 != gl.getNamedBufferParameteriv) 2021e5c31af7Sopenharmony_ci { 2022e5c31af7Sopenharmony_ci Buffer::GetNamedParameter(gl, buffer.m_id, GL_BUFFER_STORAGE_FLAGS, &queried_flags); 2023e5c31af7Sopenharmony_ci Buffer::GetNamedParameter(gl, buffer.m_id, GL_BUFFER_IMMUTABLE_STORAGE, &queried_immutable); 2024e5c31af7Sopenharmony_ci Buffer::GetNamedParameter(gl, buffer.m_id, GL_BUFFER_SIZE, &queried_size); 2025e5c31af7Sopenharmony_ci 2026e5c31af7Sopenharmony_ci if (queried_flags != (GLint)flags) 2027e5c31af7Sopenharmony_ci { 2028e5c31af7Sopenharmony_ci test_result = false; 2029e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2030e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2031e5c31af7Sopenharmony_ci << "GetNamedBufferParameteriv reported invalid state of GL_BUFFER_STORAGE_FLAGS: " << queried_flags 2032e5c31af7Sopenharmony_ci << " expected: " << flags << tcu::TestLog::EndMessage; 2033e5c31af7Sopenharmony_ci } 2034e5c31af7Sopenharmony_ci } 2035e5c31af7Sopenharmony_ci 2036e5c31af7Sopenharmony_ci if (queried_flags != (GLint)flags) 2037e5c31af7Sopenharmony_ci { 2038e5c31af7Sopenharmony_ci test_result = false; 2039e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2040e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2041e5c31af7Sopenharmony_ci << "GetNamedBufferParameteriv reported invalid state of GL_BUFFER_STORAGE_FLAGS: " << queried_flags 2042e5c31af7Sopenharmony_ci << " expected: " << flags << tcu::TestLog::EndMessage; 2043e5c31af7Sopenharmony_ci } 2044e5c31af7Sopenharmony_ci 2045e5c31af7Sopenharmony_ci if (queried_immutable != GL_TRUE) 2046e5c31af7Sopenharmony_ci { 2047e5c31af7Sopenharmony_ci test_result = false; 2048e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2049e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2050e5c31af7Sopenharmony_ci << "GetNamedBufferParameteriv reported invalid state of GL_BUFFER_IMMUTABLE_STORAGE: " 2051e5c31af7Sopenharmony_ci << queried_immutable << " expected: " << GL_TRUE << tcu::TestLog::EndMessage; 2052e5c31af7Sopenharmony_ci } 2053e5c31af7Sopenharmony_ci 2054e5c31af7Sopenharmony_ci if (queried_size != data_size) 2055e5c31af7Sopenharmony_ci { 2056e5c31af7Sopenharmony_ci test_result = false; 2057e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2058e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2059e5c31af7Sopenharmony_ci << "GetNamedBufferParameteriv reported invalid state of GL_BUFFER_SIZE: " << queried_size 2060e5c31af7Sopenharmony_ci << " expected: " << data_size << tcu::TestLog::EndMessage; 2061e5c31af7Sopenharmony_ci } 2062e5c31af7Sopenharmony_ci 2063e5c31af7Sopenharmony_ci queried_flags = -1; 2064e5c31af7Sopenharmony_ci queried_immutable = -1; 2065e5c31af7Sopenharmony_ci queried_size = -1; 2066e5c31af7Sopenharmony_ci 2067e5c31af7Sopenharmony_ci Buffer::GetParameter(gl, GL_ARRAY_BUFFER, GL_BUFFER_STORAGE_FLAGS, &queried_flags); 2068e5c31af7Sopenharmony_ci Buffer::GetParameter(gl, GL_ARRAY_BUFFER, GL_BUFFER_IMMUTABLE_STORAGE, &queried_immutable); 2069e5c31af7Sopenharmony_ci Buffer::GetParameter(gl, GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &queried_size); 2070e5c31af7Sopenharmony_ci 2071e5c31af7Sopenharmony_ci if (queried_flags != (GLint)flags) 2072e5c31af7Sopenharmony_ci { 2073e5c31af7Sopenharmony_ci test_result = false; 2074e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2075e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2076e5c31af7Sopenharmony_ci << "GetBufferParameteriv reported invalid state of GL_BUFFER_STORAGE_FLAGS: " << queried_flags 2077e5c31af7Sopenharmony_ci << " expected: " << flags << tcu::TestLog::EndMessage; 2078e5c31af7Sopenharmony_ci } 2079e5c31af7Sopenharmony_ci 2080e5c31af7Sopenharmony_ci if (queried_immutable != GL_TRUE) 2081e5c31af7Sopenharmony_ci { 2082e5c31af7Sopenharmony_ci test_result = false; 2083e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2084e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2085e5c31af7Sopenharmony_ci << "GetBufferParameteriv reported invalid state of GL_BUFFER_IMMUTABLE_STORAGE: " << queried_immutable 2086e5c31af7Sopenharmony_ci << " expected: " << GL_TRUE << tcu::TestLog::EndMessage; 2087e5c31af7Sopenharmony_ci } 2088e5c31af7Sopenharmony_ci 2089e5c31af7Sopenharmony_ci if (queried_size != data_size) 2090e5c31af7Sopenharmony_ci { 2091e5c31af7Sopenharmony_ci test_result = false; 2092e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2093e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2094e5c31af7Sopenharmony_ci << "GetBufferParameteriv reported invalid state of GL_BUFFER_SIZE: " << queried_size 2095e5c31af7Sopenharmony_ci << " expected: " << data_size << tcu::TestLog::EndMessage; 2096e5c31af7Sopenharmony_ci } 2097e5c31af7Sopenharmony_ci 2098e5c31af7Sopenharmony_ci if (0 != access) 2099e5c31af7Sopenharmony_ci { 2100e5c31af7Sopenharmony_ci GLint queried_access = -1; 2101e5c31af7Sopenharmony_ci 2102e5c31af7Sopenharmony_ci Buffer::MapOwner tmp(buffer.MapRange(0 /* offset */, data_size, access)); 2103e5c31af7Sopenharmony_ci 2104e5c31af7Sopenharmony_ci if (0 != gl.getNamedBufferParameteriv) 2105e5c31af7Sopenharmony_ci { 2106e5c31af7Sopenharmony_ci Buffer::GetNamedParameter(gl, buffer.m_id, GL_BUFFER_ACCESS_FLAGS, &queried_access); 2107e5c31af7Sopenharmony_ci } 2108e5c31af7Sopenharmony_ci 2109e5c31af7Sopenharmony_ci if (queried_access != (GLint)access) 2110e5c31af7Sopenharmony_ci { 2111e5c31af7Sopenharmony_ci test_result = false; 2112e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2113e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2114e5c31af7Sopenharmony_ci << "GetNamedBufferParameteriv reported invalid state of GL_BUFFER_ACCESS_FLAGS: " << queried_access 2115e5c31af7Sopenharmony_ci << " expected: " << access << tcu::TestLog::EndMessage; 2116e5c31af7Sopenharmony_ci } 2117e5c31af7Sopenharmony_ci 2118e5c31af7Sopenharmony_ci queried_access = -1; 2119e5c31af7Sopenharmony_ci 2120e5c31af7Sopenharmony_ci Buffer::GetParameter(gl, GL_ARRAY_BUFFER, GL_BUFFER_ACCESS_FLAGS, &queried_access); 2121e5c31af7Sopenharmony_ci 2122e5c31af7Sopenharmony_ci if (queried_access != (GLint)access) 2123e5c31af7Sopenharmony_ci { 2124e5c31af7Sopenharmony_ci test_result = false; 2125e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2126e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2127e5c31af7Sopenharmony_ci << "GetBufferParameteriv reported invalid state of GL_BUFFER_ACCESS_FLAGS: " << queried_access 2128e5c31af7Sopenharmony_ci << " expected: " << access << tcu::TestLog::EndMessage; 2129e5c31af7Sopenharmony_ci } 2130e5c31af7Sopenharmony_ci } 2131e5c31af7Sopenharmony_ci 2132e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0 /* id */, GL_ARRAY_BUFFER); 2133e5c31af7Sopenharmony_ci } 2134e5c31af7Sopenharmony_ci 2135e5c31af7Sopenharmony_ci /* Set result */ 2136e5c31af7Sopenharmony_ci if (true == test_result) 2137e5c31af7Sopenharmony_ci { 2138e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2139e5c31af7Sopenharmony_ci } 2140e5c31af7Sopenharmony_ci else 2141e5c31af7Sopenharmony_ci { 2142e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2143e5c31af7Sopenharmony_ci } 2144e5c31af7Sopenharmony_ci 2145e5c31af7Sopenharmony_ci /* Done */ 2146e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2147e5c31af7Sopenharmony_ci} 2148e5c31af7Sopenharmony_ci 2149e5c31af7Sopenharmony_ci/** Constructor 2150e5c31af7Sopenharmony_ci * 2151e5c31af7Sopenharmony_ci * @param context Test context 2152e5c31af7Sopenharmony_ci **/ 2153e5c31af7Sopenharmony_ciGetBufferParameterTest::testCase::testCase(glw::GLenum flags, glw::GLenum access) : m_flags(flags), m_access(access) 2154e5c31af7Sopenharmony_ci{ 2155e5c31af7Sopenharmony_ci} 2156e5c31af7Sopenharmony_ci 2157e5c31af7Sopenharmony_ci/** Constructor 2158e5c31af7Sopenharmony_ci * 2159e5c31af7Sopenharmony_ci * @param context Test context 2160e5c31af7Sopenharmony_ci **/ 2161e5c31af7Sopenharmony_ciDynamicStorageTest::DynamicStorageTest(deqp::Context& context) 2162e5c31af7Sopenharmony_ci : TestCase(context, "dynamic_storage", "Test if DYNAMIC_STORAGE_BIT is respected") 2163e5c31af7Sopenharmony_ci{ 2164e5c31af7Sopenharmony_ci /* Nothing to be done here */ 2165e5c31af7Sopenharmony_ci} 2166e5c31af7Sopenharmony_ci 2167e5c31af7Sopenharmony_ci/** Execute test 2168e5c31af7Sopenharmony_ci * 2169e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP otherwise 2170e5c31af7Sopenharmony_ci **/ 2171e5c31af7Sopenharmony_citcu::TestNode::IterateResult DynamicStorageTest::iterate() 2172e5c31af7Sopenharmony_ci{ 2173e5c31af7Sopenharmony_ci static const size_t data_size = 64; 2174e5c31af7Sopenharmony_ci 2175e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2176e5c31af7Sopenharmony_ci 2177e5c31af7Sopenharmony_ci bool test_result = true; 2178e5c31af7Sopenharmony_ci 2179e5c31af7Sopenharmony_ci /* 2180e5c31af7Sopenharmony_ci * - prepare 64 bytes immutable buffer filled with value 1; Bind the buffer to 2181e5c31af7Sopenharmony_ci * COPY_READ_BUFFER; 2182e5c31af7Sopenharmony_ci * - prepare 64 bytes immutable buffer filled with value 2; Do not set 2183e5c31af7Sopenharmony_ci * DYNAMIC_STORAGE_BIT for <flags>; Bind the buffer to COPY_WRITE_BUFFER; 2184e5c31af7Sopenharmony_ci * - execute BufferSubData to update COPY_WRITE_BUFFER buffer with 64 bytes 2185e5c31af7Sopenharmony_ci * filled with value 3; INVLIAD_OPERATION error should be generated; 2186e5c31af7Sopenharmony_ci * - inspect contents of buffer to verify it is filled with 2; 2187e5c31af7Sopenharmony_ci * - execute CopyBufferSubData to transfer data from COPY_READ_BUFFER to 2188e5c31af7Sopenharmony_ci * COPY_WRITE_BUFFER; No error should be generated; 2189e5c31af7Sopenharmony_ci * - inspect contents of buffer to verify it is filled with 1; 2190e5c31af7Sopenharmony_ci */ 2191e5c31af7Sopenharmony_ci { 2192e5c31af7Sopenharmony_ci /* Prepare buffers */ 2193e5c31af7Sopenharmony_ci GLubyte read_data[data_size]; 2194e5c31af7Sopenharmony_ci GLubyte temp_data[data_size]; 2195e5c31af7Sopenharmony_ci GLubyte update_data[data_size]; 2196e5c31af7Sopenharmony_ci GLubyte write_data[data_size]; 2197e5c31af7Sopenharmony_ci 2198e5c31af7Sopenharmony_ci for (size_t i = 0; i < data_size; ++i) 2199e5c31af7Sopenharmony_ci { 2200e5c31af7Sopenharmony_ci read_data[i] = 1; 2201e5c31af7Sopenharmony_ci temp_data[i] = 0; 2202e5c31af7Sopenharmony_ci update_data[i] = 3; 2203e5c31af7Sopenharmony_ci write_data[i] = 2; 2204e5c31af7Sopenharmony_ci } 2205e5c31af7Sopenharmony_ci 2206e5c31af7Sopenharmony_ci Buffer read_buffer(m_context); 2207e5c31af7Sopenharmony_ci Buffer write_buffer(m_context); 2208e5c31af7Sopenharmony_ci 2209e5c31af7Sopenharmony_ci read_buffer.InitStorage(GL_COPY_READ_BUFFER, 0 /* flags */, data_size, read_data); 2210e5c31af7Sopenharmony_ci write_buffer.InitStorage(GL_COPY_WRITE_BUFFER, 0 /* flags */, data_size, write_data); 2211e5c31af7Sopenharmony_ci 2212e5c31af7Sopenharmony_ci /* Check bufferSubData */ 2213e5c31af7Sopenharmony_ci write_buffer.Bind(); 2214e5c31af7Sopenharmony_ci gl.bufferSubData(GL_COPY_WRITE_BUFFER, 0 /* offset */, data_size, update_data); 2215e5c31af7Sopenharmony_ci 2216e5c31af7Sopenharmony_ci GLenum error = gl.getError(); 2217e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != error) 2218e5c31af7Sopenharmony_ci { 2219e5c31af7Sopenharmony_ci test_result = false; 2220e5c31af7Sopenharmony_ci 2221e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2222e5c31af7Sopenharmony_ci << tcu::TestLog::Message << "Invalid error was generated. BufferSubData was executed on store without " 2223e5c31af7Sopenharmony_ci "DYNAMIC_STORAGE_BIT. Expected INVALID_OPERATION, got: " 2224e5c31af7Sopenharmony_ci << glu::getErrorStr(error).toString().c_str() << tcu::TestLog::EndMessage; 2225e5c31af7Sopenharmony_ci } 2226e5c31af7Sopenharmony_ci 2227e5c31af7Sopenharmony_ci Buffer::GetSubData(gl, GL_COPY_WRITE_BUFFER, 0 /* offset */, data_size, temp_data); 2228e5c31af7Sopenharmony_ci 2229e5c31af7Sopenharmony_ci if (0 != memcmp(temp_data, write_data, data_size)) 2230e5c31af7Sopenharmony_ci { 2231e5c31af7Sopenharmony_ci test_result = false; 2232e5c31af7Sopenharmony_ci 2233e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2234e5c31af7Sopenharmony_ci << tcu::TestLog::Message << "BufferSubData modified contents of store without DYNAMIC_STORAGE_BIT." 2235e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2236e5c31af7Sopenharmony_ci } 2237e5c31af7Sopenharmony_ci 2238e5c31af7Sopenharmony_ci /* Check copyBufferSubData */ 2239e5c31af7Sopenharmony_ci read_buffer.Bind(); 2240e5c31af7Sopenharmony_ci gl.copyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0 /* readOffset */, 0 /* writeOffset */, 2241e5c31af7Sopenharmony_ci data_size); 2242e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CopyBufferSubData"); 2243e5c31af7Sopenharmony_ci 2244e5c31af7Sopenharmony_ci Buffer::GetSubData(gl, GL_COPY_WRITE_BUFFER, 0 /* offset */, data_size, temp_data); 2245e5c31af7Sopenharmony_ci 2246e5c31af7Sopenharmony_ci if (0 != memcmp(temp_data, read_data, data_size)) 2247e5c31af7Sopenharmony_ci { 2248e5c31af7Sopenharmony_ci test_result = false; 2249e5c31af7Sopenharmony_ci 2250e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 2251e5c31af7Sopenharmony_ci << "CopyBufferSubData stored invalid contents in write target buffer." 2252e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2253e5c31af7Sopenharmony_ci } 2254e5c31af7Sopenharmony_ci } 2255e5c31af7Sopenharmony_ci 2256e5c31af7Sopenharmony_ci /* 2257e5c31af7Sopenharmony_ci * - delete buffer and create new one; This time <flags> should contain 2258e5c31af7Sopenharmony_ci * DYNAMIC_STORAGE_BIT; Bind the buffer to COPY_WRITE_BUFFER; 2259e5c31af7Sopenharmony_ci * - execute BufferSubData to update COPY_WRITE_BUFFER buffer with 64 bytes 2260e5c31af7Sopenharmony_ci * filled with value 3; No error should be generated; 2261e5c31af7Sopenharmony_ci * - inspect contents of buffer to verify it is filled with 3; 2262e5c31af7Sopenharmony_ci */ 2263e5c31af7Sopenharmony_ci { 2264e5c31af7Sopenharmony_ci /* Prepare buffers */ 2265e5c31af7Sopenharmony_ci GLubyte temp_data[data_size]; 2266e5c31af7Sopenharmony_ci GLubyte update_data[data_size]; 2267e5c31af7Sopenharmony_ci GLubyte write_data[data_size]; 2268e5c31af7Sopenharmony_ci 2269e5c31af7Sopenharmony_ci for (size_t i = 0; i < data_size; ++i) 2270e5c31af7Sopenharmony_ci { 2271e5c31af7Sopenharmony_ci temp_data[i] = 0; 2272e5c31af7Sopenharmony_ci update_data[i] = 3; 2273e5c31af7Sopenharmony_ci write_data[i] = 2; 2274e5c31af7Sopenharmony_ci } 2275e5c31af7Sopenharmony_ci 2276e5c31af7Sopenharmony_ci Buffer write_buffer(m_context); 2277e5c31af7Sopenharmony_ci 2278e5c31af7Sopenharmony_ci write_buffer.InitStorage(GL_COPY_WRITE_BUFFER, GL_DYNAMIC_STORAGE_BIT, data_size, write_data); 2279e5c31af7Sopenharmony_ci 2280e5c31af7Sopenharmony_ci /* Check bufferSubData */ 2281e5c31af7Sopenharmony_ci write_buffer.Bind(); 2282e5c31af7Sopenharmony_ci gl.bufferSubData(GL_COPY_WRITE_BUFFER, 0 /* offset */, data_size, update_data); 2283e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BufferSubData"); 2284e5c31af7Sopenharmony_ci 2285e5c31af7Sopenharmony_ci Buffer::GetSubData(gl, GL_COPY_WRITE_BUFFER, 0 /* offset */, data_size, temp_data); 2286e5c31af7Sopenharmony_ci 2287e5c31af7Sopenharmony_ci if (0 != memcmp(temp_data, update_data, data_size)) 2288e5c31af7Sopenharmony_ci { 2289e5c31af7Sopenharmony_ci test_result = false; 2290e5c31af7Sopenharmony_ci 2291e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 2292e5c31af7Sopenharmony_ci << "BufferSubData stored invalid contents in write target buffer." 2293e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2294e5c31af7Sopenharmony_ci } 2295e5c31af7Sopenharmony_ci } 2296e5c31af7Sopenharmony_ci 2297e5c31af7Sopenharmony_ci /* Set result */ 2298e5c31af7Sopenharmony_ci if (true == test_result) 2299e5c31af7Sopenharmony_ci { 2300e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2301e5c31af7Sopenharmony_ci } 2302e5c31af7Sopenharmony_ci else 2303e5c31af7Sopenharmony_ci { 2304e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2305e5c31af7Sopenharmony_ci } 2306e5c31af7Sopenharmony_ci 2307e5c31af7Sopenharmony_ci /* Done */ 2308e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2309e5c31af7Sopenharmony_ci} 2310e5c31af7Sopenharmony_ci 2311e5c31af7Sopenharmony_ci/** Constructor 2312e5c31af7Sopenharmony_ci * 2313e5c31af7Sopenharmony_ci * @param context Test context 2314e5c31af7Sopenharmony_ci **/ 2315e5c31af7Sopenharmony_ciMapPersistentBufferSubDataTest::MapPersistentBufferSubDataTest(deqp::Context& context) 2316e5c31af7Sopenharmony_ci : TestCase(context, "map_persistent_buffer_sub_data", "Test sub buffer operations against mapped buffer") 2317e5c31af7Sopenharmony_ci{ 2318e5c31af7Sopenharmony_ci /* Nothing to be done here */ 2319e5c31af7Sopenharmony_ci} 2320e5c31af7Sopenharmony_ci 2321e5c31af7Sopenharmony_ci/** Execute test 2322e5c31af7Sopenharmony_ci * 2323e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP otherwise 2324e5c31af7Sopenharmony_ci **/ 2325e5c31af7Sopenharmony_citcu::TestNode::IterateResult MapPersistentBufferSubDataTest::iterate() 2326e5c31af7Sopenharmony_ci{ 2327e5c31af7Sopenharmony_ci static const size_t data_size = 64; 2328e5c31af7Sopenharmony_ci static const GLintptr mapped_region_offset = 16; 2329e5c31af7Sopenharmony_ci static const GLsizeiptr mapped_region_size = 16; 2330e5c31af7Sopenharmony_ci static const testCase test_cases[] = { 2331e5c31af7Sopenharmony_ci { 0, 16, false }, /* before mapped region */ 2332e5c31af7Sopenharmony_ci { 32, 16, false }, /* after mapped region */ 2333e5c31af7Sopenharmony_ci { 8, 16, true }, /* at the beginning */ 2334e5c31af7Sopenharmony_ci { 24, 16, true }, /* at the end */ 2335e5c31af7Sopenharmony_ci { 12, 8, true }, /* in the middle */ 2336e5c31af7Sopenharmony_ci }; 2337e5c31af7Sopenharmony_ci static const size_t n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]); 2338e5c31af7Sopenharmony_ci 2339e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2340e5c31af7Sopenharmony_ci 2341e5c31af7Sopenharmony_ci bool test_result = true; 2342e5c31af7Sopenharmony_ci 2343e5c31af7Sopenharmony_ci /* Storage for data */ 2344e5c31af7Sopenharmony_ci GLubyte incrementing_data[data_size]; 2345e5c31af7Sopenharmony_ci 2346e5c31af7Sopenharmony_ci /* Prepare data */ 2347e5c31af7Sopenharmony_ci for (size_t i = 0; i < data_size; ++i) 2348e5c31af7Sopenharmony_ci { 2349e5c31af7Sopenharmony_ci incrementing_data[i] = (glw::GLubyte)i; 2350e5c31af7Sopenharmony_ci } 2351e5c31af7Sopenharmony_ci 2352e5c31af7Sopenharmony_ci /* Load DSA */ 2353e5c31af7Sopenharmony_ci Buffer::LoadExtDirectStateAccess(m_context); 2354e5c31af7Sopenharmony_ci 2355e5c31af7Sopenharmony_ci // No GL45 or GL_ARB_direct_state_access support 2356e5c31af7Sopenharmony_ci if (m_direct_state_access_support == FUNCTIONALITY_SUPPORT_NONE) 2357e5c31af7Sopenharmony_ci { 2358e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Unsupported"); 2359e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2360e5c31af7Sopenharmony_ci } 2361e5c31af7Sopenharmony_ci 2362e5c31af7Sopenharmony_ci /* Prepare buffer */ 2363e5c31af7Sopenharmony_ci Buffer buffer(m_context); 2364e5c31af7Sopenharmony_ci buffer.InitStorage(GL_ARRAY_BUFFER, 2365e5c31af7Sopenharmony_ci GL_DYNAMIC_STORAGE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, data_size, 2366e5c31af7Sopenharmony_ci 0 /* data */); 2367e5c31af7Sopenharmony_ci buffer.Bind(); 2368e5c31af7Sopenharmony_ci 2369e5c31af7Sopenharmony_ci /* 2370e5c31af7Sopenharmony_ci * - execute tested operation, to update whole buffer with incrementing values 2371e5c31af7Sopenharmony_ci * starting from 0; No error should be generated; 2372e5c31af7Sopenharmony_ci */ 2373e5c31af7Sopenharmony_ci gl.bufferSubData(GL_ARRAY_BUFFER, 0 /* offset */, data_size, incrementing_data); 2374e5c31af7Sopenharmony_ci GLenum error = gl.getError(); 2375e5c31af7Sopenharmony_ci 2376e5c31af7Sopenharmony_ci if (GL_NO_ERROR != error) 2377e5c31af7Sopenharmony_ci { 2378e5c31af7Sopenharmony_ci test_result = false; 2379e5c31af7Sopenharmony_ci 2380e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message << "BufferSubData generated unexpected error: " 2381e5c31af7Sopenharmony_ci << glu::getErrorStr(error).toString().c_str() << tcu::TestLog::EndMessage; 2382e5c31af7Sopenharmony_ci } 2383e5c31af7Sopenharmony_ci 2384e5c31af7Sopenharmony_ci if (0 != gl.namedBufferSubData) 2385e5c31af7Sopenharmony_ci { 2386e5c31af7Sopenharmony_ci gl.namedBufferSubData(buffer.m_id, 0 /* offset */, data_size, incrementing_data); 2387e5c31af7Sopenharmony_ci error = gl.getError(); 2388e5c31af7Sopenharmony_ci } 2389e5c31af7Sopenharmony_ci 2390e5c31af7Sopenharmony_ci gl.namedBufferSubData(buffer.m_id, 0 /* offset */, data_size, incrementing_data); 2391e5c31af7Sopenharmony_ci error = gl.getError(); 2392e5c31af7Sopenharmony_ci 2393e5c31af7Sopenharmony_ci if (GL_NO_ERROR != error) 2394e5c31af7Sopenharmony_ci { 2395e5c31af7Sopenharmony_ci test_result = false; 2396e5c31af7Sopenharmony_ci 2397e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2398e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2399e5c31af7Sopenharmony_ci << "NamedBufferSubData generated unexpected error: " << glu::getErrorStr(error).toString().c_str() 2400e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2401e5c31af7Sopenharmony_ci } 2402e5c31af7Sopenharmony_ci 2403e5c31af7Sopenharmony_ci /* 2404e5c31af7Sopenharmony_ci * - map buffer contents with MapBufferRange; <access> should contain 2405e5c31af7Sopenharmony_ci * MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT; Provide 16 as <offset> 2406e5c31af7Sopenharmony_ci * and <size>; 2407e5c31af7Sopenharmony_ci * - mapped region should contain values from 16 to 31; 2408e5c31af7Sopenharmony_ci * - execute tested operation, to update portions of buffer specified below; 2409e5c31af7Sopenharmony_ci * No error should be generated; 2410e5c31af7Sopenharmony_ci */ 2411e5c31af7Sopenharmony_ci { 2412e5c31af7Sopenharmony_ci const Buffer::MapOwner map(buffer.MapRange(mapped_region_offset, mapped_region_size, 2413e5c31af7Sopenharmony_ci GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)); 2414e5c31af7Sopenharmony_ci 2415e5c31af7Sopenharmony_ci if (0 != memcmp(map.m_data, incrementing_data + mapped_region_offset, mapped_region_size)) 2416e5c31af7Sopenharmony_ci { 2417e5c31af7Sopenharmony_ci test_result = false; 2418e5c31af7Sopenharmony_ci 2419e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message << "Mapped region contains unexpected data" 2420e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2421e5c31af7Sopenharmony_ci } 2422e5c31af7Sopenharmony_ci 2423e5c31af7Sopenharmony_ci for (size_t i = 0; i < n_test_cases; ++i) 2424e5c31af7Sopenharmony_ci { 2425e5c31af7Sopenharmony_ci const GLintptr offset = test_cases[i].m_offset; 2426e5c31af7Sopenharmony_ci const GLsizeiptr size = test_cases[i].m_size; 2427e5c31af7Sopenharmony_ci 2428e5c31af7Sopenharmony_ci gl.bufferSubData(GL_ARRAY_BUFFER, offset, size, incrementing_data); 2429e5c31af7Sopenharmony_ci error = gl.getError(); 2430e5c31af7Sopenharmony_ci 2431e5c31af7Sopenharmony_ci if (GL_NO_ERROR != error) 2432e5c31af7Sopenharmony_ci { 2433e5c31af7Sopenharmony_ci test_result = false; 2434e5c31af7Sopenharmony_ci 2435e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2436e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2437e5c31af7Sopenharmony_ci << "BufferSubData generated unexpected error: " << glu::getErrorStr(error).toString().c_str() 2438e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2439e5c31af7Sopenharmony_ci } 2440e5c31af7Sopenharmony_ci 2441e5c31af7Sopenharmony_ci if (0 != gl.namedBufferSubData) 2442e5c31af7Sopenharmony_ci { 2443e5c31af7Sopenharmony_ci gl.namedBufferSubData(buffer.m_id, offset, size, incrementing_data); 2444e5c31af7Sopenharmony_ci error = gl.getError(); 2445e5c31af7Sopenharmony_ci } 2446e5c31af7Sopenharmony_ci 2447e5c31af7Sopenharmony_ci if (GL_NO_ERROR != error) 2448e5c31af7Sopenharmony_ci { 2449e5c31af7Sopenharmony_ci test_result = false; 2450e5c31af7Sopenharmony_ci 2451e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2452e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2453e5c31af7Sopenharmony_ci << "NamedBufferSubData generated unexpected error: " << glu::getErrorStr(error).toString().c_str() 2454e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2455e5c31af7Sopenharmony_ci } 2456e5c31af7Sopenharmony_ci } 2457e5c31af7Sopenharmony_ci } 2458e5c31af7Sopenharmony_ci 2459e5c31af7Sopenharmony_ci /* 2460e5c31af7Sopenharmony_ci * - unmap buffer; 2461e5c31af7Sopenharmony_ci * - map buffer contents again, this time do not provide MAP_PERSISTENT_BIT; 2462e5c31af7Sopenharmony_ci * - execute tested operation to update regions specified below; It is expected 2463e5c31af7Sopenharmony_ci * that INVALID_OPERATION will be generated for cases that cross mapped region; 2464e5c31af7Sopenharmony_ci * No error should be generated for other cases. 2465e5c31af7Sopenharmony_ci */ 2466e5c31af7Sopenharmony_ci { 2467e5c31af7Sopenharmony_ci Buffer::MapOwner tmp( 2468e5c31af7Sopenharmony_ci buffer.MapRange(mapped_region_offset, mapped_region_size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)); 2469e5c31af7Sopenharmony_ci 2470e5c31af7Sopenharmony_ci for (size_t i = 0; i < n_test_cases; ++i) 2471e5c31af7Sopenharmony_ci { 2472e5c31af7Sopenharmony_ci const GLintptr offset = test_cases[i].m_offset; 2473e5c31af7Sopenharmony_ci const GLsizeiptr size = test_cases[i].m_size; 2474e5c31af7Sopenharmony_ci const bool is_error_expected = test_cases[i].m_cross_mapped_region; 2475e5c31af7Sopenharmony_ci const GLenum expected_error = (true == is_error_expected) ? GL_INVALID_OPERATION : GL_NO_ERROR; 2476e5c31af7Sopenharmony_ci 2477e5c31af7Sopenharmony_ci gl.bufferSubData(GL_ARRAY_BUFFER, offset, size, incrementing_data); 2478e5c31af7Sopenharmony_ci error = gl.getError(); 2479e5c31af7Sopenharmony_ci 2480e5c31af7Sopenharmony_ci if (expected_error != error) 2481e5c31af7Sopenharmony_ci { 2482e5c31af7Sopenharmony_ci test_result = false; 2483e5c31af7Sopenharmony_ci 2484e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2485e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2486e5c31af7Sopenharmony_ci << "BufferSubData generated wrong error: " << glu::getErrorStr(error).toString().c_str() 2487e5c31af7Sopenharmony_ci << ", expected: " << glu::getErrorStr(expected_error).toString().c_str() 2488e5c31af7Sopenharmony_ci << ". Mapped region: offset: " << mapped_region_offset << ", size: " << mapped_region_size 2489e5c31af7Sopenharmony_ci << ". Operation region: offset: " << offset << ", size: " << size << tcu::TestLog::EndMessage; 2490e5c31af7Sopenharmony_ci } 2491e5c31af7Sopenharmony_ci 2492e5c31af7Sopenharmony_ci if (0 != gl.namedBufferSubData) 2493e5c31af7Sopenharmony_ci { 2494e5c31af7Sopenharmony_ci gl.namedBufferSubData(buffer.m_id, offset, size, incrementing_data); 2495e5c31af7Sopenharmony_ci error = gl.getError(); 2496e5c31af7Sopenharmony_ci } 2497e5c31af7Sopenharmony_ci 2498e5c31af7Sopenharmony_ci if (expected_error != error) 2499e5c31af7Sopenharmony_ci { 2500e5c31af7Sopenharmony_ci test_result = false; 2501e5c31af7Sopenharmony_ci 2502e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2503e5c31af7Sopenharmony_ci << tcu::TestLog::Message 2504e5c31af7Sopenharmony_ci << "NamedBufferSubData generated wrong error: " << glu::getErrorStr(error).toString().c_str() 2505e5c31af7Sopenharmony_ci << ", expected: " << glu::getErrorStr(expected_error).toString().c_str() 2506e5c31af7Sopenharmony_ci << ". Mapped region: offset: " << mapped_region_offset << ", size: " << mapped_region_size 2507e5c31af7Sopenharmony_ci << ". Operation region: offset: " << offset << ", size: " << size << tcu::TestLog::EndMessage; 2508e5c31af7Sopenharmony_ci } 2509e5c31af7Sopenharmony_ci } 2510e5c31af7Sopenharmony_ci } 2511e5c31af7Sopenharmony_ci 2512e5c31af7Sopenharmony_ci /* Set result */ 2513e5c31af7Sopenharmony_ci if (true == test_result) 2514e5c31af7Sopenharmony_ci { 2515e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2516e5c31af7Sopenharmony_ci } 2517e5c31af7Sopenharmony_ci else 2518e5c31af7Sopenharmony_ci { 2519e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2520e5c31af7Sopenharmony_ci } 2521e5c31af7Sopenharmony_ci 2522e5c31af7Sopenharmony_ci /* Done */ 2523e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2524e5c31af7Sopenharmony_ci} 2525e5c31af7Sopenharmony_ci 2526e5c31af7Sopenharmony_ci/** Constructor 2527e5c31af7Sopenharmony_ci * 2528e5c31af7Sopenharmony_ci * @param context Test context 2529e5c31af7Sopenharmony_ci **/ 2530e5c31af7Sopenharmony_ciMapPersistentTextureTest::MapPersistentTextureTest(deqp::Context& context) 2531e5c31af7Sopenharmony_ci : TestCase(context, "map_persistent_texture", "Test texture operations against mapped buffer") 2532e5c31af7Sopenharmony_ci , m_compressed_image_size(0) 2533e5c31af7Sopenharmony_ci , m_compressed_internal_format(0) 2534e5c31af7Sopenharmony_ci{ 2535e5c31af7Sopenharmony_ci /* Nothing to be done here */ 2536e5c31af7Sopenharmony_ci} 2537e5c31af7Sopenharmony_ci 2538e5c31af7Sopenharmony_ci/** Execute test 2539e5c31af7Sopenharmony_ci * 2540e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP otherwise 2541e5c31af7Sopenharmony_ci **/ 2542e5c31af7Sopenharmony_citcu::TestNode::IterateResult MapPersistentTextureTest::iterate() 2543e5c31af7Sopenharmony_ci{ 2544e5c31af7Sopenharmony_ci static const size_t data_size = 256; 2545e5c31af7Sopenharmony_ci 2546e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2547e5c31af7Sopenharmony_ci 2548e5c31af7Sopenharmony_ci bool test_result = true; 2549e5c31af7Sopenharmony_ci 2550e5c31af7Sopenharmony_ci /* Storage for data */ 2551e5c31af7Sopenharmony_ci GLubyte data[data_size]; 2552e5c31af7Sopenharmony_ci 2553e5c31af7Sopenharmony_ci /* Prepare data */ 2554e5c31af7Sopenharmony_ci for (size_t i = 0; i < data_size; ++i) 2555e5c31af7Sopenharmony_ci { 2556e5c31af7Sopenharmony_ci data[i] = (glw::GLubyte)i; 2557e5c31af7Sopenharmony_ci } 2558e5c31af7Sopenharmony_ci 2559e5c31af7Sopenharmony_ci /* Load DSA */ 2560e5c31af7Sopenharmony_ci Buffer::LoadExtDirectStateAccess(m_context); 2561e5c31af7Sopenharmony_ci Texture::LoadExtDirectStateAccess(m_context); 2562e5c31af7Sopenharmony_ci 2563e5c31af7Sopenharmony_ci /* Get info about compressed image */ 2564e5c31af7Sopenharmony_ci getCompressedInfo(); 2565e5c31af7Sopenharmony_ci 2566e5c31af7Sopenharmony_ci /* Prepare buffer */ 2567e5c31af7Sopenharmony_ci Buffer buffer(m_context); 2568e5c31af7Sopenharmony_ci buffer.InitStorage(GL_PIXEL_UNPACK_BUFFER, GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, data_size, 2569e5c31af7Sopenharmony_ci data); 2570e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0 /* id */, GL_PIXEL_UNPACK_BUFFER); 2571e5c31af7Sopenharmony_ci 2572e5c31af7Sopenharmony_ci /* 2573e5c31af7Sopenharmony_ci * - prepare texture in a way that is relevant for tested operation; 2574e5c31af7Sopenharmony_ci * - execute tested operation, no error should be generated; 2575e5c31af7Sopenharmony_ci * - delete texture and prepare next one; 2576e5c31af7Sopenharmony_ci */ 2577e5c31af7Sopenharmony_ci for (GLuint i = 0; i < TESTED_OPERATION_MAX; ++i) 2578e5c31af7Sopenharmony_ci { 2579e5c31af7Sopenharmony_ci const TESTED_OPERATION operation = (TESTED_OPERATION)i; 2580e5c31af7Sopenharmony_ci 2581e5c31af7Sopenharmony_ci bool result = verifyTestedOperation(operation, buffer, GL_NO_ERROR); 2582e5c31af7Sopenharmony_ci 2583e5c31af7Sopenharmony_ci if (false == result) 2584e5c31af7Sopenharmony_ci { 2585e5c31af7Sopenharmony_ci test_result = false; 2586e5c31af7Sopenharmony_ci 2587e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 2588e5c31af7Sopenharmony_ci << "Buffer bound to PIXEL_UNPACK_BUFFER is not mapped" 2589e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2590e5c31af7Sopenharmony_ci } 2591e5c31af7Sopenharmony_ci } 2592e5c31af7Sopenharmony_ci 2593e5c31af7Sopenharmony_ci /* 2594e5c31af7Sopenharmony_ci * - map buffer contents with MapBufferRange, <access> should contain 2595e5c31af7Sopenharmony_ci * MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT; 2596e5c31af7Sopenharmony_ci * - execute tested operation, no error should be generated; 2597e5c31af7Sopenharmony_ci */ 2598e5c31af7Sopenharmony_ci for (GLuint i = 0; i < TESTED_OPERATION_MAX; ++i) 2599e5c31af7Sopenharmony_ci { 2600e5c31af7Sopenharmony_ci const TESTED_OPERATION operation = (TESTED_OPERATION)i; 2601e5c31af7Sopenharmony_ci 2602e5c31af7Sopenharmony_ci { 2603e5c31af7Sopenharmony_ci Buffer::MapOwner tmp( 2604e5c31af7Sopenharmony_ci buffer.MapRange(0 /* offset */, data_size, GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)); 2605e5c31af7Sopenharmony_ci } 2606e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0 /* id */, GL_PIXEL_UNPACK_BUFFER); 2607e5c31af7Sopenharmony_ci 2608e5c31af7Sopenharmony_ci bool result = verifyTestedOperation(operation, buffer, GL_NO_ERROR); 2609e5c31af7Sopenharmony_ci 2610e5c31af7Sopenharmony_ci if (false == result) 2611e5c31af7Sopenharmony_ci { 2612e5c31af7Sopenharmony_ci test_result = false; 2613e5c31af7Sopenharmony_ci 2614e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 2615e5c31af7Sopenharmony_ci << "Buffer bound to PIXEL_UNPACK_BUFFER is persistently mapped" 2616e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2617e5c31af7Sopenharmony_ci } 2618e5c31af7Sopenharmony_ci } 2619e5c31af7Sopenharmony_ci 2620e5c31af7Sopenharmony_ci /* Set result */ 2621e5c31af7Sopenharmony_ci if (true == test_result) 2622e5c31af7Sopenharmony_ci { 2623e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2624e5c31af7Sopenharmony_ci } 2625e5c31af7Sopenharmony_ci else 2626e5c31af7Sopenharmony_ci { 2627e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2628e5c31af7Sopenharmony_ci } 2629e5c31af7Sopenharmony_ci 2630e5c31af7Sopenharmony_ci /* Done */ 2631e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2632e5c31af7Sopenharmony_ci} 2633e5c31af7Sopenharmony_ci 2634e5c31af7Sopenharmony_ci/** Return name of operation 2635e5c31af7Sopenharmony_ci * 2636e5c31af7Sopenharmony_ci * @param operation Operation which name will be returned 2637e5c31af7Sopenharmony_ci * 2638e5c31af7Sopenharmony_ci * @return Name of operation or 0 in case of invalid enum 2639e5c31af7Sopenharmony_ci **/ 2640e5c31af7Sopenharmony_ciconst char* MapPersistentTextureTest::getOperationName(TESTED_OPERATION operation) 2641e5c31af7Sopenharmony_ci{ 2642e5c31af7Sopenharmony_ci const char* name = 0; 2643e5c31af7Sopenharmony_ci 2644e5c31af7Sopenharmony_ci switch (operation) 2645e5c31af7Sopenharmony_ci { 2646e5c31af7Sopenharmony_ci case OP_COMPRESSED_TEX_IMAGE: 2647e5c31af7Sopenharmony_ci name = "CompressedTexImage"; 2648e5c31af7Sopenharmony_ci break; 2649e5c31af7Sopenharmony_ci case OP_COMPRESSED_TEX_SUB_IMAGE: 2650e5c31af7Sopenharmony_ci name = "CompressedTexSubImage"; 2651e5c31af7Sopenharmony_ci break; 2652e5c31af7Sopenharmony_ci case OP_COMPRESSED_TEXTURE_SUB_IMAGE: 2653e5c31af7Sopenharmony_ci name = "CompressedTextureSubImage"; 2654e5c31af7Sopenharmony_ci break; 2655e5c31af7Sopenharmony_ci case OP_TEX_IMAGE: 2656e5c31af7Sopenharmony_ci name = "TexImage"; 2657e5c31af7Sopenharmony_ci break; 2658e5c31af7Sopenharmony_ci case OP_TEX_SUB_IMAGE: 2659e5c31af7Sopenharmony_ci name = "TexSubImage"; 2660e5c31af7Sopenharmony_ci break; 2661e5c31af7Sopenharmony_ci default: 2662e5c31af7Sopenharmony_ci TCU_FAIL("Invalid enum"); 2663e5c31af7Sopenharmony_ci } 2664e5c31af7Sopenharmony_ci 2665e5c31af7Sopenharmony_ci return name; 2666e5c31af7Sopenharmony_ci} 2667e5c31af7Sopenharmony_ci 2668e5c31af7Sopenharmony_ci/** Check format and size of compressed image 2669e5c31af7Sopenharmony_ci * 2670e5c31af7Sopenharmony_ci **/ 2671e5c31af7Sopenharmony_civoid MapPersistentTextureTest::getCompressedInfo() 2672e5c31af7Sopenharmony_ci{ 2673e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2674e5c31af7Sopenharmony_ci 2675e5c31af7Sopenharmony_ci /* Texture creation */ 2676e5c31af7Sopenharmony_ci Texture texture(m_context); 2677e5c31af7Sopenharmony_ci Texture::Generate(gl, texture.m_id); 2678e5c31af7Sopenharmony_ci Texture::Bind(gl, texture.m_id, GL_TEXTURE_2D); 2679e5c31af7Sopenharmony_ci Texture::Image(gl, GL_TEXTURE_2D, 0, GL_COMPRESSED_RED_RGTC1, 8, 8, 1, GL_RED, GL_UNSIGNED_BYTE, 2680e5c31af7Sopenharmony_ci 0); // glspec 4.5 pg 216 2681e5c31af7Sopenharmony_ci 2682e5c31af7Sopenharmony_ci /* Queries */ 2683e5c31af7Sopenharmony_ci Texture::GetLevelParameter(gl, GL_TEXTURE_2D, 0 /* level */, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, 2684e5c31af7Sopenharmony_ci &m_compressed_image_size); 2685e5c31af7Sopenharmony_ci Texture::GetLevelParameter(gl, GL_TEXTURE_2D, 0 /* level */, GL_TEXTURE_INTERNAL_FORMAT, 2686e5c31af7Sopenharmony_ci &m_compressed_internal_format); 2687e5c31af7Sopenharmony_ci} 2688e5c31af7Sopenharmony_ci 2689e5c31af7Sopenharmony_ci/** Verifies results of tested operation 2690e5c31af7Sopenharmony_ci * 2691e5c31af7Sopenharmony_ci * @param operation Operation to be tested 2692e5c31af7Sopenharmony_ci * @param buffer Buffer that will be used as GL_PIXEL_UNPACK_BUFFER 2693e5c31af7Sopenharmony_ci * @param expected_error Expected error 2694e5c31af7Sopenharmony_ci * 2695e5c31af7Sopenharmony_ci * @return false in case of any error, true otherwise 2696e5c31af7Sopenharmony_ci **/ 2697e5c31af7Sopenharmony_cibool MapPersistentTextureTest::verifyTestedOperation(TESTED_OPERATION operation, Buffer& buffer, 2698e5c31af7Sopenharmony_ci glw::GLenum expected_error) 2699e5c31af7Sopenharmony_ci{ 2700e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2701e5c31af7Sopenharmony_ci 2702e5c31af7Sopenharmony_ci bool result = true; 2703e5c31af7Sopenharmony_ci 2704e5c31af7Sopenharmony_ci GLenum error = GL_NO_ERROR; 2705e5c31af7Sopenharmony_ci Texture texture(m_context); 2706e5c31af7Sopenharmony_ci 2707e5c31af7Sopenharmony_ci /* Prepare texture */ 2708e5c31af7Sopenharmony_ci Texture::Generate(gl, texture.m_id); 2709e5c31af7Sopenharmony_ci Texture::Bind(gl, texture.m_id, GL_TEXTURE_2D); 2710e5c31af7Sopenharmony_ci 2711e5c31af7Sopenharmony_ci switch (operation) 2712e5c31af7Sopenharmony_ci { 2713e5c31af7Sopenharmony_ci case OP_COMPRESSED_TEX_IMAGE: 2714e5c31af7Sopenharmony_ci case OP_TEX_IMAGE: 2715e5c31af7Sopenharmony_ci break; 2716e5c31af7Sopenharmony_ci case OP_COMPRESSED_TEX_SUB_IMAGE: 2717e5c31af7Sopenharmony_ci case OP_COMPRESSED_TEXTURE_SUB_IMAGE: 2718e5c31af7Sopenharmony_ci Texture::CompressedImage(gl, GL_TEXTURE_2D, 0 /* level */, m_compressed_internal_format, 8 /* width */, 2719e5c31af7Sopenharmony_ci 8 /* height */, 0 /* depth */, m_compressed_image_size /* imageSize */, 2720e5c31af7Sopenharmony_ci 0 /* empty image */); 2721e5c31af7Sopenharmony_ci break; 2722e5c31af7Sopenharmony_ci case OP_TEX_SUB_IMAGE: 2723e5c31af7Sopenharmony_ci Texture::Image(gl, GL_TEXTURE_2D, 0 /* level */, GL_R8, 8 /* width */, 8 /* height */, 0 /* depth */, GL_RED, 2724e5c31af7Sopenharmony_ci GL_UNSIGNED_BYTE, 0 /* empty image */); 2725e5c31af7Sopenharmony_ci break; 2726e5c31af7Sopenharmony_ci default: 2727e5c31af7Sopenharmony_ci TCU_FAIL("Invalid enum"); 2728e5c31af7Sopenharmony_ci } 2729e5c31af7Sopenharmony_ci 2730e5c31af7Sopenharmony_ci /* Bind buffer to PIXEL_UNPACK */ 2731e5c31af7Sopenharmony_ci Buffer::Bind(gl, buffer.m_id, GL_PIXEL_UNPACK_BUFFER); 2732e5c31af7Sopenharmony_ci 2733e5c31af7Sopenharmony_ci /* Execute operation */ 2734e5c31af7Sopenharmony_ci switch (operation) 2735e5c31af7Sopenharmony_ci { 2736e5c31af7Sopenharmony_ci case OP_COMPRESSED_TEX_IMAGE: 2737e5c31af7Sopenharmony_ci gl.compressedTexImage2D(GL_TEXTURE_2D, 0 /* level */, m_compressed_internal_format, 8 /* width */, 2738e5c31af7Sopenharmony_ci 8 /* height */, 0 /* border */, m_compressed_image_size /* imageSize */, 2739e5c31af7Sopenharmony_ci 0 /* offset to pixel unpack buffer */); 2740e5c31af7Sopenharmony_ci error = gl.getError(); 2741e5c31af7Sopenharmony_ci break; 2742e5c31af7Sopenharmony_ci case OP_COMPRESSED_TEX_SUB_IMAGE: 2743e5c31af7Sopenharmony_ci gl.compressedTexSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, 8 /* width */, 8 /* height */, 2744e5c31af7Sopenharmony_ci m_compressed_internal_format, m_compressed_image_size, 2745e5c31af7Sopenharmony_ci 0 /* offset to pixel unpack buffer */); 2746e5c31af7Sopenharmony_ci error = gl.getError(); 2747e5c31af7Sopenharmony_ci break; 2748e5c31af7Sopenharmony_ci case OP_COMPRESSED_TEXTURE_SUB_IMAGE: 2749e5c31af7Sopenharmony_ci if (0 != gl.compressedTextureSubImage2D) 2750e5c31af7Sopenharmony_ci { 2751e5c31af7Sopenharmony_ci gl.compressedTextureSubImage2D(texture.m_id, 0 /* level */, 0 /* x */, 0 /* y */, 8 /* width */, 2752e5c31af7Sopenharmony_ci 8 /* height */, m_compressed_internal_format, m_compressed_image_size, 2753e5c31af7Sopenharmony_ci 0 /* offset to pixel unpack buffer */); 2754e5c31af7Sopenharmony_ci error = gl.getError(); 2755e5c31af7Sopenharmony_ci } 2756e5c31af7Sopenharmony_ci else 2757e5c31af7Sopenharmony_ci { 2758e5c31af7Sopenharmony_ci /* Not supported, ignore */ 2759e5c31af7Sopenharmony_ci error = expected_error; 2760e5c31af7Sopenharmony_ci } 2761e5c31af7Sopenharmony_ci break; 2762e5c31af7Sopenharmony_ci case OP_TEX_IMAGE: 2763e5c31af7Sopenharmony_ci gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, GL_R8, 8 /* width */, 8 /* height */, 0 /* border */, GL_RED, 2764e5c31af7Sopenharmony_ci GL_UNSIGNED_BYTE, 0 /* offset to pixel unpack buffer */); 2765e5c31af7Sopenharmony_ci error = gl.getError(); 2766e5c31af7Sopenharmony_ci break; 2767e5c31af7Sopenharmony_ci case OP_TEX_SUB_IMAGE: 2768e5c31af7Sopenharmony_ci gl.texSubImage2D(GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, 8 /* width */, 8 /* height */, GL_RED, 2769e5c31af7Sopenharmony_ci GL_UNSIGNED_BYTE, 0 /* offset to pixel unpack buffer */); 2770e5c31af7Sopenharmony_ci error = gl.getError(); 2771e5c31af7Sopenharmony_ci break; 2772e5c31af7Sopenharmony_ci default: 2773e5c31af7Sopenharmony_ci TCU_FAIL("Invalid enum"); 2774e5c31af7Sopenharmony_ci } 2775e5c31af7Sopenharmony_ci 2776e5c31af7Sopenharmony_ci /* Unbind buffer */ 2777e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0 /* id */, GL_PIXEL_UNPACK_BUFFER); 2778e5c31af7Sopenharmony_ci 2779e5c31af7Sopenharmony_ci /* Check result */ 2780e5c31af7Sopenharmony_ci if (expected_error != error) 2781e5c31af7Sopenharmony_ci { 2782e5c31af7Sopenharmony_ci result = false; 2783e5c31af7Sopenharmony_ci 2784e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message << getOperationName(operation) 2785e5c31af7Sopenharmony_ci << " generated wrong error: " << glu::getErrorStr(error).toString().c_str() 2786e5c31af7Sopenharmony_ci << ", expected: " << glu::getErrorStr(expected_error).toString().c_str() 2787e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2788e5c31af7Sopenharmony_ci } 2789e5c31af7Sopenharmony_ci 2790e5c31af7Sopenharmony_ci /* Done */ 2791e5c31af7Sopenharmony_ci return result; 2792e5c31af7Sopenharmony_ci} 2793e5c31af7Sopenharmony_ci 2794e5c31af7Sopenharmony_ci/** Constructor 2795e5c31af7Sopenharmony_ci * 2796e5c31af7Sopenharmony_ci * @param context Test context 2797e5c31af7Sopenharmony_ci **/ 2798e5c31af7Sopenharmony_ciMapPersistentReadPixelsTest::MapPersistentReadPixelsTest(deqp::Context& context) 2799e5c31af7Sopenharmony_ci : TestCase(context, "map_persistent_read_pixels", "Test read pixels operation against mapped buffer") 2800e5c31af7Sopenharmony_ci{ 2801e5c31af7Sopenharmony_ci /* Nothing to be done here */ 2802e5c31af7Sopenharmony_ci} 2803e5c31af7Sopenharmony_ci 2804e5c31af7Sopenharmony_ci/** Execute test 2805e5c31af7Sopenharmony_ci * 2806e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP otherwise 2807e5c31af7Sopenharmony_ci **/ 2808e5c31af7Sopenharmony_citcu::TestNode::IterateResult MapPersistentReadPixelsTest::iterate() 2809e5c31af7Sopenharmony_ci{ 2810e5c31af7Sopenharmony_ci static const GLuint height = 8; 2811e5c31af7Sopenharmony_ci static const GLuint width = 8; 2812e5c31af7Sopenharmony_ci static const size_t data_size = width * height; 2813e5c31af7Sopenharmony_ci 2814e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2815e5c31af7Sopenharmony_ci 2816e5c31af7Sopenharmony_ci bool test_result = true; 2817e5c31af7Sopenharmony_ci 2818e5c31af7Sopenharmony_ci /* Prepare data */ 2819e5c31af7Sopenharmony_ci GLubyte initial_texture_data[data_size]; 2820e5c31af7Sopenharmony_ci GLubyte updated_texture_data[data_size]; 2821e5c31af7Sopenharmony_ci 2822e5c31af7Sopenharmony_ci for (size_t i = 0; i < data_size; ++i) 2823e5c31af7Sopenharmony_ci { 2824e5c31af7Sopenharmony_ci initial_texture_data[i] = (glw::GLubyte)i; 2825e5c31af7Sopenharmony_ci updated_texture_data[i] = (glw::GLubyte)(data_size - i); 2826e5c31af7Sopenharmony_ci } 2827e5c31af7Sopenharmony_ci 2828e5c31af7Sopenharmony_ci /* Prepare GL objects */ 2829e5c31af7Sopenharmony_ci Buffer buffer(m_context); 2830e5c31af7Sopenharmony_ci Framebuffer framebuffer(m_context); 2831e5c31af7Sopenharmony_ci Texture texture(m_context); 2832e5c31af7Sopenharmony_ci 2833e5c31af7Sopenharmony_ci buffer.InitStorage(GL_PIXEL_PACK_BUFFER, GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, data_size, 2834e5c31af7Sopenharmony_ci 0 /* data */); 2835e5c31af7Sopenharmony_ci 2836e5c31af7Sopenharmony_ci Texture::Generate(gl, texture.m_id); 2837e5c31af7Sopenharmony_ci Texture::Bind(gl, texture.m_id, GL_TEXTURE_2D); 2838e5c31af7Sopenharmony_ci Texture::Storage(gl, GL_TEXTURE_2D, 1 /* levels */, GL_R8UI, width, height, 0 /* depth */); 2839e5c31af7Sopenharmony_ci Texture::SubImage(gl, GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height, 0 /* depth */, 2840e5c31af7Sopenharmony_ci GL_RED_INTEGER, GL_UNSIGNED_BYTE, initial_texture_data); 2841e5c31af7Sopenharmony_ci 2842e5c31af7Sopenharmony_ci Framebuffer::Generate(gl, framebuffer.m_id); 2843e5c31af7Sopenharmony_ci Framebuffer::Bind(gl, GL_READ_FRAMEBUFFER, framebuffer.m_id); 2844e5c31af7Sopenharmony_ci Framebuffer::AttachTexture(gl, GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture.m_id, width, height); 2845e5c31af7Sopenharmony_ci 2846e5c31af7Sopenharmony_ci /* 2847e5c31af7Sopenharmony_ci * - execute ReadPixels to transfer texture contents to buffer, no error should 2848e5c31af7Sopenharmony_ci * be generated; 2849e5c31af7Sopenharmony_ci */ 2850e5c31af7Sopenharmony_ci buffer.Bind(); 2851e5c31af7Sopenharmony_ci gl.readPixels(0 /* x */, 0 /* y */, width, height, GL_RED_INTEGER, GL_UNSIGNED_BYTE, 2852e5c31af7Sopenharmony_ci 0 /* offset in PIXEL_PACK_BUFFER */); 2853e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "ReadPixels to not mapped PIXEL_PACK buffer"); 2854e5c31af7Sopenharmony_ci 2855e5c31af7Sopenharmony_ci /* 2856e5c31af7Sopenharmony_ci * - update contents of texture with different image; 2857e5c31af7Sopenharmony_ci * - map buffer contents with MapBufferRange, <access> should contain 2858e5c31af7Sopenharmony_ci * MAP_PERSISTENT_BIT, MAP_READ_BIT and MAP_WRITE_BIT; 2859e5c31af7Sopenharmony_ci * - execute ReadPixels to transfer texture contents to buffer, no error should 2860e5c31af7Sopenharmony_ci * be generated; 2861e5c31af7Sopenharmony_ci * - execute MemoryBarrier with CLIENT_MAPPED_BUFFER_BARRIER_BIT and Finish; 2862e5c31af7Sopenharmony_ci * - inspect contents of mapped buffer, to verify that latest data transfer was 2863e5c31af7Sopenharmony_ci * successful; 2864e5c31af7Sopenharmony_ci * - unmap buffer 2865e5c31af7Sopenharmony_ci */ 2866e5c31af7Sopenharmony_ci { 2867e5c31af7Sopenharmony_ci Texture::SubImage(gl, GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, 0 /* z */, width, height, 2868e5c31af7Sopenharmony_ci 0 /* depth */, GL_RED_INTEGER, GL_UNSIGNED_BYTE, updated_texture_data); 2869e5c31af7Sopenharmony_ci 2870e5c31af7Sopenharmony_ci const Buffer::MapOwner map( 2871e5c31af7Sopenharmony_ci buffer.MapRange(0 /* offset */, data_size, GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)); 2872e5c31af7Sopenharmony_ci 2873e5c31af7Sopenharmony_ci buffer.Bind(); 2874e5c31af7Sopenharmony_ci gl.readPixels(0 /* x */, 0 /* y */, width, height, GL_RED_INTEGER, GL_UNSIGNED_BYTE, 2875e5c31af7Sopenharmony_ci 0 /* offset in PIXEL_PACK_BUFFER */); 2876e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "ReadPixels to persistently mapped PIXEL_PACK buffer"); 2877e5c31af7Sopenharmony_ci 2878e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT); 2879e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier"); 2880e5c31af7Sopenharmony_ci 2881e5c31af7Sopenharmony_ci gl.finish(); 2882e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Finish"); 2883e5c31af7Sopenharmony_ci 2884e5c31af7Sopenharmony_ci if (0 != memcmp(updated_texture_data, map.m_data, data_size)) 2885e5c31af7Sopenharmony_ci { 2886e5c31af7Sopenharmony_ci test_result = false; 2887e5c31af7Sopenharmony_ci 2888e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2889e5c31af7Sopenharmony_ci << tcu::TestLog::Message << "Wrong contents of persistently mapped PIXEL_PACK buffer after ReadPixels" 2890e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 2891e5c31af7Sopenharmony_ci } 2892e5c31af7Sopenharmony_ci } 2893e5c31af7Sopenharmony_ci 2894e5c31af7Sopenharmony_ci /* 2895e5c31af7Sopenharmony_ci * - map buffer contents again, this time do not provide MAP_PERSISTENT_BIT; 2896e5c31af7Sopenharmony_ci * - execute ReadPixels to transfer texture contents to buffer, 2897e5c31af7Sopenharmony_ci * INVALID_OPERATION error should be generated. 2898e5c31af7Sopenharmony_ci */ 2899e5c31af7Sopenharmony_ci { 2900e5c31af7Sopenharmony_ci Buffer::MapOwner tmp(buffer.MapRange(0 /* offset */, data_size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)); 2901e5c31af7Sopenharmony_ci 2902e5c31af7Sopenharmony_ci buffer.Bind(); 2903e5c31af7Sopenharmony_ci gl.readPixels(0 /* x */, 0 /* y */, width, height, GL_RED_INTEGER, GL_UNSIGNED_BYTE, 2904e5c31af7Sopenharmony_ci 0 /* offset in PIXEL_PACK_BUFFER */); 2905e5c31af7Sopenharmony_ci GLenum error = gl.getError(); 2906e5c31af7Sopenharmony_ci 2907e5c31af7Sopenharmony_ci if (GL_INVALID_OPERATION != error) 2908e5c31af7Sopenharmony_ci { 2909e5c31af7Sopenharmony_ci test_result = false; 2910e5c31af7Sopenharmony_ci 2911e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 2912e5c31af7Sopenharmony_ci << tcu::TestLog::Message << "Wrong error was generated by ReadPixels. Expected INVALID_OPERATION as " 2913e5c31af7Sopenharmony_ci "PIXEL_PACK buffer is mapped. Got: " 2914e5c31af7Sopenharmony_ci << glu::getErrorStr(error).toString().c_str() << tcu::TestLog::EndMessage; 2915e5c31af7Sopenharmony_ci } 2916e5c31af7Sopenharmony_ci } 2917e5c31af7Sopenharmony_ci 2918e5c31af7Sopenharmony_ci /* Set result */ 2919e5c31af7Sopenharmony_ci if (true == test_result) 2920e5c31af7Sopenharmony_ci { 2921e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2922e5c31af7Sopenharmony_ci } 2923e5c31af7Sopenharmony_ci else 2924e5c31af7Sopenharmony_ci { 2925e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 2926e5c31af7Sopenharmony_ci } 2927e5c31af7Sopenharmony_ci 2928e5c31af7Sopenharmony_ci /* Done */ 2929e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 2930e5c31af7Sopenharmony_ci} 2931e5c31af7Sopenharmony_ci 2932e5c31af7Sopenharmony_ci/** Constructor 2933e5c31af7Sopenharmony_ci * 2934e5c31af7Sopenharmony_ci * @param context Test context 2935e5c31af7Sopenharmony_ci **/ 2936e5c31af7Sopenharmony_ciMapPersistentDispatchTest::MapPersistentDispatchTest(deqp::Context& context) 2937e5c31af7Sopenharmony_ci : TestCase(context, "map_persistent_dispatch", "test dispatch operation against mapped buffer") 2938e5c31af7Sopenharmony_ci{ 2939e5c31af7Sopenharmony_ci /* Nothing to be done here */ 2940e5c31af7Sopenharmony_ci} 2941e5c31af7Sopenharmony_ci 2942e5c31af7Sopenharmony_ci/** Constructor 2943e5c31af7Sopenharmony_ci * 2944e5c31af7Sopenharmony_ci * @param context Test context 2945e5c31af7Sopenharmony_ci * @param test_name Test name 2946e5c31af7Sopenharmony_ci * @param test_description Test description 2947e5c31af7Sopenharmony_ci **/ 2948e5c31af7Sopenharmony_ciMapPersistentDispatchTest::MapPersistentDispatchTest(deqp::Context& context, const GLchar* test_name, 2949e5c31af7Sopenharmony_ci const GLchar* test_description) 2950e5c31af7Sopenharmony_ci : TestCase(context, test_name, test_description) 2951e5c31af7Sopenharmony_ci{ 2952e5c31af7Sopenharmony_ci /* Nothing to be done here */ 2953e5c31af7Sopenharmony_ci} 2954e5c31af7Sopenharmony_ci 2955e5c31af7Sopenharmony_ci/** Execute test 2956e5c31af7Sopenharmony_ci * 2957e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP otherwise 2958e5c31af7Sopenharmony_ci **/ 2959e5c31af7Sopenharmony_citcu::TestNode::IterateResult MapPersistentDispatchTest::iterate() 2960e5c31af7Sopenharmony_ci{ 2961e5c31af7Sopenharmony_ci static const GLchar* compute_shader = "#version 430 core\n" 2962e5c31af7Sopenharmony_ci "\n" 2963e5c31af7Sopenharmony_ci "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 2964e5c31af7Sopenharmony_ci "\n" 2965e5c31af7Sopenharmony_ci "layout (binding = 0, std430) buffer DestinationData {\n" 2966e5c31af7Sopenharmony_ci " uint values[];\n" 2967e5c31af7Sopenharmony_ci "} destination;\n" 2968e5c31af7Sopenharmony_ci "\n" 2969e5c31af7Sopenharmony_ci "layout (binding = 1, std430) buffer SourceData {\n" 2970e5c31af7Sopenharmony_ci " uint values[];\n" 2971e5c31af7Sopenharmony_ci "} source;\n" 2972e5c31af7Sopenharmony_ci "\n" 2973e5c31af7Sopenharmony_ci "void main()\n" 2974e5c31af7Sopenharmony_ci "{\n" 2975e5c31af7Sopenharmony_ci " uint index = gl_GlobalInvocationID.x;\n" 2976e5c31af7Sopenharmony_ci " uint sum = 0u;\n" 2977e5c31af7Sopenharmony_ci "\n" 2978e5c31af7Sopenharmony_ci " for (uint i = 0u; i <= index; ++i)\n" 2979e5c31af7Sopenharmony_ci " {\n" 2980e5c31af7Sopenharmony_ci " sum += source.values[i];\n" 2981e5c31af7Sopenharmony_ci " }\n" 2982e5c31af7Sopenharmony_ci "\n" 2983e5c31af7Sopenharmony_ci " destination.values[index] = sum;\n" 2984e5c31af7Sopenharmony_ci "}\n" 2985e5c31af7Sopenharmony_ci "\n"; 2986e5c31af7Sopenharmony_ci static const GLuint data_size = 16; 2987e5c31af7Sopenharmony_ci static const GLuint destination_binding = 0; 2988e5c31af7Sopenharmony_ci static const GLuint source_binding = 1; 2989e5c31af7Sopenharmony_ci 2990e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 2991e5c31af7Sopenharmony_ci 2992e5c31af7Sopenharmony_ci bool test_result = true; 2993e5c31af7Sopenharmony_ci 2994e5c31af7Sopenharmony_ci /* Prepare data */ 2995e5c31af7Sopenharmony_ci GLuint destination_data[data_size]; 2996e5c31af7Sopenharmony_ci GLuint modified_source_data[data_size]; 2997e5c31af7Sopenharmony_ci GLuint modified_sum_data[data_size]; 2998e5c31af7Sopenharmony_ci GLuint source_data[data_size]; 2999e5c31af7Sopenharmony_ci GLuint sum_data[data_size]; 3000e5c31af7Sopenharmony_ci 3001e5c31af7Sopenharmony_ci GLuint modified_sum = 0; 3002e5c31af7Sopenharmony_ci GLuint sum = 0; 3003e5c31af7Sopenharmony_ci 3004e5c31af7Sopenharmony_ci for (GLuint i = 0; i < data_size; ++i) 3005e5c31af7Sopenharmony_ci { 3006e5c31af7Sopenharmony_ci destination_data[i] = 0; 3007e5c31af7Sopenharmony_ci modified_source_data[i] = data_size - i; 3008e5c31af7Sopenharmony_ci source_data[i] = i; 3009e5c31af7Sopenharmony_ci 3010e5c31af7Sopenharmony_ci modified_sum += modified_source_data[i]; 3011e5c31af7Sopenharmony_ci sum += source_data[i]; 3012e5c31af7Sopenharmony_ci 3013e5c31af7Sopenharmony_ci modified_sum_data[i] = modified_sum; 3014e5c31af7Sopenharmony_ci sum_data[i] = sum; 3015e5c31af7Sopenharmony_ci } 3016e5c31af7Sopenharmony_ci 3017e5c31af7Sopenharmony_ci /* Prepare buffers */ 3018e5c31af7Sopenharmony_ci Buffer destination(m_context); 3019e5c31af7Sopenharmony_ci Buffer source(m_context); 3020e5c31af7Sopenharmony_ci 3021e5c31af7Sopenharmony_ci destination.InitStorage(GL_SHADER_STORAGE_BUFFER, GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT, 3022e5c31af7Sopenharmony_ci data_size * sizeof(GLuint), destination_data); 3023e5c31af7Sopenharmony_ci 3024e5c31af7Sopenharmony_ci source.InitStorage(GL_SHADER_STORAGE_BUFFER, GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT, 3025e5c31af7Sopenharmony_ci data_size * sizeof(GLuint), source_data); 3026e5c31af7Sopenharmony_ci 3027e5c31af7Sopenharmony_ci /* Prepare program */ 3028e5c31af7Sopenharmony_ci Program program(m_context); 3029e5c31af7Sopenharmony_ci program.Init(compute_shader, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */); 3030e5c31af7Sopenharmony_ci 3031e5c31af7Sopenharmony_ci /* 3032e5c31af7Sopenharmony_ci * - bind buffers to SHADER_STORAGE_BUFFER; 3033e5c31af7Sopenharmony_ci * - use MapBufferRange to map both buffers; <access> shall be set as follows: 3034e5c31af7Sopenharmony_ci * * MAP_COHERENT_BIT and MAP_PERSISTENT_BIT flags set for both 3035e5c31af7Sopenharmony_ci * * MAP_WRITE_BIT flag shall be set for source; 3036e5c31af7Sopenharmony_ci * * MAP_READ_BIT flag shall be set for destination; 3037e5c31af7Sopenharmony_ci * - dispatch program for 16x1x1 groups; 3038e5c31af7Sopenharmony_ci * - modify contents of source buffer via mapped memory; 3039e5c31af7Sopenharmony_ci * - execute Finish; 3040e5c31af7Sopenharmony_ci * - inspect contents of destination buffer via mapped memory; It is expected 3041e5c31af7Sopenharmony_ci * that it will contain results based on original content of source buffer; 3042e5c31af7Sopenharmony_ci * - dispatch program for 16x1x1 groups; 3043e5c31af7Sopenharmony_ci * - execute Finish; 3044e5c31af7Sopenharmony_ci * - inspect contents of destination buffer via mapped memory; It is expected 3045e5c31af7Sopenharmony_ci * that it will contain results based on modified content of source buffer. 3046e5c31af7Sopenharmony_ci */ 3047e5c31af7Sopenharmony_ci { 3048e5c31af7Sopenharmony_ci /* Set program */ 3049e5c31af7Sopenharmony_ci Program::Use(gl, program.m_id); 3050e5c31af7Sopenharmony_ci 3051e5c31af7Sopenharmony_ci /* Map buffers */ 3052e5c31af7Sopenharmony_ci destination.Bind(); 3053e5c31af7Sopenharmony_ci const Buffer::MapOwner destination_map(destination.MapRange( 3054e5c31af7Sopenharmony_ci 0 /* offset */, data_size * sizeof(GLuint), GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT)); 3055e5c31af7Sopenharmony_ci 3056e5c31af7Sopenharmony_ci source.Bind(); 3057e5c31af7Sopenharmony_ci const Buffer::MapOwner source_map( 3058e5c31af7Sopenharmony_ci source.MapRange(0 /* offset */, data_size * sizeof(GLuint), 3059e5c31af7Sopenharmony_ci GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT)); 3060e5c31af7Sopenharmony_ci 3061e5c31af7Sopenharmony_ci /* Clear binding point */ 3062e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0, GL_SHADER_STORAGE_BUFFER); 3063e5c31af7Sopenharmony_ci 3064e5c31af7Sopenharmony_ci /* Bind buffers */ 3065e5c31af7Sopenharmony_ci Buffer::BindBase(gl, destination.m_id, GL_SHADER_STORAGE_BUFFER, destination_binding); 3066e5c31af7Sopenharmony_ci Buffer::BindBase(gl, source.m_id, GL_SHADER_STORAGE_BUFFER, source_binding); 3067e5c31af7Sopenharmony_ci 3068e5c31af7Sopenharmony_ci /* Execute program for 16x1x1 groups */ 3069e5c31af7Sopenharmony_ci gl.dispatchCompute(16, 1, 1); 3070e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute with persistently mapped buffers"); 3071e5c31af7Sopenharmony_ci 3072e5c31af7Sopenharmony_ci /* Make sure that program executed */ 3073e5c31af7Sopenharmony_ci gl.finish(); 3074e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Finish"); 3075e5c31af7Sopenharmony_ci 3076e5c31af7Sopenharmony_ci if (0 != memcmp(destination_map.m_data, sum_data, data_size * sizeof(GLuint))) 3077e5c31af7Sopenharmony_ci { 3078e5c31af7Sopenharmony_ci test_result = false; 3079e5c31af7Sopenharmony_ci 3080e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 3081e5c31af7Sopenharmony_ci << "Contents of mapped region does not correspond with expected results" 3082e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3083e5c31af7Sopenharmony_ci } 3084e5c31af7Sopenharmony_ci 3085e5c31af7Sopenharmony_ci /* Modify source buffer via mapped area */ 3086e5c31af7Sopenharmony_ci memcpy(source_map.m_data, modified_source_data, data_size * sizeof(GLuint)); 3087e5c31af7Sopenharmony_ci 3088e5c31af7Sopenharmony_ci /* Execute program for 16x1x1 groups */ 3089e5c31af7Sopenharmony_ci gl.dispatchCompute(16, 1, 1); 3090e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute with persistently mapped buffers"); 3091e5c31af7Sopenharmony_ci 3092e5c31af7Sopenharmony_ci /* Make sure that program executed */ 3093e5c31af7Sopenharmony_ci gl.finish(); 3094e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Finish"); 3095e5c31af7Sopenharmony_ci 3096e5c31af7Sopenharmony_ci if (0 != memcmp(destination_map.m_data, modified_sum_data, data_size * sizeof(GLuint))) 3097e5c31af7Sopenharmony_ci { 3098e5c31af7Sopenharmony_ci test_result = false; 3099e5c31af7Sopenharmony_ci 3100e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 3101e5c31af7Sopenharmony_ci << "Contents of mapped region does not correspond with expected results" 3102e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3103e5c31af7Sopenharmony_ci } 3104e5c31af7Sopenharmony_ci } 3105e5c31af7Sopenharmony_ci 3106e5c31af7Sopenharmony_ci /* Set result */ 3107e5c31af7Sopenharmony_ci if (true == test_result) 3108e5c31af7Sopenharmony_ci { 3109e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3110e5c31af7Sopenharmony_ci } 3111e5c31af7Sopenharmony_ci else 3112e5c31af7Sopenharmony_ci { 3113e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3114e5c31af7Sopenharmony_ci } 3115e5c31af7Sopenharmony_ci 3116e5c31af7Sopenharmony_ci /* Done */ 3117e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 3118e5c31af7Sopenharmony_ci} 3119e5c31af7Sopenharmony_ci 3120e5c31af7Sopenharmony_ci/** Constructor 3121e5c31af7Sopenharmony_ci * 3122e5c31af7Sopenharmony_ci * @param context Test context 3123e5c31af7Sopenharmony_ci **/ 3124e5c31af7Sopenharmony_ciMapPersistentFlushTest::MapPersistentFlushTest(deqp::Context& context) 3125e5c31af7Sopenharmony_ci : TestCase(context, "map_persistent_flush", "Test mapped buffer against flushing") 3126e5c31af7Sopenharmony_ci{ 3127e5c31af7Sopenharmony_ci /* Nothing to be done here */ 3128e5c31af7Sopenharmony_ci} 3129e5c31af7Sopenharmony_ci 3130e5c31af7Sopenharmony_ci/** Execute test 3131e5c31af7Sopenharmony_ci * 3132e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP otherwise 3133e5c31af7Sopenharmony_ci **/ 3134e5c31af7Sopenharmony_citcu::TestNode::IterateResult MapPersistentFlushTest::iterate() 3135e5c31af7Sopenharmony_ci{ 3136e5c31af7Sopenharmony_ci static const GLchar* compute_shader = "#version 430 core\n" 3137e5c31af7Sopenharmony_ci "\n" 3138e5c31af7Sopenharmony_ci "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 3139e5c31af7Sopenharmony_ci "\n" 3140e5c31af7Sopenharmony_ci "layout (binding = 0, std430) buffer DestinationData {\n" 3141e5c31af7Sopenharmony_ci " uint values[];\n" 3142e5c31af7Sopenharmony_ci "} destination;\n" 3143e5c31af7Sopenharmony_ci "\n" 3144e5c31af7Sopenharmony_ci "layout (binding = 1, std430) buffer SourceData {\n" 3145e5c31af7Sopenharmony_ci " uint values[];\n" 3146e5c31af7Sopenharmony_ci "} source;\n" 3147e5c31af7Sopenharmony_ci "\n" 3148e5c31af7Sopenharmony_ci "void main()\n" 3149e5c31af7Sopenharmony_ci "{\n" 3150e5c31af7Sopenharmony_ci " uint index = gl_GlobalInvocationID.x;\n" 3151e5c31af7Sopenharmony_ci " uint sum = 0u;\n" 3152e5c31af7Sopenharmony_ci "\n" 3153e5c31af7Sopenharmony_ci " for (uint i = 0u; i <= index; ++i)\n" 3154e5c31af7Sopenharmony_ci " {\n" 3155e5c31af7Sopenharmony_ci " sum += source.values[i];\n" 3156e5c31af7Sopenharmony_ci " }\n" 3157e5c31af7Sopenharmony_ci "\n" 3158e5c31af7Sopenharmony_ci " destination.values[index] = sum;\n" 3159e5c31af7Sopenharmony_ci "}\n" 3160e5c31af7Sopenharmony_ci "\n"; 3161e5c31af7Sopenharmony_ci static const GLuint data_size = 16; 3162e5c31af7Sopenharmony_ci static const GLuint destination_binding = 0; 3163e5c31af7Sopenharmony_ci static const GLuint source_binding = 1; 3164e5c31af7Sopenharmony_ci 3165e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 3166e5c31af7Sopenharmony_ci 3167e5c31af7Sopenharmony_ci bool test_result = true; 3168e5c31af7Sopenharmony_ci 3169e5c31af7Sopenharmony_ci /* Prepare data */ 3170e5c31af7Sopenharmony_ci GLuint destination_data[data_size]; 3171e5c31af7Sopenharmony_ci GLuint modified_source_data[data_size]; 3172e5c31af7Sopenharmony_ci GLuint modified_sum_data[data_size]; 3173e5c31af7Sopenharmony_ci GLuint source_data[data_size]; 3174e5c31af7Sopenharmony_ci GLuint sum_data[data_size]; 3175e5c31af7Sopenharmony_ci 3176e5c31af7Sopenharmony_ci GLuint modified_sum = 0; 3177e5c31af7Sopenharmony_ci GLuint sum = 0; 3178e5c31af7Sopenharmony_ci 3179e5c31af7Sopenharmony_ci for (GLuint i = 0; i < data_size; ++i) 3180e5c31af7Sopenharmony_ci { 3181e5c31af7Sopenharmony_ci destination_data[i] = 0; 3182e5c31af7Sopenharmony_ci modified_source_data[i] = data_size - i; 3183e5c31af7Sopenharmony_ci source_data[i] = i; 3184e5c31af7Sopenharmony_ci 3185e5c31af7Sopenharmony_ci modified_sum += modified_source_data[i]; 3186e5c31af7Sopenharmony_ci sum += source_data[i]; 3187e5c31af7Sopenharmony_ci 3188e5c31af7Sopenharmony_ci modified_sum_data[i] = modified_sum; 3189e5c31af7Sopenharmony_ci sum_data[i] = sum; 3190e5c31af7Sopenharmony_ci } 3191e5c31af7Sopenharmony_ci 3192e5c31af7Sopenharmony_ci /* Prepare buffers */ 3193e5c31af7Sopenharmony_ci Buffer destination(m_context); 3194e5c31af7Sopenharmony_ci Buffer source(m_context); 3195e5c31af7Sopenharmony_ci 3196e5c31af7Sopenharmony_ci destination.InitStorage(GL_SHADER_STORAGE_BUFFER, GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT, 3197e5c31af7Sopenharmony_ci data_size * sizeof(GLuint), destination_data); 3198e5c31af7Sopenharmony_ci 3199e5c31af7Sopenharmony_ci source.InitStorage(GL_SHADER_STORAGE_BUFFER, GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT, 3200e5c31af7Sopenharmony_ci data_size * sizeof(GLuint), source_data); 3201e5c31af7Sopenharmony_ci 3202e5c31af7Sopenharmony_ci /* Prepare program */ 3203e5c31af7Sopenharmony_ci Program program(m_context); 3204e5c31af7Sopenharmony_ci program.Init(compute_shader, "" /* fs */, "" /* gs */, "" /* tcs */, "" /* tes */, "" /* vs */); 3205e5c31af7Sopenharmony_ci 3206e5c31af7Sopenharmony_ci /* 3207e5c31af7Sopenharmony_ci * - bind buffers to SHADER_STORAGE_BUFFER; 3208e5c31af7Sopenharmony_ci * - use MapBufferRange to map both buffers; <access> shall be set as follows: 3209e5c31af7Sopenharmony_ci * * MAP_COHERENT_BIT and MAP_PERSISTENT_BIT flags set for both 3210e5c31af7Sopenharmony_ci * * MAP_WRITE_BIT flag shall be set for source; 3211e5c31af7Sopenharmony_ci * * MAP_READ_BIT flag shall be set for destination; 3212e5c31af7Sopenharmony_ci * - dispatch program for 16x1x1 groups; 3213e5c31af7Sopenharmony_ci * - modify contents of source buffer via mapped memory; 3214e5c31af7Sopenharmony_ci * - execute Finish; 3215e5c31af7Sopenharmony_ci * - inspect contents of destination buffer via mapped memory; It is expected 3216e5c31af7Sopenharmony_ci * that it will contain results based on original content of source buffer; 3217e5c31af7Sopenharmony_ci * - dispatch program for 16x1x1 groups; 3218e5c31af7Sopenharmony_ci * - execute Finish; 3219e5c31af7Sopenharmony_ci * - inspect contents of destination buffer via mapped memory; It is expected 3220e5c31af7Sopenharmony_ci * that it will contain results based on modified content of source buffer. 3221e5c31af7Sopenharmony_ci */ 3222e5c31af7Sopenharmony_ci { 3223e5c31af7Sopenharmony_ci /* Set program */ 3224e5c31af7Sopenharmony_ci Program::Use(gl, program.m_id); 3225e5c31af7Sopenharmony_ci 3226e5c31af7Sopenharmony_ci /* Map buffers */ 3227e5c31af7Sopenharmony_ci destination.Bind(); 3228e5c31af7Sopenharmony_ci const Buffer::MapOwner destination_map(destination.MapRange( 3229e5c31af7Sopenharmony_ci 0 /* offset */, data_size * sizeof(GLuint), GL_MAP_COHERENT_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT)); 3230e5c31af7Sopenharmony_ci 3231e5c31af7Sopenharmony_ci source.Bind(); 3232e5c31af7Sopenharmony_ci const Buffer::MapOwner source_map( 3233e5c31af7Sopenharmony_ci source.MapRange(0 /* offset */, data_size * sizeof(GLuint), 3234e5c31af7Sopenharmony_ci GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT)); 3235e5c31af7Sopenharmony_ci 3236e5c31af7Sopenharmony_ci /* Clear binding point */ 3237e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0, GL_SHADER_STORAGE_BUFFER); 3238e5c31af7Sopenharmony_ci 3239e5c31af7Sopenharmony_ci /* Bind buffers */ 3240e5c31af7Sopenharmony_ci Buffer::BindBase(gl, destination.m_id, GL_SHADER_STORAGE_BUFFER, destination_binding); 3241e5c31af7Sopenharmony_ci Buffer::BindBase(gl, source.m_id, GL_SHADER_STORAGE_BUFFER, source_binding); 3242e5c31af7Sopenharmony_ci 3243e5c31af7Sopenharmony_ci /* Execute program for 16x1x1 groups */ 3244e5c31af7Sopenharmony_ci gl.dispatchCompute(16, 1, 1); 3245e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute with persistently mapped buffers"); 3246e5c31af7Sopenharmony_ci 3247e5c31af7Sopenharmony_ci /* Make sure that program executed */ 3248e5c31af7Sopenharmony_ci gl.finish(); 3249e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Finish"); 3250e5c31af7Sopenharmony_ci 3251e5c31af7Sopenharmony_ci if (0 != memcmp(destination_map.m_data, sum_data, data_size * sizeof(GLuint))) 3252e5c31af7Sopenharmony_ci { 3253e5c31af7Sopenharmony_ci test_result = false; 3254e5c31af7Sopenharmony_ci 3255e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 3256e5c31af7Sopenharmony_ci << "Contents of mapped region does not correspond with expected results" 3257e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3258e5c31af7Sopenharmony_ci } 3259e5c31af7Sopenharmony_ci 3260e5c31af7Sopenharmony_ci /* Modify source buffer via mapped area */ 3261e5c31af7Sopenharmony_ci memcpy(source_map.m_data, modified_source_data, data_size * sizeof(GLuint)); 3262e5c31af7Sopenharmony_ci 3263e5c31af7Sopenharmony_ci /* 3264e5c31af7Sopenharmony_ci * - apply FlushMappedBufferRange to ensure that modifications of source buffer 3265e5c31af7Sopenharmony_ci * are visible to server. 3266e5c31af7Sopenharmony_ci */ 3267e5c31af7Sopenharmony_ci source.Bind(); 3268e5c31af7Sopenharmony_ci gl.flushMappedBufferRange(GL_SHADER_STORAGE_BUFFER, 0 /* offset */, data_size * sizeof(GLuint)); 3269e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "FlushMappedBufferRange"); 3270e5c31af7Sopenharmony_ci 3271e5c31af7Sopenharmony_ci /* Clear binding point */ 3272e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0, GL_SHADER_STORAGE_BUFFER); 3273e5c31af7Sopenharmony_ci 3274e5c31af7Sopenharmony_ci /* Execute program for 16x1x1 groups */ 3275e5c31af7Sopenharmony_ci gl.dispatchCompute(16, 1, 1); 3276e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DispatchCompute with persistently mapped buffers"); 3277e5c31af7Sopenharmony_ci 3278e5c31af7Sopenharmony_ci /* Make sure that program executed */ 3279e5c31af7Sopenharmony_ci gl.finish(); 3280e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "Finish"); 3281e5c31af7Sopenharmony_ci 3282e5c31af7Sopenharmony_ci if (0 != memcmp(destination_map.m_data, modified_sum_data, data_size * sizeof(GLuint))) 3283e5c31af7Sopenharmony_ci { 3284e5c31af7Sopenharmony_ci test_result = false; 3285e5c31af7Sopenharmony_ci 3286e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 3287e5c31af7Sopenharmony_ci << "Contents of mapped region does not correspond with expected results" 3288e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3289e5c31af7Sopenharmony_ci } 3290e5c31af7Sopenharmony_ci } 3291e5c31af7Sopenharmony_ci 3292e5c31af7Sopenharmony_ci /* Set result */ 3293e5c31af7Sopenharmony_ci if (true == test_result) 3294e5c31af7Sopenharmony_ci { 3295e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3296e5c31af7Sopenharmony_ci } 3297e5c31af7Sopenharmony_ci else 3298e5c31af7Sopenharmony_ci { 3299e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3300e5c31af7Sopenharmony_ci } 3301e5c31af7Sopenharmony_ci 3302e5c31af7Sopenharmony_ci /* Done */ 3303e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 3304e5c31af7Sopenharmony_ci} 3305e5c31af7Sopenharmony_ci 3306e5c31af7Sopenharmony_ci/** Constructor 3307e5c31af7Sopenharmony_ci * 3308e5c31af7Sopenharmony_ci * @param context Test context 3309e5c31af7Sopenharmony_ci **/ 3310e5c31af7Sopenharmony_ciMapPersistentDrawTest::MapPersistentDrawTest(deqp::Context& context) 3311e5c31af7Sopenharmony_ci : TestCase(context, "map_persistent_draw", "Test draw operation against mapped buffer") 3312e5c31af7Sopenharmony_ci{ 3313e5c31af7Sopenharmony_ci /* Nothing to be done here */ 3314e5c31af7Sopenharmony_ci} 3315e5c31af7Sopenharmony_ci 3316e5c31af7Sopenharmony_ci/** Execute test 3317e5c31af7Sopenharmony_ci * 3318e5c31af7Sopenharmony_ci * @return tcu::TestNode::STOP otherwise 3319e5c31af7Sopenharmony_ci **/ 3320e5c31af7Sopenharmony_citcu::TestNode::IterateResult MapPersistentDrawTest::iterate() 3321e5c31af7Sopenharmony_ci{ 3322e5c31af7Sopenharmony_ci /* 3323e5c31af7Sopenharmony_ci * * fragment shader should pass value of "gs_fs_color" varying to red 3324e5c31af7Sopenharmony_ci * channel of output color; 3325e5c31af7Sopenharmony_ci */ 3326e5c31af7Sopenharmony_ci static const GLchar* fragment_shader = "#version 440 core\n" 3327e5c31af7Sopenharmony_ci "\n" 3328e5c31af7Sopenharmony_ci "in float gs_fs_color;\n" 3329e5c31af7Sopenharmony_ci "out vec4 fs_out_color;\n" 3330e5c31af7Sopenharmony_ci "\n" 3331e5c31af7Sopenharmony_ci "void main()\n" 3332e5c31af7Sopenharmony_ci "{\n" 3333e5c31af7Sopenharmony_ci " fs_out_color = vec4(gs_fs_color, 0, 0, 1);\n" 3334e5c31af7Sopenharmony_ci "}\n" 3335e5c31af7Sopenharmony_ci "\n"; 3336e5c31af7Sopenharmony_ci 3337e5c31af7Sopenharmony_ci /* 3338e5c31af7Sopenharmony_ci * * geometry shader should: 3339e5c31af7Sopenharmony_ci * - define single uniform buffer array "rectangles" with unspecified size; 3340e5c31af7Sopenharmony_ci * Rectangles should have two vec2 fields: position and size; 3341e5c31af7Sopenharmony_ci * - define a separate atomic_uint "atom_color" per input point; 3342e5c31af7Sopenharmony_ci * - increment "atom_color" once per input point; 3343e5c31af7Sopenharmony_ci * - output a quad that is placed at rectangles[vs_gs_index].position and 3344e5c31af7Sopenharmony_ci * has size equal rectangles[vs_gs_index].size; 3345e5c31af7Sopenharmony_ci * - define output float varying "gs_fs_color" equal to "atom_color" / 255; 3346e5c31af7Sopenharmony_ci */ 3347e5c31af7Sopenharmony_ci static const GLchar* geometry_shader = 3348e5c31af7Sopenharmony_ci "#version 440 core\n" 3349e5c31af7Sopenharmony_ci "\n" 3350e5c31af7Sopenharmony_ci "layout(points) in;\n" 3351e5c31af7Sopenharmony_ci "layout(triangle_strip, max_vertices = 4) out;\n" 3352e5c31af7Sopenharmony_ci "\n" 3353e5c31af7Sopenharmony_ci "struct Rectangle {\n" 3354e5c31af7Sopenharmony_ci " vec2 position;\n" 3355e5c31af7Sopenharmony_ci " vec2 size;\n" 3356e5c31af7Sopenharmony_ci "};\n" 3357e5c31af7Sopenharmony_ci "\n" 3358e5c31af7Sopenharmony_ci "layout (std140, binding = 0) uniform Rectangles {\n" 3359e5c31af7Sopenharmony_ci " Rectangle rectangle[2];\n" 3360e5c31af7Sopenharmony_ci "} rectangles;\n" 3361e5c31af7Sopenharmony_ci "\n" 3362e5c31af7Sopenharmony_ci "layout (binding = 0) uniform atomic_uint atom_color[2];\n" 3363e5c31af7Sopenharmony_ci "layout (binding = 0) uniform atomic_uint invocation_hit_count[2];\n" 3364e5c31af7Sopenharmony_ci "\n" 3365e5c31af7Sopenharmony_ci "in uint vs_gs_index[];\n" 3366e5c31af7Sopenharmony_ci "out float gs_fs_color;\n" 3367e5c31af7Sopenharmony_ci "\n" 3368e5c31af7Sopenharmony_ci "void main()\n" 3369e5c31af7Sopenharmony_ci "{\n" 3370e5c31af7Sopenharmony_ci " if (atomicCounterIncrement(invocation_hit_count[gl_PrimitiveIDIn]) == 0)\n" 3371e5c31af7Sopenharmony_ci " {\n" 3372e5c31af7Sopenharmony_ci " atomicCounterIncrement(atom_color[gl_PrimitiveIDIn]);\n" 3373e5c31af7Sopenharmony_ci " }\n" 3374e5c31af7Sopenharmony_ci " memoryBarrierAtomicCounter();\n" 3375e5c31af7Sopenharmony_ci " const uint atom_color_value = atomicCounter(atom_color[gl_PrimitiveIDIn]);" 3376e5c31af7Sopenharmony_ci " //const uint atom_color_value = vs_gs_index[0];\n" 3377e5c31af7Sopenharmony_ci " const float color = float(atom_color_value) / 255.0;\n" 3378e5c31af7Sopenharmony_ci " //const float color = rectangles.rectangle[1].size.x;\n" 3379e5c31af7Sopenharmony_ci "\n" 3380e5c31af7Sopenharmony_ci " const float left = rectangles.rectangle[vs_gs_index[0]].position.x;\n" 3381e5c31af7Sopenharmony_ci " const float bottom = rectangles.rectangle[vs_gs_index[0]].position.y;\n" 3382e5c31af7Sopenharmony_ci " const float right = rectangles.rectangle[vs_gs_index[0]].size.x + left;\n" 3383e5c31af7Sopenharmony_ci " const float top = rectangles.rectangle[vs_gs_index[0]].size.y + bottom;\n" 3384e5c31af7Sopenharmony_ci "\n" 3385e5c31af7Sopenharmony_ci " //const float left = rectangles.rectangle[0].position.x;\n" 3386e5c31af7Sopenharmony_ci " //const float bottom = rectangles.rectangle[0].position.y;\n" 3387e5c31af7Sopenharmony_ci " //const float right = rectangles.rectangle[0].size.x + left;\n" 3388e5c31af7Sopenharmony_ci " //const float top = rectangles.rectangle[0].size.y + bottom;\n" 3389e5c31af7Sopenharmony_ci "\n" 3390e5c31af7Sopenharmony_ci " gs_fs_color = color;\n" 3391e5c31af7Sopenharmony_ci " gl_Position = vec4(left, bottom, 0, 1);\n" 3392e5c31af7Sopenharmony_ci " EmitVertex();\n" 3393e5c31af7Sopenharmony_ci "\n" 3394e5c31af7Sopenharmony_ci " gs_fs_color = color;\n" 3395e5c31af7Sopenharmony_ci " gl_Position = vec4(left, top, 0, 1);\n" 3396e5c31af7Sopenharmony_ci " EmitVertex();\n" 3397e5c31af7Sopenharmony_ci "\n" 3398e5c31af7Sopenharmony_ci " gs_fs_color = color;\n" 3399e5c31af7Sopenharmony_ci " gl_Position = vec4(right, bottom, 0, 1);\n" 3400e5c31af7Sopenharmony_ci " EmitVertex();\n" 3401e5c31af7Sopenharmony_ci "\n" 3402e5c31af7Sopenharmony_ci " gs_fs_color = color;\n" 3403e5c31af7Sopenharmony_ci " gl_Position = vec4(right, top, 0, 1);\n" 3404e5c31af7Sopenharmony_ci " EmitVertex();\n" 3405e5c31af7Sopenharmony_ci "}\n" 3406e5c31af7Sopenharmony_ci "\n"; 3407e5c31af7Sopenharmony_ci 3408e5c31af7Sopenharmony_ci /* 3409e5c31af7Sopenharmony_ci * * vertex shader should output single varying "vs_gs_index" of type uint, 3410e5c31af7Sopenharmony_ci * equal to gl_VertexID; 3411e5c31af7Sopenharmony_ci */ 3412e5c31af7Sopenharmony_ci static const GLchar* vertex_shader = "#version 440 core\n" 3413e5c31af7Sopenharmony_ci "\n" 3414e5c31af7Sopenharmony_ci "out uint vs_gs_index;\n" 3415e5c31af7Sopenharmony_ci "\n" 3416e5c31af7Sopenharmony_ci "void main()\n" 3417e5c31af7Sopenharmony_ci "{\n" 3418e5c31af7Sopenharmony_ci " vs_gs_index = gl_VertexID;\n" 3419e5c31af7Sopenharmony_ci "}\n" 3420e5c31af7Sopenharmony_ci "\n"; 3421e5c31af7Sopenharmony_ci 3422e5c31af7Sopenharmony_ci static const GLuint atom_binding = 0; 3423e5c31af7Sopenharmony_ci static const size_t atom_data_size = 4 * sizeof(GLuint); 3424e5c31af7Sopenharmony_ci static const GLuint expected_atom_first = 2; 3425e5c31af7Sopenharmony_ci static const GLuint expected_atom_second = 6; 3426e5c31af7Sopenharmony_ci static const GLuint expected_pixel = 0xff000004; 3427e5c31af7Sopenharmony_ci static const GLuint height = 16; 3428e5c31af7Sopenharmony_ci static const GLuint n_rectangles = 2; 3429e5c31af7Sopenharmony_ci static const GLuint pixel_size = 4 * sizeof(GLubyte); 3430e5c31af7Sopenharmony_ci static const GLuint rectangles_binding = 0; 3431e5c31af7Sopenharmony_ci static const size_t rectangle_size = 2 * 2 * sizeof(GLfloat); /* 2 * vec2 */ 3432e5c31af7Sopenharmony_ci static const size_t rectangles_data_size = n_rectangles * rectangle_size; 3433e5c31af7Sopenharmony_ci static const GLuint width = 16; 3434e5c31af7Sopenharmony_ci static const GLuint line_size = width * pixel_size; 3435e5c31af7Sopenharmony_ci static const GLuint pixel_offset = 8 * line_size + 7 * pixel_size; 3436e5c31af7Sopenharmony_ci static const size_t texture_data_size = height * line_size; 3437e5c31af7Sopenharmony_ci 3438e5c31af7Sopenharmony_ci const Functions& gl = m_context.getRenderContext().getFunctions(); 3439e5c31af7Sopenharmony_ci 3440e5c31af7Sopenharmony_ci bool test_result = true; 3441e5c31af7Sopenharmony_ci 3442e5c31af7Sopenharmony_ci /* Prepare data */ 3443e5c31af7Sopenharmony_ci GLuint atom_first_data[4] = {1, 1, 0, 0}; 3444e5c31af7Sopenharmony_ci GLuint atom_second_data[4] = {5, 5, 0, 0}; 3445e5c31af7Sopenharmony_ci GLubyte rectangles_first_data[rectangles_data_size]; 3446e5c31af7Sopenharmony_ci GLubyte rectangles_second_data[rectangles_data_size]; 3447e5c31af7Sopenharmony_ci GLubyte texture_data[texture_data_size]; 3448e5c31af7Sopenharmony_ci 3449e5c31af7Sopenharmony_ci { 3450e5c31af7Sopenharmony_ci GLfloat* ptr = (GLfloat*)rectangles_first_data; 3451e5c31af7Sopenharmony_ci 3452e5c31af7Sopenharmony_ci /* First.position*/ 3453e5c31af7Sopenharmony_ci ptr[0] = -0.5f; 3454e5c31af7Sopenharmony_ci ptr[1] = -0.5f; 3455e5c31af7Sopenharmony_ci 3456e5c31af7Sopenharmony_ci /* First.size*/ 3457e5c31af7Sopenharmony_ci ptr[2] = 1.0f; 3458e5c31af7Sopenharmony_ci ptr[3] = 1.0f; 3459e5c31af7Sopenharmony_ci 3460e5c31af7Sopenharmony_ci /* Second.position*/ 3461e5c31af7Sopenharmony_ci ptr[4 + 0] = -0.75f; 3462e5c31af7Sopenharmony_ci ptr[4 + 1] = -0.75f; 3463e5c31af7Sopenharmony_ci 3464e5c31af7Sopenharmony_ci /* Second.size*/ 3465e5c31af7Sopenharmony_ci ptr[4 + 2] = 1.5f; 3466e5c31af7Sopenharmony_ci ptr[4 + 3] = 1.5f; 3467e5c31af7Sopenharmony_ci } 3468e5c31af7Sopenharmony_ci 3469e5c31af7Sopenharmony_ci { 3470e5c31af7Sopenharmony_ci GLfloat* ptr = (GLfloat*)rectangles_second_data; 3471e5c31af7Sopenharmony_ci 3472e5c31af7Sopenharmony_ci /* First.position*/ 3473e5c31af7Sopenharmony_ci ptr[0] = -1.0f; 3474e5c31af7Sopenharmony_ci ptr[1] = -1.0f; 3475e5c31af7Sopenharmony_ci 3476e5c31af7Sopenharmony_ci /* First.size*/ 3477e5c31af7Sopenharmony_ci ptr[2] = 0.5f; 3478e5c31af7Sopenharmony_ci ptr[3] = 0.5f; 3479e5c31af7Sopenharmony_ci 3480e5c31af7Sopenharmony_ci /* Second.position*/ 3481e5c31af7Sopenharmony_ci ptr[4 + 0] = 0.5f; 3482e5c31af7Sopenharmony_ci ptr[4 + 1] = 0.5f; 3483e5c31af7Sopenharmony_ci 3484e5c31af7Sopenharmony_ci /* Second.size*/ 3485e5c31af7Sopenharmony_ci ptr[4 + 2] = 0.5f; 3486e5c31af7Sopenharmony_ci ptr[4 + 3] = 0.5f; 3487e5c31af7Sopenharmony_ci } 3488e5c31af7Sopenharmony_ci 3489e5c31af7Sopenharmony_ci /* Prepare buffers */ 3490e5c31af7Sopenharmony_ci Buffer atom(m_context); 3491e5c31af7Sopenharmony_ci Buffer rectangles(m_context); 3492e5c31af7Sopenharmony_ci 3493e5c31af7Sopenharmony_ci atom.InitStorage(GL_ATOMIC_COUNTER_BUFFER, GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, 3494e5c31af7Sopenharmony_ci atom_data_size, 0); 3495e5c31af7Sopenharmony_ci 3496e5c31af7Sopenharmony_ci rectangles.InitStorage(GL_UNIFORM_BUFFER, GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT, rectangles_data_size, 0); 3497e5c31af7Sopenharmony_ci 3498e5c31af7Sopenharmony_ci /* Prepare framebuffer */ 3499e5c31af7Sopenharmony_ci Framebuffer framebuffer(m_context); 3500e5c31af7Sopenharmony_ci Texture texture(m_context); 3501e5c31af7Sopenharmony_ci 3502e5c31af7Sopenharmony_ci Texture::Generate(gl, texture.m_id); 3503e5c31af7Sopenharmony_ci Texture::Bind(gl, texture.m_id, GL_TEXTURE_2D); 3504e5c31af7Sopenharmony_ci Texture::Storage(gl, GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, width, height, 0 /* depth */); 3505e5c31af7Sopenharmony_ci 3506e5c31af7Sopenharmony_ci Framebuffer::Generate(gl, framebuffer.m_id); 3507e5c31af7Sopenharmony_ci Framebuffer::Bind(gl, GL_DRAW_FRAMEBUFFER, framebuffer.m_id); 3508e5c31af7Sopenharmony_ci Framebuffer::AttachTexture(gl, GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture.m_id, width, height); 3509e5c31af7Sopenharmony_ci 3510e5c31af7Sopenharmony_ci /* Prepare VAO */ 3511e5c31af7Sopenharmony_ci VertexArray vao(m_context); 3512e5c31af7Sopenharmony_ci 3513e5c31af7Sopenharmony_ci VertexArray::Generate(gl, vao.m_id); 3514e5c31af7Sopenharmony_ci VertexArray::Bind(gl, vao.m_id); 3515e5c31af7Sopenharmony_ci 3516e5c31af7Sopenharmony_ci /* Prepare program */ 3517e5c31af7Sopenharmony_ci Program program(m_context); 3518e5c31af7Sopenharmony_ci program.Init("" /* cs */, fragment_shader, geometry_shader, "" /* tcs */, "" /* tes */, vertex_shader); 3519e5c31af7Sopenharmony_ci Program::Use(gl, program.m_id); 3520e5c31af7Sopenharmony_ci 3521e5c31af7Sopenharmony_ci /* 3522e5c31af7Sopenharmony_ci * - make persistent mapping of both buffers for reads and writes; 3523e5c31af7Sopenharmony_ci * - modify "rectangles" buffer via mapped memory with the following two sets 3524e5c31af7Sopenharmony_ci * * position [-0.5,-0.5], size [1.0,1.0], 3525e5c31af7Sopenharmony_ci * * position [-0.25,-0.25], size [1.5,1.5]; 3526e5c31af7Sopenharmony_ci * - modify "atom_color" buffer via mapped memory to value 1; 3527e5c31af7Sopenharmony_ci * - execute MemoryBarrier for CLIENT_MAPPED_BUFFER_BARRIER_BIT; 3528e5c31af7Sopenharmony_ci * - enable blending with functions ONE for both source and destination; 3529e5c31af7Sopenharmony_ci * - execute DrawArrays for two vertices; 3530e5c31af7Sopenharmony_ci * - execute MemoryBarrier for ALL_BARRIER_BITS and Finish; 3531e5c31af7Sopenharmony_ci * - inspect contents of: 3532e5c31af7Sopenharmony_ci * * texture - to verify that pixel at 8,8 is filled with RGBA8(4,0,0,0), 3533e5c31af7Sopenharmony_ci * * "atom_color" - to verify that it is equal to 2; 3534e5c31af7Sopenharmony_ci * - modify "rectangles" buffer via mapped memory with the following two sets 3535e5c31af7Sopenharmony_ci * * position [-1.0,-1.0], size [0.5,0.5], 3536e5c31af7Sopenharmony_ci * * position [0.5,0.5], size [0.5,0.5]; 3537e5c31af7Sopenharmony_ci * - modify "atom_color" buffer via mapped memory to value 5; 3538e5c31af7Sopenharmony_ci * - execute MemoryBarrier for CLIENT_MAPPED_BUFFER_BARRIER_BIT; 3539e5c31af7Sopenharmony_ci * - execute DrawArrays for two vertices; 3540e5c31af7Sopenharmony_ci * - execute MemoryBarrier for ALL_BARRIER_BITS and Finish; 3541e5c31af7Sopenharmony_ci * - inspect contents of: 3542e5c31af7Sopenharmony_ci * * texture - to verify that pixel at 8,8 is filled with RGBA8(4,0,0,0), 3543e5c31af7Sopenharmony_ci * * "atom_color" - to verify that it is equal to 6; 3544e5c31af7Sopenharmony_ci * 3545e5c31af7Sopenharmony_ci * Additionally: change MemoryBarrier to FlushMapped*BufferRange if context supports OpenGL 4.5 Core Profile. 3546e5c31af7Sopenharmony_ci */ 3547e5c31af7Sopenharmony_ci { 3548e5c31af7Sopenharmony_ci /* Choose specification */ 3549e5c31af7Sopenharmony_ci const bool is_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); 3550e5c31af7Sopenharmony_ci 3551e5c31af7Sopenharmony_ci /* Map buffers */ 3552e5c31af7Sopenharmony_ci atom.Bind(); 3553e5c31af7Sopenharmony_ci const Buffer::MapOwner atom_map(atom.MapRange(0 /* offset */, atom_data_size, 3554e5c31af7Sopenharmony_ci GL_MAP_PERSISTENT_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | 3555e5c31af7Sopenharmony_ci (is_gl_45 ? GL_MAP_FLUSH_EXPLICIT_BIT : 0))); 3556e5c31af7Sopenharmony_ci 3557e5c31af7Sopenharmony_ci rectangles.Bind(); 3558e5c31af7Sopenharmony_ci const Buffer::MapOwner rectangles_map( 3559e5c31af7Sopenharmony_ci rectangles.MapRange(0 /* offset */, rectangles_data_size, 3560e5c31af7Sopenharmony_ci GL_MAP_PERSISTENT_BIT | GL_MAP_WRITE_BIT | (is_gl_45 ? GL_MAP_FLUSH_EXPLICIT_BIT : 0))); 3561e5c31af7Sopenharmony_ci 3562e5c31af7Sopenharmony_ci /* Clear binding points */ 3563e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0, GL_ATOMIC_COUNTER_BUFFER); 3564e5c31af7Sopenharmony_ci Buffer::Bind(gl, 0, GL_UNIFORM_BUFFER); 3565e5c31af7Sopenharmony_ci 3566e5c31af7Sopenharmony_ci /* Bind buffers */ 3567e5c31af7Sopenharmony_ci Buffer::BindBase(gl, atom.m_id, GL_ATOMIC_COUNTER_BUFFER, atom_binding); 3568e5c31af7Sopenharmony_ci Buffer::BindBase(gl, rectangles.m_id, GL_UNIFORM_BUFFER, rectangles_binding); 3569e5c31af7Sopenharmony_ci 3570e5c31af7Sopenharmony_ci /* Set up blending */ 3571e5c31af7Sopenharmony_ci gl.enable(GL_BLEND); 3572e5c31af7Sopenharmony_ci gl.blendFunc(GL_ONE, GL_ONE); 3573e5c31af7Sopenharmony_ci 3574e5c31af7Sopenharmony_ci /* Modify buffers */ 3575e5c31af7Sopenharmony_ci memcpy(atom_map.m_data, atom_first_data, atom_data_size); 3576e5c31af7Sopenharmony_ci memcpy(rectangles_map.m_data, rectangles_first_data, rectangles_data_size); 3577e5c31af7Sopenharmony_ci 3578e5c31af7Sopenharmony_ci /* Execute barrier or flush content. */ 3579e5c31af7Sopenharmony_ci if (is_gl_45) 3580e5c31af7Sopenharmony_ci { 3581e5c31af7Sopenharmony_ci gl.flushMappedBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, atom_data_size); 3582e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glFlushMappedBufferRange"); 3583e5c31af7Sopenharmony_ci 3584e5c31af7Sopenharmony_ci gl.flushMappedBufferRange(GL_UNIFORM_BUFFER, 0, rectangles_data_size); 3585e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glFlushMappedBufferRange"); 3586e5c31af7Sopenharmony_ci } 3587e5c31af7Sopenharmony_ci else 3588e5c31af7Sopenharmony_ci { 3589e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT); 3590e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier"); 3591e5c31af7Sopenharmony_ci } 3592e5c31af7Sopenharmony_ci 3593e5c31af7Sopenharmony_ci /* Clear drawbuffer */ 3594e5c31af7Sopenharmony_ci GLint clear_color[4] = { 0, 0, 0, 0 }; 3595e5c31af7Sopenharmony_ci gl.clearBufferiv(GL_COLOR, 0, clear_color); 3596e5c31af7Sopenharmony_ci 3597e5c31af7Sopenharmony_ci /* Execute program for 2 vertices */ 3598e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, 2); 3599e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays with persistently mapped buffers"); 3600e5c31af7Sopenharmony_ci 3601e5c31af7Sopenharmony_ci /* Execute barrier */ 3602e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_ALL_BARRIER_BITS); 3603e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier"); 3604e5c31af7Sopenharmony_ci 3605e5c31af7Sopenharmony_ci /* Inspect texture */ 3606e5c31af7Sopenharmony_ci Texture::GetData(gl, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_BYTE, texture_data); 3607e5c31af7Sopenharmony_ci if (0 != memcmp(texture_data + pixel_offset, &expected_pixel, pixel_size)) 3608e5c31af7Sopenharmony_ci { 3609e5c31af7Sopenharmony_ci test_result = false; 3610e5c31af7Sopenharmony_ci 3611e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 3612e5c31af7Sopenharmony_ci << "Contents of framebuffer does not correspond with expected results" 3613e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3614e5c31af7Sopenharmony_ci tcu::ConstPixelBufferAccess img( 3615e5c31af7Sopenharmony_ci tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), width, height, 3616e5c31af7Sopenharmony_ci 1 /* depth */, texture_data); 3617e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 3618e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Framebuffer", "Framebuffer contents using initial buffer data", img); 3619e5c31af7Sopenharmony_ci } 3620e5c31af7Sopenharmony_ci 3621e5c31af7Sopenharmony_ci /* Inspect atom */ 3622e5c31af7Sopenharmony_ci if (0 != memcmp(atom_map.m_data, &expected_atom_first, sizeof(GLuint))) 3623e5c31af7Sopenharmony_ci { 3624e5c31af7Sopenharmony_ci test_result = false; 3625e5c31af7Sopenharmony_ci 3626e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 3627e5c31af7Sopenharmony_ci << "Contents of ATOMIC_COUNTER buffer are invalid." 3628e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3629e5c31af7Sopenharmony_ci } 3630e5c31af7Sopenharmony_ci 3631e5c31af7Sopenharmony_ci /* Modify buffers */ 3632e5c31af7Sopenharmony_ci memcpy(atom_map.m_data, atom_second_data, atom_data_size); 3633e5c31af7Sopenharmony_ci memcpy(rectangles_map.m_data, rectangles_second_data, rectangles_data_size); 3634e5c31af7Sopenharmony_ci 3635e5c31af7Sopenharmony_ci /* Execute barrier or flush content. */ 3636e5c31af7Sopenharmony_ci if (is_gl_45) 3637e5c31af7Sopenharmony_ci { 3638e5c31af7Sopenharmony_ci gl.flushMappedBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, atom_data_size); 3639e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glFlushMappedBufferRange"); 3640e5c31af7Sopenharmony_ci 3641e5c31af7Sopenharmony_ci gl.flushMappedBufferRange(GL_UNIFORM_BUFFER, 0, rectangles_data_size); 3642e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "glFlushMappedBufferRange"); 3643e5c31af7Sopenharmony_ci } 3644e5c31af7Sopenharmony_ci else 3645e5c31af7Sopenharmony_ci { 3646e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT); 3647e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier"); 3648e5c31af7Sopenharmony_ci } 3649e5c31af7Sopenharmony_ci 3650e5c31af7Sopenharmony_ci /* Execute program for 2 vertices */ 3651e5c31af7Sopenharmony_ci gl.drawArrays(GL_POINTS, 0, 2); 3652e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawArrays with persistently mapped buffers"); 3653e5c31af7Sopenharmony_ci 3654e5c31af7Sopenharmony_ci /* Execute barrier */ 3655e5c31af7Sopenharmony_ci gl.memoryBarrier(GL_ALL_BARRIER_BITS); 3656e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier"); 3657e5c31af7Sopenharmony_ci 3658e5c31af7Sopenharmony_ci /* Inspect texture */ 3659e5c31af7Sopenharmony_ci Texture::GetData(gl, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_BYTE, texture_data); 3660e5c31af7Sopenharmony_ci if (0 != memcmp(texture_data + pixel_offset, &expected_pixel, pixel_size)) 3661e5c31af7Sopenharmony_ci { 3662e5c31af7Sopenharmony_ci test_result = false; 3663e5c31af7Sopenharmony_ci 3664e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 3665e5c31af7Sopenharmony_ci << "Contents of framebuffer does not correspond with expected results" 3666e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3667e5c31af7Sopenharmony_ci tcu::ConstPixelBufferAccess img( 3668e5c31af7Sopenharmony_ci tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), width, height, 3669e5c31af7Sopenharmony_ci 1 /* depth */, texture_data); 3670e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() 3671e5c31af7Sopenharmony_ci << tcu::TestLog::Image("Framebuffer", "Framebuffer contents using updated buffer data", img); 3672e5c31af7Sopenharmony_ci } 3673e5c31af7Sopenharmony_ci 3674e5c31af7Sopenharmony_ci /* Inspect atom */ 3675e5c31af7Sopenharmony_ci if (0 != memcmp(atom_map.m_data, &expected_atom_second, sizeof(GLuint))) 3676e5c31af7Sopenharmony_ci { 3677e5c31af7Sopenharmony_ci test_result = false; 3678e5c31af7Sopenharmony_ci 3679e5c31af7Sopenharmony_ci m_context.getTestContext().getLog() << tcu::TestLog::Message 3680e5c31af7Sopenharmony_ci << "Contents of ATOMIC_COUNTER buffer are invalid." 3681e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 3682e5c31af7Sopenharmony_ci } 3683e5c31af7Sopenharmony_ci } 3684e5c31af7Sopenharmony_ci 3685e5c31af7Sopenharmony_ci /* Set result */ 3686e5c31af7Sopenharmony_ci if (true == test_result) 3687e5c31af7Sopenharmony_ci { 3688e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 3689e5c31af7Sopenharmony_ci } 3690e5c31af7Sopenharmony_ci else 3691e5c31af7Sopenharmony_ci { 3692e5c31af7Sopenharmony_ci m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 3693e5c31af7Sopenharmony_ci } 3694e5c31af7Sopenharmony_ci 3695e5c31af7Sopenharmony_ci /* Done */ 3696e5c31af7Sopenharmony_ci return tcu::TestNode::STOP; 3697e5c31af7Sopenharmony_ci} 3698e5c31af7Sopenharmony_ci} /* BufferStorage */ 3699e5c31af7Sopenharmony_ci 3700e5c31af7Sopenharmony_ci/** Constructor. 3701e5c31af7Sopenharmony_ci * 3702e5c31af7Sopenharmony_ci * @param context Rendering context. 3703e5c31af7Sopenharmony_ci **/ 3704e5c31af7Sopenharmony_ciBufferStorageTests::BufferStorageTests(deqp::Context& context) 3705e5c31af7Sopenharmony_ci : TestCaseGroup(context, "buffer_storage", "Verifies \"buffer storage\" functionality") 3706e5c31af7Sopenharmony_ci{ 3707e5c31af7Sopenharmony_ci /* Left blank on purpose */ 3708e5c31af7Sopenharmony_ci} 3709e5c31af7Sopenharmony_ci 3710e5c31af7Sopenharmony_ci/** Initializes a texture_storage_multisample test group. 3711e5c31af7Sopenharmony_ci * 3712e5c31af7Sopenharmony_ci **/ 3713e5c31af7Sopenharmony_civoid BufferStorageTests::init(void) 3714e5c31af7Sopenharmony_ci{ 3715e5c31af7Sopenharmony_ci addChild(new BufferStorage::ErrorsTest(m_context)); 3716e5c31af7Sopenharmony_ci addChild(new BufferStorage::GetBufferParameterTest(m_context)); 3717e5c31af7Sopenharmony_ci addChild(new BufferStorage::DynamicStorageTest(m_context)); 3718e5c31af7Sopenharmony_ci addChild(new BufferStorage::MapPersistentBufferSubDataTest(m_context)); 3719e5c31af7Sopenharmony_ci addChild(new BufferStorage::MapPersistentTextureTest(m_context)); 3720e5c31af7Sopenharmony_ci addChild(new BufferStorage::MapPersistentReadPixelsTest(m_context)); 3721e5c31af7Sopenharmony_ci addChild(new BufferStorage::MapPersistentDispatchTest(m_context)); 3722e5c31af7Sopenharmony_ci addChild(new BufferStorage::MapPersistentFlushTest(m_context)); 3723e5c31af7Sopenharmony_ci addChild(new BufferStorage::MapPersistentDrawTest(m_context)); 3724e5c31af7Sopenharmony_ci} 3725e5c31af7Sopenharmony_ci} /* gl4cts namespace */ 3726