1#ifndef _GL3CTEXTURESWIZZLETESTS_HPP 2#define _GL3CTEXTURESWIZZLETESTS_HPP 3/*------------------------------------------------------------------------- 4 * OpenGL Conformance Test Suite 5 * ----------------------------- 6 * 7 * Copyright (c) 2015-2016 The Khronos Group Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 */ /*! 22 * \file 23 * \brief 24 */ /*-------------------------------------------------------------------*/ 25 26/** 27 * \file gl3cTextureSwizzleTests.hpp 28 * \brief Declares test classes for "Texture Swizzle" functionality. 29 */ /*-------------------------------------------------------------------*/ 30 31#include "glcTestCase.hpp" 32#include "glwDefs.hpp" 33#include "glwEnums.hpp" 34#include "tcuDefs.hpp" 35#include "tcuVector.hpp" 36#include <queue> 37 38namespace gl3cts 39{ 40namespace TextureSwizzle 41{ 42class Utils 43{ 44public: 45 /** Store information about program object 46 * 47 **/ 48 struct programInfo 49 { 50 programInfo(deqp::Context& context); 51 ~programInfo(); 52 53 void build(const glw::GLchar* fragment_shader_code, const glw::GLchar* vertex_shader_code); 54 void compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const; 55 void link() const; 56 57 deqp::Context& m_context; 58 59 glw::GLuint m_fragment_shader_id; 60 glw::GLuint m_program_object_id; 61 glw::GLuint m_vertex_shader_id; 62 }; 63 64 /* Public static methods */ 65 static void replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text, 66 std::string& string); 67}; 68 69/** Implements APIErrors test, description follows: 70 * 71 * Verifies that errors are generated as expected. 72 * 73 * Check if: 74 * - INVALID_OPERATION is generated by TexParameter* routines when <pname> is 75 * one of [TEXTURE_SWIZZLE_R, TEXTURE_SWIZZLE_G, TEXTURE_SWIZZLE_B, 76 * TEXTURE_SWIZZLE_A] and <param> is not one of [RED, GREEN, BLUE, ALPHA, ZERO, 77 * ONE]; 78 * - INVALID_OPERATION is generated by TexParameter*v routines when <pname> is 79 * TEXTURE_SWIZZLE_RGBA and any of four values pointed by <param> is not one of 80 * [RED, GREEN, BLUE, ALPHA, ZERO, ONE]. 81 **/ 82class APIErrorsTest : public deqp::TestCase 83{ 84public: 85 /* Public methods */ 86 APIErrorsTest(deqp::Context& context); 87 88 virtual void deinit(); 89 virtual tcu::TestNode::IterateResult iterate(); 90 91private: 92 /* Private methods */ 93 void verifyError(const glw::GLenum expected_error); 94 95 /* Private fields */ 96 glw::GLuint m_id; 97}; 98 99/** Implements IntialState test, description follows: 100 * 101 * Verifies that intial state is as expected. 102 * 103 * Steps: 104 * - create a texture; 105 * - verify that query for TEXTURE_SWIZZLE_R results with RED; 106 * - verify that query for TEXTURE_SWIZZLE_G results with GREEN; 107 * - verify that query for TEXTURE_SWIZZLE_B results with BLUE; 108 * - verify that query for TEXTURE_SWIZZLE_A results with ALPHA; 109 * - verify that query for TEXTURE_SWIZZLE_RGBA results with [RED, GREEN, BLUE, 110 * ALPHA]. 111 * 112 * Use GetTexParameter to query states. If GL_ARB_direct_state_access is 113 * supported than repeat the steps with GetTextureParameter. 114 * Repeat the steps for all supported texture targets. 115 **/ 116class IntialStateTest : public deqp::TestCase 117{ 118public: 119 /* Public methods */ 120 IntialStateTest(deqp::Context& context); 121 122 virtual void deinit(); 123 virtual tcu::TestNode::IterateResult iterate(); 124 125private: 126 /* Private methods */ 127 void verifyValues(const glw::GLenum texture_target); 128 129 /* Private fields */ 130 glw::GLuint m_id; 131}; 132 133/** Implements Smoke test, description follows: 134 * 135 * Verifies that all swizzle combinations work with all texture access 136 * routines. 137 * 138 * Steps: 139 * - prepare a source texture so that each channel is filled with specific 140 * value; 141 * - for each TEXTURE_SWIZZLE state combination: 142 * * for each channel [R, G, B, A]: 143 * + prepare a 2D single channeled texture with format matching sampled 144 * channel and set it up as output color in framebuffer; 145 * + prepare a program that will implement the following snippet in vertex 146 * stage and output the value of result: 147 * 148 * result = texture(source).C; 149 * 150 * + set swizzle states with channel specific enums; 151 * + draw a full-screen quad; 152 * + verify that the output texture is filled with correct value; 153 * + set swizzle states with RGBA enum; 154 * + draw a full-screen quad; 155 * + verify that the output texture is filled with correct value; 156 * + prepare a program that will implement the following snippet in 157 * fragment stage and output the value of result: 158 * 159 * result = texture(source).C; 160 * 161 * + set swizzle states with channel specific enums; 162 * + draw a full-screen quad; 163 * + verify that the output texture is filled with correct value; 164 * + set swizzle states with RGBA enum; 165 * + draw a full-screen quad; 166 * + verify that the output texture is filled with correct value. 167 * 168 * Value is correct when: 169 * - it matches value assigned to the specified channel; 170 * - it is one for missing alpha channel; 171 * - it is zero for missing channel; 172 * - it is one for ONE; 173 * - it is zero for ZERO. 174 * 175 * Before any draw output texture should be cleared. 176 * Source texture should be RGBA32UI 2D_ARRAY 1x1 of length 1 with 177 * single mipmap at level 0. 178 * Dimenssions of destination texture should be 8x8. 179 * Repeat the steps for the following texture access routines: 180 * - textureProj, 181 * - textureLod, 182 * - textureOffset, 183 * - texelFetch, 184 * - texelFetchOffset, 185 * - textureProjOffset, 186 * - textureLodOffset, 187 * - textureProjLod, 188 * - textureProjLodOffset, 189 * - textureGrad, 190 * - textureGradOffset, 191 * - textureProjGrad, 192 * - textureProjGradOffset. 193 **/ 194class SmokeTest : public deqp::TestCase 195{ 196public: 197 /* Public methods */ 198 SmokeTest(deqp::Context& context); 199 SmokeTest(deqp::Context& context, const glw::GLchar* name, const glw::GLchar* description); 200 201 virtual void deinit(); 202 virtual tcu::TestNode::IterateResult iterate(); 203 204protected: 205 /* Protected types */ 206 struct testCase 207 { 208 size_t m_channel_index; 209 size_t m_source_texture_format_index; 210 size_t m_source_texture_target_index; 211 size_t m_texture_access_index; 212 glw::GLint m_texture_swizzle_red; 213 glw::GLint m_texture_swizzle_green; 214 glw::GLint m_texture_swizzle_blue; 215 glw::GLint m_texture_swizzle_alpha; 216 glw::GLint m_texture_sizes[4]; 217 }; 218 219 /* Protected methods */ 220 void captureAndVerify(const testCase& test_case, size_t output_format_index, glw::GLint output_channel_size, 221 size_t index_of_swizzled_channel); 222 223 void deinitOutputTexture(); 224 void deinitTextures(); 225 226 void draw(glw::GLenum target, const glw::GLint* texture_swizzle, bool use_rgba_enum); 227 228 void executeTestCase(const testCase& test_case); 229 230 virtual bool fillSourceTexture(size_t format_idx, size_t target_idx); 231 232 std::string getFragmentShader(const testCase& test_case, size_t output_format_index, bool is_tested_stage); 233 234 std::string getVertexShader(const testCase& test_case, bool is_tested_stage); 235 236 bool isTargetSupported(size_t target_idx); 237 238 bool isTargetSuppByAccess(size_t access_idx, size_t target_idx); 239 240 bool isTargetSuppByFormat(size_t format_idx, size_t target_idx); 241 242 void logTestCaseDetials(const testCase& test_case); 243 244 void prepareAndTestProgram(const testCase& test_case, size_t output_format_index, glw::GLint output_channel_size, 245 size_t index_of_swizzled_channel, bool test_vertex_stage); 246 247 std::string prepareArguments(const testCase& test_case); 248 std::string prepareCoordinates(const testCase& test_case); 249 250 std::string prepareDerivatives(const testCase& test_case, size_t index); 251 252 std::string prepareOffsets(const testCase& test_case); 253 void prepareOutputTexture(size_t format_idx); 254 255 std::string prepareSample(); 256 void prepareSourceTexture(size_t format_idx, size_t target_idx, glw::GLint out_sizes[4]); 257 258 void testInit(); 259 260 virtual void verifyOutputImage(const testCase& test_case, size_t output_format_index, 261 glw::GLint output_channel_size, size_t index_of_swizzled_channel, 262 const glw::GLubyte* data); 263 264 /* Protected fields */ 265 bool m_is_ms_supported; 266 glw::GLuint m_prepare_fbo_id; 267 glw::GLuint m_out_tex_id; 268 glw::GLuint m_source_tex_id; 269 glw::GLuint m_test_fbo_id; 270 glw::GLuint m_vao_id; 271 272 /* Protected constants */ 273 static const glw::GLsizei m_depth; 274 static const glw::GLsizei m_height; 275 static const glw::GLsizei m_width; 276 static const glw::GLsizei m_output_height; 277 static const glw::GLsizei m_output_width; 278}; 279 280/** Implements Functional test, description follows: 281 * 282 * Verifies that swizzle is respected for textures of different formats and 283 * targets. 284 * 285 * Modify Smoke in the following aspects: 286 * - repeat the steps for all supported sized internal formats and 287 * texture targets; 288 * - repeat the steps for the texture_swizzle combinations listed below; 289 * - use only texelFetch routine. 290 * 291 * List of texture_swizzle combinations to test: 292 * - ABGR, 293 * - 01RA, 294 * - 0000, 295 * - 1111, 296 * - BBBB. 297 * 298 * Depth-stencil textures can be sampled only via RED channel. Test should set 299 * DEPTH_STENCIL_TEXTURE_MODE to select which channel will be accessed. 300 * 301 * For multisampled targets maximum supported number of samples should be used 302 * and fetch should be done to last sample. 303 * 304 * Support of multisampled targets by TexParameter* routines was introduced in 305 * extension GL_ARB_texture_storage_multisample, which is part of core 306 * specification since 4.3. Therefore texture_swizzle functionality may be used 307 * with multisampled targets only if either context is at least 4.3 or 308 * extension GL_ARB_texture_storage_multisample is supported. 309 **/ 310class FunctionalTest : public SmokeTest 311{ 312public: 313 /* Public methods */ 314 FunctionalTest(deqp::Context& context); 315 316 virtual tcu::TestNode::IterateResult iterate(); 317 318protected: 319 /* Protected methods */ 320 virtual bool fillSourceTexture(size_t format_idx, size_t target_idx); 321 322 bool fillMSTexture(size_t format_idx, size_t target_idx); 323 324 void prepareProgram(size_t format_idx, Utils::programInfo& program); 325 326 std::string prepareValues(size_t format_idx); 327 328 virtual void verifyOutputImage(const testCase& test_case, size_t output_format_index, 329 glw::GLint output_channel_size, size_t index_of_swizzled_channel, 330 const glw::GLubyte* data); 331 332private: 333 /* Private types */ 334 class wrongResults : public std::exception 335 { 336 public: 337 wrongResults(const FunctionalTest::testCase& test_case) : m_test_case(test_case) 338 { 339 } 340 341 virtual ~wrongResults() throw() 342 { 343 } 344 345 virtual const char* what() const throw() 346 { 347 return "Found pixel with wrong value"; 348 } 349 350 FunctionalTest::testCase m_test_case; 351 }; 352}; 353} 354 355/** Group class for GPU Shader 5 conformance tests */ 356class TextureSwizzleTests : public deqp::TestCaseGroup 357{ 358public: 359 /* Public methods */ 360 TextureSwizzleTests(deqp::Context& context); 361 virtual ~TextureSwizzleTests() 362 { 363 } 364 365 virtual void init(void); 366 367private: 368 /* Private methods */ 369 TextureSwizzleTests(const TextureSwizzleTests&); 370 TextureSwizzleTests& operator=(const TextureSwizzleTests&); 371}; 372} /* gl3cts namespace */ 373 374#endif // _GL3CTEXTURESWIZZLETESTS_HPP 375