1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite 3e5c31af7Sopenharmony_ci * ----------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2014-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#include "es31cSeparateShaderObjsTests.hpp" 25e5c31af7Sopenharmony_ci#include "deMath.h" 26e5c31af7Sopenharmony_ci#include "deRandom.hpp" 27e5c31af7Sopenharmony_ci#include "deString.h" 28e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 29e5c31af7Sopenharmony_ci#include "gluDrawUtil.hpp" 30e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp" 31e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 32e5c31af7Sopenharmony_ci#include "glw.h" 33e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 34e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 35e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 36e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp" 37e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 38e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 39e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 40e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ci#include <map> 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_ci/*************************************************************************/ 45e5c31af7Sopenharmony_ci/* Test Plan for shared_shader_objects: 46e5c31af7Sopenharmony_ci * Overview 47e5c31af7Sopenharmony_ci * 48e5c31af7Sopenharmony_ci * This is a conformance test for XXX_separate_shader_objects extension. The 49e5c31af7Sopenharmony_ci * results of the tests are verified by checking the expected GL error, 50e5c31af7Sopenharmony_ci * by checking the expected state with state query functions and by rendering 51e5c31af7Sopenharmony_ci * test images and comparing specified pixels with expected values. Not all of 52e5c31af7Sopenharmony_ci * the methods are applicable for all tests. Additional details such as 53e5c31af7Sopenharmony_ci * expected error codes are included in test descriptions. 54e5c31af7Sopenharmony_ci * 55e5c31af7Sopenharmony_ci *New Tests 56e5c31af7Sopenharmony_ci * 57e5c31af7Sopenharmony_ci *-- Tests for invidual API functions 58e5c31af7Sopenharmony_ci * 59e5c31af7Sopenharmony_ci * 60e5c31af7Sopenharmony_ci * CreateShaderProgramv tests 61e5c31af7Sopenharmony_ci * 62e5c31af7Sopenharmony_ci * Positive tests: 63e5c31af7Sopenharmony_ci * 64e5c31af7Sopenharmony_ci * * Test with valid parameters and verify that program and GL state are set 65e5c31af7Sopenharmony_ci * accordingly to the code sequence defined in the extension spec. 66e5c31af7Sopenharmony_ci * * Test with vertex and fragment shader types. 67e5c31af7Sopenharmony_ci * * Test with few different count/strings parameters (count >= 1) 68e5c31af7Sopenharmony_ci * 69e5c31af7Sopenharmony_ci * Negative tests: 70e5c31af7Sopenharmony_ci * 71e5c31af7Sopenharmony_ci * * Test with invalid type. Expect INVALID_ENUM and zero return value. 72e5c31af7Sopenharmony_ci * * Test with uncompilable / unlinkable source. Expect no errors. Program 73e5c31af7Sopenharmony_ci * should be returned Program info log may contain information about link / 74e5c31af7Sopenharmony_ci * compile failure. 75e5c31af7Sopenharmony_ci * * Test with count < 0. Expect INVALID_VALUE and zero return value. 76e5c31af7Sopenharmony_ci * 77e5c31af7Sopenharmony_ci * 78e5c31af7Sopenharmony_ci * UseProgramStages tests 79e5c31af7Sopenharmony_ci * 80e5c31af7Sopenharmony_ci * Positive tests: 81e5c31af7Sopenharmony_ci * 82e5c31af7Sopenharmony_ci * * Test with a program containing 83e5c31af7Sopenharmony_ci * - vertex stage only 84e5c31af7Sopenharmony_ci * - fragment stage only 85e5c31af7Sopenharmony_ci * - both stages 86e5c31af7Sopenharmony_ci * * Test with null program to reset a stage or stages. Expect no errors. 87e5c31af7Sopenharmony_ci * * Test with a program that doesn't contain code for a stage defined in the 88e5c31af7Sopenharmony_ci * stages bitfield. Expect no errors. 89e5c31af7Sopenharmony_ci * * Test with a new program pipeline object that has not yet been used/bound. 90e5c31af7Sopenharmony_ci * 91e5c31af7Sopenharmony_ci * Negative tests: 92e5c31af7Sopenharmony_ci * 93e5c31af7Sopenharmony_ci * * Test with invalid stages bitfield (with unused bits). Expect INVALID_VALUE GL error. 94e5c31af7Sopenharmony_ci * * Test with deleted/nonexistent pipeline. Expect INVALID_OPERATION GL error. 95e5c31af7Sopenharmony_ci * * Test with program that isn't separable. Expect INVALID_OPERATION GL error. 96e5c31af7Sopenharmony_ci * * Test with program that isn't linked succesfully. Expect INVALID_OPERATION 97e5c31af7Sopenharmony_ci * GL error. 98e5c31af7Sopenharmony_ci * * Test with deleted/nonexistent program. Expect INVALID_OPERATION error. 99e5c31af7Sopenharmony_ci * 100e5c31af7Sopenharmony_ci * 101e5c31af7Sopenharmony_ci * ActiveShaderProgram tests 102e5c31af7Sopenharmony_ci * 103e5c31af7Sopenharmony_ci * Positive tests: 104e5c31af7Sopenharmony_ci * 105e5c31af7Sopenharmony_ci * * Test with a new program pipeline object that has not yet been used/bound. 106e5c31af7Sopenharmony_ci * 107e5c31af7Sopenharmony_ci * Negative tests: 108e5c31af7Sopenharmony_ci * 109e5c31af7Sopenharmony_ci * * Test with deleted/nonexistent program pipeline object. Expect INVALID_OPERATION and no 110e5c31af7Sopenharmony_ci * changes to active program. 111e5c31af7Sopenharmony_ci * * Test with nonexistent/deleted/unsuccesfully linked program. Expect 112e5c31af7Sopenharmony_ci * INVALID_OPERATION GL error and no changes to active program. 113e5c31af7Sopenharmony_ci * 114e5c31af7Sopenharmony_ci * 115e5c31af7Sopenharmony_ci * GenProgramPipelines tests 116e5c31af7Sopenharmony_ci * 117e5c31af7Sopenharmony_ci * Positive tests: 118e5c31af7Sopenharmony_ci * 119e5c31af7Sopenharmony_ci * * Test creating different amounts of program pipeline object names. 120e5c31af7Sopenharmony_ci * Verify with IsProgramPipeline. 121e5c31af7Sopenharmony_ci * 122e5c31af7Sopenharmony_ci * 123e5c31af7Sopenharmony_ci * BindProgramPipeline tests 124e5c31af7Sopenharmony_ci * 125e5c31af7Sopenharmony_ci * Positive tests: 126e5c31af7Sopenharmony_ci * 127e5c31af7Sopenharmony_ci * * Test binding existing program pipeline object. Verify with 128e5c31af7Sopenharmony_ci * PROGRAM_PIPELINE_BINDING 129e5c31af7Sopenharmony_ci * * Test binding zero program pipeline object. Verify 130e5c31af7Sopenharmony_ci * PROGRAM_PIPELINE_BINDING is reset to 0 131e5c31af7Sopenharmony_ci * 132e5c31af7Sopenharmony_ci * Negative tests: 133e5c31af7Sopenharmony_ci * 134e5c31af7Sopenharmony_ci * * Test binding deleted/nonexistent program pipeline object. Expect 135e5c31af7Sopenharmony_ci * INVALID_OPERATION GL error and no changes to bound pipeline. 136e5c31af7Sopenharmony_ci * 137e5c31af7Sopenharmony_ci * 138e5c31af7Sopenharmony_ci * DeleteProgramPipelines tests 139e5c31af7Sopenharmony_ci * 140e5c31af7Sopenharmony_ci * Positive tests: 141e5c31af7Sopenharmony_ci * 142e5c31af7Sopenharmony_ci * * Test deleting zero and unused names. Expect no errors (should be no-op) 143e5c31af7Sopenharmony_ci * * Test deleting different amounts of existing pipeline names. Verify 144e5c31af7Sopenharmony_ci * deletion with IsProgramPipeline. 145e5c31af7Sopenharmony_ci * * Test deleting bound names. Expect pipeline binding revert to zero, verify 146e5c31af7Sopenharmony_ci * with PROGRAM_PIPELINE_BINDING. 147e5c31af7Sopenharmony_ci * 148e5c31af7Sopenharmony_ci * 149e5c31af7Sopenharmony_ci * IsProgramPipeline 150e5c31af7Sopenharmony_ci * 151e5c31af7Sopenharmony_ci * Positive tests: 152e5c31af7Sopenharmony_ci * 153e5c31af7Sopenharmony_ci * * Test with deleted/nonexistent program pipeline names. 154e5c31af7Sopenharmony_ci * * Test with existing program pipeline names. 155e5c31af7Sopenharmony_ci * 156e5c31af7Sopenharmony_ci * 157e5c31af7Sopenharmony_ci * ProgramParameteri / PROGRAM_SEPARABLE tests 158e5c31af7Sopenharmony_ci * 159e5c31af7Sopenharmony_ci * Positive tests: 160e5c31af7Sopenharmony_ci * 161e5c31af7Sopenharmony_ci * * Test setting TRUE and FALSE values for existing, unlinked programs. 162e5c31af7Sopenharmony_ci * Verify with GetProgramParameteri 163e5c31af7Sopenharmony_ci * 164e5c31af7Sopenharmony_ci * Negative tests: 165e5c31af7Sopenharmony_ci * 166e5c31af7Sopenharmony_ci * * Test with nonexistent/deleted program. Expect INVALID_OPERATION GL error 167e5c31af7Sopenharmony_ci * * Test with invalid value. Expect INVALID_VALUE GL error 168e5c31af7Sopenharmony_ci * 169e5c31af7Sopenharmony_ci * 170e5c31af7Sopenharmony_ci * GetProgramPipelineiv tests 171e5c31af7Sopenharmony_ci * 172e5c31af7Sopenharmony_ci * Positive tests: 173e5c31af7Sopenharmony_ci * 174e5c31af7Sopenharmony_ci * * Test with new program pipeline object that has not yet been used/bound 175e5c31af7Sopenharmony_ci * * Test ACTIVE_PROGRAM 176e5c31af7Sopenharmony_ci * * Test VERTEX_SHADER 177e5c31af7Sopenharmony_ci * * Test FRAGMENT_SHADER 178e5c31af7Sopenharmony_ci * * Test VALIDATE_STATUS 179e5c31af7Sopenharmony_ci * * Test INFO_LOG_LENGTH 180e5c31af7Sopenharmony_ci * 181e5c31af7Sopenharmony_ci * Negative tests: 182e5c31af7Sopenharmony_ci * 183e5c31af7Sopenharmony_ci * * Test with deleted/nonexistent pipeline. Expect INVALID_OPERATION GL error 184e5c31af7Sopenharmony_ci * 185e5c31af7Sopenharmony_ci * 186e5c31af7Sopenharmony_ci * ValidateProgramPipeline tests: 187e5c31af7Sopenharmony_ci * 188e5c31af7Sopenharmony_ci * Positive tests: 189e5c31af7Sopenharmony_ci * 190e5c31af7Sopenharmony_ci * * Test with valid program pipeline. Expect VALIDATE_STATUS = TRUE 191e5c31af7Sopenharmony_ci * * Test with invalid program pipeline Expect VALIDATE_STATUS = FALSE 192e5c31af7Sopenharmony_ci * * Test with empty program pipeline (uninitialized, but bound). Expect VALIDATE_STATUS = FALSE. 193e5c31af7Sopenharmony_ci * * Test that initial (unvalidated) VALIDATE_STATUS is FALSE 194e5c31af7Sopenharmony_ci * * Test with a new program pipeline object that has not been used/bound yet 195e5c31af7Sopenharmony_ci * 196e5c31af7Sopenharmony_ci * Negative tests: 197e5c31af7Sopenharmony_ci * 198e5c31af7Sopenharmony_ci * * Test with deleted/nonexistent program pipeline object. Expect 199e5c31af7Sopenharmony_ci * INVALID_OPERATION 200e5c31af7Sopenharmony_ci * 201e5c31af7Sopenharmony_ci * 202e5c31af7Sopenharmony_ci * ProgramUniform* tests 203e5c31af7Sopenharmony_ci * 204e5c31af7Sopenharmony_ci * Positive tests: 205e5c31af7Sopenharmony_ci * 206e5c31af7Sopenharmony_ci * * Test all ProgramUniform* methods with few different parameters combinations 207e5c31af7Sopenharmony_ci * * Setup pipeline with programs A and B. Update uniforms for A and verify 208e5c31af7Sopenharmony_ci * that only A is affected. 209e5c31af7Sopenharmony_ci * * Test with a program with all combinations of 210e5c31af7Sopenharmony_ci * - program is/isn't part of a bound pipeline 211e5c31af7Sopenharmony_ci * - program is/isn't made current with UseProgram 212e5c31af7Sopenharmony_ci * - program is/isn't made active with ActiveShaderProgram 213e5c31af7Sopenharmony_ci * in all cases, only the uniforms of the specified program should be 214e5c31af7Sopenharmony_ci * updated. 215e5c31af7Sopenharmony_ci * 216e5c31af7Sopenharmony_ci * Negative tests: 217e5c31af7Sopenharmony_ci * 218e5c31af7Sopenharmony_ci * * Test with deleted/nonexistent program. Expect INVALID_VALUE GL error. 219e5c31af7Sopenharmony_ci * * Test with unsuccesfully linked program. Expect INVALID_OPERATION GL error. 220e5c31af7Sopenharmony_ci * 221e5c31af7Sopenharmony_ci * 222e5c31af7Sopenharmony_ci * GetProgramPipelineInfoLog tests 223e5c31af7Sopenharmony_ci * 224e5c31af7Sopenharmony_ci * Run ValidateProgramPipeline for valid / invalid program pipeline object 225e5c31af7Sopenharmony_ci * before running the tests. NOTE: The spec doesn't require that the driver 226e5c31af7Sopenharmony_ci * updates the pipeline info log. It may or may not contain information about 227e5c31af7Sopenharmony_ci * validation. 228e5c31af7Sopenharmony_ci * 229e5c31af7Sopenharmony_ci * Positive tests 230e5c31af7Sopenharmony_ci * 231e5c31af7Sopenharmony_ci * * Test with NULL length. 232e5c31af7Sopenharmony_ci * * Test with zero bufSize. Expect no errors 233e5c31af7Sopenharmony_ci * * Test with varying bufSizes (where 0 < bufSize <= INFO_LOG_LENGTH). Except 234e5c31af7Sopenharmony_ci * * length = (bufSize - 1) and zero-terminated string with matching length in 235e5c31af7Sopenharmony_ci * infoLog. 236e5c31af7Sopenharmony_ci * 237e5c31af7Sopenharmony_ci * Negative tests 238e5c31af7Sopenharmony_ci * 239e5c31af7Sopenharmony_ci * * Test with deleted/nonexistent program pipeline object. Expect 240e5c31af7Sopenharmony_ci * GL_INVALID_VALUE error (the error is still missing from the spec) 241e5c31af7Sopenharmony_ci * 242e5c31af7Sopenharmony_ci * 243e5c31af7Sopenharmony_ci *-- Other tests 244e5c31af7Sopenharmony_ci * 245e5c31af7Sopenharmony_ci * 246e5c31af7Sopenharmony_ci * UseProgram vs. BindProgramPipeline tests 247e5c31af7Sopenharmony_ci * 248e5c31af7Sopenharmony_ci * Positive tests: 249e5c31af7Sopenharmony_ci * 250e5c31af7Sopenharmony_ci * * Test that a program made active with UseProgram has precedence over 251e5c31af7Sopenharmony_ci * program pipeline object bound with BindProgramPipeline. 252e5c31af7Sopenharmony_ci * * Test that program(s) in bound program pipeline object will be used if 253e5c31af7Sopenharmony_ci * there is no active program set with UseProgram 254e5c31af7Sopenharmony_ci * * Test that a state without active program or without bound pipeline object 255e5c31af7Sopenharmony_ci * generates no errors. 256e5c31af7Sopenharmony_ci * 257e5c31af7Sopenharmony_ci * 258e5c31af7Sopenharmony_ci * Pipeline setup tests 259e5c31af7Sopenharmony_ci * 260e5c31af7Sopenharmony_ci * Positive tests: 261e5c31af7Sopenharmony_ci * 262e5c31af7Sopenharmony_ci * * Test that missing pipeline stages produces no errors: 263e5c31af7Sopenharmony_ci * - no program set with UseProgramStages for vertex or frargment stages 264e5c31af7Sopenharmony_ci * - no vertex or fragment code in a program set for the stage 265e5c31af7Sopenharmony_ci * 266e5c31af7Sopenharmony_ci * Negative tests: 267e5c31af7Sopenharmony_ci * 268e5c31af7Sopenharmony_ci * * Test that program with both vertex and fragment shaders cannot be attached 269e5c31af7Sopenharmony_ci * just to vertex or fragment stage. Expect DrawArrays/Elements to generate 270e5c31af7Sopenharmony_ci * INVALID_OPERATION and pipeline VALIDATE_STATUS set to FALSE. 271e5c31af7Sopenharmony_ci * - Run with and without validating the pipeline with ValidateProgramPipeline 272e5c31af7Sopenharmony_ci * 273e5c31af7Sopenharmony_ci * 274e5c31af7Sopenharmony_ci * Shader/program management tests 275e5c31af7Sopenharmony_ci * 276e5c31af7Sopenharmony_ci * Positive tests: 277e5c31af7Sopenharmony_ci * 278e5c31af7Sopenharmony_ci * * Test creating separable shader objects both by 279e5c31af7Sopenharmony_ci * - Using the core functions combined with PROGRAM_SEPARABLE flag 280e5c31af7Sopenharmony_ci * - CreateShaderProgram 281e5c31af7Sopenharmony_ci * * Test that separable program can contain and links properly if there are 282e5c31af7Sopenharmony_ci * - vertex stage 283e5c31af7Sopenharmony_ci * - fragment stage 284e5c31af7Sopenharmony_ci * - both stages 285e5c31af7Sopenharmony_ci * * Test that active program isn't deleted immediately (deletion doesn't 286e5c31af7Sopenharmony_ci * affect rendering state) 287e5c31af7Sopenharmony_ci * * Test that program in current pipeline isn't deleted immediately 288e5c31af7Sopenharmony_ci * * Test that attaching/detaching/recompiling a shader in active program or 289e5c31af7Sopenharmony_ci * program in current pipeline doesn't affect the program link status or 290e5c31af7Sopenharmony_ci * rendering state. 291e5c31af7Sopenharmony_ci * * Test that succesfully re-linking active program or program in current 292e5c31af7Sopenharmony_ci * pipeline affects the rendering state. 293e5c31af7Sopenharmony_ci * 294e5c31af7Sopenharmony_ci * Negative tests: 295e5c31af7Sopenharmony_ci * 296e5c31af7Sopenharmony_ci * aren't present. 297e5c31af7Sopenharmony_ci * * Test that unsuccesfully re-linking active program or program in current 298e5c31af7Sopenharmony_ci * pipeline sets LINK_STATUS=FALSE but doesn't affect the rendering state. 299e5c31af7Sopenharmony_ci * * Test that unsuccesfully linked program cannot be made part of a program 300e5c31af7Sopenharmony_ci * pipeline object. 301e5c31af7Sopenharmony_ci * 302e5c31af7Sopenharmony_ci * 303e5c31af7Sopenharmony_ci * Uniform update tests 304e5c31af7Sopenharmony_ci * 305e5c31af7Sopenharmony_ci * Positive cases: 306e5c31af7Sopenharmony_ci * 307e5c31af7Sopenharmony_ci * with UseProgram. 308e5c31af7Sopenharmony_ci * * Test that Uniform* functions update the uniforms of a program made active with 309e5c31af7Sopenharmony_ci * ActiveShader program if no program has been made active with UseProgram. 310e5c31af7Sopenharmony_ci * * Test that ProgramUniform* functions update the uniforms of a specified 311e5c31af7Sopenharmony_ci * program regardless of active program (probably already covered with 312e5c31af7Sopenharmony_ci * "ProgramUniform* tests") 313e5c31af7Sopenharmony_ci * 314e5c31af7Sopenharmony_ci * Negative cases: 315e5c31af7Sopenharmony_ci * 316e5c31af7Sopenharmony_ci * * Test that Uniform* functions set INVALID_OPERATION if there is no active 317e5c31af7Sopenharmony_ci * program set with UseProgram nor ActiveShaderProgram 318e5c31af7Sopenharmony_ci * 319e5c31af7Sopenharmony_ci * 320e5c31af7Sopenharmony_ci * Shader interface matching tests 321e5c31af7Sopenharmony_ci * 322e5c31af7Sopenharmony_ci * Positive tests: 323e5c31af7Sopenharmony_ci * 324e5c31af7Sopenharmony_ci * * Test that partially or completely mismatching shaders do not generate 325e5c31af7Sopenharmony_ci * validation nor other GL errors (just undefined inputs) 326e5c31af7Sopenharmony_ci * * Test that exactly matching shaders work. 327e5c31af7Sopenharmony_ci * * Test that variables with matching layout qualifiers match and are defined 328e5c31af7Sopenharmony_ci * even if the shaders don't match exactly. 329e5c31af7Sopenharmony_ci * - Test with int, uint and float component types 330e5c31af7Sopenharmony_ci * - Test with different vector sizes, where output vector size >= input 331e5c31af7Sopenharmony_ci * vector size 332e5c31af7Sopenharmony_ci * 333e5c31af7Sopenharmony_ci * 334e5c31af7Sopenharmony_ci * End Test Plan */ 335e5c31af7Sopenharmony_ci/*************************************************************************/ 336e5c31af7Sopenharmony_ci 337e5c31af7Sopenharmony_cinamespace glcts 338e5c31af7Sopenharmony_ci{ 339e5c31af7Sopenharmony_ci 340e5c31af7Sopenharmony_ciusing tcu::TestLog; 341e5c31af7Sopenharmony_ciusing std::string; 342e5c31af7Sopenharmony_ciusing std::vector; 343e5c31af7Sopenharmony_ci 344e5c31af7Sopenharmony_ci// A fragment shader to allow testing various scalar and vector 345e5c31af7Sopenharmony_ci// uniforms as well as array [2] varieties. To keep the uniforms 346e5c31af7Sopenharmony_ci// active they are compared against constants. 347e5c31af7Sopenharmony_cistatic const char* s_unifFragShaderSrc = 348e5c31af7Sopenharmony_ci "precision highp float;\n" 349e5c31af7Sopenharmony_ci "uniform ${SCALAR_TYPE} uVal0;\n" 350e5c31af7Sopenharmony_ci "uniform ${VECTOR_TYPE}2 uVal1;\n" 351e5c31af7Sopenharmony_ci "uniform ${VECTOR_TYPE}3 uVal2;\n" 352e5c31af7Sopenharmony_ci "uniform ${VECTOR_TYPE}4 uVal3;\n" 353e5c31af7Sopenharmony_ci "\n" 354e5c31af7Sopenharmony_ci "uniform ${SCALAR_TYPE} uVal4[2];\n" 355e5c31af7Sopenharmony_ci "uniform ${VECTOR_TYPE}2 uVal5[2];\n" 356e5c31af7Sopenharmony_ci "uniform ${VECTOR_TYPE}3 uVal6[2];\n" 357e5c31af7Sopenharmony_ci "uniform ${VECTOR_TYPE}4 uVal7[2];\n" 358e5c31af7Sopenharmony_ci "\n" 359e5c31af7Sopenharmony_ci "const ${SCALAR_TYPE} kVal0= 1${SFX};\n" 360e5c31af7Sopenharmony_ci "const ${VECTOR_TYPE}2 kVal1 = ${VECTOR_TYPE}2(2${SFX}, 3${SFX});\n" 361e5c31af7Sopenharmony_ci "const ${VECTOR_TYPE}3 kVal2 = ${VECTOR_TYPE}3(4${SFX}, 5${SFX}, 6${SFX});\n" 362e5c31af7Sopenharmony_ci "const ${VECTOR_TYPE}4 kVal3 = ${VECTOR_TYPE}4(7${SFX}, 8${SFX}, 9${SFX}, 10${SFX});\n" 363e5c31af7Sopenharmony_ci "\n" 364e5c31af7Sopenharmony_ci "const ${SCALAR_TYPE} kArr4_0 = 11${SFX};\n" 365e5c31af7Sopenharmony_ci "const ${SCALAR_TYPE} kArr4_1 = 12${SFX};\n" 366e5c31af7Sopenharmony_ci "const ${VECTOR_TYPE}2 kArr5_0 = ${VECTOR_TYPE}2(13${SFX}, 14${SFX});\n" 367e5c31af7Sopenharmony_ci "const ${VECTOR_TYPE}2 kArr5_1 = ${VECTOR_TYPE}2(15${SFX}, 16${SFX});\n" 368e5c31af7Sopenharmony_ci "const ${VECTOR_TYPE}3 kArr6_0 = ${VECTOR_TYPE}3(17${SFX}, 18${SFX}, 19${SFX});\n" 369e5c31af7Sopenharmony_ci "const ${VECTOR_TYPE}3 kArr6_1 = ${VECTOR_TYPE}3(20${SFX}, 21${SFX}, 22${SFX});\n" 370e5c31af7Sopenharmony_ci "const ${VECTOR_TYPE}4 kArr7_0 = ${VECTOR_TYPE}4(23${SFX}, 24${SFX}, 25${SFX}, 26${SFX});\n" 371e5c31af7Sopenharmony_ci "const ${VECTOR_TYPE}4 kArr7_1 = ${VECTOR_TYPE}4(27${SFX}, 28${SFX}, 29${SFX}, 30${SFX});\n" 372e5c31af7Sopenharmony_ci "\n" 373e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 o_color;\n" 374e5c31af7Sopenharmony_ci "\n" 375e5c31af7Sopenharmony_ci "void main() {\n" 376e5c31af7Sopenharmony_ci " if ((uVal0 != kVal0) ||\n" 377e5c31af7Sopenharmony_ci " (uVal1 != kVal1) ||\n" 378e5c31af7Sopenharmony_ci " (uVal2 != kVal2) ||\n" 379e5c31af7Sopenharmony_ci " (uVal3 != kVal3) ||\n" 380e5c31af7Sopenharmony_ci " (uVal4[0] != kArr4_0) || (uVal4[1] != kArr4_1) ||\n" 381e5c31af7Sopenharmony_ci " (uVal5[0] != kArr5_0) || (uVal5[1] != kArr5_1) ||\n" 382e5c31af7Sopenharmony_ci " (uVal6[0] != kArr6_0) || (uVal6[1] != kArr6_1) ||\n" 383e5c31af7Sopenharmony_ci " (uVal7[0] != kArr7_0) || (uVal7[1] != kArr7_1)) {\n" 384e5c31af7Sopenharmony_ci " o_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 385e5c31af7Sopenharmony_ci " } else {\n" 386e5c31af7Sopenharmony_ci " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 387e5c31af7Sopenharmony_ci " }\n" 388e5c31af7Sopenharmony_ci "}\n"; 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_ci// A fragment shader to test uniforms of square matrices 391e5c31af7Sopenharmony_cistatic const char* s_unifFragSquareMatShaderSrc = "precision highp float;\n" 392e5c31af7Sopenharmony_ci "uniform mat2 uValM2[2];\n" 393e5c31af7Sopenharmony_ci "uniform mat3 uValM3[2];\n" 394e5c31af7Sopenharmony_ci "uniform mat4 uValM4[2];\n" 395e5c31af7Sopenharmony_ci "\n" 396e5c31af7Sopenharmony_ci "const mat2 kMat2_0 = mat2(91.0, 92.0, 93.0, 94.0);\n" 397e5c31af7Sopenharmony_ci "const mat2 kMat2_1 = mat2(95.0, 96.0, 97.0, 98.0);\n" 398e5c31af7Sopenharmony_ci "const mat3 kMat3_0 = mat3(vec3( 99.0, 100.0, 101.0),\n" 399e5c31af7Sopenharmony_ci " vec3(102.0, 103.0, 104.0),\n" 400e5c31af7Sopenharmony_ci " vec3(105.0, 106.0, 107.0));\n" 401e5c31af7Sopenharmony_ci "const mat3 kMat3_1 = mat3(vec3(108.0, 109.0, 110.0),\n" 402e5c31af7Sopenharmony_ci " vec3(111.0, 112.0, 113.0),\n" 403e5c31af7Sopenharmony_ci " vec3(114.0, 115.0, 116.0));\n" 404e5c31af7Sopenharmony_ci "const mat4 kMat4_0 = mat4(vec4(117.0, 118.0, 119.0, 120.0),\n" 405e5c31af7Sopenharmony_ci " vec4(121.0, 122.0, 123.0, 124.0),\n" 406e5c31af7Sopenharmony_ci " vec4(125.0, 126.0, 127.0, 128.0),\n" 407e5c31af7Sopenharmony_ci " vec4(129.0, 130.0, 131.0, 132.0));\n" 408e5c31af7Sopenharmony_ci "const mat4 kMat4_1 = mat4(vec4(133.0, 134.0, 135.0, 136.0),\n" 409e5c31af7Sopenharmony_ci " vec4(137.0, 138.0, 139.0, 140.0),\n" 410e5c31af7Sopenharmony_ci " vec4(141.0, 142.0, 143.0, 144.0),\n" 411e5c31af7Sopenharmony_ci " vec4(145.0, 146.0, 147.0, 148.0));\n" 412e5c31af7Sopenharmony_ci "\n" 413e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 o_color;\n" 414e5c31af7Sopenharmony_ci "\n" 415e5c31af7Sopenharmony_ci "void main() {\n" 416e5c31af7Sopenharmony_ci " if ((uValM2[0] != kMat2_0) || (uValM2[1] != kMat2_1) ||\n" 417e5c31af7Sopenharmony_ci " (uValM3[0] != kMat3_0) || (uValM3[1] != kMat3_1) ||\n" 418e5c31af7Sopenharmony_ci " (uValM4[0] != kMat4_0) || (uValM4[1] != kMat4_1)) {\n" 419e5c31af7Sopenharmony_ci " o_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 420e5c31af7Sopenharmony_ci " } else {\n" 421e5c31af7Sopenharmony_ci " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 422e5c31af7Sopenharmony_ci " }\n" 423e5c31af7Sopenharmony_ci "}\n"; 424e5c31af7Sopenharmony_ci 425e5c31af7Sopenharmony_ci// A fragment shader to test uniforms of square matrices 426e5c31af7Sopenharmony_cistatic const char* s_unifFragNonSquareMatShaderSrc = 427e5c31af7Sopenharmony_ci "precision highp float;\n" 428e5c31af7Sopenharmony_ci "uniform mat2x3 uValM2x3[2];\n" 429e5c31af7Sopenharmony_ci "uniform mat3x2 uValM3x2[2];\n" 430e5c31af7Sopenharmony_ci "uniform mat2x4 uValM2x4[2];\n" 431e5c31af7Sopenharmony_ci "uniform mat4x2 uValM4x2[2];\n" 432e5c31af7Sopenharmony_ci "uniform mat3x4 uValM3x4[2];\n" 433e5c31af7Sopenharmony_ci "uniform mat4x3 uValM4x3[2];\n" 434e5c31af7Sopenharmony_ci "\n" 435e5c31af7Sopenharmony_ci "const mat2x3 kMat2x3_0 = mat2x3(vec2(149.0, 150.0),\n" 436e5c31af7Sopenharmony_ci " vec2(151.0, 152.0),\n" 437e5c31af7Sopenharmony_ci " vec2(153.0, 154.0));\n" 438e5c31af7Sopenharmony_ci "const mat2x3 kMat2x3_1 = mat2x3(vec2(155.0, 156.0),\n" 439e5c31af7Sopenharmony_ci " vec2(157.0, 158.0),\n" 440e5c31af7Sopenharmony_ci " vec2(159.0, 160.0));\n" 441e5c31af7Sopenharmony_ci "const mat3x2 kMat3x2_0 = mat3x2(vec3(161.0, 162.0, 163.0),\n" 442e5c31af7Sopenharmony_ci " vec3(164.0, 165.0, 166.0));\n" 443e5c31af7Sopenharmony_ci "const mat3x2 kMat3x2_1 = mat3x2(vec3(167.0, 168.0, 169.0),\n" 444e5c31af7Sopenharmony_ci " vec3(170.0, 171.0, 172.0));\n" 445e5c31af7Sopenharmony_ci "const mat2x4 kMat2x4_0 = mat2x4(vec2(173.0, 174.0),\n" 446e5c31af7Sopenharmony_ci " vec2(175.0, 176.0),\n" 447e5c31af7Sopenharmony_ci " vec2(177.0, 178.0),\n" 448e5c31af7Sopenharmony_ci " vec2(179.0, 180.0));\n" 449e5c31af7Sopenharmony_ci "const mat2x4 kMat2x4_1 = mat2x4(vec2(181.0, 182.0),\n" 450e5c31af7Sopenharmony_ci " vec2(183.0, 184.0),\n" 451e5c31af7Sopenharmony_ci " vec2(185.0, 186.0),\n" 452e5c31af7Sopenharmony_ci " vec2(187.0, 188.0));\n" 453e5c31af7Sopenharmony_ci "const mat4x2 kMat4x2_0 = mat4x2(vec4(189.0, 190.0, 191.0, 192.0),\n" 454e5c31af7Sopenharmony_ci " vec4(193.0, 194.0, 195.0, 196.0));\n" 455e5c31af7Sopenharmony_ci "const mat4x2 kMat4x2_1 = mat4x2(vec4(197.0, 198.0, 199.0, 200.0),\n" 456e5c31af7Sopenharmony_ci " vec4(201.0, 202.0, 203.0, 204.0));\n" 457e5c31af7Sopenharmony_ci "const mat3x4 kMat3x4_0 = mat3x4(vec3(205.0, 206.0, 207.0),\n" 458e5c31af7Sopenharmony_ci " vec3(208.0, 209.0, 210.0),\n" 459e5c31af7Sopenharmony_ci " vec3(211.0, 212.0, 213.0),\n" 460e5c31af7Sopenharmony_ci " vec3(214.0, 215.0, 216.0));\n" 461e5c31af7Sopenharmony_ci "const mat3x4 kMat3x4_1 = mat3x4(vec3(217.0, 218.0, 219.0),\n" 462e5c31af7Sopenharmony_ci " vec3(220.0, 221.0, 222.0),\n" 463e5c31af7Sopenharmony_ci " vec3(223.0, 224.0, 225.0),\n" 464e5c31af7Sopenharmony_ci " vec3(226.0, 227.0, 228.0));\n" 465e5c31af7Sopenharmony_ci "const mat4x3 kMat4x3_0 = mat4x3(vec4(229.0, 230.0, 231.0, 232.0),\n" 466e5c31af7Sopenharmony_ci " vec4(233.0, 234.0, 235.0, 236.0),\n" 467e5c31af7Sopenharmony_ci " vec4(237.0, 238.0, 239.0, 240.0));\n" 468e5c31af7Sopenharmony_ci "const mat4x3 kMat4x3_1 = mat4x3(vec4(241.0, 242.0, 243.0, 244.0),\n" 469e5c31af7Sopenharmony_ci " vec4(245.0, 246.0, 247.0, 248.0),\n" 470e5c31af7Sopenharmony_ci " vec4(249.0, 250.0, 251.0, 252.0));\n" 471e5c31af7Sopenharmony_ci "\n" 472e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 o_color;\n" 473e5c31af7Sopenharmony_ci "\n" 474e5c31af7Sopenharmony_ci "void main() {\n" 475e5c31af7Sopenharmony_ci " if ((uValM2x3[0] != kMat2x3_0) || (uValM2x3[1] != kMat2x3_1) ||\n" 476e5c31af7Sopenharmony_ci " (uValM3x2[0] != kMat3x2_0) || (uValM3x2[1] != kMat3x2_1) ||\n" 477e5c31af7Sopenharmony_ci " (uValM2x4[0] != kMat2x4_0) || (uValM2x4[1] != kMat2x4_1) ||\n" 478e5c31af7Sopenharmony_ci " (uValM4x2[0] != kMat4x2_0) || (uValM4x2[1] != kMat4x2_1) ||\n" 479e5c31af7Sopenharmony_ci " (uValM3x4[0] != kMat3x4_0) || (uValM3x4[1] != kMat3x4_1) ||\n" 480e5c31af7Sopenharmony_ci " (uValM4x3[0] != kMat4x3_0) || (uValM4x3[1] != kMat4x3_1)) {\n" 481e5c31af7Sopenharmony_ci " o_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 482e5c31af7Sopenharmony_ci " } else {\n" 483e5c31af7Sopenharmony_ci " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 484e5c31af7Sopenharmony_ci " }\n" 485e5c31af7Sopenharmony_ci "}\n"; 486e5c31af7Sopenharmony_ci 487e5c31af7Sopenharmony_cistatic std::string generateBasicVertexSrc(glu::GLSLVersion glslVersion) 488e5c31af7Sopenharmony_ci{ 489e5c31af7Sopenharmony_ci std::stringstream str; 490e5c31af7Sopenharmony_ci 491e5c31af7Sopenharmony_ci str << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 492e5c31af7Sopenharmony_ci str << "in highp vec4 a_position;\n"; 493e5c31af7Sopenharmony_ci if (glslVersion >= glu::GLSL_VERSION_410) 494e5c31af7Sopenharmony_ci { 495e5c31af7Sopenharmony_ci str << "out gl_PerVertex {\n" 496e5c31af7Sopenharmony_ci " vec4 gl_Position;\n" 497e5c31af7Sopenharmony_ci "};\n"; 498e5c31af7Sopenharmony_ci } 499e5c31af7Sopenharmony_ci str << "void main (void)\n" 500e5c31af7Sopenharmony_ci "{\n" 501e5c31af7Sopenharmony_ci " gl_Position = a_position;\n" 502e5c31af7Sopenharmony_ci "}\n"; 503e5c31af7Sopenharmony_ci 504e5c31af7Sopenharmony_ci return str.str(); 505e5c31af7Sopenharmony_ci} 506e5c31af7Sopenharmony_ci 507e5c31af7Sopenharmony_cistatic std::string generateBasicFragmentSrc(glu::GLSLVersion glslVersion) 508e5c31af7Sopenharmony_ci{ 509e5c31af7Sopenharmony_ci std::stringstream str; 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ci str << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 512e5c31af7Sopenharmony_ci str << "uniform highp vec4 u_color;\n" 513e5c31af7Sopenharmony_ci "layout(location = 0) out mediump vec4 o_color;\n" 514e5c31af7Sopenharmony_ci "void main (void)\n" 515e5c31af7Sopenharmony_ci "{\n" 516e5c31af7Sopenharmony_ci " o_color = u_color;\n" 517e5c31af7Sopenharmony_ci "}\n"; 518e5c31af7Sopenharmony_ci 519e5c31af7Sopenharmony_ci return str.str(); 520e5c31af7Sopenharmony_ci} 521e5c31af7Sopenharmony_ci 522e5c31af7Sopenharmony_ci// Testcase for glCreateShaderProgramv 523e5c31af7Sopenharmony_ciclass CreateShadProgCase : public TestCase 524e5c31af7Sopenharmony_ci{ 525e5c31af7Sopenharmony_cipublic: 526e5c31af7Sopenharmony_ci CreateShadProgCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion) 527e5c31af7Sopenharmony_ci : TestCase(context, name, description), m_glslVersion(glslVersion) 528e5c31af7Sopenharmony_ci { 529e5c31af7Sopenharmony_ci } 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_ci ~CreateShadProgCase(void) 532e5c31af7Sopenharmony_ci { 533e5c31af7Sopenharmony_ci } 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci // Check program validity created with CreateShaderProgram 536e5c31af7Sopenharmony_ci bool checkCSProg(const glw::Functions& gl, GLuint program, int expectedSep = GL_TRUE, int expectedLink = GL_TRUE) 537e5c31af7Sopenharmony_ci { 538e5c31af7Sopenharmony_ci int separable = GL_FALSE; 539e5c31af7Sopenharmony_ci int linked = GL_FALSE; 540e5c31af7Sopenharmony_ci if (program != 0) 541e5c31af7Sopenharmony_ci { 542e5c31af7Sopenharmony_ci gl.getProgramiv(program, GL_PROGRAM_SEPARABLE, &separable); 543e5c31af7Sopenharmony_ci gl.getProgramiv(program, GL_LINK_STATUS, &linked); 544e5c31af7Sopenharmony_ci } 545e5c31af7Sopenharmony_ci 546e5c31af7Sopenharmony_ci return (program != 0) && (separable == expectedSep) && (linked == expectedLink); 547e5c31af7Sopenharmony_ci } 548e5c31af7Sopenharmony_ci 549e5c31af7Sopenharmony_ci IterateResult iterate(void) 550e5c31af7Sopenharmony_ci { 551e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 552e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 553e5c31af7Sopenharmony_ci int i; 554e5c31af7Sopenharmony_ci const char* srcStrings[10]; 555e5c31af7Sopenharmony_ci glw::GLuint program; 556e5c31af7Sopenharmony_ci glw::GLenum err; 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_ci // CreateShaderProgramv verification 559e5c31af7Sopenharmony_ci log << TestLog::Message << "Begin:CreateShadProgCase iterate" << TestLog::EndMessage; 560e5c31af7Sopenharmony_ci 561e5c31af7Sopenharmony_ci // vertex shader 562e5c31af7Sopenharmony_ci i = 0; 563e5c31af7Sopenharmony_ci srcStrings[i++] = glu::getGLSLVersionDeclaration(m_glslVersion); 564e5c31af7Sopenharmony_ci srcStrings[i++] = "\n"; 565e5c31af7Sopenharmony_ci if (m_glslVersion >= glu::GLSL_VERSION_410) 566e5c31af7Sopenharmony_ci { 567e5c31af7Sopenharmony_ci srcStrings[i++] = "out gl_PerVertex {\n" 568e5c31af7Sopenharmony_ci " vec4 gl_Position;\n" 569e5c31af7Sopenharmony_ci "};\n"; 570e5c31af7Sopenharmony_ci } 571e5c31af7Sopenharmony_ci srcStrings[i++] = "in vec4 a_position;\n"; 572e5c31af7Sopenharmony_ci srcStrings[i++] = "void main ()\n"; 573e5c31af7Sopenharmony_ci srcStrings[i++] = "{\n"; 574e5c31af7Sopenharmony_ci srcStrings[i++] = " gl_Position = a_position;\n"; 575e5c31af7Sopenharmony_ci srcStrings[i++] = "}\n"; 576e5c31af7Sopenharmony_ci 577e5c31af7Sopenharmony_ci program = gl.createShaderProgramv(GL_VERTEX_SHADER, i, srcStrings); 578e5c31af7Sopenharmony_ci if (!checkCSProg(gl, program)) 579e5c31af7Sopenharmony_ci { 580e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed for vertex shader"); 581e5c31af7Sopenharmony_ci } 582e5c31af7Sopenharmony_ci 583e5c31af7Sopenharmony_ci gl.deleteProgram(program); 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci // Half as many strings 586e5c31af7Sopenharmony_ci i = 0; 587e5c31af7Sopenharmony_ci srcStrings[i++] = glu::getGLSLVersionDeclaration(m_glslVersion); 588e5c31af7Sopenharmony_ci srcStrings[i++] = "\n"; 589e5c31af7Sopenharmony_ci if (m_glslVersion >= glu::GLSL_VERSION_410) 590e5c31af7Sopenharmony_ci { 591e5c31af7Sopenharmony_ci srcStrings[i++] = "out gl_PerVertex {\n" 592e5c31af7Sopenharmony_ci " vec4 gl_Position;\n" 593e5c31af7Sopenharmony_ci "};\n"; 594e5c31af7Sopenharmony_ci } 595e5c31af7Sopenharmony_ci srcStrings[i++] = "in vec4 a_position;\n" 596e5c31af7Sopenharmony_ci "void main ()\n"; 597e5c31af7Sopenharmony_ci srcStrings[i++] = "{\n" 598e5c31af7Sopenharmony_ci " gl_Position = a_position;\n"; 599e5c31af7Sopenharmony_ci srcStrings[i++] = "}\n"; 600e5c31af7Sopenharmony_ci 601e5c31af7Sopenharmony_ci program = gl.createShaderProgramv(GL_VERTEX_SHADER, i, srcStrings); 602e5c31af7Sopenharmony_ci if (!checkCSProg(gl, program)) 603e5c31af7Sopenharmony_ci { 604e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed for vertex shader"); 605e5c31af7Sopenharmony_ci } 606e5c31af7Sopenharmony_ci 607e5c31af7Sopenharmony_ci gl.deleteProgram(program); 608e5c31af7Sopenharmony_ci 609e5c31af7Sopenharmony_ci // Fragment shader 610e5c31af7Sopenharmony_ci i = 0; 611e5c31af7Sopenharmony_ci srcStrings[i++] = glu::getGLSLVersionDeclaration(m_glslVersion); 612e5c31af7Sopenharmony_ci srcStrings[i++] = "\nin highp vec4 u_color;\n"; 613e5c31af7Sopenharmony_ci srcStrings[i++] = "layout(location = 0) out mediump vec4 o_color;\n"; 614e5c31af7Sopenharmony_ci srcStrings[i++] = "void main ()\n"; 615e5c31af7Sopenharmony_ci srcStrings[i++] = "{\n"; 616e5c31af7Sopenharmony_ci srcStrings[i++] = " o_color = u_color;\n"; 617e5c31af7Sopenharmony_ci srcStrings[i++] = "}\n"; 618e5c31af7Sopenharmony_ci 619e5c31af7Sopenharmony_ci program = gl.createShaderProgramv(GL_FRAGMENT_SHADER, i, srcStrings); 620e5c31af7Sopenharmony_ci if (!checkCSProg(gl, program)) 621e5c31af7Sopenharmony_ci { 622e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed for fragment shader"); 623e5c31af7Sopenharmony_ci } 624e5c31af7Sopenharmony_ci 625e5c31af7Sopenharmony_ci gl.deleteProgram(program); 626e5c31af7Sopenharmony_ci 627e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShaderProgramv failed"); 628e5c31af7Sopenharmony_ci 629e5c31af7Sopenharmony_ci // Negative Cases 630e5c31af7Sopenharmony_ci 631e5c31af7Sopenharmony_ci // invalid type 632e5c31af7Sopenharmony_ci program = gl.createShaderProgramv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, i, srcStrings); 633e5c31af7Sopenharmony_ci err = gl.getError(); 634e5c31af7Sopenharmony_ci if ((program != 0) || (err != GL_INVALID_ENUM)) 635e5c31af7Sopenharmony_ci { 636e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed"); 637e5c31af7Sopenharmony_ci } 638e5c31af7Sopenharmony_ci 639e5c31af7Sopenharmony_ci // Negative count 640e5c31af7Sopenharmony_ci program = gl.createShaderProgramv(GL_FRAGMENT_SHADER, -1, srcStrings); 641e5c31af7Sopenharmony_ci err = gl.getError(); 642e5c31af7Sopenharmony_ci if ((program != 0) || (err != GL_INVALID_VALUE)) 643e5c31af7Sopenharmony_ci { 644e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed"); 645e5c31af7Sopenharmony_ci } 646e5c31af7Sopenharmony_ci 647e5c31af7Sopenharmony_ci // source compile error 648e5c31af7Sopenharmony_ci i = 0; 649e5c31af7Sopenharmony_ci srcStrings[i++] = glu::getGLSLVersionDeclaration(m_glslVersion); 650e5c31af7Sopenharmony_ci srcStrings[i++] = "\nin highp vec4 u_color;\n"; 651e5c31af7Sopenharmony_ci srcStrings[i++] = "layout(location = 0) out mediump vec4 o_color;\n"; 652e5c31af7Sopenharmony_ci srcStrings[i++] = "void main ()\n"; 653e5c31af7Sopenharmony_ci srcStrings[i++] = "{\n"; 654e5c31af7Sopenharmony_ci srcStrings[i++] = " o_color = u_color;\n"; 655e5c31af7Sopenharmony_ci 656e5c31af7Sopenharmony_ci program = gl.createShaderProgramv(GL_FRAGMENT_SHADER, i, srcStrings); 657e5c31af7Sopenharmony_ci // expect valid program and false for link status 658e5c31af7Sopenharmony_ci if (!checkCSProg(gl, program, GL_FALSE, GL_FALSE)) 659e5c31af7Sopenharmony_ci { 660e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed for fragment shader"); 661e5c31af7Sopenharmony_ci } 662e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShaderProgramv failed"); 663e5c31af7Sopenharmony_ci gl.deleteProgram(program); 664e5c31af7Sopenharmony_ci 665e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 666e5c31af7Sopenharmony_ci return STOP; 667e5c31af7Sopenharmony_ci } 668e5c31af7Sopenharmony_ci 669e5c31af7Sopenharmony_ciprivate: 670e5c31af7Sopenharmony_ci glu::GLSLVersion m_glslVersion; 671e5c31af7Sopenharmony_ci}; 672e5c31af7Sopenharmony_ci 673e5c31af7Sopenharmony_ci// Testcase for glUseProgamStages 674e5c31af7Sopenharmony_ciclass UseProgStagesCase : public TestCase 675e5c31af7Sopenharmony_ci{ 676e5c31af7Sopenharmony_cipublic: 677e5c31af7Sopenharmony_ci UseProgStagesCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion) 678e5c31af7Sopenharmony_ci : TestCase(context, name, description), m_glslVersion(glslVersion) 679e5c31af7Sopenharmony_ci { 680e5c31af7Sopenharmony_ci } 681e5c31af7Sopenharmony_ci 682e5c31af7Sopenharmony_ci ~UseProgStagesCase(void) 683e5c31af7Sopenharmony_ci { 684e5c31af7Sopenharmony_ci } 685e5c31af7Sopenharmony_ci 686e5c31af7Sopenharmony_ci IterateResult iterate(void) 687e5c31af7Sopenharmony_ci { 688e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 689e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 690e5c31af7Sopenharmony_ci glw::GLenum err; 691e5c31af7Sopenharmony_ci glw::GLuint pipeline; 692e5c31af7Sopenharmony_ci glw::GLuint progIdV, progIdF; 693e5c31af7Sopenharmony_ci glw::GLuint programVtx, programFrag; 694e5c31af7Sopenharmony_ci const char* shaderSrc[1]; 695e5c31af7Sopenharmony_ci std::string vtx; 696e5c31af7Sopenharmony_ci std::string frag; 697e5c31af7Sopenharmony_ci glw::GLint linkStatus; 698e5c31af7Sopenharmony_ci 699e5c31af7Sopenharmony_ci vtx = generateBasicVertexSrc(m_glslVersion); 700e5c31af7Sopenharmony_ci frag = generateBasicFragmentSrc(m_glslVersion); 701e5c31af7Sopenharmony_ci 702e5c31af7Sopenharmony_ci // UseProgramStages verification 703e5c31af7Sopenharmony_ci log << TestLog::Message << "Begin:UseProgStagesCase iterate" << TestLog::EndMessage; 704e5c31af7Sopenharmony_ci 705e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, &pipeline); 706e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipeline); 707e5c31af7Sopenharmony_ci 708e5c31af7Sopenharmony_ci // Use Vertex Shader 709e5c31af7Sopenharmony_ci shaderSrc[0] = vtx.c_str(); 710e5c31af7Sopenharmony_ci programVtx = gl.createShaderProgramv(GL_VERTEX_SHADER, 1, shaderSrc); 711e5c31af7Sopenharmony_ci 712e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, programVtx); 713e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_VERTEX_SHADER, (glw::GLint*)&progIdV); 714e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_FRAGMENT_SHADER, (glw::GLint*)&progIdF); 715e5c31af7Sopenharmony_ci if ((programVtx == 0) || (progIdV != programVtx) || (progIdF != 0)) 716e5c31af7Sopenharmony_ci { 717e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 718e5c31af7Sopenharmony_ci } 719e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages failed"); 720e5c31af7Sopenharmony_ci 721e5c31af7Sopenharmony_ci // Use Fragment Shader 722e5c31af7Sopenharmony_ci shaderSrc[0] = frag.c_str(); 723e5c31af7Sopenharmony_ci programFrag = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1, shaderSrc); 724e5c31af7Sopenharmony_ci 725e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, programFrag); 726e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_FRAGMENT_SHADER, (glw::GLint*)&progIdF); 727e5c31af7Sopenharmony_ci if ((programFrag == 0) || (progIdF != programFrag) || (progIdF == progIdV)) 728e5c31af7Sopenharmony_ci { 729e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 730e5c31af7Sopenharmony_ci } 731e5c31af7Sopenharmony_ci 732e5c31af7Sopenharmony_ci // Reset stages 733e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, 0); 734e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_VERTEX_SHADER, (glw::GLint*)&progIdV); 735e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_FRAGMENT_SHADER, (glw::GLint*)&progIdF); 736e5c31af7Sopenharmony_ci if ((progIdV != 0) || (progIdF != 0)) 737e5c31af7Sopenharmony_ci { 738e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 739e5c31af7Sopenharmony_ci } 740e5c31af7Sopenharmony_ci 741e5c31af7Sopenharmony_ci // One program for both. 742e5c31af7Sopenharmony_ci glu::ShaderProgram progVF(m_context.getRenderContext(), glu::makeVtxFragSources(vtx.c_str(), frag.c_str())); 743e5c31af7Sopenharmony_ci 744e5c31af7Sopenharmony_ci // Make separable and relink 745e5c31af7Sopenharmony_ci gl.programParameteri(progVF.getProgram(), GL_PROGRAM_SEPARABLE, GL_TRUE); 746e5c31af7Sopenharmony_ci gl.linkProgram(progVF.getProgram()); 747e5c31af7Sopenharmony_ci gl.getProgramiv(progVF.getProgram(), GL_LINK_STATUS, &linkStatus); 748e5c31af7Sopenharmony_ci if (linkStatus != 1) 749e5c31af7Sopenharmony_ci { 750e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 751e5c31af7Sopenharmony_ci } 752e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages failed"); 753e5c31af7Sopenharmony_ci 754e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, progVF.getProgram()); 755e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_VERTEX_SHADER, (glw::GLint*)&progIdV); 756e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_FRAGMENT_SHADER, (glw::GLint*)&progIdF); 757e5c31af7Sopenharmony_ci if ((progIdV != progVF.getProgram()) || (progIdV != progIdF)) 758e5c31af7Sopenharmony_ci { 759e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 760e5c31af7Sopenharmony_ci } 761e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages failed"); 762e5c31af7Sopenharmony_ci 763e5c31af7Sopenharmony_ci // Use a fragment program with vertex bit 764e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, 0); 765e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, programFrag); 766e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages failed"); 767e5c31af7Sopenharmony_ci 768e5c31af7Sopenharmony_ci // Unbound pipeline 769e5c31af7Sopenharmony_ci gl.bindProgramPipeline(0); 770e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, &pipeline); 771e5c31af7Sopenharmony_ci pipeline = 0; 772e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, &pipeline); 773e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, programVtx); 774e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, programFrag); 775e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_VERTEX_SHADER, (glw::GLint*)&progIdV); 776e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_FRAGMENT_SHADER, (glw::GLint*)&progIdF); 777e5c31af7Sopenharmony_ci if ((progIdV != programVtx) || (progIdF != programFrag)) 778e5c31af7Sopenharmony_ci { 779e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 780e5c31af7Sopenharmony_ci } 781e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages failed"); 782e5c31af7Sopenharmony_ci 783e5c31af7Sopenharmony_ci // Negative Cases 784e5c31af7Sopenharmony_ci 785e5c31af7Sopenharmony_ci // Invalid stages 786e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_ALL_SHADER_BITS ^ (GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT), programVtx); 787e5c31af7Sopenharmony_ci err = gl.getError(); 788e5c31af7Sopenharmony_ci if (err != GL_INVALID_VALUE) 789e5c31af7Sopenharmony_ci { 790e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 791e5c31af7Sopenharmony_ci } 792e5c31af7Sopenharmony_ci 793e5c31af7Sopenharmony_ci // Program that is not separable 794e5c31af7Sopenharmony_ci gl.programParameteri(progVF.getProgram(), GL_PROGRAM_SEPARABLE, GL_FALSE); 795e5c31af7Sopenharmony_ci gl.linkProgram(progVF.getProgram()); 796e5c31af7Sopenharmony_ci gl.getProgramiv(progVF.getProgram(), GL_LINK_STATUS, &linkStatus); 797e5c31af7Sopenharmony_ci if (linkStatus != 1) 798e5c31af7Sopenharmony_ci { 799e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 800e5c31af7Sopenharmony_ci } 801e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages failed"); 802e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, progVF.getProgram()); 803e5c31af7Sopenharmony_ci err = gl.getError(); 804e5c31af7Sopenharmony_ci if (err != GL_INVALID_OPERATION) 805e5c31af7Sopenharmony_ci { 806e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 807e5c31af7Sopenharmony_ci } 808e5c31af7Sopenharmony_ci 809e5c31af7Sopenharmony_ci // Program that is not successfully linked 810e5c31af7Sopenharmony_ci // remove the main keyword 811e5c31af7Sopenharmony_ci std::string fragNoMain = frag; 812e5c31af7Sopenharmony_ci unsigned int pos = (unsigned int)fragNoMain.find("main"); 813e5c31af7Sopenharmony_ci fragNoMain.replace(pos, 4, "niaM"); 814e5c31af7Sopenharmony_ci glu::ShaderProgram progNoLink(m_context.getRenderContext(), 815e5c31af7Sopenharmony_ci glu::makeVtxFragSources(vtx.c_str(), fragNoMain.c_str())); 816e5c31af7Sopenharmony_ci 817e5c31af7Sopenharmony_ci gl.programParameteri(progNoLink.getProgram(), GL_PROGRAM_SEPARABLE, GL_TRUE); 818e5c31af7Sopenharmony_ci gl.linkProgram(progNoLink.getProgram()); 819e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, progNoLink.getProgram()); 820e5c31af7Sopenharmony_ci err = gl.getError(); 821e5c31af7Sopenharmony_ci if (err != GL_INVALID_OPERATION) 822e5c31af7Sopenharmony_ci { 823e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 824e5c31af7Sopenharmony_ci } 825e5c31af7Sopenharmony_ci 826e5c31af7Sopenharmony_ci // Invalid pipeline 827e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline + 1000, GL_VERTEX_SHADER_BIT, programVtx); 828e5c31af7Sopenharmony_ci err = gl.getError(); 829e5c31af7Sopenharmony_ci if (err != GL_INVALID_OPERATION) 830e5c31af7Sopenharmony_ci { 831e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 832e5c31af7Sopenharmony_ci } 833e5c31af7Sopenharmony_ci 834e5c31af7Sopenharmony_ci // Invalid pipeline 835e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, &pipeline); 836e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, programVtx); 837e5c31af7Sopenharmony_ci err = gl.getError(); 838e5c31af7Sopenharmony_ci if (err != GL_INVALID_OPERATION) 839e5c31af7Sopenharmony_ci { 840e5c31af7Sopenharmony_ci TCU_FAIL("UseProgramStages failed"); 841e5c31af7Sopenharmony_ci } 842e5c31af7Sopenharmony_ci 843e5c31af7Sopenharmony_ci gl.deleteProgram(programVtx); 844e5c31af7Sopenharmony_ci gl.deleteProgram(programFrag); 845e5c31af7Sopenharmony_ci 846e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 847e5c31af7Sopenharmony_ci return STOP; 848e5c31af7Sopenharmony_ci } 849e5c31af7Sopenharmony_ci 850e5c31af7Sopenharmony_ciprivate: 851e5c31af7Sopenharmony_ci glu::GLSLVersion m_glslVersion; 852e5c31af7Sopenharmony_ci}; 853e5c31af7Sopenharmony_ci 854e5c31af7Sopenharmony_ci// Testcase for pipeline api 855e5c31af7Sopenharmony_ciclass PipelineApiCase : public TestCase 856e5c31af7Sopenharmony_ci{ 857e5c31af7Sopenharmony_cipublic: 858e5c31af7Sopenharmony_ci PipelineApiCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion) 859e5c31af7Sopenharmony_ci : TestCase(context, name, description), m_glslVersion(glslVersion) 860e5c31af7Sopenharmony_ci { 861e5c31af7Sopenharmony_ci } 862e5c31af7Sopenharmony_ci 863e5c31af7Sopenharmony_ci ~PipelineApiCase(void) 864e5c31af7Sopenharmony_ci { 865e5c31af7Sopenharmony_ci } 866e5c31af7Sopenharmony_ci 867e5c31af7Sopenharmony_ci // Validate glGetProgramPipelineInfoLog 868e5c31af7Sopenharmony_ci void checkProgInfoLog(const glw::Functions& gl, GLuint pipeline) 869e5c31af7Sopenharmony_ci { 870e5c31af7Sopenharmony_ci glw::GLint value; 871e5c31af7Sopenharmony_ci glw::GLsizei bufSize; 872e5c31af7Sopenharmony_ci glw::GLsizei length; 873e5c31af7Sopenharmony_ci glw::GLenum err; 874e5c31af7Sopenharmony_ci 875e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_INFO_LOG_LENGTH, &value); 876e5c31af7Sopenharmony_ci std::vector<char> infoLogBuf(value + 1); 877e5c31af7Sopenharmony_ci 878e5c31af7Sopenharmony_ci bufSize = 0; 879e5c31af7Sopenharmony_ci gl.getProgramPipelineInfoLog(pipeline, bufSize, &length, &infoLogBuf[0]); 880e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramPipelineInfoLog failed"); 881e5c31af7Sopenharmony_ci 882e5c31af7Sopenharmony_ci bufSize = value / 2; // read half the log 883e5c31af7Sopenharmony_ci gl.getProgramPipelineInfoLog(pipeline, bufSize, &length, &infoLogBuf[0]); 884e5c31af7Sopenharmony_ci if ((bufSize != 0) && (bufSize != length + 1)) 885e5c31af7Sopenharmony_ci { 886e5c31af7Sopenharmony_ci TCU_FAIL("GetProgramPipelineInfoLog failed"); 887e5c31af7Sopenharmony_ci } 888e5c31af7Sopenharmony_ci bufSize = value; 889e5c31af7Sopenharmony_ci gl.getProgramPipelineInfoLog(pipeline, bufSize, &length, &infoLogBuf[0]); 890e5c31af7Sopenharmony_ci if ((bufSize != 0) && (bufSize != length + 1)) 891e5c31af7Sopenharmony_ci { 892e5c31af7Sopenharmony_ci TCU_FAIL("GetProgramPipelineInfoLog failed"); 893e5c31af7Sopenharmony_ci } 894e5c31af7Sopenharmony_ci 895e5c31af7Sopenharmony_ci // Negative case for GetProgramPipelineInfoLog 896e5c31af7Sopenharmony_ci 897e5c31af7Sopenharmony_ci gl.getProgramPipelineInfoLog(pipeline + 101, bufSize, &length, &infoLogBuf[0]); 898e5c31af7Sopenharmony_ci err = gl.getError(); 899e5c31af7Sopenharmony_ci if (err != GL_INVALID_VALUE) 900e5c31af7Sopenharmony_ci { 901e5c31af7Sopenharmony_ci TCU_FAIL("GetProgramPipelineInfoLog failed"); 902e5c31af7Sopenharmony_ci } 903e5c31af7Sopenharmony_ci } 904e5c31af7Sopenharmony_ci 905e5c31af7Sopenharmony_ci IterateResult iterate(void) 906e5c31af7Sopenharmony_ci { 907e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 908e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 909e5c31af7Sopenharmony_ci glw::GLenum err; 910e5c31af7Sopenharmony_ci const int maxpipelines = 10; 911e5c31af7Sopenharmony_ci glw::GLuint pipelines[maxpipelines]; 912e5c31af7Sopenharmony_ci std::string vtx; 913e5c31af7Sopenharmony_ci std::string frag; 914e5c31af7Sopenharmony_ci glw::GLint linkStatus; 915e5c31af7Sopenharmony_ci glw::GLuint value; 916e5c31af7Sopenharmony_ci 917e5c31af7Sopenharmony_ci vtx = generateBasicVertexSrc(m_glslVersion); 918e5c31af7Sopenharmony_ci frag = generateBasicFragmentSrc(m_glslVersion); 919e5c31af7Sopenharmony_ci 920e5c31af7Sopenharmony_ci // Pipeline API verification 921e5c31af7Sopenharmony_ci log << TestLog::Message << "Begin:PipelineApiCase iterate" << TestLog::EndMessage; 922e5c31af7Sopenharmony_ci 923e5c31af7Sopenharmony_ci glu::ShaderProgram progVF(m_context.getRenderContext(), glu::makeVtxFragSources(vtx.c_str(), frag.c_str())); 924e5c31af7Sopenharmony_ci 925e5c31af7Sopenharmony_ci // Make separable and relink 926e5c31af7Sopenharmony_ci gl.programParameteri(progVF.getProgram(), GL_PROGRAM_SEPARABLE, GL_TRUE); 927e5c31af7Sopenharmony_ci gl.linkProgram(progVF.getProgram()); 928e5c31af7Sopenharmony_ci gl.getProgramiv(progVF.getProgram(), GL_LINK_STATUS, &linkStatus); 929e5c31af7Sopenharmony_ci if (linkStatus != 1) 930e5c31af7Sopenharmony_ci { 931e5c31af7Sopenharmony_ci TCU_FAIL("LinkProgram failed"); 932e5c31af7Sopenharmony_ci } 933e5c31af7Sopenharmony_ci 934e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, pipelines); 935e5c31af7Sopenharmony_ci 936e5c31af7Sopenharmony_ci // ActiveShaderProgram 937e5c31af7Sopenharmony_ci gl.activeShaderProgram(pipelines[0], progVF.getProgram()); 938e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "ActiveShaderProgram failed"); 939e5c31af7Sopenharmony_ci 940e5c31af7Sopenharmony_ci // Negative cases for ActiveShaderProgram 941e5c31af7Sopenharmony_ci 942e5c31af7Sopenharmony_ci // Nonexistent program 943e5c31af7Sopenharmony_ci gl.activeShaderProgram(pipelines[0], progVF.getProgram() + 100); 944e5c31af7Sopenharmony_ci err = gl.getError(); 945e5c31af7Sopenharmony_ci if (err != GL_INVALID_VALUE) 946e5c31af7Sopenharmony_ci { 947e5c31af7Sopenharmony_ci TCU_FAIL("ActiveShaderProgram failed"); 948e5c31af7Sopenharmony_ci } 949e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_ACTIVE_PROGRAM, (glw::GLint*)&value); 950e5c31af7Sopenharmony_ci if (value != progVF.getProgram()) 951e5c31af7Sopenharmony_ci { 952e5c31af7Sopenharmony_ci TCU_FAIL("ActiveShaderProgram failed"); 953e5c31af7Sopenharmony_ci } 954e5c31af7Sopenharmony_ci 955e5c31af7Sopenharmony_ci // Deleted pipeline 956e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, pipelines); 957e5c31af7Sopenharmony_ci gl.activeShaderProgram(pipelines[0], progVF.getProgram()); 958e5c31af7Sopenharmony_ci err = gl.getError(); 959e5c31af7Sopenharmony_ci if (err != GL_INVALID_OPERATION) 960e5c31af7Sopenharmony_ci { 961e5c31af7Sopenharmony_ci TCU_FAIL("ActiveShaderProgram failed"); 962e5c31af7Sopenharmony_ci } 963e5c31af7Sopenharmony_ci 964e5c31af7Sopenharmony_ci // GenProgramPipeline 965e5c31af7Sopenharmony_ci 966e5c31af7Sopenharmony_ci gl.genProgramPipelines(2, &pipelines[0]); 967e5c31af7Sopenharmony_ci gl.genProgramPipelines(3, &pipelines[2]); 968e5c31af7Sopenharmony_ci gl.genProgramPipelines(5, &pipelines[5]); 969e5c31af7Sopenharmony_ci 970e5c31af7Sopenharmony_ci for (int i = 0; i < maxpipelines; i++) 971e5c31af7Sopenharmony_ci { 972e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipelines[i]); // has to be bound to be recognized 973e5c31af7Sopenharmony_ci if (!gl.isProgramPipeline(pipelines[i])) 974e5c31af7Sopenharmony_ci { 975e5c31af7Sopenharmony_ci TCU_FAIL("GenProgramPipelines failed"); 976e5c31af7Sopenharmony_ci } 977e5c31af7Sopenharmony_ci } 978e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(maxpipelines, pipelines); 979e5c31af7Sopenharmony_ci 980e5c31af7Sopenharmony_ci // BindProgramPipeline 981e5c31af7Sopenharmony_ci 982e5c31af7Sopenharmony_ci gl.genProgramPipelines(2, pipelines); 983e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipelines[0]); 984e5c31af7Sopenharmony_ci gl.getIntegerv(GL_PROGRAM_PIPELINE_BINDING, (glw::GLint*)&value); 985e5c31af7Sopenharmony_ci if (value != pipelines[0]) 986e5c31af7Sopenharmony_ci { 987e5c31af7Sopenharmony_ci TCU_FAIL("BindProgramPipeline failed"); 988e5c31af7Sopenharmony_ci } 989e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipelines[1]); 990e5c31af7Sopenharmony_ci gl.getIntegerv(GL_PROGRAM_PIPELINE_BINDING, (glw::GLint*)&value); 991e5c31af7Sopenharmony_ci if (value != pipelines[1]) 992e5c31af7Sopenharmony_ci { 993e5c31af7Sopenharmony_ci TCU_FAIL("BindProgramPipeline failed"); 994e5c31af7Sopenharmony_ci } 995e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "BindProgramPipeline failed"); 996e5c31af7Sopenharmony_ci 997e5c31af7Sopenharmony_ci // Negative Case for BindProgramPipeline 998e5c31af7Sopenharmony_ci 999e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipelines[2]); // deleted pipeline 1000e5c31af7Sopenharmony_ci gl.getIntegerv(GL_PROGRAM_PIPELINE_BINDING, (glw::GLint*)&value); 1001e5c31af7Sopenharmony_ci err = gl.getError(); 1002e5c31af7Sopenharmony_ci if ((err != GL_INVALID_OPERATION) || (value != pipelines[1])) 1003e5c31af7Sopenharmony_ci { 1004e5c31af7Sopenharmony_ci TCU_FAIL("BindProgramPipeline failed"); 1005e5c31af7Sopenharmony_ci } 1006e5c31af7Sopenharmony_ci 1007e5c31af7Sopenharmony_ci // DeleteProgramPipelines 1008e5c31af7Sopenharmony_ci 1009e5c31af7Sopenharmony_ci gl.genProgramPipelines(8, &pipelines[2]); // back to 10 total 1010e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(2, &pipelines[8]); 1011e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(3, &pipelines[5]); 1012e5c31af7Sopenharmony_ci pipelines[9] = 0; 1013e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(maxpipelines, pipelines); // 5 good, 4 deleted, 1 zero 1014e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(0, pipelines); 1015e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DeleteProgramPipelines failed"); 1016e5c31af7Sopenharmony_ci for (int i = 0; i < maxpipelines; i++) 1017e5c31af7Sopenharmony_ci { 1018e5c31af7Sopenharmony_ci if (gl.isProgramPipeline(pipelines[i])) 1019e5c31af7Sopenharmony_ci { 1020e5c31af7Sopenharmony_ci TCU_FAIL("DeleteProgramPipelines failed"); 1021e5c31af7Sopenharmony_ci } 1022e5c31af7Sopenharmony_ci } 1023e5c31af7Sopenharmony_ci gl.getIntegerv(GL_PROGRAM_PIPELINE_BINDING, (glw::GLint*)&value); 1024e5c31af7Sopenharmony_ci if (value != 0) 1025e5c31af7Sopenharmony_ci { 1026e5c31af7Sopenharmony_ci TCU_FAIL("DeleteProgramPipelines failed"); 1027e5c31af7Sopenharmony_ci } 1028e5c31af7Sopenharmony_ci 1029e5c31af7Sopenharmony_ci // IsProgramPipeline 1030e5c31af7Sopenharmony_ci 1031e5c31af7Sopenharmony_ci pipelines[1] = 0x1000; 1032e5c31af7Sopenharmony_ci pipelines[2] += 100; 1033e5c31af7Sopenharmony_ci for (int i = 0; i < 3; i++) 1034e5c31af7Sopenharmony_ci { 1035e5c31af7Sopenharmony_ci // 1 deleted and 2 bogus values 1036e5c31af7Sopenharmony_ci if (gl.isProgramPipeline(pipelines[i])) 1037e5c31af7Sopenharmony_ci { 1038e5c31af7Sopenharmony_ci TCU_FAIL("IsProgramPipeline failed"); 1039e5c31af7Sopenharmony_ci } 1040e5c31af7Sopenharmony_ci } 1041e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, pipelines); 1042e5c31af7Sopenharmony_ci if (gl.isProgramPipeline(pipelines[0])) 1043e5c31af7Sopenharmony_ci { 1044e5c31af7Sopenharmony_ci TCU_FAIL("IsProgramPipeline failed"); 1045e5c31af7Sopenharmony_ci } 1046e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, pipelines); 1047e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "IsProgramPipeline failed"); 1048e5c31af7Sopenharmony_ci 1049e5c31af7Sopenharmony_ci // ProgramParameteri PROGRAM_SEPARABLE 1050e5c31af7Sopenharmony_ci // NOTE: The query for PROGRAM_SEPARABLE must query latched 1051e5c31af7Sopenharmony_ci // state. In other words, the state of the binary after 1052e5c31af7Sopenharmony_ci // it was linked. So in the tests below, the queries 1053e5c31af7Sopenharmony_ci // should return the default state GL_FALSE since the 1054e5c31af7Sopenharmony_ci // program has no linked binary. 1055e5c31af7Sopenharmony_ci 1056e5c31af7Sopenharmony_ci glw::GLuint programSep = gl.createProgram(); 1057e5c31af7Sopenharmony_ci int separable; 1058e5c31af7Sopenharmony_ci gl.programParameteri(programSep, GL_PROGRAM_SEPARABLE, GL_TRUE); 1059e5c31af7Sopenharmony_ci gl.getProgramiv(programSep, GL_PROGRAM_SEPARABLE, &separable); 1060e5c31af7Sopenharmony_ci if (separable != GL_FALSE) 1061e5c31af7Sopenharmony_ci { 1062e5c31af7Sopenharmony_ci TCU_FAIL("programParameteri PROGRAM_SEPARABLE failed"); 1063e5c31af7Sopenharmony_ci } 1064e5c31af7Sopenharmony_ci gl.programParameteri(programSep, GL_PROGRAM_SEPARABLE, GL_FALSE); 1065e5c31af7Sopenharmony_ci gl.getProgramiv(programSep, GL_PROGRAM_SEPARABLE, &separable); 1066e5c31af7Sopenharmony_ci if (separable != 0) 1067e5c31af7Sopenharmony_ci { 1068e5c31af7Sopenharmony_ci TCU_FAIL("programParameteri PROGRAM_SEPARABLE failed"); 1069e5c31af7Sopenharmony_ci } 1070e5c31af7Sopenharmony_ci 1071e5c31af7Sopenharmony_ci // Negative Case for ProgramParameteri PROGRAM_SEPARABLE 1072e5c31af7Sopenharmony_ci 1073e5c31af7Sopenharmony_ci gl.deleteProgram(programSep); 1074e5c31af7Sopenharmony_ci gl.programParameteri(programSep, GL_PROGRAM_SEPARABLE, GL_TRUE); 1075e5c31af7Sopenharmony_ci err = gl.getError(); 1076e5c31af7Sopenharmony_ci if (err != GL_INVALID_VALUE) 1077e5c31af7Sopenharmony_ci { 1078e5c31af7Sopenharmony_ci TCU_FAIL("programParameteri PROGRAM_SEPARABLE failed"); 1079e5c31af7Sopenharmony_ci } 1080e5c31af7Sopenharmony_ci gl.programParameteri(progVF.getProgram(), GL_PROGRAM_SEPARABLE, 501); 1081e5c31af7Sopenharmony_ci err = gl.getError(); 1082e5c31af7Sopenharmony_ci if (err != GL_INVALID_VALUE) 1083e5c31af7Sopenharmony_ci { 1084e5c31af7Sopenharmony_ci TCU_FAIL("programParameteri PROGRAM_SEPARABLE failed"); 1085e5c31af7Sopenharmony_ci } 1086e5c31af7Sopenharmony_ci 1087e5c31af7Sopenharmony_ci // GetProgramPipelineiv 1088e5c31af7Sopenharmony_ci 1089e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, pipelines); 1090e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_ACTIVE_PROGRAM, (glw::GLint*)&value); 1091e5c31af7Sopenharmony_ci if (value != 0) 1092e5c31af7Sopenharmony_ci { 1093e5c31af7Sopenharmony_ci TCU_FAIL("GetProgramPipelineiv failed for ACTIVE_PROGRAM"); 1094e5c31af7Sopenharmony_ci } 1095e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_VERTEX_SHADER, (glw::GLint*)&value); 1096e5c31af7Sopenharmony_ci if (value != 0) 1097e5c31af7Sopenharmony_ci { 1098e5c31af7Sopenharmony_ci TCU_FAIL("GetProgramPipelineiv failed for VERTEX_SHADER"); 1099e5c31af7Sopenharmony_ci } 1100e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_FRAGMENT_SHADER, (glw::GLint*)&value); 1101e5c31af7Sopenharmony_ci if (value != 0) 1102e5c31af7Sopenharmony_ci { 1103e5c31af7Sopenharmony_ci TCU_FAIL("GetProgramPipelineiv failed for FRAGMENT_SHADER"); 1104e5c31af7Sopenharmony_ci } 1105e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_VALIDATE_STATUS, (glw::GLint*)&value); 1106e5c31af7Sopenharmony_ci if (value != 0) 1107e5c31af7Sopenharmony_ci { 1108e5c31af7Sopenharmony_ci TCU_FAIL("GetProgramPipelineiv failed for VALIDATE_STATUS"); 1109e5c31af7Sopenharmony_ci } 1110e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_INFO_LOG_LENGTH, (glw::GLint*)&value); 1111e5c31af7Sopenharmony_ci if (value != 0) 1112e5c31af7Sopenharmony_ci { 1113e5c31af7Sopenharmony_ci TCU_FAIL("GetProgramPipelineiv failed for INFO_LOG_LENGTH"); 1114e5c31af7Sopenharmony_ci } 1115e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramPipelineiv failed"); 1116e5c31af7Sopenharmony_ci 1117e5c31af7Sopenharmony_ci // Negative Case for GetProgramPipelineiv 1118e5c31af7Sopenharmony_ci 1119e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, pipelines); 1120e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_ACTIVE_PROGRAM, (glw::GLint*)&value); 1121e5c31af7Sopenharmony_ci err = gl.getError(); 1122e5c31af7Sopenharmony_ci if (err != GL_INVALID_OPERATION) 1123e5c31af7Sopenharmony_ci { 1124e5c31af7Sopenharmony_ci TCU_FAIL("GetProgramPipelineiv failed for ACTIVE_PROGRAM"); 1125e5c31af7Sopenharmony_ci } 1126e5c31af7Sopenharmony_ci 1127e5c31af7Sopenharmony_ci // ValidateProgramPipeline 1128e5c31af7Sopenharmony_ci 1129e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, pipelines); // Unvalidated 1130e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_VALIDATE_STATUS, (glw::GLint*)&value); 1131e5c31af7Sopenharmony_ci if (value != 0) 1132e5c31af7Sopenharmony_ci { 1133e5c31af7Sopenharmony_ci TCU_FAIL("ValidateProgramPipeline failed"); 1134e5c31af7Sopenharmony_ci } 1135e5c31af7Sopenharmony_ci 1136e5c31af7Sopenharmony_ci gl.validateProgramPipeline(pipelines[0]); // Not bound yet 1137e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_VALIDATE_STATUS, (glw::GLint*)&value); 1138e5c31af7Sopenharmony_ci if (value != 0) 1139e5c31af7Sopenharmony_ci { 1140e5c31af7Sopenharmony_ci TCU_FAIL("ValidateProgramPipeline failed"); 1141e5c31af7Sopenharmony_ci } 1142e5c31af7Sopenharmony_ci 1143e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipelines[0]); 1144e5c31af7Sopenharmony_ci 1145e5c31af7Sopenharmony_ci gl.validateProgramPipeline(pipelines[0]); // Still empty program pipeline. 1146e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_VALIDATE_STATUS, (glw::GLint*)&value); 1147e5c31af7Sopenharmony_ci if (value != 0) 1148e5c31af7Sopenharmony_ci { 1149e5c31af7Sopenharmony_ci TCU_FAIL("ValidateProgramPipeline failed with empty program pipeline"); 1150e5c31af7Sopenharmony_ci } 1151e5c31af7Sopenharmony_ci 1152e5c31af7Sopenharmony_ci gl.useProgramStages(pipelines[0], GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, progVF.getProgram()); 1153e5c31af7Sopenharmony_ci gl.validateProgramPipeline(pipelines[0]); 1154e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_VALIDATE_STATUS, (glw::GLint*)&value); 1155e5c31af7Sopenharmony_ci if (value != 1) 1156e5c31af7Sopenharmony_ci { 1157e5c31af7Sopenharmony_ci TCU_FAIL("ValidateProgramPipeline failed"); 1158e5c31af7Sopenharmony_ci } 1159e5c31af7Sopenharmony_ci 1160e5c31af7Sopenharmony_ci // GetProgramPipelineInfoLog 1161e5c31af7Sopenharmony_ci checkProgInfoLog(gl, pipelines[0]); 1162e5c31af7Sopenharmony_ci 1163e5c31af7Sopenharmony_ci // ValidateProgramPipeline additional 1164e5c31af7Sopenharmony_ci // Relink the bound separable program as not separable 1165e5c31af7Sopenharmony_ci gl.programParameteri(progVF.getProgram(), GL_PROGRAM_SEPARABLE, GL_FALSE); 1166e5c31af7Sopenharmony_ci gl.linkProgram(progVF.getProgram()); 1167e5c31af7Sopenharmony_ci err = gl.getError(); 1168e5c31af7Sopenharmony_ci gl.validateProgramPipeline(pipelines[0]); 1169e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipelines[0], GL_VALIDATE_STATUS, (glw::GLint*)&value); 1170e5c31af7Sopenharmony_ci if (value != 0) 1171e5c31af7Sopenharmony_ci { 1172e5c31af7Sopenharmony_ci TCU_FAIL("ValidateProgramPipeline failed"); 1173e5c31af7Sopenharmony_ci } 1174e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "ValidateProgramPipeline failed"); 1175e5c31af7Sopenharmony_ci 1176e5c31af7Sopenharmony_ci // GetProgramPipelineInfoLog 1177e5c31af7Sopenharmony_ci checkProgInfoLog(gl, pipelines[0]); 1178e5c31af7Sopenharmony_ci 1179e5c31af7Sopenharmony_ci // Negative Case for ValidateProgramPipeline 1180e5c31af7Sopenharmony_ci 1181e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, pipelines); 1182e5c31af7Sopenharmony_ci gl.validateProgramPipeline(pipelines[0]); 1183e5c31af7Sopenharmony_ci err = gl.getError(); 1184e5c31af7Sopenharmony_ci if (err != GL_INVALID_OPERATION) 1185e5c31af7Sopenharmony_ci { 1186e5c31af7Sopenharmony_ci TCU_FAIL("ValidateProgramPipeline failed"); 1187e5c31af7Sopenharmony_ci } 1188e5c31af7Sopenharmony_ci 1189e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1190e5c31af7Sopenharmony_ci return STOP; 1191e5c31af7Sopenharmony_ci } 1192e5c31af7Sopenharmony_ci 1193e5c31af7Sopenharmony_ciprivate: 1194e5c31af7Sopenharmony_ci glu::GLSLVersion m_glslVersion; 1195e5c31af7Sopenharmony_ci}; 1196e5c31af7Sopenharmony_ci 1197e5c31af7Sopenharmony_ci// Testcase for glProgramUniform 1198e5c31af7Sopenharmony_ciclass ProgramUniformCase : public TestCase 1199e5c31af7Sopenharmony_ci{ 1200e5c31af7Sopenharmony_cipublic: 1201e5c31af7Sopenharmony_ci ProgramUniformCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion) 1202e5c31af7Sopenharmony_ci : TestCase(context, name, description), m_glslVersion(glslVersion) 1203e5c31af7Sopenharmony_ci { 1204e5c31af7Sopenharmony_ci } 1205e5c31af7Sopenharmony_ci 1206e5c31af7Sopenharmony_ci ~ProgramUniformCase(void) 1207e5c31af7Sopenharmony_ci { 1208e5c31af7Sopenharmony_ci } 1209e5c31af7Sopenharmony_ci 1210e5c31af7Sopenharmony_ci bool isDataTypeSquareMatrix(glu::DataType dtyp) 1211e5c31af7Sopenharmony_ci { 1212e5c31af7Sopenharmony_ci return (dtyp == glu::TYPE_FLOAT_MAT2) || (dtyp == glu::TYPE_FLOAT_MAT3) || (dtyp == glu::TYPE_FLOAT_MAT4); 1213e5c31af7Sopenharmony_ci } 1214e5c31af7Sopenharmony_ci 1215e5c31af7Sopenharmony_ci // outFragSrc will hold a fragment program that is DataType specific 1216e5c31af7Sopenharmony_ci void generateUniformFragSrc(std::string& outFragSrc, glu::GLSLVersion glslVersion, glu::DataType dType) 1217e5c31af7Sopenharmony_ci { 1218e5c31af7Sopenharmony_ci std::ostringstream fragSrc; 1219e5c31af7Sopenharmony_ci 1220e5c31af7Sopenharmony_ci fragSrc << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 1221e5c31af7Sopenharmony_ci if (isDataTypeMatrix(dType) && isDataTypeSquareMatrix(dType)) 1222e5c31af7Sopenharmony_ci { 1223e5c31af7Sopenharmony_ci fragSrc << s_unifFragSquareMatShaderSrc; 1224e5c31af7Sopenharmony_ci } 1225e5c31af7Sopenharmony_ci else if (isDataTypeMatrix(dType) && !isDataTypeSquareMatrix(dType)) 1226e5c31af7Sopenharmony_ci { 1227e5c31af7Sopenharmony_ci fragSrc << s_unifFragNonSquareMatShaderSrc; 1228e5c31af7Sopenharmony_ci } 1229e5c31af7Sopenharmony_ci else 1230e5c31af7Sopenharmony_ci { 1231e5c31af7Sopenharmony_ci fragSrc << s_unifFragShaderSrc; 1232e5c31af7Sopenharmony_ci } 1233e5c31af7Sopenharmony_ci 1234e5c31af7Sopenharmony_ci std::map<std::string, std::string> params; 1235e5c31af7Sopenharmony_ci 1236e5c31af7Sopenharmony_ci if (dType == glu::TYPE_INT) 1237e5c31af7Sopenharmony_ci { 1238e5c31af7Sopenharmony_ci params.insert(std::pair<std::string, std::string>("SCALAR_TYPE", "int")); 1239e5c31af7Sopenharmony_ci params.insert(std::pair<std::string, std::string>("VECTOR_TYPE", "ivec")); 1240e5c31af7Sopenharmony_ci params.insert(std::pair<std::string, std::string>("SFX", "")); 1241e5c31af7Sopenharmony_ci } 1242e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_UINT) 1243e5c31af7Sopenharmony_ci { 1244e5c31af7Sopenharmony_ci params.insert(std::pair<std::string, std::string>("SCALAR_TYPE", "uint")); 1245e5c31af7Sopenharmony_ci params.insert(std::pair<std::string, std::string>("VECTOR_TYPE", "uvec")); 1246e5c31af7Sopenharmony_ci params.insert(std::pair<std::string, std::string>("SFX", "u")); 1247e5c31af7Sopenharmony_ci } 1248e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_FLOAT) 1249e5c31af7Sopenharmony_ci { 1250e5c31af7Sopenharmony_ci params.insert(std::pair<std::string, std::string>("SCALAR_TYPE", "float")); 1251e5c31af7Sopenharmony_ci params.insert(std::pair<std::string, std::string>("VECTOR_TYPE", "vec")); 1252e5c31af7Sopenharmony_ci params.insert(std::pair<std::string, std::string>("SFX", ".0")); 1253e5c31af7Sopenharmony_ci } 1254e5c31af7Sopenharmony_ci 1255e5c31af7Sopenharmony_ci tcu::StringTemplate fragTmpl(fragSrc.str().c_str()); 1256e5c31af7Sopenharmony_ci outFragSrc = fragTmpl.specialize(params); 1257e5c31af7Sopenharmony_ci } 1258e5c31af7Sopenharmony_ci 1259e5c31af7Sopenharmony_ci // Set the integer programUniforms 1260e5c31af7Sopenharmony_ci void progUniformi(const glw::Functions& gl, glw::GLuint prog, int arraySize, int* location, int* value) 1261e5c31af7Sopenharmony_ci { 1262e5c31af7Sopenharmony_ci gl.programUniform1i(prog, location[0], value[0]); 1263e5c31af7Sopenharmony_ci value += 1; 1264e5c31af7Sopenharmony_ci gl.programUniform2i(prog, location[1], value[0], value[1]); 1265e5c31af7Sopenharmony_ci value += 2; 1266e5c31af7Sopenharmony_ci gl.programUniform3i(prog, location[2], value[0], value[1], value[2]); 1267e5c31af7Sopenharmony_ci value += 3; 1268e5c31af7Sopenharmony_ci gl.programUniform4i(prog, location[3], value[0], value[1], value[2], value[3]); 1269e5c31af7Sopenharmony_ci value += 4; 1270e5c31af7Sopenharmony_ci 1271e5c31af7Sopenharmony_ci gl.programUniform1iv(prog, location[4], arraySize, value); 1272e5c31af7Sopenharmony_ci value += 1 * arraySize; 1273e5c31af7Sopenharmony_ci gl.programUniform2iv(prog, location[6], arraySize, value); 1274e5c31af7Sopenharmony_ci value += 2 * arraySize; 1275e5c31af7Sopenharmony_ci gl.programUniform3iv(prog, location[8], arraySize, value); 1276e5c31af7Sopenharmony_ci value += 3 * arraySize; 1277e5c31af7Sopenharmony_ci gl.programUniform4iv(prog, location[10], arraySize, value); 1278e5c31af7Sopenharmony_ci } 1279e5c31af7Sopenharmony_ci 1280e5c31af7Sopenharmony_ci // Set the unsigned integer programUniforms 1281e5c31af7Sopenharmony_ci void progUniformui(const glw::Functions& gl, glw::GLuint prog, int arraySize, int* location, unsigned int* value) 1282e5c31af7Sopenharmony_ci { 1283e5c31af7Sopenharmony_ci gl.programUniform1ui(prog, location[0], value[0]); 1284e5c31af7Sopenharmony_ci value += 1; 1285e5c31af7Sopenharmony_ci gl.programUniform2ui(prog, location[1], value[0], value[1]); 1286e5c31af7Sopenharmony_ci value += 2; 1287e5c31af7Sopenharmony_ci gl.programUniform3ui(prog, location[2], value[0], value[1], value[2]); 1288e5c31af7Sopenharmony_ci value += 3; 1289e5c31af7Sopenharmony_ci gl.programUniform4ui(prog, location[3], value[0], value[1], value[2], value[3]); 1290e5c31af7Sopenharmony_ci value += 4; 1291e5c31af7Sopenharmony_ci 1292e5c31af7Sopenharmony_ci gl.programUniform1uiv(prog, location[4], arraySize, value); 1293e5c31af7Sopenharmony_ci value += 1 * arraySize; 1294e5c31af7Sopenharmony_ci gl.programUniform2uiv(prog, location[6], arraySize, value); 1295e5c31af7Sopenharmony_ci value += 2 * arraySize; 1296e5c31af7Sopenharmony_ci gl.programUniform3uiv(prog, location[8], arraySize, value); 1297e5c31af7Sopenharmony_ci value += 3 * arraySize; 1298e5c31af7Sopenharmony_ci gl.programUniform4uiv(prog, location[10], arraySize, value); 1299e5c31af7Sopenharmony_ci } 1300e5c31af7Sopenharmony_ci 1301e5c31af7Sopenharmony_ci // Set the float programUniforms 1302e5c31af7Sopenharmony_ci void progUniformf(const glw::Functions& gl, glw::GLuint prog, int arraySize, int* location, float* value) 1303e5c31af7Sopenharmony_ci { 1304e5c31af7Sopenharmony_ci gl.programUniform1f(prog, location[0], value[0]); 1305e5c31af7Sopenharmony_ci value += 1; 1306e5c31af7Sopenharmony_ci gl.programUniform2f(prog, location[1], value[0], value[1]); 1307e5c31af7Sopenharmony_ci value += 2; 1308e5c31af7Sopenharmony_ci gl.programUniform3f(prog, location[2], value[0], value[1], value[2]); 1309e5c31af7Sopenharmony_ci value += 3; 1310e5c31af7Sopenharmony_ci gl.programUniform4f(prog, location[3], value[0], value[1], value[2], value[3]); 1311e5c31af7Sopenharmony_ci value += 4; 1312e5c31af7Sopenharmony_ci 1313e5c31af7Sopenharmony_ci gl.programUniform1fv(prog, location[4], arraySize, value); 1314e5c31af7Sopenharmony_ci value += 1 * arraySize; 1315e5c31af7Sopenharmony_ci gl.programUniform2fv(prog, location[6], arraySize, value); 1316e5c31af7Sopenharmony_ci value += 2 * arraySize; 1317e5c31af7Sopenharmony_ci gl.programUniform3fv(prog, location[8], arraySize, value); 1318e5c31af7Sopenharmony_ci value += 3 * arraySize; 1319e5c31af7Sopenharmony_ci gl.programUniform4fv(prog, location[10], arraySize, value); 1320e5c31af7Sopenharmony_ci } 1321e5c31af7Sopenharmony_ci 1322e5c31af7Sopenharmony_ci // Set the integer uniforms with conventional glUniformi 1323e5c31af7Sopenharmony_ci void activeUniformi(const glw::Functions& gl, int arraySize, int* location, int* value) 1324e5c31af7Sopenharmony_ci { 1325e5c31af7Sopenharmony_ci gl.uniform1i(location[0], value[0]); 1326e5c31af7Sopenharmony_ci value += 1; 1327e5c31af7Sopenharmony_ci gl.uniform2i(location[1], value[0], value[1]); 1328e5c31af7Sopenharmony_ci value += 2; 1329e5c31af7Sopenharmony_ci gl.uniform3i(location[2], value[0], value[1], value[2]); 1330e5c31af7Sopenharmony_ci value += 3; 1331e5c31af7Sopenharmony_ci gl.uniform4i(location[3], value[0], value[1], value[2], value[3]); 1332e5c31af7Sopenharmony_ci value += 4; 1333e5c31af7Sopenharmony_ci 1334e5c31af7Sopenharmony_ci gl.uniform1iv(location[4], arraySize, value); 1335e5c31af7Sopenharmony_ci value += 1 * arraySize; 1336e5c31af7Sopenharmony_ci gl.uniform2iv(location[6], arraySize, value); 1337e5c31af7Sopenharmony_ci value += 2 * arraySize; 1338e5c31af7Sopenharmony_ci gl.uniform3iv(location[8], arraySize, value); 1339e5c31af7Sopenharmony_ci value += 3 * arraySize; 1340e5c31af7Sopenharmony_ci gl.uniform4iv(location[10], arraySize, value); 1341e5c31af7Sopenharmony_ci } 1342e5c31af7Sopenharmony_ci 1343e5c31af7Sopenharmony_ci // Set the unsigned integer uniforms with conventional glUniformui 1344e5c31af7Sopenharmony_ci void activeUniformui(const glw::Functions& gl, int arraySize, int* location, unsigned int* value) 1345e5c31af7Sopenharmony_ci { 1346e5c31af7Sopenharmony_ci gl.uniform1ui(location[0], value[0]); 1347e5c31af7Sopenharmony_ci value += 1; 1348e5c31af7Sopenharmony_ci gl.uniform2ui(location[1], value[0], value[1]); 1349e5c31af7Sopenharmony_ci value += 2; 1350e5c31af7Sopenharmony_ci gl.uniform3ui(location[2], value[0], value[1], value[2]); 1351e5c31af7Sopenharmony_ci value += 3; 1352e5c31af7Sopenharmony_ci gl.uniform4ui(location[3], value[0], value[1], value[2], value[3]); 1353e5c31af7Sopenharmony_ci value += 4; 1354e5c31af7Sopenharmony_ci 1355e5c31af7Sopenharmony_ci gl.uniform1uiv(location[4], arraySize, value); 1356e5c31af7Sopenharmony_ci value += 1 * arraySize; 1357e5c31af7Sopenharmony_ci gl.uniform2uiv(location[6], arraySize, value); 1358e5c31af7Sopenharmony_ci value += 2 * arraySize; 1359e5c31af7Sopenharmony_ci gl.uniform3uiv(location[8], arraySize, value); 1360e5c31af7Sopenharmony_ci value += 3 * arraySize; 1361e5c31af7Sopenharmony_ci gl.uniform4uiv(location[10], arraySize, value); 1362e5c31af7Sopenharmony_ci } 1363e5c31af7Sopenharmony_ci 1364e5c31af7Sopenharmony_ci // Set the float uniforms with conventional glUniformui 1365e5c31af7Sopenharmony_ci void activeUniformf(const glw::Functions& gl, int arraySize, int* location, float* value) 1366e5c31af7Sopenharmony_ci { 1367e5c31af7Sopenharmony_ci gl.uniform1f(location[0], value[0]); 1368e5c31af7Sopenharmony_ci value += 1; 1369e5c31af7Sopenharmony_ci gl.uniform2f(location[1], value[0], value[1]); 1370e5c31af7Sopenharmony_ci value += 2; 1371e5c31af7Sopenharmony_ci gl.uniform3f(location[2], value[0], value[1], value[2]); 1372e5c31af7Sopenharmony_ci value += 3; 1373e5c31af7Sopenharmony_ci gl.uniform4f(location[3], value[0], value[1], value[2], value[3]); 1374e5c31af7Sopenharmony_ci value += 4; 1375e5c31af7Sopenharmony_ci 1376e5c31af7Sopenharmony_ci gl.uniform1fv(location[4], arraySize, value); 1377e5c31af7Sopenharmony_ci value += 1 * arraySize; 1378e5c31af7Sopenharmony_ci gl.uniform2fv(location[6], arraySize, value); 1379e5c31af7Sopenharmony_ci value += 2 * arraySize; 1380e5c31af7Sopenharmony_ci gl.uniform3fv(location[8], arraySize, value); 1381e5c31af7Sopenharmony_ci value += 3 * arraySize; 1382e5c31af7Sopenharmony_ci gl.uniform4fv(location[10], arraySize, value); 1383e5c31af7Sopenharmony_ci } 1384e5c31af7Sopenharmony_ci 1385e5c31af7Sopenharmony_ci // Call programUniform and verify for non-Matrix uniforms 1386e5c31af7Sopenharmony_ci // Two programs are verified independently and against each other 1387e5c31af7Sopenharmony_ci bool setAndCompareUniforms(glw::GLuint pipeline, glw::GLuint programA, glw::GLuint programB, glu::DataType dType, 1388e5c31af7Sopenharmony_ci int seed) 1389e5c31af7Sopenharmony_ci { 1390e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 1391e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1392e5c31af7Sopenharmony_ci // The fragment shader has defined uniforms of type: 1393e5c31af7Sopenharmony_ci // scalar, vec2, vec3, vec4, and then length 2 arrays of 1394e5c31af7Sopenharmony_ci // scalar, vec2, vec3, and vec4. 1395e5c31af7Sopenharmony_ci // 4 uniforms in array form and 4 not in arrays. 1396e5c31af7Sopenharmony_ci // We query a total of 12 uniform locations 1397e5c31af7Sopenharmony_ci const int nonarrayUnifCount = 4; 1398e5c31af7Sopenharmony_ci const int arrayUnifCount = 4; 1399e5c31af7Sopenharmony_ci const int arraySize = 2; 1400e5c31af7Sopenharmony_ci const int locationCount = nonarrayUnifCount + arraySize * arrayUnifCount; 1401e5c31af7Sopenharmony_ci // dwordCount represents the number of dwords to compare for each uniform location 1402e5c31af7Sopenharmony_ci // scalar, vec2, vec3, vec4, scalar[0], scalar[1], vec2[0], vec2[1], etc. 1403e5c31af7Sopenharmony_ci const int dwordCount[locationCount] = { 1, 2, 3, 4, 1, 1, 2, 2, 3, 3, 4, 4 }; 1404e5c31af7Sopenharmony_ci glw::GLint locationA[locationCount]; 1405e5c31af7Sopenharmony_ci glw::GLint locationB[locationCount]; 1406e5c31af7Sopenharmony_ci // The total amount of data the uniforms take up: 1+2+3+4 + 2*(1+2+3+4) 1407e5c31af7Sopenharmony_ci const int udataCount = 30; 1408e5c31af7Sopenharmony_ci unsigned int udata[udataCount]; // 1409e5c31af7Sopenharmony_ci int* data = (int*)&udata[0]; 1410e5c31af7Sopenharmony_ci float* fdata = (float*)&udata[0]; 1411e5c31af7Sopenharmony_ci int i, j, k; 1412e5c31af7Sopenharmony_ci std::string uniformBaseName("uVal"); 1413e5c31af7Sopenharmony_ci 1414e5c31af7Sopenharmony_ci // ProgramUniform API verification 1415e5c31af7Sopenharmony_ci log << TestLog::Message << "Begin:ProgramUniformCase iterate" << TestLog::EndMessage; 1416e5c31af7Sopenharmony_ci 1417e5c31af7Sopenharmony_ci // get uniform locations 1418e5c31af7Sopenharmony_ci // scalar and vec uniforms 1419e5c31af7Sopenharmony_ci for (i = 0; i < nonarrayUnifCount; i++) 1420e5c31af7Sopenharmony_ci { 1421e5c31af7Sopenharmony_ci string name = uniformBaseName + de::toString(i); 1422e5c31af7Sopenharmony_ci locationA[i] = gl.getUniformLocation(programA, name.c_str()); 1423e5c31af7Sopenharmony_ci locationB[i] = gl.getUniformLocation(programB, name.c_str()); 1424e5c31af7Sopenharmony_ci } 1425e5c31af7Sopenharmony_ci // uniform arrays 1426e5c31af7Sopenharmony_ci for (j = 0; j < arrayUnifCount; j++) 1427e5c31af7Sopenharmony_ci { 1428e5c31af7Sopenharmony_ci for (k = 0; k < arraySize; k++) 1429e5c31af7Sopenharmony_ci { 1430e5c31af7Sopenharmony_ci string name = uniformBaseName + de::toString(nonarrayUnifCount + j) + "[" + de::toString(k) + "]"; 1431e5c31af7Sopenharmony_ci locationA[i] = gl.getUniformLocation(programA, name.c_str()); 1432e5c31af7Sopenharmony_ci locationB[i] = gl.getUniformLocation(programB, name.c_str()); 1433e5c31af7Sopenharmony_ci i++; 1434e5c31af7Sopenharmony_ci } 1435e5c31af7Sopenharmony_ci } 1436e5c31af7Sopenharmony_ci 1437e5c31af7Sopenharmony_ci // seed data buffer with unique values 1438e5c31af7Sopenharmony_ci if (dType == glu::TYPE_FLOAT) 1439e5c31af7Sopenharmony_ci { 1440e5c31af7Sopenharmony_ci for (i = 0; i < udataCount; i++) 1441e5c31af7Sopenharmony_ci { 1442e5c31af7Sopenharmony_ci fdata[i] = (float)(seed + i); 1443e5c31af7Sopenharmony_ci } 1444e5c31af7Sopenharmony_ci } 1445e5c31af7Sopenharmony_ci else 1446e5c31af7Sopenharmony_ci { 1447e5c31af7Sopenharmony_ci for (i = 0; i < udataCount; i++) 1448e5c31af7Sopenharmony_ci { 1449e5c31af7Sopenharmony_ci data[i] = seed + i; 1450e5c31af7Sopenharmony_ci } 1451e5c31af7Sopenharmony_ci } 1452e5c31af7Sopenharmony_ci 1453e5c31af7Sopenharmony_ci // set uniforms in program A 1454e5c31af7Sopenharmony_ci if (dType == glu::TYPE_INT) 1455e5c31af7Sopenharmony_ci { 1456e5c31af7Sopenharmony_ci progUniformi(gl, programA, arraySize, locationA, data); 1457e5c31af7Sopenharmony_ci } 1458e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_UINT) 1459e5c31af7Sopenharmony_ci { 1460e5c31af7Sopenharmony_ci progUniformui(gl, programA, arraySize, locationA, udata); 1461e5c31af7Sopenharmony_ci } 1462e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_FLOAT) 1463e5c31af7Sopenharmony_ci { 1464e5c31af7Sopenharmony_ci progUniformf(gl, programA, arraySize, locationA, fdata); 1465e5c31af7Sopenharmony_ci } 1466e5c31af7Sopenharmony_ci 1467e5c31af7Sopenharmony_ci // get and compare uniforms 1468e5c31af7Sopenharmony_ci unsigned int* uValue = &udata[0]; 1469e5c31af7Sopenharmony_ci for (i = 0; i < nonarrayUnifCount + arraySize * arrayUnifCount; i++) 1470e5c31af7Sopenharmony_ci { 1471e5c31af7Sopenharmony_ci unsigned int retValA[4], retValB[4]; 1472e5c31af7Sopenharmony_ci 1473e5c31af7Sopenharmony_ci if (dType == glu::TYPE_INT) 1474e5c31af7Sopenharmony_ci { 1475e5c31af7Sopenharmony_ci gl.getUniformiv(programA, locationA[i], (int*)&retValA[0]); 1476e5c31af7Sopenharmony_ci gl.getUniformiv(programB, locationB[i], (int*)&retValB[0]); 1477e5c31af7Sopenharmony_ci } 1478e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_UINT) 1479e5c31af7Sopenharmony_ci { 1480e5c31af7Sopenharmony_ci gl.getUniformuiv(programA, locationA[i], &retValA[0]); 1481e5c31af7Sopenharmony_ci gl.getUniformuiv(programB, locationB[i], &retValB[0]); 1482e5c31af7Sopenharmony_ci } 1483e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_FLOAT) 1484e5c31af7Sopenharmony_ci { 1485e5c31af7Sopenharmony_ci gl.getUniformfv(programA, locationA[i], (float*)&retValA[0]); 1486e5c31af7Sopenharmony_ci gl.getUniformfv(programB, locationB[i], (float*)&retValB[0]); 1487e5c31af7Sopenharmony_ci } 1488e5c31af7Sopenharmony_ci 1489e5c31af7Sopenharmony_ci for (j = 0; j < dwordCount[i]; j++) 1490e5c31af7Sopenharmony_ci { 1491e5c31af7Sopenharmony_ci // Compare programA uniform to expected value and 1492e5c31af7Sopenharmony_ci // test to see if programB picked up the value. 1493e5c31af7Sopenharmony_ci if ((retValA[j] != *uValue++) || (retValA[j] == retValB[j])) 1494e5c31af7Sopenharmony_ci { 1495e5c31af7Sopenharmony_ci TCU_FAIL("ProgramUniformi failed"); 1496e5c31af7Sopenharmony_ci } 1497e5c31af7Sopenharmony_ci } 1498e5c31af7Sopenharmony_ci } 1499e5c31af7Sopenharmony_ci 1500e5c31af7Sopenharmony_ci // reseed data buffer, continuing to increment 1501e5c31af7Sopenharmony_ci if (dType == glu::TYPE_FLOAT) 1502e5c31af7Sopenharmony_ci { 1503e5c31af7Sopenharmony_ci fdata[0] = fdata[udataCount - 1] + 1.0f; 1504e5c31af7Sopenharmony_ci for (i = 1; i < udataCount; i++) 1505e5c31af7Sopenharmony_ci { 1506e5c31af7Sopenharmony_ci fdata[i] = fdata[i - 1] + 1.0f; 1507e5c31af7Sopenharmony_ci } 1508e5c31af7Sopenharmony_ci } 1509e5c31af7Sopenharmony_ci else 1510e5c31af7Sopenharmony_ci { 1511e5c31af7Sopenharmony_ci data[0] = data[udataCount - 1] + 1; 1512e5c31af7Sopenharmony_ci for (i = 1; i < udataCount; i++) 1513e5c31af7Sopenharmony_ci { 1514e5c31af7Sopenharmony_ci data[i] = data[i - 1] + 1; 1515e5c31af7Sopenharmony_ci } 1516e5c31af7Sopenharmony_ci } 1517e5c31af7Sopenharmony_ci 1518e5c31af7Sopenharmony_ci // set uniforms in program B 1519e5c31af7Sopenharmony_ci 1520e5c31af7Sopenharmony_ci if (dType == glu::TYPE_INT) 1521e5c31af7Sopenharmony_ci { 1522e5c31af7Sopenharmony_ci progUniformi(gl, programB, arraySize, locationB, data); 1523e5c31af7Sopenharmony_ci } 1524e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_UINT) 1525e5c31af7Sopenharmony_ci { 1526e5c31af7Sopenharmony_ci progUniformui(gl, programB, arraySize, locationB, udata); 1527e5c31af7Sopenharmony_ci } 1528e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_FLOAT) 1529e5c31af7Sopenharmony_ci { 1530e5c31af7Sopenharmony_ci progUniformf(gl, programB, arraySize, locationB, fdata); 1531e5c31af7Sopenharmony_ci } 1532e5c31af7Sopenharmony_ci 1533e5c31af7Sopenharmony_ci // get and compare uniforms 1534e5c31af7Sopenharmony_ci uValue = &udata[0]; 1535e5c31af7Sopenharmony_ci for (i = 0; i < nonarrayUnifCount + arraySize * arrayUnifCount; i++) 1536e5c31af7Sopenharmony_ci { 1537e5c31af7Sopenharmony_ci unsigned int retValA[4], retValB[4]; 1538e5c31af7Sopenharmony_ci 1539e5c31af7Sopenharmony_ci if (dType == glu::TYPE_INT) 1540e5c31af7Sopenharmony_ci { 1541e5c31af7Sopenharmony_ci gl.getUniformiv(programA, locationA[i], (int*)&retValA[0]); 1542e5c31af7Sopenharmony_ci gl.getUniformiv(programB, locationB[i], (int*)&retValB[0]); 1543e5c31af7Sopenharmony_ci } 1544e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_UINT) 1545e5c31af7Sopenharmony_ci { 1546e5c31af7Sopenharmony_ci gl.getUniformuiv(programA, locationA[i], &retValA[0]); 1547e5c31af7Sopenharmony_ci gl.getUniformuiv(programB, locationB[i], &retValB[0]); 1548e5c31af7Sopenharmony_ci } 1549e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_FLOAT) 1550e5c31af7Sopenharmony_ci { 1551e5c31af7Sopenharmony_ci gl.getUniformfv(programA, locationA[i], (float*)&retValA[0]); 1552e5c31af7Sopenharmony_ci gl.getUniformfv(programB, locationB[i], (float*)&retValB[0]); 1553e5c31af7Sopenharmony_ci } 1554e5c31af7Sopenharmony_ci 1555e5c31af7Sopenharmony_ci for (j = 0; j < dwordCount[i]; j++) 1556e5c31af7Sopenharmony_ci { 1557e5c31af7Sopenharmony_ci // Compare programB uniform to expected value and 1558e5c31af7Sopenharmony_ci // test to see if programA picked up the value. 1559e5c31af7Sopenharmony_ci if ((retValB[j] != *uValue++) || (retValA[j] == retValB[j])) 1560e5c31af7Sopenharmony_ci { 1561e5c31af7Sopenharmony_ci TCU_FAIL("ProgramUniformi failed"); 1562e5c31af7Sopenharmony_ci } 1563e5c31af7Sopenharmony_ci } 1564e5c31af7Sopenharmony_ci } 1565e5c31af7Sopenharmony_ci 1566e5c31af7Sopenharmony_ci // Test the conventional uniform interfaces on an ACTIVE_PROGRAM 1567e5c31af7Sopenharmony_ci glw::GLuint activeProgram = 0; 1568e5c31af7Sopenharmony_ci if (pipeline != 0) 1569e5c31af7Sopenharmony_ci { 1570e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_ACTIVE_PROGRAM, (int*)&activeProgram); 1571e5c31af7Sopenharmony_ci } 1572e5c31af7Sopenharmony_ci if ((activeProgram != 0) && ((activeProgram == programA) || (activeProgram == programB))) 1573e5c31af7Sopenharmony_ci { 1574e5c31af7Sopenharmony_ci glw::GLint* location; 1575e5c31af7Sopenharmony_ci 1576e5c31af7Sopenharmony_ci location = (activeProgram == programA) ? locationA : locationB; 1577e5c31af7Sopenharmony_ci 1578e5c31af7Sopenharmony_ci // reseed data buffer, continuing to increment 1579e5c31af7Sopenharmony_ci if (dType == glu::TYPE_FLOAT) 1580e5c31af7Sopenharmony_ci { 1581e5c31af7Sopenharmony_ci fdata[0] = fdata[udataCount - 1] + 1.0f; 1582e5c31af7Sopenharmony_ci for (i = 1; i < udataCount; i++) 1583e5c31af7Sopenharmony_ci { 1584e5c31af7Sopenharmony_ci fdata[i] = fdata[i - 1] + 1.0f; 1585e5c31af7Sopenharmony_ci } 1586e5c31af7Sopenharmony_ci } 1587e5c31af7Sopenharmony_ci else 1588e5c31af7Sopenharmony_ci { 1589e5c31af7Sopenharmony_ci data[0] = data[udataCount - 1] + 1; 1590e5c31af7Sopenharmony_ci for (i = 1; i < udataCount; i++) 1591e5c31af7Sopenharmony_ci { 1592e5c31af7Sopenharmony_ci data[i] = data[i - 1] + 1; 1593e5c31af7Sopenharmony_ci } 1594e5c31af7Sopenharmony_ci } 1595e5c31af7Sopenharmony_ci 1596e5c31af7Sopenharmony_ci // set uniforms using original glUniform* 1597e5c31af7Sopenharmony_ci 1598e5c31af7Sopenharmony_ci if (dType == glu::TYPE_INT) 1599e5c31af7Sopenharmony_ci { 1600e5c31af7Sopenharmony_ci activeUniformi(gl, arraySize, location, data); 1601e5c31af7Sopenharmony_ci } 1602e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_UINT) 1603e5c31af7Sopenharmony_ci { 1604e5c31af7Sopenharmony_ci activeUniformui(gl, arraySize, location, udata); 1605e5c31af7Sopenharmony_ci } 1606e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_FLOAT) 1607e5c31af7Sopenharmony_ci { 1608e5c31af7Sopenharmony_ci activeUniformf(gl, arraySize, location, fdata); 1609e5c31af7Sopenharmony_ci } 1610e5c31af7Sopenharmony_ci 1611e5c31af7Sopenharmony_ci // get and compare uniforms 1612e5c31af7Sopenharmony_ci uValue = &udata[0]; 1613e5c31af7Sopenharmony_ci for (i = 0; i < nonarrayUnifCount + arraySize * arrayUnifCount; i++) 1614e5c31af7Sopenharmony_ci { 1615e5c31af7Sopenharmony_ci unsigned int retVal[4]; 1616e5c31af7Sopenharmony_ci 1617e5c31af7Sopenharmony_ci if (dType == glu::TYPE_INT) 1618e5c31af7Sopenharmony_ci { 1619e5c31af7Sopenharmony_ci gl.getUniformiv(activeProgram, location[i], (int*)&retVal[0]); 1620e5c31af7Sopenharmony_ci } 1621e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_UINT) 1622e5c31af7Sopenharmony_ci { 1623e5c31af7Sopenharmony_ci gl.getUniformuiv(activeProgram, location[i], &retVal[0]); 1624e5c31af7Sopenharmony_ci } 1625e5c31af7Sopenharmony_ci else if (dType == glu::TYPE_FLOAT) 1626e5c31af7Sopenharmony_ci { 1627e5c31af7Sopenharmony_ci gl.getUniformfv(activeProgram, location[i], (float*)&retVal[0]); 1628e5c31af7Sopenharmony_ci } 1629e5c31af7Sopenharmony_ci 1630e5c31af7Sopenharmony_ci for (j = 0; j < dwordCount[i]; j++) 1631e5c31af7Sopenharmony_ci { 1632e5c31af7Sopenharmony_ci // Compare activeProgram uniform to expected value 1633e5c31af7Sopenharmony_ci if ((retVal[j] != *uValue++)) 1634e5c31af7Sopenharmony_ci { 1635e5c31af7Sopenharmony_ci TCU_FAIL("ActiveShaderProgram failed"); 1636e5c31af7Sopenharmony_ci } 1637e5c31af7Sopenharmony_ci } 1638e5c31af7Sopenharmony_ci } 1639e5c31af7Sopenharmony_ci } 1640e5c31af7Sopenharmony_ci 1641e5c31af7Sopenharmony_ci return true; 1642e5c31af7Sopenharmony_ci } 1643e5c31af7Sopenharmony_ci 1644e5c31af7Sopenharmony_ci // Call programUniform for Matrix uniforms 1645e5c31af7Sopenharmony_ci // Two programs are verified independently and against each other 1646e5c31af7Sopenharmony_ci bool setAndCompareMatrixUniforms(glw::GLuint pipeline, glw::GLuint programA, glw::GLuint programB, 1647e5c31af7Sopenharmony_ci glu::DataType dType, int seed) 1648e5c31af7Sopenharmony_ci { 1649e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 1650e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1651e5c31af7Sopenharmony_ci bool isSquareMat = isDataTypeSquareMatrix(dType); 1652e5c31af7Sopenharmony_ci // The matrix versions of the fragment shader have two element arrays 1653e5c31af7Sopenharmony_ci // of each uniform. 1654e5c31af7Sopenharmony_ci // There are 3 * 2 uniforms for the square matrix shader and 1655e5c31af7Sopenharmony_ci // 6 * 2 uniforms in the non-square matrix shader. 1656e5c31af7Sopenharmony_ci const int maxUniforms = 12; 1657e5c31af7Sopenharmony_ci int numUniforms; 1658e5c31af7Sopenharmony_ci const int arraySize = 2; 1659e5c31af7Sopenharmony_ci glw::GLint locationA[maxUniforms]; 1660e5c31af7Sopenharmony_ci glw::GLint locationB[maxUniforms]; 1661e5c31af7Sopenharmony_ci // These arrays represent the number of floats for each uniform location 1662e5c31af7Sopenharmony_ci // 2x2[0], 2x2[1], 3x3[0], 3x3[1], 4x4[0], 4x4[1] 1663e5c31af7Sopenharmony_ci const int floatCountSqu[maxUniforms] = { 4, 4, 9, 9, 16, 16, 0, 0, 0, 0, 0, 0 }; 1664e5c31af7Sopenharmony_ci // 2x3[0], 2x3[1], 2x4[0], 2x4[1], 3x2[0], 3x2[1], 3x4[0], 3x4[1], 4x2[0]... 1665e5c31af7Sopenharmony_ci const int floatCountNonSqu[maxUniforms] = { 6, 6, 8, 8, 6, 6, 12, 12, 8, 8, 12, 12 }; 1666e5c31af7Sopenharmony_ci const int* floatCount; 1667e5c31af7Sopenharmony_ci // Max data for the uniforms = 2*(2*3 + 3*2 + 2*4 + 4*2 + 3*4 + 4*3) 1668e5c31af7Sopenharmony_ci const int maxDataCount = 104; 1669e5c31af7Sopenharmony_ci float data[maxDataCount]; 1670e5c31af7Sopenharmony_ci int i, j, k; 1671e5c31af7Sopenharmony_ci std::string uniformBaseName("uValM"); 1672e5c31af7Sopenharmony_ci 1673e5c31af7Sopenharmony_ci // ProgramUniform API verification 1674e5c31af7Sopenharmony_ci log << TestLog::Message << "Begin:ProgramUniformCase for Matrix iterate" << TestLog::EndMessage; 1675e5c31af7Sopenharmony_ci 1676e5c31af7Sopenharmony_ci numUniforms = 0; 1677e5c31af7Sopenharmony_ci // get uniform locations 1678e5c31af7Sopenharmony_ci for (i = 2; i <= 4; i++) // matrix dimension m 1679e5c31af7Sopenharmony_ci { 1680e5c31af7Sopenharmony_ci for (j = 2; j <= 4; j++) // matrix dimension n 1681e5c31af7Sopenharmony_ci { 1682e5c31af7Sopenharmony_ci for (k = 0; k < arraySize; k++) 1683e5c31af7Sopenharmony_ci { 1684e5c31af7Sopenharmony_ci if ((i == j) && isSquareMat) 1685e5c31af7Sopenharmony_ci { 1686e5c31af7Sopenharmony_ci string name = uniformBaseName + de::toString(i) + "[" + de::toString(k) + "]"; 1687e5c31af7Sopenharmony_ci locationA[numUniforms] = gl.getUniformLocation(programA, name.c_str()); 1688e5c31af7Sopenharmony_ci locationB[numUniforms] = gl.getUniformLocation(programB, name.c_str()); 1689e5c31af7Sopenharmony_ci numUniforms++; 1690e5c31af7Sopenharmony_ci } 1691e5c31af7Sopenharmony_ci else if ((i != j) && !isSquareMat) 1692e5c31af7Sopenharmony_ci { 1693e5c31af7Sopenharmony_ci string name = 1694e5c31af7Sopenharmony_ci uniformBaseName + de::toString(i) + "x" + de::toString(j) + "[" + de::toString(k) + "]"; 1695e5c31af7Sopenharmony_ci locationA[numUniforms] = gl.getUniformLocation(programA, name.c_str()); 1696e5c31af7Sopenharmony_ci locationB[numUniforms] = gl.getUniformLocation(programB, name.c_str()); 1697e5c31af7Sopenharmony_ci numUniforms++; 1698e5c31af7Sopenharmony_ci } 1699e5c31af7Sopenharmony_ci } 1700e5c31af7Sopenharmony_ci } 1701e5c31af7Sopenharmony_ci } 1702e5c31af7Sopenharmony_ci DE_ASSERT((numUniforms == 6) || (numUniforms == 12)); 1703e5c31af7Sopenharmony_ci 1704e5c31af7Sopenharmony_ci // init the float data array 1705e5c31af7Sopenharmony_ci for (i = 0; i < maxDataCount; i++) 1706e5c31af7Sopenharmony_ci { 1707e5c31af7Sopenharmony_ci data[i] = (float)(seed + i); 1708e5c31af7Sopenharmony_ci } 1709e5c31af7Sopenharmony_ci 1710e5c31af7Sopenharmony_ci // Set the uniforms in programA 1711e5c31af7Sopenharmony_ci float* value = &data[0]; 1712e5c31af7Sopenharmony_ci if (isSquareMat) 1713e5c31af7Sopenharmony_ci { 1714e5c31af7Sopenharmony_ci floatCount = floatCountSqu; 1715e5c31af7Sopenharmony_ci gl.programUniformMatrix2fv(programA, locationA[0], arraySize, GL_FALSE, value); 1716e5c31af7Sopenharmony_ci value += 2 * 2 * arraySize; 1717e5c31af7Sopenharmony_ci gl.programUniformMatrix3fv(programA, locationA[2], arraySize, GL_FALSE, value); 1718e5c31af7Sopenharmony_ci value += 3 * 3 * arraySize; 1719e5c31af7Sopenharmony_ci gl.programUniformMatrix4fv(programA, locationA[4], arraySize, GL_FALSE, value); 1720e5c31af7Sopenharmony_ci } 1721e5c31af7Sopenharmony_ci else 1722e5c31af7Sopenharmony_ci { 1723e5c31af7Sopenharmony_ci floatCount = floatCountNonSqu; 1724e5c31af7Sopenharmony_ci gl.programUniformMatrix2x3fv(programA, locationA[0], arraySize, GL_FALSE, value); 1725e5c31af7Sopenharmony_ci value += 2 * 3 * arraySize; 1726e5c31af7Sopenharmony_ci gl.programUniformMatrix2x4fv(programA, locationA[2], arraySize, GL_FALSE, value); 1727e5c31af7Sopenharmony_ci value += 2 * 4 * arraySize; 1728e5c31af7Sopenharmony_ci gl.programUniformMatrix3x2fv(programA, locationA[4], arraySize, GL_FALSE, value); 1729e5c31af7Sopenharmony_ci value += 3 * 2 * arraySize; 1730e5c31af7Sopenharmony_ci gl.programUniformMatrix3x4fv(programA, locationA[6], arraySize, GL_FALSE, value); 1731e5c31af7Sopenharmony_ci value += 3 * 4 * arraySize; 1732e5c31af7Sopenharmony_ci gl.programUniformMatrix4x2fv(programA, locationA[8], arraySize, GL_FALSE, value); 1733e5c31af7Sopenharmony_ci value += 4 * 2 * arraySize; 1734e5c31af7Sopenharmony_ci gl.programUniformMatrix4x3fv(programA, locationA[10], arraySize, GL_FALSE, value); 1735e5c31af7Sopenharmony_ci } 1736e5c31af7Sopenharmony_ci 1737e5c31af7Sopenharmony_ci // get and compare the uniform data 1738e5c31af7Sopenharmony_ci value = &data[0]; 1739e5c31af7Sopenharmony_ci for (i = 0; i < numUniforms; i++) 1740e5c31af7Sopenharmony_ci { 1741e5c31af7Sopenharmony_ci float retValA[16], retValB[16]; 1742e5c31af7Sopenharmony_ci 1743e5c31af7Sopenharmony_ci gl.getUniformfv(programA, locationA[i], retValA); 1744e5c31af7Sopenharmony_ci gl.getUniformfv(programB, locationB[i], retValB); 1745e5c31af7Sopenharmony_ci 1746e5c31af7Sopenharmony_ci for (j = 0; j < floatCount[i]; j++) 1747e5c31af7Sopenharmony_ci { 1748e5c31af7Sopenharmony_ci // Compare programA uniform to expected value and 1749e5c31af7Sopenharmony_ci // test to see if programB picked up the value. 1750e5c31af7Sopenharmony_ci if ((retValA[j] != *value++) || (retValA[j] == retValB[j])) 1751e5c31af7Sopenharmony_ci { 1752e5c31af7Sopenharmony_ci TCU_FAIL("ProgramUniformi failed"); 1753e5c31af7Sopenharmony_ci } 1754e5c31af7Sopenharmony_ci } 1755e5c31af7Sopenharmony_ci } 1756e5c31af7Sopenharmony_ci 1757e5c31af7Sopenharmony_ci // reseed the float buffer 1758e5c31af7Sopenharmony_ci data[0] = data[maxDataCount - 1]; 1759e5c31af7Sopenharmony_ci for (i = 1; i < maxDataCount; i++) 1760e5c31af7Sopenharmony_ci { 1761e5c31af7Sopenharmony_ci data[i] = data[i - 1] + 1.0f; 1762e5c31af7Sopenharmony_ci } 1763e5c31af7Sopenharmony_ci 1764e5c31af7Sopenharmony_ci // set uniforms in program B 1765e5c31af7Sopenharmony_ci value = &data[0]; 1766e5c31af7Sopenharmony_ci if (isSquareMat) 1767e5c31af7Sopenharmony_ci { 1768e5c31af7Sopenharmony_ci floatCount = floatCountSqu; 1769e5c31af7Sopenharmony_ci gl.programUniformMatrix2fv(programB, locationB[0], arraySize, GL_FALSE, value); 1770e5c31af7Sopenharmony_ci value += 2 * 2 * arraySize; 1771e5c31af7Sopenharmony_ci gl.programUniformMatrix3fv(programB, locationB[2], arraySize, GL_FALSE, value); 1772e5c31af7Sopenharmony_ci value += 3 * 3 * arraySize; 1773e5c31af7Sopenharmony_ci gl.programUniformMatrix4fv(programB, locationB[4], arraySize, GL_FALSE, value); 1774e5c31af7Sopenharmony_ci } 1775e5c31af7Sopenharmony_ci else 1776e5c31af7Sopenharmony_ci { 1777e5c31af7Sopenharmony_ci floatCount = floatCountNonSqu; 1778e5c31af7Sopenharmony_ci gl.programUniformMatrix2x3fv(programB, locationB[0], arraySize, GL_FALSE, value); 1779e5c31af7Sopenharmony_ci value += 2 * 3 * arraySize; 1780e5c31af7Sopenharmony_ci gl.programUniformMatrix2x4fv(programB, locationB[2], arraySize, GL_FALSE, value); 1781e5c31af7Sopenharmony_ci value += 2 * 4 * arraySize; 1782e5c31af7Sopenharmony_ci gl.programUniformMatrix3x2fv(programB, locationB[4], arraySize, GL_FALSE, value); 1783e5c31af7Sopenharmony_ci value += 3 * 2 * arraySize; 1784e5c31af7Sopenharmony_ci gl.programUniformMatrix3x4fv(programB, locationB[6], arraySize, GL_FALSE, value); 1785e5c31af7Sopenharmony_ci value += 3 * 4 * arraySize; 1786e5c31af7Sopenharmony_ci gl.programUniformMatrix4x2fv(programB, locationB[8], arraySize, GL_FALSE, value); 1787e5c31af7Sopenharmony_ci value += 4 * 2 * arraySize; 1788e5c31af7Sopenharmony_ci gl.programUniformMatrix4x3fv(programB, locationB[10], arraySize, GL_FALSE, value); 1789e5c31af7Sopenharmony_ci } 1790e5c31af7Sopenharmony_ci 1791e5c31af7Sopenharmony_ci // get and compare the uniform data 1792e5c31af7Sopenharmony_ci value = &data[0]; 1793e5c31af7Sopenharmony_ci for (i = 0; i < numUniforms; i++) 1794e5c31af7Sopenharmony_ci { 1795e5c31af7Sopenharmony_ci float retValA[16], retValB[16]; 1796e5c31af7Sopenharmony_ci 1797e5c31af7Sopenharmony_ci gl.getUniformfv(programA, locationA[i], retValA); 1798e5c31af7Sopenharmony_ci gl.getUniformfv(programB, locationB[i], retValB); 1799e5c31af7Sopenharmony_ci 1800e5c31af7Sopenharmony_ci for (j = 0; j < floatCount[i]; j++) 1801e5c31af7Sopenharmony_ci { 1802e5c31af7Sopenharmony_ci // Compare programB uniform to expected value and 1803e5c31af7Sopenharmony_ci // test to see if programA picked up the value. 1804e5c31af7Sopenharmony_ci if ((retValB[j] != *value++) || (retValA[j] == retValB[j])) 1805e5c31af7Sopenharmony_ci { 1806e5c31af7Sopenharmony_ci TCU_FAIL("ProgramUniformi failed"); 1807e5c31af7Sopenharmony_ci } 1808e5c31af7Sopenharmony_ci } 1809e5c31af7Sopenharmony_ci } 1810e5c31af7Sopenharmony_ci 1811e5c31af7Sopenharmony_ci // Use the conventional uniform interfaces on an ACTIVE_PROGRAM 1812e5c31af7Sopenharmony_ci glw::GLuint activeProgram = 0; 1813e5c31af7Sopenharmony_ci if (pipeline != 0) 1814e5c31af7Sopenharmony_ci { 1815e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_ACTIVE_PROGRAM, (int*)&activeProgram); 1816e5c31af7Sopenharmony_ci } 1817e5c31af7Sopenharmony_ci if ((activeProgram != 0) && ((activeProgram == programA) || (activeProgram == programB))) 1818e5c31af7Sopenharmony_ci { 1819e5c31af7Sopenharmony_ci glw::GLint* location; 1820e5c31af7Sopenharmony_ci 1821e5c31af7Sopenharmony_ci location = (activeProgram == programA) ? locationA : locationB; 1822e5c31af7Sopenharmony_ci 1823e5c31af7Sopenharmony_ci // reseed the float buffer 1824e5c31af7Sopenharmony_ci data[0] = data[maxDataCount - 1]; 1825e5c31af7Sopenharmony_ci for (i = 1; i < maxDataCount; i++) 1826e5c31af7Sopenharmony_ci { 1827e5c31af7Sopenharmony_ci data[i] = data[i - 1] + 1.0f; 1828e5c31af7Sopenharmony_ci } 1829e5c31af7Sopenharmony_ci 1830e5c31af7Sopenharmony_ci // set uniforms with conventional uniform calls 1831e5c31af7Sopenharmony_ci value = &data[0]; 1832e5c31af7Sopenharmony_ci if (isSquareMat) 1833e5c31af7Sopenharmony_ci { 1834e5c31af7Sopenharmony_ci floatCount = floatCountSqu; 1835e5c31af7Sopenharmony_ci gl.uniformMatrix2fv(location[0], arraySize, GL_FALSE, value); 1836e5c31af7Sopenharmony_ci value += 2 * 2 * arraySize; 1837e5c31af7Sopenharmony_ci gl.uniformMatrix3fv(location[2], arraySize, GL_FALSE, value); 1838e5c31af7Sopenharmony_ci value += 3 * 3 * arraySize; 1839e5c31af7Sopenharmony_ci gl.uniformMatrix4fv(location[4], arraySize, GL_FALSE, value); 1840e5c31af7Sopenharmony_ci } 1841e5c31af7Sopenharmony_ci else 1842e5c31af7Sopenharmony_ci { 1843e5c31af7Sopenharmony_ci floatCount = floatCountNonSqu; 1844e5c31af7Sopenharmony_ci gl.uniformMatrix2x3fv(location[0], arraySize, GL_FALSE, value); 1845e5c31af7Sopenharmony_ci value += 2 * 3 * arraySize; 1846e5c31af7Sopenharmony_ci gl.uniformMatrix2x4fv(location[2], arraySize, GL_FALSE, value); 1847e5c31af7Sopenharmony_ci value += 2 * 4 * arraySize; 1848e5c31af7Sopenharmony_ci gl.uniformMatrix3x2fv(location[4], arraySize, GL_FALSE, value); 1849e5c31af7Sopenharmony_ci value += 3 * 2 * arraySize; 1850e5c31af7Sopenharmony_ci gl.uniformMatrix3x4fv(location[6], arraySize, GL_FALSE, value); 1851e5c31af7Sopenharmony_ci value += 3 * 4 * arraySize; 1852e5c31af7Sopenharmony_ci gl.uniformMatrix4x2fv(location[8], arraySize, GL_FALSE, value); 1853e5c31af7Sopenharmony_ci value += 4 * 2 * arraySize; 1854e5c31af7Sopenharmony_ci gl.uniformMatrix4x3fv(location[10], arraySize, GL_FALSE, value); 1855e5c31af7Sopenharmony_ci } 1856e5c31af7Sopenharmony_ci 1857e5c31af7Sopenharmony_ci // get and compare the uniform data 1858e5c31af7Sopenharmony_ci value = &data[0]; 1859e5c31af7Sopenharmony_ci for (i = 0; i < numUniforms; i++) 1860e5c31af7Sopenharmony_ci { 1861e5c31af7Sopenharmony_ci float retVal[16]; 1862e5c31af7Sopenharmony_ci 1863e5c31af7Sopenharmony_ci gl.getUniformfv(activeProgram, location[i], retVal); 1864e5c31af7Sopenharmony_ci 1865e5c31af7Sopenharmony_ci for (j = 0; j < floatCount[i]; j++) 1866e5c31af7Sopenharmony_ci { 1867e5c31af7Sopenharmony_ci // Compare activeshaderprogram uniform to expected value 1868e5c31af7Sopenharmony_ci if (retVal[j] != *value++) 1869e5c31af7Sopenharmony_ci { 1870e5c31af7Sopenharmony_ci TCU_FAIL("ActiveShaderProgram with glUniform failed"); 1871e5c31af7Sopenharmony_ci } 1872e5c31af7Sopenharmony_ci } 1873e5c31af7Sopenharmony_ci } 1874e5c31af7Sopenharmony_ci } 1875e5c31af7Sopenharmony_ci 1876e5c31af7Sopenharmony_ci return true; 1877e5c31af7Sopenharmony_ci } 1878e5c31af7Sopenharmony_ci 1879e5c31af7Sopenharmony_ci IterateResult iterate(void) 1880e5c31af7Sopenharmony_ci { 1881e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1882e5c31af7Sopenharmony_ci glu::DataType dType[5] = { glu::TYPE_INT, glu::TYPE_UINT, glu::TYPE_FLOAT, glu::TYPE_FLOAT_MAT2, 1883e5c31af7Sopenharmony_ci glu::TYPE_FLOAT_MAT2X3 }; 1884e5c31af7Sopenharmony_ci 1885e5c31af7Sopenharmony_ci // Loop over the various data types, generate fragment programs, and test uniforms 1886e5c31af7Sopenharmony_ci // (MAT2 means stands for all square matrices, MAT2x3 stands for all non-square matrices) 1887e5c31af7Sopenharmony_ci for (int i = 0; i < 5; i++) 1888e5c31af7Sopenharmony_ci { 1889e5c31af7Sopenharmony_ci glw::GLuint programA, programB; 1890e5c31af7Sopenharmony_ci glw::GLuint pipeline = 0; 1891e5c31af7Sopenharmony_ci const char* shaderSrc[1]; 1892e5c31af7Sopenharmony_ci std::string fragSrc; 1893e5c31af7Sopenharmony_ci int seed = 1000 + (1000 * i); 1894e5c31af7Sopenharmony_ci 1895e5c31af7Sopenharmony_ci generateUniformFragSrc(fragSrc, m_glslVersion, dType[i]); 1896e5c31af7Sopenharmony_ci 1897e5c31af7Sopenharmony_ci size_t length = fragSrc.size(); 1898e5c31af7Sopenharmony_ci std::vector<char> shaderbuf(length + 1); 1899e5c31af7Sopenharmony_ci fragSrc.copy(&shaderbuf[0], length); 1900e5c31af7Sopenharmony_ci shaderbuf[length] = '\0'; 1901e5c31af7Sopenharmony_ci shaderSrc[0] = &shaderbuf[0]; 1902e5c31af7Sopenharmony_ci programA = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1, shaderSrc); 1903e5c31af7Sopenharmony_ci programB = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1, shaderSrc); 1904e5c31af7Sopenharmony_ci 1905e5c31af7Sopenharmony_ci if (isDataTypeMatrix(dType[i])) 1906e5c31af7Sopenharmony_ci { 1907e5c31af7Sopenharmony_ci // programs are unbound 1908e5c31af7Sopenharmony_ci setAndCompareMatrixUniforms(pipeline, programA, programB, dType[i], seed); 1909e5c31af7Sopenharmony_ci 1910e5c31af7Sopenharmony_ci // bind one program with useProgramStages 1911e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, &pipeline); 1912e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipeline); 1913e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, programA); 1914e5c31af7Sopenharmony_ci seed += 100; 1915e5c31af7Sopenharmony_ci setAndCompareMatrixUniforms(pipeline, programA, programB, dType[i], seed); 1916e5c31af7Sopenharmony_ci 1917e5c31af7Sopenharmony_ci // make an active program with activeShaderProgram 1918e5c31af7Sopenharmony_ci gl.activeShaderProgram(pipeline, programB); 1919e5c31af7Sopenharmony_ci seed += 100; 1920e5c31af7Sopenharmony_ci setAndCompareMatrixUniforms(pipeline, programA, programB, dType[i], seed); 1921e5c31af7Sopenharmony_ci } 1922e5c31af7Sopenharmony_ci else 1923e5c31af7Sopenharmony_ci { 1924e5c31af7Sopenharmony_ci // programs are unbound 1925e5c31af7Sopenharmony_ci setAndCompareUniforms(pipeline, programA, programB, dType[i], seed); 1926e5c31af7Sopenharmony_ci 1927e5c31af7Sopenharmony_ci // bind one program with useProgramStages 1928e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, &pipeline); 1929e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipeline); 1930e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, programA); 1931e5c31af7Sopenharmony_ci seed += 100; 1932e5c31af7Sopenharmony_ci setAndCompareUniforms(pipeline, programA, programB, dType[i], seed); 1933e5c31af7Sopenharmony_ci 1934e5c31af7Sopenharmony_ci // make an active program with activeShaderProgram 1935e5c31af7Sopenharmony_ci gl.activeShaderProgram(pipeline, programB); 1936e5c31af7Sopenharmony_ci seed += 100; 1937e5c31af7Sopenharmony_ci setAndCompareUniforms(pipeline, programA, programB, dType[i], seed); 1938e5c31af7Sopenharmony_ci } 1939e5c31af7Sopenharmony_ci 1940e5c31af7Sopenharmony_ci gl.deleteProgram(programA); 1941e5c31af7Sopenharmony_ci gl.deleteProgram(programB); 1942e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, &pipeline); 1943e5c31af7Sopenharmony_ci } 1944e5c31af7Sopenharmony_ci 1945e5c31af7Sopenharmony_ci // Negative Cases 1946e5c31af7Sopenharmony_ci 1947e5c31af7Sopenharmony_ci // Program that is not successfully linked 1948e5c31af7Sopenharmony_ci glw::GLenum err; 1949e5c31af7Sopenharmony_ci std::string vtx; 1950e5c31af7Sopenharmony_ci std::string frag; 1951e5c31af7Sopenharmony_ci 1952e5c31af7Sopenharmony_ci vtx = generateBasicVertexSrc(m_glslVersion); 1953e5c31af7Sopenharmony_ci frag = generateBasicFragmentSrc(m_glslVersion); 1954e5c31af7Sopenharmony_ci 1955e5c31af7Sopenharmony_ci // remove the main keyword so it doesn't link 1956e5c31af7Sopenharmony_ci std::string fragNoMain = frag; 1957e5c31af7Sopenharmony_ci unsigned int pos = (unsigned int)fragNoMain.find("main"); 1958e5c31af7Sopenharmony_ci fragNoMain.replace(pos, 4, "niaM"); 1959e5c31af7Sopenharmony_ci glu::ShaderProgram progNoLink(m_context.getRenderContext(), 1960e5c31af7Sopenharmony_ci glu::makeVtxFragSources(vtx.c_str(), fragNoMain.c_str())); 1961e5c31af7Sopenharmony_ci gl.programParameteri(progNoLink.getProgram(), GL_PROGRAM_SEPARABLE, GL_TRUE); 1962e5c31af7Sopenharmony_ci gl.linkProgram(progNoLink.getProgram()); 1963e5c31af7Sopenharmony_ci int unifLocation = gl.getUniformLocation(progNoLink.getProgram(), "u_color"); 1964e5c31af7Sopenharmony_ci gl.programUniform4f(progNoLink.getProgram(), unifLocation, 1.0, 1.0, 1.0, 1.0); 1965e5c31af7Sopenharmony_ci err = gl.getError(); 1966e5c31af7Sopenharmony_ci if (err != GL_INVALID_OPERATION) 1967e5c31af7Sopenharmony_ci { 1968e5c31af7Sopenharmony_ci TCU_FAIL("ProgramUniformi failed"); 1969e5c31af7Sopenharmony_ci } 1970e5c31af7Sopenharmony_ci 1971e5c31af7Sopenharmony_ci // deleted program 1972e5c31af7Sopenharmony_ci gl.deleteProgram(progNoLink.getProgram()); 1973e5c31af7Sopenharmony_ci gl.programUniform4f(progNoLink.getProgram(), unifLocation, 1.0, 1.0, 1.0, 1.0); 1974e5c31af7Sopenharmony_ci err = gl.getError(); 1975e5c31af7Sopenharmony_ci if (err != GL_INVALID_VALUE) 1976e5c31af7Sopenharmony_ci { 1977e5c31af7Sopenharmony_ci TCU_FAIL("ProgramUniformi failed"); 1978e5c31af7Sopenharmony_ci } 1979e5c31af7Sopenharmony_ci 1980e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1981e5c31af7Sopenharmony_ci return STOP; 1982e5c31af7Sopenharmony_ci } 1983e5c31af7Sopenharmony_ci 1984e5c31af7Sopenharmony_ciprivate: 1985e5c31af7Sopenharmony_ci glu::GLSLVersion m_glslVersion; 1986e5c31af7Sopenharmony_ci}; 1987e5c31af7Sopenharmony_ci 1988e5c31af7Sopenharmony_ci// Testcase for state interactions 1989e5c31af7Sopenharmony_ciclass StateInteractionCase : public TestCase 1990e5c31af7Sopenharmony_ci{ 1991e5c31af7Sopenharmony_cipublic: 1992e5c31af7Sopenharmony_ci StateInteractionCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion) 1993e5c31af7Sopenharmony_ci : TestCase(context, name, description), m_glslVersion(glslVersion) 1994e5c31af7Sopenharmony_ci { 1995e5c31af7Sopenharmony_ci } 1996e5c31af7Sopenharmony_ci 1997e5c31af7Sopenharmony_ci ~StateInteractionCase(void) 1998e5c31af7Sopenharmony_ci { 1999e5c31af7Sopenharmony_ci } 2000e5c31af7Sopenharmony_ci 2001e5c31af7Sopenharmony_ci // Log the program info log 2002e5c31af7Sopenharmony_ci void logProgramInfoLog(const glw::Functions& gl, glw::GLuint program) 2003e5c31af7Sopenharmony_ci { 2004e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 2005e5c31af7Sopenharmony_ci glw::GLint value = 0; 2006e5c31af7Sopenharmony_ci glw::GLsizei bufSize = 0; 2007e5c31af7Sopenharmony_ci glw::GLsizei length = 0; 2008e5c31af7Sopenharmony_ci 2009e5c31af7Sopenharmony_ci gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &value); 2010e5c31af7Sopenharmony_ci std::vector<char> infoLogBuf(value + 1); 2011e5c31af7Sopenharmony_ci 2012e5c31af7Sopenharmony_ci gl.getProgramInfoLog(program, bufSize, &length, &infoLogBuf[0]); 2013e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog failed"); 2014e5c31af7Sopenharmony_ci 2015e5c31af7Sopenharmony_ci log << TestLog::Message << "Program Log:\n" << &infoLogBuf[0] << TestLog::EndMessage; 2016e5c31af7Sopenharmony_ci } 2017e5c31af7Sopenharmony_ci 2018e5c31af7Sopenharmony_ci // Check program validity created with CreateShaderProgram 2019e5c31af7Sopenharmony_ci bool checkCSProg(const glw::Functions& gl, GLuint program, int expectedLink = GL_TRUE) 2020e5c31af7Sopenharmony_ci { 2021e5c31af7Sopenharmony_ci int linked = GL_FALSE; 2022e5c31af7Sopenharmony_ci if (program != 0) 2023e5c31af7Sopenharmony_ci { 2024e5c31af7Sopenharmony_ci gl.getProgramiv(program, GL_LINK_STATUS, &linked); 2025e5c31af7Sopenharmony_ci 2026e5c31af7Sopenharmony_ci if (expectedLink && !linked) 2027e5c31af7Sopenharmony_ci { 2028e5c31af7Sopenharmony_ci logProgramInfoLog(gl, program); 2029e5c31af7Sopenharmony_ci } 2030e5c31af7Sopenharmony_ci } 2031e5c31af7Sopenharmony_ci 2032e5c31af7Sopenharmony_ci return (program != 0) && (linked == expectedLink); 2033e5c31af7Sopenharmony_ci } 2034e5c31af7Sopenharmony_ci 2035e5c31af7Sopenharmony_ci // Generate a vertex shader for variable input/output testing 2036e5c31af7Sopenharmony_ci void generateVarLinkVertexShaderSrc(std::string& outVtxSrc, glu::GLSLVersion glslVersion, int numOutputs) 2037e5c31af7Sopenharmony_ci { 2038e5c31af7Sopenharmony_ci std::ostringstream vtxSrc; 2039e5c31af7Sopenharmony_ci 2040e5c31af7Sopenharmony_ci vtxSrc << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 2041e5c31af7Sopenharmony_ci if (glslVersion >= glu::GLSL_VERSION_410) 2042e5c31af7Sopenharmony_ci { 2043e5c31af7Sopenharmony_ci vtxSrc << "out gl_PerVertex {\n" 2044e5c31af7Sopenharmony_ci " vec4 gl_Position;\n" 2045e5c31af7Sopenharmony_ci "};\n"; 2046e5c31af7Sopenharmony_ci } 2047e5c31af7Sopenharmony_ci vtxSrc << "in highp vec4 a_position;\n"; 2048e5c31af7Sopenharmony_ci vtxSrc << "uniform highp vec4 u_color;\n"; 2049e5c31af7Sopenharmony_ci 2050e5c31af7Sopenharmony_ci switch (numOutputs) 2051e5c31af7Sopenharmony_ci { 2052e5c31af7Sopenharmony_ci // Note all these cases fall through 2053e5c31af7Sopenharmony_ci case 5: 2054e5c31af7Sopenharmony_ci vtxSrc << "layout(location = 3) out vec4 o_val5;\n"; 2055e5c31af7Sopenharmony_ci // Fallthrough 2056e5c31af7Sopenharmony_ci case 4: 2057e5c31af7Sopenharmony_ci vtxSrc << "flat out uvec4 val4;\n"; 2058e5c31af7Sopenharmony_ci // Fallthrough 2059e5c31af7Sopenharmony_ci case 3: 2060e5c31af7Sopenharmony_ci vtxSrc << "flat out ivec2 val3;\n"; 2061e5c31af7Sopenharmony_ci // Fallthrough 2062e5c31af7Sopenharmony_ci case 2: 2063e5c31af7Sopenharmony_ci vtxSrc << "out vec3 val2[2];\n"; 2064e5c31af7Sopenharmony_ci // Fallthrough 2065e5c31af7Sopenharmony_ci case 1: 2066e5c31af7Sopenharmony_ci vtxSrc << "out vec4 val1;\n"; 2067e5c31af7Sopenharmony_ci // Fallthrough 2068e5c31af7Sopenharmony_ci default: 2069e5c31af7Sopenharmony_ci vtxSrc << "out float val0;\n"; 2070e5c31af7Sopenharmony_ci } 2071e5c31af7Sopenharmony_ci 2072e5c31af7Sopenharmony_ci vtxSrc << "void main (void)\n"; 2073e5c31af7Sopenharmony_ci vtxSrc << "{\n"; 2074e5c31af7Sopenharmony_ci vtxSrc << " gl_Position = a_position;\n"; 2075e5c31af7Sopenharmony_ci 2076e5c31af7Sopenharmony_ci // The color uniform is passed in the last declared output variable 2077e5c31af7Sopenharmony_ci switch (numOutputs) 2078e5c31af7Sopenharmony_ci { 2079e5c31af7Sopenharmony_ci case 5: 2080e5c31af7Sopenharmony_ci vtxSrc << " o_val5 = u_color;\n"; 2081e5c31af7Sopenharmony_ci break; 2082e5c31af7Sopenharmony_ci case 4: 2083e5c31af7Sopenharmony_ci vtxSrc << " val4 = uvec4(u_color);\n"; 2084e5c31af7Sopenharmony_ci break; 2085e5c31af7Sopenharmony_ci case 3: 2086e5c31af7Sopenharmony_ci vtxSrc << " val3 = ivec2(u_color);\n"; 2087e5c31af7Sopenharmony_ci break; 2088e5c31af7Sopenharmony_ci case 2: 2089e5c31af7Sopenharmony_ci vtxSrc << " val2[0] = vec3(u_color);\n"; 2090e5c31af7Sopenharmony_ci break; 2091e5c31af7Sopenharmony_ci case 1: 2092e5c31af7Sopenharmony_ci vtxSrc << " val1 = u_color;\n"; 2093e5c31af7Sopenharmony_ci break; 2094e5c31af7Sopenharmony_ci default: 2095e5c31af7Sopenharmony_ci vtxSrc << " val0 = u_color.x;\n"; 2096e5c31af7Sopenharmony_ci break; 2097e5c31af7Sopenharmony_ci } 2098e5c31af7Sopenharmony_ci vtxSrc << "}\n"; 2099e5c31af7Sopenharmony_ci 2100e5c31af7Sopenharmony_ci outVtxSrc = vtxSrc.str(); 2101e5c31af7Sopenharmony_ci } 2102e5c31af7Sopenharmony_ci 2103e5c31af7Sopenharmony_ci // Generate a fragment shader for variable input/output testing 2104e5c31af7Sopenharmony_ci void generateVarLinkFragmentShaderSrc(std::string& outFragSrc, glu::GLSLVersion glslVersion, int numInputs) 2105e5c31af7Sopenharmony_ci { 2106e5c31af7Sopenharmony_ci std::ostringstream fragSrc; 2107e5c31af7Sopenharmony_ci 2108e5c31af7Sopenharmony_ci fragSrc << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 2109e5c31af7Sopenharmony_ci fragSrc << "precision highp float;\n"; 2110e5c31af7Sopenharmony_ci fragSrc << "precision highp int;\n"; 2111e5c31af7Sopenharmony_ci 2112e5c31af7Sopenharmony_ci switch (numInputs) 2113e5c31af7Sopenharmony_ci { 2114e5c31af7Sopenharmony_ci // Note all these cases fall through 2115e5c31af7Sopenharmony_ci case 5: 2116e5c31af7Sopenharmony_ci fragSrc << "layout(location = 3) in vec4 i_val5;\n"; 2117e5c31af7Sopenharmony_ci // Fallthrough 2118e5c31af7Sopenharmony_ci case 4: 2119e5c31af7Sopenharmony_ci fragSrc << "flat in uvec4 val4;\n"; 2120e5c31af7Sopenharmony_ci // Fallthrough 2121e5c31af7Sopenharmony_ci case 3: 2122e5c31af7Sopenharmony_ci fragSrc << "flat in ivec2 val3;\n"; 2123e5c31af7Sopenharmony_ci // Fallthrough 2124e5c31af7Sopenharmony_ci case 2: 2125e5c31af7Sopenharmony_ci fragSrc << "in vec3 val2[2];\n"; 2126e5c31af7Sopenharmony_ci // Fallthrough 2127e5c31af7Sopenharmony_ci case 1: 2128e5c31af7Sopenharmony_ci fragSrc << "in vec4 val1;\n"; 2129e5c31af7Sopenharmony_ci // Fallthrough 2130e5c31af7Sopenharmony_ci default: 2131e5c31af7Sopenharmony_ci fragSrc << "in float val0;\n"; 2132e5c31af7Sopenharmony_ci } 2133e5c31af7Sopenharmony_ci 2134e5c31af7Sopenharmony_ci fragSrc << "layout(location = 0) out mediump vec4 o_color;\n"; 2135e5c31af7Sopenharmony_ci fragSrc << "void main (void)\n"; 2136e5c31af7Sopenharmony_ci fragSrc << "{\n"; 2137e5c31af7Sopenharmony_ci 2138e5c31af7Sopenharmony_ci switch (numInputs) 2139e5c31af7Sopenharmony_ci { 2140e5c31af7Sopenharmony_ci case 5: 2141e5c31af7Sopenharmony_ci fragSrc << " o_color = i_val5;\n"; 2142e5c31af7Sopenharmony_ci break; 2143e5c31af7Sopenharmony_ci case 4: 2144e5c31af7Sopenharmony_ci fragSrc << " o_color = vec4(val4);\n"; 2145e5c31af7Sopenharmony_ci break; 2146e5c31af7Sopenharmony_ci case 3: 2147e5c31af7Sopenharmony_ci fragSrc << " o_color = vec4(val3, 1.0, 1.0);\n"; 2148e5c31af7Sopenharmony_ci break; 2149e5c31af7Sopenharmony_ci case 2: 2150e5c31af7Sopenharmony_ci fragSrc << " o_color = vec4(val2[0], 1.0);\n"; 2151e5c31af7Sopenharmony_ci break; 2152e5c31af7Sopenharmony_ci case 1: 2153e5c31af7Sopenharmony_ci fragSrc << " o_color = vec4(val1);\n"; 2154e5c31af7Sopenharmony_ci break; 2155e5c31af7Sopenharmony_ci default: 2156e5c31af7Sopenharmony_ci fragSrc << " o_color = vec4(val0, val0, val0, 1.0);\n"; 2157e5c31af7Sopenharmony_ci break; 2158e5c31af7Sopenharmony_ci } 2159e5c31af7Sopenharmony_ci 2160e5c31af7Sopenharmony_ci fragSrc << "}\n"; 2161e5c31af7Sopenharmony_ci 2162e5c31af7Sopenharmony_ci outFragSrc = fragSrc.str(); 2163e5c31af7Sopenharmony_ci } 2164e5c31af7Sopenharmony_ci 2165e5c31af7Sopenharmony_ci // Verify the surface is filled with the expected color 2166e5c31af7Sopenharmony_ci bool checkSurface(tcu::Surface surface, tcu::RGBA expectedColor) 2167e5c31af7Sopenharmony_ci { 2168e5c31af7Sopenharmony_ci int numFailedPixels = 0; 2169e5c31af7Sopenharmony_ci for (int y = 0; y < surface.getHeight(); y++) 2170e5c31af7Sopenharmony_ci { 2171e5c31af7Sopenharmony_ci for (int x = 0; x < surface.getWidth(); x++) 2172e5c31af7Sopenharmony_ci { 2173e5c31af7Sopenharmony_ci if (surface.getPixel(x, y) != expectedColor) 2174e5c31af7Sopenharmony_ci numFailedPixels += 1; 2175e5c31af7Sopenharmony_ci } 2176e5c31af7Sopenharmony_ci } 2177e5c31af7Sopenharmony_ci 2178e5c31af7Sopenharmony_ci return (numFailedPixels == 0); 2179e5c31af7Sopenharmony_ci } 2180e5c31af7Sopenharmony_ci 2181e5c31af7Sopenharmony_ci IterateResult iterate(void) 2182e5c31af7Sopenharmony_ci { 2183e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 2184e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2185e5c31af7Sopenharmony_ci const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget(); 2186e5c31af7Sopenharmony_ci int viewportW = de::min(16, renderTarget.getWidth()); 2187e5c31af7Sopenharmony_ci int viewportH = de::min(16, renderTarget.getHeight()); 2188e5c31af7Sopenharmony_ci tcu::Surface renderedFrame(viewportW, viewportH); 2189e5c31af7Sopenharmony_ci 2190e5c31af7Sopenharmony_ci glw::GLuint programA, programB; 2191e5c31af7Sopenharmony_ci glw::GLuint vao, vertexBuf, indexBuf; 2192e5c31af7Sopenharmony_ci std::string vtx; 2193e5c31af7Sopenharmony_ci std::string frag, frag2; 2194e5c31af7Sopenharmony_ci glw::GLuint pipeline; 2195e5c31af7Sopenharmony_ci const char* srcStrings[1]; 2196e5c31af7Sopenharmony_ci glw::GLenum err; 2197e5c31af7Sopenharmony_ci 2198e5c31af7Sopenharmony_ci log << TestLog::Message << "Begin:StateInteractionCase iterate" << TestLog::EndMessage; 2199e5c31af7Sopenharmony_ci 2200e5c31af7Sopenharmony_ci gl.viewport(0, 0, viewportW, viewportH); 2201e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 2202e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 2203e5c31af7Sopenharmony_ci 2204e5c31af7Sopenharmony_ci // Check the precedence of glUseProgram over glBindProgramPipeline 2205e5c31af7Sopenharmony_ci // The program bound with glUseProgram will draw green, the programs 2206e5c31af7Sopenharmony_ci // bound with glBindProgramPipeline will render blue. 2207e5c31af7Sopenharmony_ci vtx = generateBasicVertexSrc(m_glslVersion); 2208e5c31af7Sopenharmony_ci frag = generateBasicFragmentSrc(m_glslVersion); 2209e5c31af7Sopenharmony_ci 2210e5c31af7Sopenharmony_ci glu::ShaderProgram progVF(m_context.getRenderContext(), glu::makeVtxFragSources(vtx.c_str(), frag.c_str())); 2211e5c31af7Sopenharmony_ci 2212e5c31af7Sopenharmony_ci gl.useProgram(progVF.getProgram()); 2213e5c31af7Sopenharmony_ci // Ouput green in the fragment shader 2214e5c31af7Sopenharmony_ci gl.uniform4f(gl.getUniformLocation(progVF.getProgram(), "u_color"), 0.0f, 1.0f, 0.0f, 1.0f); 2215e5c31af7Sopenharmony_ci 2216e5c31af7Sopenharmony_ci // Create and bind a pipeline with a different fragment shader 2217e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, &pipeline); 2218e5c31af7Sopenharmony_ci // Use a different uniform name in another fragment shader 2219e5c31af7Sopenharmony_ci frag2 = frag; 2220e5c31af7Sopenharmony_ci size_t pos = 0; 2221e5c31af7Sopenharmony_ci while ((pos = frag2.find("u_color", pos)) != std::string::npos) 2222e5c31af7Sopenharmony_ci { 2223e5c31af7Sopenharmony_ci frag2.replace(pos, 7, "u_clrPB"); 2224e5c31af7Sopenharmony_ci pos += 7; 2225e5c31af7Sopenharmony_ci } 2226e5c31af7Sopenharmony_ci 2227e5c31af7Sopenharmony_ci srcStrings[0] = vtx.c_str(); 2228e5c31af7Sopenharmony_ci programA = gl.createShaderProgramv(GL_VERTEX_SHADER, 1, srcStrings); 2229e5c31af7Sopenharmony_ci if (!checkCSProg(gl, programA)) 2230e5c31af7Sopenharmony_ci { 2231e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed for vertex shader"); 2232e5c31af7Sopenharmony_ci } 2233e5c31af7Sopenharmony_ci srcStrings[0] = frag2.c_str(); 2234e5c31af7Sopenharmony_ci programB = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1, srcStrings); 2235e5c31af7Sopenharmony_ci if (!checkCSProg(gl, programB)) 2236e5c31af7Sopenharmony_ci { 2237e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed for fragment shader"); 2238e5c31af7Sopenharmony_ci } 2239e5c31af7Sopenharmony_ci // Program B outputs blue. 2240e5c31af7Sopenharmony_ci gl.programUniform4f(programB, gl.getUniformLocation(programB, "u_clrPB"), 0.0f, 0.0f, 1.0f, 1.0f); 2241e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, programA); 2242e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, programB); 2243e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipeline); 2244e5c31af7Sopenharmony_ci 2245e5c31af7Sopenharmony_ci static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 }; 2246e5c31af7Sopenharmony_ci const float position[] = { -1.0f, -1.0f, +1.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f, 2247e5c31af7Sopenharmony_ci +1.0f, -1.0f, 0.0f, 1.0f, +1.0f, +1.0f, -1.0f, 1.0f }; 2248e5c31af7Sopenharmony_ci 2249e5c31af7Sopenharmony_ci // Draw a quad with glu::draw 2250e5c31af7Sopenharmony_ci glu::VertexArrayBinding posArray = glu::va::Float("a_position", 4, 4, 0, &position[0]); 2251e5c31af7Sopenharmony_ci glu::draw(m_context.getRenderContext(), progVF.getProgram(), 1, &posArray, 2252e5c31af7Sopenharmony_ci glu::pr::Triangles(DE_LENGTH_OF_ARRAY(quadIndices), &quadIndices[0])); 2253e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "StateInteraction glu::draw failure"); 2254e5c31af7Sopenharmony_ci 2255e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, renderedFrame.getAccess()); 2256e5c31af7Sopenharmony_ci 2257e5c31af7Sopenharmony_ci // useProgram takes precedence and the buffer should be green 2258e5c31af7Sopenharmony_ci if (!checkSurface(renderedFrame, tcu::RGBA::green())) 2259e5c31af7Sopenharmony_ci { 2260e5c31af7Sopenharmony_ci TCU_FAIL("StateInteraction failed; surface should be green"); 2261e5c31af7Sopenharmony_ci } 2262e5c31af7Sopenharmony_ci 2263e5c31af7Sopenharmony_ci // The position attribute locations may be different. 2264e5c31af7Sopenharmony_ci int posLoc = gl.getAttribLocation(progVF.getProgram(), "a_position"); 2265e5c31af7Sopenharmony_ci 2266e5c31af7Sopenharmony_ci if (glu::isContextTypeES(m_context.getRenderContext().getType())) 2267e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(posLoc); 2268e5c31af7Sopenharmony_ci 2269e5c31af7Sopenharmony_ci /* Set up a vertex array object */ 2270e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &vao); 2271e5c31af7Sopenharmony_ci gl.bindVertexArray(vao); 2272e5c31af7Sopenharmony_ci 2273e5c31af7Sopenharmony_ci gl.genBuffers(1, &indexBuf); 2274e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf); 2275e5c31af7Sopenharmony_ci gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quadIndices), quadIndices, GL_STATIC_DRAW); 2276e5c31af7Sopenharmony_ci 2277e5c31af7Sopenharmony_ci gl.genBuffers(1, &vertexBuf); 2278e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuf); 2279e5c31af7Sopenharmony_ci gl.bufferData(GL_ARRAY_BUFFER, sizeof(position), position, GL_STATIC_DRAW); 2280e5c31af7Sopenharmony_ci 2281e5c31af7Sopenharmony_ci posLoc = gl.getAttribLocation(programA, "a_position"); 2282e5c31af7Sopenharmony_ci gl.vertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, 0); 2283e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(posLoc); 2284e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, 0); 2285e5c31af7Sopenharmony_ci 2286e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "VAO setup failure"); 2287e5c31af7Sopenharmony_ci 2288e5c31af7Sopenharmony_ci // bindProgramPipeline without a program installed by useProgram 2289e5c31af7Sopenharmony_ci // Rerender the quad. Don't use glu::draw because it takes the 2290e5c31af7Sopenharmony_ci // program as a parameter and sets state. 2291e5c31af7Sopenharmony_ci gl.useProgram(0); 2292e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipeline); 2293e5c31af7Sopenharmony_ci 2294e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2295e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements failure"); 2296e5c31af7Sopenharmony_ci 2297e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, renderedFrame.getAccess()); 2298e5c31af7Sopenharmony_ci 2299e5c31af7Sopenharmony_ci // bindProgramPipeline will render blue 2300e5c31af7Sopenharmony_ci if (!checkSurface(renderedFrame, tcu::RGBA::blue())) 2301e5c31af7Sopenharmony_ci { 2302e5c31af7Sopenharmony_ci TCU_FAIL("StateInteraction failed; surface should be blue"); 2303e5c31af7Sopenharmony_ci } 2304e5c31af7Sopenharmony_ci 2305e5c31af7Sopenharmony_ci // Test rendering with no program bound. Rendering is undefined 2306e5c31af7Sopenharmony_ci // but shouldn't produce an error. 2307e5c31af7Sopenharmony_ci gl.useProgram(0); 2308e5c31af7Sopenharmony_ci gl.bindProgramPipeline(0); 2309e5c31af7Sopenharmony_ci 2310e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2311e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements failure"); 2312e5c31af7Sopenharmony_ci 2313e5c31af7Sopenharmony_ci // Render call with missing pipeline stages should not generate an error 2314e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, 0); 2315e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, programB); 2316e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipeline); 2317e5c31af7Sopenharmony_ci 2318e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2319e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements failure"); 2320e5c31af7Sopenharmony_ci 2321e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, programA); 2322e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, 0); 2323e5c31af7Sopenharmony_ci 2324e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2325e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements failure"); 2326e5c31af7Sopenharmony_ci 2327e5c31af7Sopenharmony_ci // Missing program for fragment shader 2328e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT, programA); 2329e5c31af7Sopenharmony_ci 2330e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2331e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements failure"); 2332e5c31af7Sopenharmony_ci 2333e5c31af7Sopenharmony_ci // Separable program with both vertex and fragment shaders attached to only one stage 2334e5c31af7Sopenharmony_ci 2335e5c31af7Sopenharmony_ci gl.programParameteri(progVF.getProgram(), GL_PROGRAM_SEPARABLE, GL_TRUE); 2336e5c31af7Sopenharmony_ci gl.linkProgram(progVF.getProgram()); 2337e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, progVF.getProgram()); 2338e5c31af7Sopenharmony_ci 2339e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2340e5c31af7Sopenharmony_ci err = gl.getError(); 2341e5c31af7Sopenharmony_ci if (err != GL_INVALID_OPERATION) 2342e5c31af7Sopenharmony_ci { 2343e5c31af7Sopenharmony_ci TCU_FAIL("DrawElements failed"); 2344e5c31af7Sopenharmony_ci } 2345e5c31af7Sopenharmony_ci 2346e5c31af7Sopenharmony_ci gl.validateProgramPipeline(pipeline); 2347e5c31af7Sopenharmony_ci glw::GLint value; 2348e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_VALIDATE_STATUS, (glw::GLint*)&value); 2349e5c31af7Sopenharmony_ci if (value != 0) 2350e5c31af7Sopenharmony_ci { 2351e5c31af7Sopenharmony_ci TCU_FAIL("Program pipeline validation failed"); 2352e5c31af7Sopenharmony_ci } 2353e5c31af7Sopenharmony_ci 2354e5c31af7Sopenharmony_ci // attached to just the fragment shader 2355e5c31af7Sopenharmony_ci // Call validateProgramPipeline before rendering this time 2356e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, 0); 2357e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, progVF.getProgram()); 2358e5c31af7Sopenharmony_ci 2359e5c31af7Sopenharmony_ci gl.validateProgramPipeline(pipeline); 2360e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_VALIDATE_STATUS, (glw::GLint*)&value); 2361e5c31af7Sopenharmony_ci if (value != 0) 2362e5c31af7Sopenharmony_ci { 2363e5c31af7Sopenharmony_ci TCU_FAIL("Program pipeline validation failed"); 2364e5c31af7Sopenharmony_ci } 2365e5c31af7Sopenharmony_ci 2366e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2367e5c31af7Sopenharmony_ci err = gl.getError(); 2368e5c31af7Sopenharmony_ci if (err != GL_INVALID_OPERATION) 2369e5c31af7Sopenharmony_ci { 2370e5c31af7Sopenharmony_ci TCU_FAIL("DrawElements failed"); 2371e5c31af7Sopenharmony_ci } 2372e5c31af7Sopenharmony_ci 2373e5c31af7Sopenharmony_ci // Program deletion 2374e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, programA); 2375e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, programB); 2376e5c31af7Sopenharmony_ci 2377e5c31af7Sopenharmony_ci // Program B renders red this time 2378e5c31af7Sopenharmony_ci gl.programUniform4f(programB, gl.getUniformLocation(programB, "u_clrPB"), 1.0f, 0.0f, 0.0f, 1.0f); 2379e5c31af7Sopenharmony_ci 2380e5c31af7Sopenharmony_ci gl.deleteProgram(programB); 2381e5c31af7Sopenharmony_ci 2382e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2383e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, renderedFrame.getAccess()); 2384e5c31af7Sopenharmony_ci 2385e5c31af7Sopenharmony_ci // expect red 2386e5c31af7Sopenharmony_ci if (!checkSurface(renderedFrame, tcu::RGBA::red())) 2387e5c31af7Sopenharmony_ci { 2388e5c31af7Sopenharmony_ci TCU_FAIL("StateInteraction failed; surface should be red"); 2389e5c31af7Sopenharmony_ci } 2390e5c31af7Sopenharmony_ci 2391e5c31af7Sopenharmony_ci // Attach new shader 2392e5c31af7Sopenharmony_ci srcStrings[0] = frag2.c_str(); 2393e5c31af7Sopenharmony_ci programB = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1, srcStrings); 2394e5c31af7Sopenharmony_ci if (!checkCSProg(gl, programB)) 2395e5c31af7Sopenharmony_ci { 2396e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed for fragment shader"); 2397e5c31af7Sopenharmony_ci } 2398e5c31af7Sopenharmony_ci // Render green 2399e5c31af7Sopenharmony_ci gl.programUniform4f(programB, gl.getUniformLocation(programB, "u_clrPB"), 0.0f, 1.0f, 0.0f, 1.0f); 2400e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, programB); 2401e5c31af7Sopenharmony_ci 2402e5c31af7Sopenharmony_ci // new shader 2403e5c31af7Sopenharmony_ci glw::GLuint vshader = gl.createShader(GL_FRAGMENT_SHADER); 2404e5c31af7Sopenharmony_ci srcStrings[0] = frag.c_str(); // First frag shader with u_color uniform 2405e5c31af7Sopenharmony_ci gl.shaderSource(vshader, 1, srcStrings, NULL); 2406e5c31af7Sopenharmony_ci gl.compileShader(vshader); 2407e5c31af7Sopenharmony_ci gl.getShaderiv(vshader, GL_COMPILE_STATUS, &value); 2408e5c31af7Sopenharmony_ci DE_ASSERT(value == GL_TRUE); 2409e5c31af7Sopenharmony_ci gl.attachShader(programB, vshader); 2410e5c31af7Sopenharmony_ci 2411e5c31af7Sopenharmony_ci // changing shader shouldn't affect link_status 2412e5c31af7Sopenharmony_ci gl.getProgramiv(programB, GL_LINK_STATUS, &value); 2413e5c31af7Sopenharmony_ci if (value != 1) 2414e5c31af7Sopenharmony_ci { 2415e5c31af7Sopenharmony_ci TCU_FAIL("Shader attachment shouldn't affect link status"); 2416e5c31af7Sopenharmony_ci } 2417e5c31af7Sopenharmony_ci 2418e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2419e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements failure"); 2420e5c31af7Sopenharmony_ci 2421e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, renderedFrame.getAccess()); 2422e5c31af7Sopenharmony_ci 2423e5c31af7Sopenharmony_ci // expect green 2424e5c31af7Sopenharmony_ci if (!checkSurface(renderedFrame, tcu::RGBA::green())) 2425e5c31af7Sopenharmony_ci { 2426e5c31af7Sopenharmony_ci TCU_FAIL("StateInteraction failed; surface should be green"); 2427e5c31af7Sopenharmony_ci } 2428e5c31af7Sopenharmony_ci 2429e5c31af7Sopenharmony_ci // Negative Case: Unsuccessfully linked program should not affect current program 2430e5c31af7Sopenharmony_ci 2431e5c31af7Sopenharmony_ci // Render white 2432e5c31af7Sopenharmony_ci gl.programUniform4f(programB, gl.getUniformLocation(programB, "u_clrPB"), 1.0f, 1.0f, 1.0f, 1.0f); 2433e5c31af7Sopenharmony_ci std::string noMain = frag; 2434e5c31af7Sopenharmony_ci pos = noMain.find("main", 0); 2435e5c31af7Sopenharmony_ci noMain.replace(pos, 4, "niaM"); 2436e5c31af7Sopenharmony_ci 2437e5c31af7Sopenharmony_ci srcStrings[0] = noMain.c_str(); 2438e5c31af7Sopenharmony_ci gl.shaderSource(vshader, 1, srcStrings, NULL); 2439e5c31af7Sopenharmony_ci gl.compileShader(vshader); 2440e5c31af7Sopenharmony_ci gl.getShaderiv(vshader, GL_COMPILE_STATUS, &value); 2441e5c31af7Sopenharmony_ci gl.attachShader(programB, vshader); 2442e5c31af7Sopenharmony_ci gl.linkProgram(programB); 2443e5c31af7Sopenharmony_ci err = gl.getError(); 2444e5c31af7Sopenharmony_ci 2445e5c31af7Sopenharmony_ci // link_status should be false 2446e5c31af7Sopenharmony_ci gl.getProgramiv(programB, GL_LINK_STATUS, &value); 2447e5c31af7Sopenharmony_ci if (value != 0) 2448e5c31af7Sopenharmony_ci { 2449e5c31af7Sopenharmony_ci TCU_FAIL("StateInteraction failed; link failure"); 2450e5c31af7Sopenharmony_ci } 2451e5c31af7Sopenharmony_ci 2452e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2453e5c31af7Sopenharmony_ci 2454e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, renderedFrame.getAccess()); 2455e5c31af7Sopenharmony_ci 2456e5c31af7Sopenharmony_ci // expect white 2457e5c31af7Sopenharmony_ci if (!checkSurface(renderedFrame, tcu::RGBA::white())) 2458e5c31af7Sopenharmony_ci { 2459e5c31af7Sopenharmony_ci TCU_FAIL("StateInteraction failed; surface should be white"); 2460e5c31af7Sopenharmony_ci } 2461e5c31af7Sopenharmony_ci 2462e5c31af7Sopenharmony_ci gl.deleteProgram(programA); 2463e5c31af7Sopenharmony_ci gl.deleteProgram(programB); 2464e5c31af7Sopenharmony_ci 2465e5c31af7Sopenharmony_ci // Shader interface matching inputs/outputs 2466e5c31af7Sopenharmony_ci 2467e5c31af7Sopenharmony_ci int maxVars = 6; // generate code supports 6 variables 2468e5c31af7Sopenharmony_ci for (int numInputs = 0; numInputs < maxVars; numInputs++) 2469e5c31af7Sopenharmony_ci { 2470e5c31af7Sopenharmony_ci for (int numOutputs = 0; numOutputs < maxVars; numOutputs++) 2471e5c31af7Sopenharmony_ci { 2472e5c31af7Sopenharmony_ci 2473e5c31af7Sopenharmony_ci generateVarLinkVertexShaderSrc(vtx, m_glslVersion, numOutputs); 2474e5c31af7Sopenharmony_ci generateVarLinkFragmentShaderSrc(frag, m_glslVersion, numInputs); 2475e5c31af7Sopenharmony_ci 2476e5c31af7Sopenharmony_ci srcStrings[0] = vtx.c_str(); 2477e5c31af7Sopenharmony_ci programA = gl.createShaderProgramv(GL_VERTEX_SHADER, 1, srcStrings); 2478e5c31af7Sopenharmony_ci if (!checkCSProg(gl, programA)) 2479e5c31af7Sopenharmony_ci { 2480e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed for vertex shader"); 2481e5c31af7Sopenharmony_ci } 2482e5c31af7Sopenharmony_ci 2483e5c31af7Sopenharmony_ci srcStrings[0] = frag.c_str(); 2484e5c31af7Sopenharmony_ci programB = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1, srcStrings); 2485e5c31af7Sopenharmony_ci if (!checkCSProg(gl, programB)) 2486e5c31af7Sopenharmony_ci { 2487e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed for fragment shader"); 2488e5c31af7Sopenharmony_ci } 2489e5c31af7Sopenharmony_ci 2490e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, programA); 2491e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, programB); 2492e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgramStages failure"); 2493e5c31af7Sopenharmony_ci 2494e5c31af7Sopenharmony_ci gl.validateProgramPipeline(pipeline); 2495e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_VALIDATE_STATUS, (glw::GLint*)&value); 2496e5c31af7Sopenharmony_ci 2497e5c31af7Sopenharmony_ci // Matched input and output variables should render 2498e5c31af7Sopenharmony_ci if (numInputs == numOutputs) 2499e5c31af7Sopenharmony_ci { 2500e5c31af7Sopenharmony_ci if (value != 1) 2501e5c31af7Sopenharmony_ci { 2502e5c31af7Sopenharmony_ci log << TestLog::Message << "Matched input and output variables should validate successfully.\n" 2503e5c31af7Sopenharmony_ci << "Vertex Shader:\n" 2504e5c31af7Sopenharmony_ci << vtx << "Fragment Shader:\n" 2505e5c31af7Sopenharmony_ci << frag << TestLog::EndMessage; 2506e5c31af7Sopenharmony_ci TCU_FAIL("StateInteraction failed"); 2507e5c31af7Sopenharmony_ci } 2508e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 2509e5c31af7Sopenharmony_ci // white 2510e5c31af7Sopenharmony_ci gl.programUniform4f(programA, gl.getUniformLocation(programA, "u_color"), 1.0f, 1.0f, 1.0f, 1.0f); 2511e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2512e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements failure"); 2513e5c31af7Sopenharmony_ci 2514e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, renderedFrame.getAccess()); 2515e5c31af7Sopenharmony_ci 2516e5c31af7Sopenharmony_ci // expect white 2517e5c31af7Sopenharmony_ci if (!checkSurface(renderedFrame, tcu::RGBA::white())) 2518e5c31af7Sopenharmony_ci { 2519e5c31af7Sopenharmony_ci TCU_FAIL("StateInteraction failed; surface should be white"); 2520e5c31af7Sopenharmony_ci } 2521e5c31af7Sopenharmony_ci } 2522e5c31af7Sopenharmony_ci else 2523e5c31af7Sopenharmony_ci { 2524e5c31af7Sopenharmony_ci // Mismatched input and output variables 2525e5c31af7Sopenharmony_ci // For OpenGL ES contexts, this should cause a validation failure 2526e5c31af7Sopenharmony_ci // For OpenGL contexts, validation should succeed. 2527e5c31af7Sopenharmony_ci if (glu::isContextTypeES(m_context.getRenderContext().getType()) != (value == 0)) 2528e5c31af7Sopenharmony_ci { 2529e5c31af7Sopenharmony_ci log << TestLog::Message << "Mismatched input and output variables; validation should " 2530e5c31af7Sopenharmony_ci << (glu::isContextTypeES(m_context.getRenderContext().getType()) ? "fail.\n" : "succeed.\n") 2531e5c31af7Sopenharmony_ci << "Vertex Shader:\n" 2532e5c31af7Sopenharmony_ci << vtx << "Fragment Shader:\n" 2533e5c31af7Sopenharmony_ci << frag << TestLog::EndMessage; 2534e5c31af7Sopenharmony_ci TCU_FAIL("StateInteraction failed"); 2535e5c31af7Sopenharmony_ci } 2536e5c31af7Sopenharmony_ci } 2537e5c31af7Sopenharmony_ci 2538e5c31af7Sopenharmony_ci gl.deleteProgram(programA); 2539e5c31af7Sopenharmony_ci gl.deleteProgram(programB); 2540e5c31af7Sopenharmony_ci } 2541e5c31af7Sopenharmony_ci } 2542e5c31af7Sopenharmony_ci 2543e5c31af7Sopenharmony_ci gl.bindProgramPipeline(0); 2544e5c31af7Sopenharmony_ci gl.bindVertexArray(0); 2545e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, &pipeline); 2546e5c31af7Sopenharmony_ci gl.deleteShader(vshader); 2547e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &vao); 2548e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &indexBuf); 2549e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &vertexBuf); 2550e5c31af7Sopenharmony_ci 2551e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2552e5c31af7Sopenharmony_ci return STOP; 2553e5c31af7Sopenharmony_ci } 2554e5c31af7Sopenharmony_ci 2555e5c31af7Sopenharmony_ciprivate: 2556e5c31af7Sopenharmony_ci glu::GLSLVersion m_glslVersion; 2557e5c31af7Sopenharmony_ci}; 2558e5c31af7Sopenharmony_ci 2559e5c31af7Sopenharmony_ci// Testcase for interface qualifiers matching 2560e5c31af7Sopenharmony_ciclass InterfaceMatchingCase : public TestCase 2561e5c31af7Sopenharmony_ci{ 2562e5c31af7Sopenharmony_cipublic: 2563e5c31af7Sopenharmony_ci enum TestType 2564e5c31af7Sopenharmony_ci { 2565e5c31af7Sopenharmony_ci DEFAULT_PRECISION, 2566e5c31af7Sopenharmony_ci SET_DEFAULT_PRECISION, 2567e5c31af7Sopenharmony_ci SET_PRECISION 2568e5c31af7Sopenharmony_ci }; 2569e5c31af7Sopenharmony_ci 2570e5c31af7Sopenharmony_ci std::string getTestTypeName(TestType testType) 2571e5c31af7Sopenharmony_ci { 2572e5c31af7Sopenharmony_ci switch (testType) 2573e5c31af7Sopenharmony_ci { 2574e5c31af7Sopenharmony_ci case DEFAULT_PRECISION: 2575e5c31af7Sopenharmony_ci return "use predeclared precision"; 2576e5c31af7Sopenharmony_ci case SET_DEFAULT_PRECISION: 2577e5c31af7Sopenharmony_ci return "set default precision"; 2578e5c31af7Sopenharmony_ci case SET_PRECISION: 2579e5c31af7Sopenharmony_ci return "explicit precision"; 2580e5c31af7Sopenharmony_ci } 2581e5c31af7Sopenharmony_ci return ""; 2582e5c31af7Sopenharmony_ci } 2583e5c31af7Sopenharmony_ci 2584e5c31af7Sopenharmony_ci InterfaceMatchingCase(Context& context, const char* name, glu::GLSLVersion glslVersion) 2585e5c31af7Sopenharmony_ci : TestCase(context, name, "matching precision qualifiers between stages"), m_glslVersion(glslVersion) 2586e5c31af7Sopenharmony_ci { 2587e5c31af7Sopenharmony_ci } 2588e5c31af7Sopenharmony_ci 2589e5c31af7Sopenharmony_ci ~InterfaceMatchingCase(void) 2590e5c31af7Sopenharmony_ci { 2591e5c31af7Sopenharmony_ci } 2592e5c31af7Sopenharmony_ci 2593e5c31af7Sopenharmony_ci string getDefaultFragmentPrecision() 2594e5c31af7Sopenharmony_ci { 2595e5c31af7Sopenharmony_ci return ""; 2596e5c31af7Sopenharmony_ci } 2597e5c31af7Sopenharmony_ci 2598e5c31af7Sopenharmony_ci // Generate a vertex shader for variable input/output precision testing 2599e5c31af7Sopenharmony_ci virtual void generateVarLinkVertexShaderSrc(std::string& outVtxSrc, glu::GLSLVersion glslVersion, 2600e5c31af7Sopenharmony_ci const string& precision, TestType testMode) = 0; 2601e5c31af7Sopenharmony_ci 2602e5c31af7Sopenharmony_ci // Generate a fragment shader for variable input/output precision testing 2603e5c31af7Sopenharmony_ci virtual void generateVarLinkFragmentShaderSrc(std::string& outFragSrc, glu::GLSLVersion glslVersion, 2604e5c31af7Sopenharmony_ci const string& precision, TestType testMode) = 0; 2605e5c31af7Sopenharmony_ci 2606e5c31af7Sopenharmony_ci // Verify the surface is filled with the expected color 2607e5c31af7Sopenharmony_ci bool checkSurface(tcu::Surface surface, tcu::RGBA expectedColor) 2608e5c31af7Sopenharmony_ci { 2609e5c31af7Sopenharmony_ci int numFailedPixels = 0; 2610e5c31af7Sopenharmony_ci for (int y = 0; y < surface.getHeight(); y++) 2611e5c31af7Sopenharmony_ci { 2612e5c31af7Sopenharmony_ci for (int x = 0; x < surface.getWidth(); x++) 2613e5c31af7Sopenharmony_ci { 2614e5c31af7Sopenharmony_ci if (surface.getPixel(x, y) != expectedColor) 2615e5c31af7Sopenharmony_ci numFailedPixels += 1; 2616e5c31af7Sopenharmony_ci } 2617e5c31af7Sopenharmony_ci } 2618e5c31af7Sopenharmony_ci return (numFailedPixels == 0); 2619e5c31af7Sopenharmony_ci } 2620e5c31af7Sopenharmony_ci 2621e5c31af7Sopenharmony_ci // Log the program info log 2622e5c31af7Sopenharmony_ci void logProgramInfoLog(const glw::Functions& gl, glw::GLuint program) 2623e5c31af7Sopenharmony_ci { 2624e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 2625e5c31af7Sopenharmony_ci glw::GLint value = 0; 2626e5c31af7Sopenharmony_ci glw::GLsizei bufSize = 0; 2627e5c31af7Sopenharmony_ci glw::GLsizei length = 0; 2628e5c31af7Sopenharmony_ci 2629e5c31af7Sopenharmony_ci gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &value); 2630e5c31af7Sopenharmony_ci std::vector<char> infoLogBuf(value + 1); 2631e5c31af7Sopenharmony_ci 2632e5c31af7Sopenharmony_ci gl.getProgramInfoLog(program, bufSize, &length, &infoLogBuf[0]); 2633e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog failed"); 2634e5c31af7Sopenharmony_ci 2635e5c31af7Sopenharmony_ci log << TestLog::Message << "Program Log:\n" << &infoLogBuf[0] << TestLog::EndMessage; 2636e5c31af7Sopenharmony_ci } 2637e5c31af7Sopenharmony_ci 2638e5c31af7Sopenharmony_ci // Check program validity created with CreateShaderProgram 2639e5c31af7Sopenharmony_ci bool checkCSProg(const glw::Functions& gl, GLuint program, int expectedLink = GL_TRUE) 2640e5c31af7Sopenharmony_ci { 2641e5c31af7Sopenharmony_ci int linked = GL_FALSE; 2642e5c31af7Sopenharmony_ci if (program != 0) 2643e5c31af7Sopenharmony_ci { 2644e5c31af7Sopenharmony_ci gl.getProgramiv(program, GL_LINK_STATUS, &linked); 2645e5c31af7Sopenharmony_ci 2646e5c31af7Sopenharmony_ci if (expectedLink && !linked) 2647e5c31af7Sopenharmony_ci { 2648e5c31af7Sopenharmony_ci logProgramInfoLog(gl, program); 2649e5c31af7Sopenharmony_ci } 2650e5c31af7Sopenharmony_ci } 2651e5c31af7Sopenharmony_ci 2652e5c31af7Sopenharmony_ci return (program != 0) && (linked == expectedLink); 2653e5c31af7Sopenharmony_ci } 2654e5c31af7Sopenharmony_ci 2655e5c31af7Sopenharmony_ci IterateResult iterate(void) 2656e5c31af7Sopenharmony_ci { 2657e5c31af7Sopenharmony_ci TestLog& log = m_testCtx.getLog(); 2658e5c31af7Sopenharmony_ci const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2659e5c31af7Sopenharmony_ci const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget(); 2660e5c31af7Sopenharmony_ci int viewportW = de::min(16, renderTarget.getWidth()); 2661e5c31af7Sopenharmony_ci int viewportH = de::min(16, renderTarget.getHeight()); 2662e5c31af7Sopenharmony_ci tcu::Surface renderedFrame(viewportW, viewportH); 2663e5c31af7Sopenharmony_ci 2664e5c31af7Sopenharmony_ci glw::GLuint programA, programB; 2665e5c31af7Sopenharmony_ci glw::GLuint vao, vertexBuf, indexBuf; 2666e5c31af7Sopenharmony_ci std::string vtx; 2667e5c31af7Sopenharmony_ci std::string frag, frag2; 2668e5c31af7Sopenharmony_ci glw::GLuint pipeline; 2669e5c31af7Sopenharmony_ci const char* srcStrings[1]; 2670e5c31af7Sopenharmony_ci glw::GLuint value; 2671e5c31af7Sopenharmony_ci 2672e5c31af7Sopenharmony_ci gl.viewport(0, 0, viewportW, viewportH); 2673e5c31af7Sopenharmony_ci gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); 2674e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 2675e5c31af7Sopenharmony_ci 2676e5c31af7Sopenharmony_ci static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 }; 2677e5c31af7Sopenharmony_ci const float position[] = { -1.0f, -1.0f, +1.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f, 2678e5c31af7Sopenharmony_ci +1.0f, -1.0f, 0.0f, 1.0f, +1.0f, +1.0f, -1.0f, 1.0f }; 2679e5c31af7Sopenharmony_ci 2680e5c31af7Sopenharmony_ci /* Set up a vertex array object */ 2681e5c31af7Sopenharmony_ci gl.genVertexArrays(1, &vao); 2682e5c31af7Sopenharmony_ci gl.bindVertexArray(vao); 2683e5c31af7Sopenharmony_ci 2684e5c31af7Sopenharmony_ci gl.genBuffers(1, &indexBuf); 2685e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf); 2686e5c31af7Sopenharmony_ci gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quadIndices), quadIndices, GL_STATIC_DRAW); 2687e5c31af7Sopenharmony_ci 2688e5c31af7Sopenharmony_ci gl.genBuffers(1, &vertexBuf); 2689e5c31af7Sopenharmony_ci gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuf); 2690e5c31af7Sopenharmony_ci gl.bufferData(GL_ARRAY_BUFFER, sizeof(position), position, GL_STATIC_DRAW); 2691e5c31af7Sopenharmony_ci 2692e5c31af7Sopenharmony_ci /* Set up shader pipeline */ 2693e5c31af7Sopenharmony_ci gl.genProgramPipelines(1, &pipeline); 2694e5c31af7Sopenharmony_ci gl.bindProgramPipeline(pipeline); 2695e5c31af7Sopenharmony_ci 2696e5c31af7Sopenharmony_ci struct PrecisionTests 2697e5c31af7Sopenharmony_ci { 2698e5c31af7Sopenharmony_ci TestType testType; 2699e5c31af7Sopenharmony_ci std::string precision; 2700e5c31af7Sopenharmony_ci }; 2701e5c31af7Sopenharmony_ci 2702e5c31af7Sopenharmony_ci PrecisionTests vertexPrecisionTests[] = { 2703e5c31af7Sopenharmony_ci { DEFAULT_PRECISION, "highp" }, { SET_DEFAULT_PRECISION, "highp" }, { SET_DEFAULT_PRECISION, "mediump" }, 2704e5c31af7Sopenharmony_ci { SET_DEFAULT_PRECISION, "lowp" }, { SET_PRECISION, "highp" }, { SET_PRECISION, "mediump" }, 2705e5c31af7Sopenharmony_ci { SET_PRECISION, "lowp" } 2706e5c31af7Sopenharmony_ci }; 2707e5c31af7Sopenharmony_ci 2708e5c31af7Sopenharmony_ci PrecisionTests fragmentPrecisionTests[] = { { DEFAULT_PRECISION, getDefaultFragmentPrecision() }, 2709e5c31af7Sopenharmony_ci { SET_DEFAULT_PRECISION, "highp" }, 2710e5c31af7Sopenharmony_ci { SET_DEFAULT_PRECISION, "mediump" }, 2711e5c31af7Sopenharmony_ci { SET_DEFAULT_PRECISION, "lowp" }, 2712e5c31af7Sopenharmony_ci { SET_PRECISION, "highp" }, 2713e5c31af7Sopenharmony_ci { SET_PRECISION, "mediump" }, 2714e5c31af7Sopenharmony_ci { SET_PRECISION, "lowp" } }; 2715e5c31af7Sopenharmony_ci 2716e5c31af7Sopenharmony_ci // Shader interface matching inputs/outputs precision 2717e5c31af7Sopenharmony_ci int maxTests = 7; 2718e5c31af7Sopenharmony_ci for (int vertexTestIteration = 0; vertexTestIteration < maxTests; vertexTestIteration++) 2719e5c31af7Sopenharmony_ci { 2720e5c31af7Sopenharmony_ci std::string vertexPrecision = vertexPrecisionTests[vertexTestIteration].precision; 2721e5c31af7Sopenharmony_ci TestType vertexTestType = vertexPrecisionTests[vertexTestIteration].testType; 2722e5c31af7Sopenharmony_ci for (int fragmentTestIteration = 0; fragmentTestIteration < maxTests; fragmentTestIteration++) 2723e5c31af7Sopenharmony_ci { 2724e5c31af7Sopenharmony_ci std::string fragmentPrecision = fragmentPrecisionTests[fragmentTestIteration].precision; 2725e5c31af7Sopenharmony_ci TestType fragmentTestType = fragmentPrecisionTests[fragmentTestIteration].testType; 2726e5c31af7Sopenharmony_ci if (fragmentPrecision.empty()) 2727e5c31af7Sopenharmony_ci continue; 2728e5c31af7Sopenharmony_ci 2729e5c31af7Sopenharmony_ci log << TestLog::Message << "vertex shader precision: " << vertexPrecision 2730e5c31af7Sopenharmony_ci << ", shader test mode: " << getTestTypeName(vertexTestType) << TestLog::EndMessage; 2731e5c31af7Sopenharmony_ci 2732e5c31af7Sopenharmony_ci log << TestLog::Message << "fragment shader precision: " << fragmentPrecision 2733e5c31af7Sopenharmony_ci << ", shader test mode: " << getTestTypeName(fragmentTestType) << TestLog::EndMessage; 2734e5c31af7Sopenharmony_ci 2735e5c31af7Sopenharmony_ci generateVarLinkVertexShaderSrc(vtx, m_glslVersion, vertexPrecision, vertexTestType); 2736e5c31af7Sopenharmony_ci generateVarLinkFragmentShaderSrc(frag, m_glslVersion, fragmentPrecision, fragmentTestType); 2737e5c31af7Sopenharmony_ci 2738e5c31af7Sopenharmony_ci srcStrings[0] = vtx.c_str(); 2739e5c31af7Sopenharmony_ci programA = gl.createShaderProgramv(GL_VERTEX_SHADER, 1, srcStrings); 2740e5c31af7Sopenharmony_ci if (!checkCSProg(gl, programA)) 2741e5c31af7Sopenharmony_ci { 2742e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed for vertex shader"); 2743e5c31af7Sopenharmony_ci } 2744e5c31af7Sopenharmony_ci srcStrings[0] = frag.c_str(); 2745e5c31af7Sopenharmony_ci programB = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1, srcStrings); 2746e5c31af7Sopenharmony_ci if (!checkCSProg(gl, programB)) 2747e5c31af7Sopenharmony_ci { 2748e5c31af7Sopenharmony_ci TCU_FAIL("CreateShaderProgramv failed for fragment shader"); 2749e5c31af7Sopenharmony_ci } 2750e5c31af7Sopenharmony_ci 2751e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_VERTEX_SHADER_BIT, programA); 2752e5c31af7Sopenharmony_ci gl.useProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, programB); 2753e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "InterfaceMatching failure"); 2754e5c31af7Sopenharmony_ci 2755e5c31af7Sopenharmony_ci // Mismatched input and output qualifiers 2756e5c31af7Sopenharmony_ci // For OpenGL ES contexts, this should result in a validation failure. 2757e5c31af7Sopenharmony_ci // For OpenGL contexts, validation should succeed. 2758e5c31af7Sopenharmony_ci gl.validateProgramPipeline(pipeline); 2759e5c31af7Sopenharmony_ci gl.getProgramPipelineiv(pipeline, GL_VALIDATE_STATUS, (glw::GLint*)&value); 2760e5c31af7Sopenharmony_ci int precisionCompareResult = fragmentPrecision.compare(vertexPrecision); 2761e5c31af7Sopenharmony_ci if (glu::isContextTypeES(m_context.getRenderContext().getType()) && (precisionCompareResult != 0)) 2762e5c31af7Sopenharmony_ci { 2763e5c31af7Sopenharmony_ci // precision mismatch 2764e5c31af7Sopenharmony_ci if (value != GL_FALSE) 2765e5c31af7Sopenharmony_ci { 2766e5c31af7Sopenharmony_ci log.startShaderProgram( 2767e5c31af7Sopenharmony_ci false, "Precision mismatch, pipeline validation status GL_TRUE expected GL_FALSE"); 2768e5c31af7Sopenharmony_ci log.writeShader(QP_SHADER_TYPE_VERTEX, vtx.c_str(), true, ""); 2769e5c31af7Sopenharmony_ci log.writeShader(QP_SHADER_TYPE_FRAGMENT, frag.c_str(), true, ""); 2770e5c31af7Sopenharmony_ci log.endShaderProgram(); 2771e5c31af7Sopenharmony_ci TCU_FAIL("InterfaceMatchingCase failed"); 2772e5c31af7Sopenharmony_ci } 2773e5c31af7Sopenharmony_ci else 2774e5c31af7Sopenharmony_ci { 2775e5c31af7Sopenharmony_ci log << TestLog::Message << "Precision mismatch, Pipeline validation status GL_FALSE -> OK" 2776e5c31af7Sopenharmony_ci << TestLog::EndMessage; 2777e5c31af7Sopenharmony_ci } 2778e5c31af7Sopenharmony_ci } 2779e5c31af7Sopenharmony_ci else 2780e5c31af7Sopenharmony_ci { 2781e5c31af7Sopenharmony_ci if (value != GL_TRUE) 2782e5c31af7Sopenharmony_ci { 2783e5c31af7Sopenharmony_ci std::stringstream str; 2784e5c31af7Sopenharmony_ci str << "Precision " << (precisionCompareResult ? "mismatch" : "matches") 2785e5c31af7Sopenharmony_ci << ", pipeline validation status GL_FALSE expected GL_TRUE"; 2786e5c31af7Sopenharmony_ci 2787e5c31af7Sopenharmony_ci log.startShaderProgram(false, str.str().c_str()); 2788e5c31af7Sopenharmony_ci log.writeShader(QP_SHADER_TYPE_VERTEX, vtx.c_str(), true, ""); 2789e5c31af7Sopenharmony_ci log.writeShader(QP_SHADER_TYPE_FRAGMENT, frag.c_str(), true, ""); 2790e5c31af7Sopenharmony_ci log.endShaderProgram(); 2791e5c31af7Sopenharmony_ci TCU_FAIL("InterfaceMatchingCase failed"); 2792e5c31af7Sopenharmony_ci } 2793e5c31af7Sopenharmony_ci else 2794e5c31af7Sopenharmony_ci { 2795e5c31af7Sopenharmony_ci log << TestLog::Message << "Precision " << (precisionCompareResult ? "mismatch" : "matches") 2796e5c31af7Sopenharmony_ci << ", pipeline validation status GL_TRUE -> OK" << TestLog::EndMessage; 2797e5c31af7Sopenharmony_ci // precision matches 2798e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 2799e5c31af7Sopenharmony_ci // white 2800e5c31af7Sopenharmony_ci int posLoc = gl.getAttribLocation(programA, "a_position"); 2801e5c31af7Sopenharmony_ci gl.vertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, 0); 2802e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(posLoc); 2803e5c31af7Sopenharmony_ci gl.programUniform4f(programA, gl.getUniformLocation(programA, "u_color"), 1.0f, 1.0f, 1.0f, 2804e5c31af7Sopenharmony_ci 1.0f); 2805e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "StateInteraction failure, set uniform value"); 2806e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2807e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "DrawElements failure"); 2808e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(posLoc); 2809e5c31af7Sopenharmony_ci 2810e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, renderedFrame.getAccess()); 2811e5c31af7Sopenharmony_ci 2812e5c31af7Sopenharmony_ci // expect white 2813e5c31af7Sopenharmony_ci if (!checkSurface(renderedFrame, tcu::RGBA::white())) 2814e5c31af7Sopenharmony_ci { 2815e5c31af7Sopenharmony_ci TCU_FAIL("InterfaceMatchingCase failed; surface should be white"); 2816e5c31af7Sopenharmony_ci } 2817e5c31af7Sopenharmony_ci } 2818e5c31af7Sopenharmony_ci } 2819e5c31af7Sopenharmony_ci 2820e5c31af7Sopenharmony_ci // validate non separable program 2821e5c31af7Sopenharmony_ci 2822e5c31af7Sopenharmony_ci glu::ShaderProgram progVF(m_context.getRenderContext(), 2823e5c31af7Sopenharmony_ci glu::makeVtxFragSources(vtx.c_str(), frag.c_str())); 2824e5c31af7Sopenharmony_ci 2825e5c31af7Sopenharmony_ci gl.useProgram(progVF.getProgram()); 2826e5c31af7Sopenharmony_ci gl.uniform4f(gl.getUniformLocation(progVF.getProgram(), "u_color"), 1.0f, 1.0f, 1.0f, 1.0f); 2827e5c31af7Sopenharmony_ci if (!progVF.getProgramInfo().linkOk) 2828e5c31af7Sopenharmony_ci { 2829e5c31af7Sopenharmony_ci log << progVF; 2830e5c31af7Sopenharmony_ci log << TestLog::Message << "Non separable program link status GL_FALSE expected GL_TRUE" 2831e5c31af7Sopenharmony_ci << TestLog::EndMessage; 2832e5c31af7Sopenharmony_ci TCU_FAIL("InterfaceMatchingCase failed, non separable program should link"); 2833e5c31af7Sopenharmony_ci } 2834e5c31af7Sopenharmony_ci 2835e5c31af7Sopenharmony_ci int posLoc = gl.getAttribLocation(progVF.getProgram(), "a_position"); 2836e5c31af7Sopenharmony_ci gl.vertexAttribPointer(posLoc, 4, GL_FLOAT, GL_FALSE, 0, 0); 2837e5c31af7Sopenharmony_ci gl.enableVertexAttribArray(posLoc); 2838e5c31af7Sopenharmony_ci gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(quadIndices), GL_UNSIGNED_SHORT, NULL); 2839e5c31af7Sopenharmony_ci gl.disableVertexAttribArray(posLoc); 2840e5c31af7Sopenharmony_ci 2841e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(gl.getError(), "StateInteraction failure, non separable program draw call"); 2842e5c31af7Sopenharmony_ci glu::readPixels(m_context.getRenderContext(), 0, 0, renderedFrame.getAccess()); 2843e5c31af7Sopenharmony_ci // expect white 2844e5c31af7Sopenharmony_ci if (!checkSurface(renderedFrame, tcu::RGBA::white())) 2845e5c31af7Sopenharmony_ci { 2846e5c31af7Sopenharmony_ci TCU_FAIL("InterfaceMatchingCase failed, non separable program, unexpected color found"); 2847e5c31af7Sopenharmony_ci } 2848e5c31af7Sopenharmony_ci 2849e5c31af7Sopenharmony_ci gl.deleteProgram(programA); 2850e5c31af7Sopenharmony_ci gl.deleteProgram(programB); 2851e5c31af7Sopenharmony_ci gl.useProgram(0); 2852e5c31af7Sopenharmony_ci } 2853e5c31af7Sopenharmony_ci } 2854e5c31af7Sopenharmony_ci gl.bindVertexArray(0); 2855e5c31af7Sopenharmony_ci gl.deleteVertexArrays(1, &vao); 2856e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &indexBuf); 2857e5c31af7Sopenharmony_ci gl.deleteBuffers(1, &vertexBuf); 2858e5c31af7Sopenharmony_ci gl.bindProgramPipeline(0); 2859e5c31af7Sopenharmony_ci gl.deleteProgramPipelines(1, &pipeline); 2860e5c31af7Sopenharmony_ci 2861e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2862e5c31af7Sopenharmony_ci return STOP; 2863e5c31af7Sopenharmony_ci } 2864e5c31af7Sopenharmony_ci 2865e5c31af7Sopenharmony_ciprotected: 2866e5c31af7Sopenharmony_ci glu::GLSLVersion m_glslVersion; 2867e5c31af7Sopenharmony_ci}; 2868e5c31af7Sopenharmony_ci 2869e5c31af7Sopenharmony_ciclass InterfaceMatchingCaseFloat : public InterfaceMatchingCase 2870e5c31af7Sopenharmony_ci{ 2871e5c31af7Sopenharmony_cipublic: 2872e5c31af7Sopenharmony_ci InterfaceMatchingCaseFloat(Context& context, const char* name, glu::GLSLVersion glslVersion) 2873e5c31af7Sopenharmony_ci : InterfaceMatchingCase(context, name, glslVersion) 2874e5c31af7Sopenharmony_ci { 2875e5c31af7Sopenharmony_ci } 2876e5c31af7Sopenharmony_ci 2877e5c31af7Sopenharmony_ci void generateVarLinkVertexShaderSrc(std::string& outVtxSrc, glu::GLSLVersion glslVersion, const string& precision, 2878e5c31af7Sopenharmony_ci TestType testMode) 2879e5c31af7Sopenharmony_ci { 2880e5c31af7Sopenharmony_ci std::ostringstream vtxSrc; 2881e5c31af7Sopenharmony_ci vtxSrc << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 2882e5c31af7Sopenharmony_ci if (glslVersion >= glu::GLSL_VERSION_410) 2883e5c31af7Sopenharmony_ci { 2884e5c31af7Sopenharmony_ci vtxSrc << "out gl_PerVertex {\n" 2885e5c31af7Sopenharmony_ci " vec4 gl_Position;\n" 2886e5c31af7Sopenharmony_ci "};\n"; 2887e5c31af7Sopenharmony_ci } 2888e5c31af7Sopenharmony_ci vtxSrc << "in highp vec4 a_position;\n"; 2889e5c31af7Sopenharmony_ci vtxSrc << "uniform highp vec4 u_color;\n"; 2890e5c31af7Sopenharmony_ci switch (testMode) 2891e5c31af7Sopenharmony_ci { 2892e5c31af7Sopenharmony_ci case SET_DEFAULT_PRECISION: 2893e5c31af7Sopenharmony_ci vtxSrc << "precision " << precision << " float;\n"; 2894e5c31af7Sopenharmony_ci // Fallthrough 2895e5c31af7Sopenharmony_ci case DEFAULT_PRECISION: 2896e5c31af7Sopenharmony_ci vtxSrc << "out float var;\n"; 2897e5c31af7Sopenharmony_ci break; 2898e5c31af7Sopenharmony_ci case SET_PRECISION: 2899e5c31af7Sopenharmony_ci vtxSrc << "out " << precision << " float var;\n"; 2900e5c31af7Sopenharmony_ci break; 2901e5c31af7Sopenharmony_ci } 2902e5c31af7Sopenharmony_ci vtxSrc << "void main (void)\n"; 2903e5c31af7Sopenharmony_ci vtxSrc << "{\n"; 2904e5c31af7Sopenharmony_ci vtxSrc << " gl_Position = a_position;\n"; 2905e5c31af7Sopenharmony_ci vtxSrc << " var = u_color.r;\n"; 2906e5c31af7Sopenharmony_ci vtxSrc << "}\n"; 2907e5c31af7Sopenharmony_ci outVtxSrc = vtxSrc.str(); 2908e5c31af7Sopenharmony_ci } 2909e5c31af7Sopenharmony_ci 2910e5c31af7Sopenharmony_ci void generateVarLinkFragmentShaderSrc(std::string& outFragSrc, glu::GLSLVersion glslVersion, 2911e5c31af7Sopenharmony_ci const string& precision, TestType testMode) 2912e5c31af7Sopenharmony_ci { 2913e5c31af7Sopenharmony_ci std::ostringstream fragSrc; 2914e5c31af7Sopenharmony_ci fragSrc << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 2915e5c31af7Sopenharmony_ci switch (testMode) 2916e5c31af7Sopenharmony_ci { 2917e5c31af7Sopenharmony_ci case SET_DEFAULT_PRECISION: 2918e5c31af7Sopenharmony_ci fragSrc << "precision " << precision << " float;\n"; 2919e5c31af7Sopenharmony_ci // Fallthrough 2920e5c31af7Sopenharmony_ci case DEFAULT_PRECISION: 2921e5c31af7Sopenharmony_ci fragSrc << "in float var;\n"; 2922e5c31af7Sopenharmony_ci break; 2923e5c31af7Sopenharmony_ci case SET_PRECISION: 2924e5c31af7Sopenharmony_ci fragSrc << "in " << precision << " float var;\n"; 2925e5c31af7Sopenharmony_ci break; 2926e5c31af7Sopenharmony_ci } 2927e5c31af7Sopenharmony_ci fragSrc << "layout(location = 0) out mediump vec4 o_color;\n"; 2928e5c31af7Sopenharmony_ci fragSrc << "void main (void)\n"; 2929e5c31af7Sopenharmony_ci fragSrc << "{\n"; 2930e5c31af7Sopenharmony_ci fragSrc << " o_color = vec4(var);\n"; 2931e5c31af7Sopenharmony_ci fragSrc << "}\n"; 2932e5c31af7Sopenharmony_ci outFragSrc = fragSrc.str(); 2933e5c31af7Sopenharmony_ci } 2934e5c31af7Sopenharmony_ci}; 2935e5c31af7Sopenharmony_ci 2936e5c31af7Sopenharmony_ciclass InterfaceMatchingCaseInt : public InterfaceMatchingCase 2937e5c31af7Sopenharmony_ci{ 2938e5c31af7Sopenharmony_cipublic: 2939e5c31af7Sopenharmony_ci InterfaceMatchingCaseInt(Context& context, const char* name, glu::GLSLVersion glslVersion) 2940e5c31af7Sopenharmony_ci : InterfaceMatchingCase(context, name, glslVersion) 2941e5c31af7Sopenharmony_ci { 2942e5c31af7Sopenharmony_ci } 2943e5c31af7Sopenharmony_ci 2944e5c31af7Sopenharmony_ci std::string getDefaultFragmentPrecision() 2945e5c31af7Sopenharmony_ci { 2946e5c31af7Sopenharmony_ci return "mediump"; 2947e5c31af7Sopenharmony_ci } 2948e5c31af7Sopenharmony_ci 2949e5c31af7Sopenharmony_ci void generateVarLinkVertexShaderSrc(std::string& outVtxSrc, glu::GLSLVersion glslVersion, const string& precision, 2950e5c31af7Sopenharmony_ci TestType testMode) 2951e5c31af7Sopenharmony_ci { 2952e5c31af7Sopenharmony_ci std::ostringstream vtxSrc; 2953e5c31af7Sopenharmony_ci vtxSrc << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 2954e5c31af7Sopenharmony_ci if (glslVersion >= glu::GLSL_VERSION_410) 2955e5c31af7Sopenharmony_ci { 2956e5c31af7Sopenharmony_ci vtxSrc << "out gl_PerVertex {\n" 2957e5c31af7Sopenharmony_ci " vec4 gl_Position;\n" 2958e5c31af7Sopenharmony_ci "};\n"; 2959e5c31af7Sopenharmony_ci } 2960e5c31af7Sopenharmony_ci vtxSrc << "in highp vec4 a_position;\n"; 2961e5c31af7Sopenharmony_ci vtxSrc << "uniform highp vec4 u_color;\n"; 2962e5c31af7Sopenharmony_ci switch (testMode) 2963e5c31af7Sopenharmony_ci { 2964e5c31af7Sopenharmony_ci case SET_DEFAULT_PRECISION: 2965e5c31af7Sopenharmony_ci vtxSrc << "precision " << precision << " int;\n"; 2966e5c31af7Sopenharmony_ci // Fallthrough 2967e5c31af7Sopenharmony_ci case DEFAULT_PRECISION: 2968e5c31af7Sopenharmony_ci vtxSrc << "flat out int var;\n"; 2969e5c31af7Sopenharmony_ci break; 2970e5c31af7Sopenharmony_ci case SET_PRECISION: 2971e5c31af7Sopenharmony_ci vtxSrc << "flat out " << precision << " int var;\n"; 2972e5c31af7Sopenharmony_ci break; 2973e5c31af7Sopenharmony_ci } 2974e5c31af7Sopenharmony_ci vtxSrc << "void main (void)\n"; 2975e5c31af7Sopenharmony_ci vtxSrc << "{\n"; 2976e5c31af7Sopenharmony_ci vtxSrc << " gl_Position = a_position;\n"; 2977e5c31af7Sopenharmony_ci vtxSrc << " var = int(u_color.r);\n"; 2978e5c31af7Sopenharmony_ci vtxSrc << "}\n"; 2979e5c31af7Sopenharmony_ci outVtxSrc = vtxSrc.str(); 2980e5c31af7Sopenharmony_ci } 2981e5c31af7Sopenharmony_ci 2982e5c31af7Sopenharmony_ci void generateVarLinkFragmentShaderSrc(std::string& outFragSrc, glu::GLSLVersion glslVersion, 2983e5c31af7Sopenharmony_ci const string& precision, TestType testMode) 2984e5c31af7Sopenharmony_ci { 2985e5c31af7Sopenharmony_ci std::ostringstream fragSrc; 2986e5c31af7Sopenharmony_ci fragSrc << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 2987e5c31af7Sopenharmony_ci switch (testMode) 2988e5c31af7Sopenharmony_ci { 2989e5c31af7Sopenharmony_ci case SET_DEFAULT_PRECISION: 2990e5c31af7Sopenharmony_ci fragSrc << "precision " << precision << " int;\n"; 2991e5c31af7Sopenharmony_ci // Fallthrough 2992e5c31af7Sopenharmony_ci case DEFAULT_PRECISION: 2993e5c31af7Sopenharmony_ci fragSrc << "flat in int var;\n"; 2994e5c31af7Sopenharmony_ci break; 2995e5c31af7Sopenharmony_ci case SET_PRECISION: 2996e5c31af7Sopenharmony_ci fragSrc << "flat in " << precision << " int var;\n"; 2997e5c31af7Sopenharmony_ci break; 2998e5c31af7Sopenharmony_ci } 2999e5c31af7Sopenharmony_ci fragSrc << "layout(location = 0) out mediump vec4 o_color;\n"; 3000e5c31af7Sopenharmony_ci fragSrc << "void main (void)\n"; 3001e5c31af7Sopenharmony_ci fragSrc << "{\n"; 3002e5c31af7Sopenharmony_ci fragSrc << " o_color = vec4(var);\n"; 3003e5c31af7Sopenharmony_ci fragSrc << "}\n"; 3004e5c31af7Sopenharmony_ci outFragSrc = fragSrc.str(); 3005e5c31af7Sopenharmony_ci } 3006e5c31af7Sopenharmony_ci}; 3007e5c31af7Sopenharmony_ci 3008e5c31af7Sopenharmony_ciclass InterfaceMatchingCaseUInt : public InterfaceMatchingCase 3009e5c31af7Sopenharmony_ci{ 3010e5c31af7Sopenharmony_cipublic: 3011e5c31af7Sopenharmony_ci InterfaceMatchingCaseUInt(Context& context, const char* name, glu::GLSLVersion glslVersion) 3012e5c31af7Sopenharmony_ci : InterfaceMatchingCase(context, name, glslVersion) 3013e5c31af7Sopenharmony_ci { 3014e5c31af7Sopenharmony_ci } 3015e5c31af7Sopenharmony_ci 3016e5c31af7Sopenharmony_ci std::string getDefaultFragmentPrecision() 3017e5c31af7Sopenharmony_ci { 3018e5c31af7Sopenharmony_ci return "mediump"; 3019e5c31af7Sopenharmony_ci } 3020e5c31af7Sopenharmony_ci 3021e5c31af7Sopenharmony_ci void generateVarLinkVertexShaderSrc(std::string& outVtxSrc, glu::GLSLVersion glslVersion, const string& precision, 3022e5c31af7Sopenharmony_ci TestType testMode) 3023e5c31af7Sopenharmony_ci { 3024e5c31af7Sopenharmony_ci std::ostringstream vtxSrc; 3025e5c31af7Sopenharmony_ci vtxSrc << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 3026e5c31af7Sopenharmony_ci if (glslVersion >= glu::GLSL_VERSION_410) 3027e5c31af7Sopenharmony_ci { 3028e5c31af7Sopenharmony_ci vtxSrc << "out gl_PerVertex {\n" 3029e5c31af7Sopenharmony_ci " vec4 gl_Position;\n" 3030e5c31af7Sopenharmony_ci "};\n"; 3031e5c31af7Sopenharmony_ci } 3032e5c31af7Sopenharmony_ci vtxSrc << "in highp vec4 a_position;\n"; 3033e5c31af7Sopenharmony_ci vtxSrc << "uniform highp vec4 u_color;\n"; 3034e5c31af7Sopenharmony_ci switch (testMode) 3035e5c31af7Sopenharmony_ci { 3036e5c31af7Sopenharmony_ci case SET_DEFAULT_PRECISION: 3037e5c31af7Sopenharmony_ci vtxSrc << "precision " << precision << " int;\n"; 3038e5c31af7Sopenharmony_ci // Fallthrough 3039e5c31af7Sopenharmony_ci case DEFAULT_PRECISION: 3040e5c31af7Sopenharmony_ci vtxSrc << "flat out uint var;\n"; 3041e5c31af7Sopenharmony_ci break; 3042e5c31af7Sopenharmony_ci case SET_PRECISION: 3043e5c31af7Sopenharmony_ci vtxSrc << "flat out " << precision << " uint var;\n"; 3044e5c31af7Sopenharmony_ci break; 3045e5c31af7Sopenharmony_ci } 3046e5c31af7Sopenharmony_ci vtxSrc << "void main (void)\n"; 3047e5c31af7Sopenharmony_ci vtxSrc << "{\n"; 3048e5c31af7Sopenharmony_ci vtxSrc << " gl_Position = a_position;\n"; 3049e5c31af7Sopenharmony_ci vtxSrc << " var = uint(u_color.r);\n"; 3050e5c31af7Sopenharmony_ci vtxSrc << "}\n"; 3051e5c31af7Sopenharmony_ci outVtxSrc = vtxSrc.str(); 3052e5c31af7Sopenharmony_ci } 3053e5c31af7Sopenharmony_ci 3054e5c31af7Sopenharmony_ci void generateVarLinkFragmentShaderSrc(std::string& outFragSrc, glu::GLSLVersion glslVersion, 3055e5c31af7Sopenharmony_ci const string& precision, TestType testMode) 3056e5c31af7Sopenharmony_ci { 3057e5c31af7Sopenharmony_ci std::ostringstream fragSrc; 3058e5c31af7Sopenharmony_ci fragSrc << glu::getGLSLVersionDeclaration(glslVersion) << "\n"; 3059e5c31af7Sopenharmony_ci switch (testMode) 3060e5c31af7Sopenharmony_ci { 3061e5c31af7Sopenharmony_ci case SET_DEFAULT_PRECISION: 3062e5c31af7Sopenharmony_ci fragSrc << "precision " << precision << " int;\n"; 3063e5c31af7Sopenharmony_ci // Fallthrough 3064e5c31af7Sopenharmony_ci case DEFAULT_PRECISION: 3065e5c31af7Sopenharmony_ci fragSrc << "flat in uint var;\n"; 3066e5c31af7Sopenharmony_ci break; 3067e5c31af7Sopenharmony_ci case SET_PRECISION: 3068e5c31af7Sopenharmony_ci fragSrc << "flat in " << precision << " uint var;\n"; 3069e5c31af7Sopenharmony_ci break; 3070e5c31af7Sopenharmony_ci } 3071e5c31af7Sopenharmony_ci fragSrc << "layout(location = 0) out mediump vec4 o_color;\n"; 3072e5c31af7Sopenharmony_ci fragSrc << "void main (void)\n"; 3073e5c31af7Sopenharmony_ci fragSrc << "{\n"; 3074e5c31af7Sopenharmony_ci fragSrc << " o_color = vec4(var);\n"; 3075e5c31af7Sopenharmony_ci fragSrc << "}\n"; 3076e5c31af7Sopenharmony_ci outFragSrc = fragSrc.str(); 3077e5c31af7Sopenharmony_ci } 3078e5c31af7Sopenharmony_ci}; 3079e5c31af7Sopenharmony_ci 3080e5c31af7Sopenharmony_ciSeparateShaderObjsTests::SeparateShaderObjsTests(Context& context, glu::GLSLVersion glslVersion) 3081e5c31af7Sopenharmony_ci : TestCaseGroup(context, "sepshaderobjs", "separate_shader_object tests"), m_glslVersion(glslVersion) 3082e5c31af7Sopenharmony_ci{ 3083e5c31af7Sopenharmony_ci DE_ASSERT(glslVersion == glu::GLSL_VERSION_310_ES || glslVersion >= glu::GLSL_VERSION_440); 3084e5c31af7Sopenharmony_ci} 3085e5c31af7Sopenharmony_ci 3086e5c31af7Sopenharmony_ciSeparateShaderObjsTests::~SeparateShaderObjsTests(void) 3087e5c31af7Sopenharmony_ci{ 3088e5c31af7Sopenharmony_ci} 3089e5c31af7Sopenharmony_ci 3090e5c31af7Sopenharmony_civoid SeparateShaderObjsTests::init(void) 3091e5c31af7Sopenharmony_ci{ 3092e5c31af7Sopenharmony_ci 3093e5c31af7Sopenharmony_ci // API validation for CreateShaderProgram 3094e5c31af7Sopenharmony_ci addChild(new CreateShadProgCase(m_context, "CreateShadProgApi", "createShaderProgram API", m_glslVersion)); 3095e5c31af7Sopenharmony_ci // API validation for UseProgramStages 3096e5c31af7Sopenharmony_ci addChild(new UseProgStagesCase(m_context, "UseProgStagesApi", "useProgramStages API", m_glslVersion)); 3097e5c31af7Sopenharmony_ci // API validation for pipeline related functions 3098e5c31af7Sopenharmony_ci addChild(new PipelineApiCase(m_context, "PipelineApi", "Pipeline API", m_glslVersion)); 3099e5c31af7Sopenharmony_ci // API validation for variations of ProgramUniform 3100e5c31af7Sopenharmony_ci addChild(new ProgramUniformCase(m_context, "ProgUniformAPI", "ProgramUniform API", m_glslVersion)); 3101e5c31af7Sopenharmony_ci // State interactions 3102e5c31af7Sopenharmony_ci addChild(new StateInteractionCase(m_context, "StateInteraction", "SSO State Interactions", m_glslVersion)); 3103e5c31af7Sopenharmony_ci // input / output precision matching 3104e5c31af7Sopenharmony_ci addChild(new InterfaceMatchingCaseFloat(m_context, "InterfacePrecisionMatchingFloat", m_glslVersion)); 3105e5c31af7Sopenharmony_ci addChild(new InterfaceMatchingCaseInt(m_context, "InterfacePrecisionMatchingInt", m_glslVersion)); 3106e5c31af7Sopenharmony_ci addChild(new InterfaceMatchingCaseUInt(m_context, "InterfacePrecisionMatchingUInt", m_glslVersion)); 3107e5c31af7Sopenharmony_ci} 3108e5c31af7Sopenharmony_ci 3109e5c31af7Sopenharmony_ci} // glcts 3110