1 #ifndef _GL3CTRANSFORMFEEDBACKTESTS_HPP 2 #define _GL3CTRANSFORMFEEDBACKTESTS_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 */ /*! 28 * \file gl3cTransformFeedback.hpp 29 * \brief Transform Feedback Test Suite Interface 30 */ /*-------------------------------------------------------------------*/ 31 32 #include "glcTestCase.hpp" 33 #include "glwDefs.hpp" 34 #include "tcuDefs.hpp" 35 36 /* Includes. */ 37 #include <map> 38 #include <string> 39 #include <typeinfo> 40 #include <vector> 41 42 #include "glwEnums.hpp" 43 #include "glwFunctions.hpp" 44 45 namespace gl3cts 46 { 47 namespace TransformFeedback 48 { 49 class Tests : public deqp::TestCaseGroup 50 { 51 public: 52 Tests(deqp::Context &context); 53 ~Tests(void); 54 virtual void init(void); 55 56 private: 57 Tests(const Tests &other); 58 Tests &operator=(const Tests &other); 59 }; 60 61 /** APIErrors 62 * 63 * Verifies if errors are generated as specified. 64 * Four test shall be run: 65 * - Test api errors defined in GL_EXT_transform_feedback. 66 * - Test api errors defined in GL_ARB_transform_feedback2. 67 * - Test api errors defined in GL_ARB_transform_feedback3. 68 * - Test api errors defined in GL_ARB_transform_feedback_instanced. 69 */ 70 class APIErrors : public deqp::TestCase 71 { 72 public: 73 APIErrors(deqp::Context &context); 74 ~APIErrors(void); 75 IterateResult iterate(void); 76 77 private: 78 deqp::Context &m_context; 79 80 static const glw::GLchar *m_tessellation_control_shader; 81 static const glw::GLchar *m_tessellation_evaluation_shader; 82 static const glw::GLchar *m_geometry_shader; 83 static const glw::GLchar *s_vertex_shader_with_input_output; 84 static const glw::GLchar *s_vertex_shader_with_output; 85 static const glw::GLchar *s_vertex_shader_without_output; 86 static const glw::GLchar *s_fragment_shader; 87 static const glw::GLchar *m_varying_name; 88 89 static const glw::GLfloat m_buffer_1_data[]; 90 static const glw::GLsizei m_buffer_1_size; 91 92 glw::GLuint m_buffer_0; 93 glw::GLuint m_buffer_1; 94 95 glw::GLuint m_vertex_array_object; 96 97 glw::GLuint m_transform_feedback_object_0; 98 glw::GLuint m_transform_feedback_object_1; 99 100 glw::GLuint m_query_object; 101 102 glw::GLuint m_program_id_with_input_output; 103 glw::GLuint m_program_id_with_output; 104 glw::GLuint m_program_id_without_output; 105 glw::GLuint m_program_id_with_geometry_shader; 106 glw::GLuint m_program_id_with_tessellation_shaders; 107 108 /** Check the following if EXT_transform_feedback is supported or context is 109 * at least 3.0: 110 * 111 * - INVALID_VALUE is generated by BindBufferRange, BindBufferOffset and 112 * BindBufferBase when <index> is greater or equal to 113 * MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS; 114 * - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset 115 * when <size> is less or equal to zero; 116 * - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset 117 * when <offset> is not word-aligned; 118 * - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset 119 * when <size> is not word-aligned; 120 * - INVALID_OPERATION is generated by BindBufferRange, BindBufferOffset and 121 * BindBufferBase when <target> is TRANSFORM_FEEDBACK_BUFFER and transform 122 * feedback is active; 123 * - INVALID_OPERATION is generated by UseProgram when transform feedback is 124 * active; 125 * - INVALID_OPERATION is generated by LinkProgram when <program> is currently 126 * active and transform feedback is active; 127 * - INVALID_OPERATION is generated by BeginTransformFeedback when transform 128 * feedback is active; 129 * - INVALID_OPERATION is generated by EndTransformFeedback when transform 130 * feedback is inactive; 131 * - INVALID_OPERATION is generated by draw command when generated primitives 132 * type does not match <primitiveMode>; 133 * - INVALID_OPERATION is generated by BeginTransformFeedback when any binding 134 * point used by XFB does not have buffer bound; 135 * - INVALID_OPERATION is generated by BeginTransformFeedback when no program 136 * is active; 137 * - INVALID_OPERATION is generated by BeginTransformFeedback when no variable 138 * are specified to be captured in the active program; 139 * - INVALID_VALUE is generated by TransformFeedbackVaryings when <program> is 140 * not id of the program object; 141 * - INVALID_VALUE is generated by TransformFeedbackVaryings when <bufferMode> 142 * is SEPARATE_ATTRIBS and <count> is exceeds limits; 143 * - IVALID_VALUE is generated by GetTransformFeedbackVarying when <index> is 144 * greater than or equal to TRANSFORM_FEEDBACK_VARYINGS; 145 * - INVALID_VALUE is generated by GetIntegerIndexdv when <index> exceeds the 146 * limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is one of the 147 * following: 148 * * TRANSFORM_FEEDBACK_BUFFER_BINDING, 149 * * TRANSFORM_FEEDBACK_BUFFER_START, 150 * * TRANSFORM_FEEDBACK_BUFFER_SIZE; 151 * - INVALID_VALUE is generated by GetBooleanIndexedv when <index> exceeds the 152 * limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is 153 * TRANSFORM_FEEDBACK_BUFFER_BINDING. 154 */ 155 bool testExtension1(void); 156 157 /** Check the following if ARB_transform_feedback2 is supported or context is 158 * at least 4.0: 159 * 160 * - INVALID_OPERATION is generated by BindTransformFeedback if current 161 * transform feedback is active and not paused; 162 * - INVALID_OPERATION is generated by DeleteTransformFeedbacks if any of <ids> 163 * is active; 164 * - INVALID_OPERATION is generated by PauseTransformFeedback if current 165 * transform feedback is not active or paused; 166 * - INVALID_OPERATION is generated by ResumeTransformFeedback if current 167 * transform feedback is not active or not paused; 168 * - No error is generated by draw command when transform feedback is paused 169 * and primitive modes do not match; 170 * - No error is generated by UseProgram when transform feedback is paused; 171 * - INVALID_OPERATION is generated by LinkProgram when <program> is used by 172 * some transform feedback object that is currently not active; 173 * - INVALID_VALUE is generated by DrawTransformFeedback if <id> is not name of 174 * transform feedback object; 175 * - INVALID_OPERATION is generated by DrawTransformFeedback when 176 * EndTransformFeedback was never called for the object named <id>. 177 */ 178 bool testExtension2(void); 179 180 /** Check the following if ARB_transform_feedback3 is supported or context is 181 * at least 4.0: 182 * 183 * - INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and 184 * GetQueryIndexediv when <target> is TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN and 185 * <index> exceeds limits of MAX_VERTEX_STREAMS; 186 * - INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and 187 * GetQueryIndexediv when <target> is PRIMITIVES_GENERATED and <index> exceeds 188 * limits of MAX_VERTEX_STREAMS; 189 * - INVALID_OPERATION is generated by EndQueryIndexed when name of active 190 * query at <index> of <target> is zero; 191 * - INVALID_VALUE is generated by DrawTransformFeedbackStream when <stream> 192 * exceeds limits of MAX_VERTEX_STREAMS; 193 * - INVALID_OPERATION is generated by TransformFeedbackVaryings when 194 * <varyings> contains any of the special names while <bufferMode> is not 195 * INTERLEAVED_ATTRIBS; 196 * - INVALID_OPERATION is generated by TransformFeedbackVaryings when 197 * <varyings> contains more "gl_NextBuffer" entries than allowed limit of 198 * MAX_TRANSFORM_FEEDBACK_BUFFERS; 199 */ 200 bool testExtension3(void); 201 202 /** Check the following if ARB_transform_feedback_instanced is supported or 203 * context is at least 4.2: 204 * 205 * - INVALID_ENUM is generated by DrawTransformFeedbackInstanced and 206 * DrawTransformFeedbackStreamInstanced if <mode> is invalid; 207 * - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and 208 * DrawTransformFeedbackStreamInstanced if <mode> does not match geometry 209 * shader; 210 * - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and 211 * DrawTransformFeedbackStreamInstanced if <mode> does not match tessellation; 212 * - INVALID_VALUE is generated by DrawTransformFeedbackStreamInstanced if 213 * <stream> is greater than or equal to MAX_VERTEX_STREAMS; 214 * - INVALID_VALUE is generated by DrawTransformFeedbackInstanced and 215 * DrawTransformFeedbackStreamInstanced if <id> is not name of transform 216 * feedback object; 217 * - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and 218 * DrawTransformFeedbackStreamInstanced if a non-zero buffer object name is 219 * bound to an enabled array and the buffer object's data store is currently 220 * mapped; 221 * - INVALID_OPERATION is generated if by DrawTransformFeedbackStreamInstanced 222 * if EndTransformFeedback was never called for the object named <id>. 223 */ 224 bool testInstanced(void); 225 226 typedef GLW_APICALL void(GLW_APIENTRY *BindBufferOffsetEXT_ProcAddress)(glw::GLenum target, glw::GLuint index, 227 glw::GLuint buffer, glw::GLintptr offset); 228 typedef GLW_APICALL void(GLW_APIENTRY *GetIntegerIndexedvEXT_ProcAddress)(glw::GLenum param, glw::GLuint index, 229 glw::GLint *values); 230 typedef GLW_APICALL void(GLW_APIENTRY *GetBooleanIndexedvEXT_ProcAddress)(glw::GLenum param, glw::GLuint index, 231 glw::GLboolean *values); 232 233 BindBufferOffsetEXT_ProcAddress m_glBindBufferOffsetEXT; 234 GetIntegerIndexedvEXT_ProcAddress m_glGetIntegerIndexedvEXT; 235 GetBooleanIndexedvEXT_ProcAddress m_glGetBooleanIndexedvEXT; 236 }; 237 238 /** LinkingErrors 239 * 240 * Verifies that linker reports errors as specified. 241 * 242 * Test should be run if EXT_transform_feedback is supported or context is 243 * at least 3.0. 244 * 245 * Check if link process fails under the following conditions: 246 * - <count> specified by TransformFeedbackVaryings is non-zero and program has 247 * neither vertex nor geometry shader; 248 * - <varyings> specified by TransformFeedbackVaryings contains name of 249 * variable that is not available for capture; 250 * - <varyings> specified by TransformFeedbackVaryings contains name of 251 * variable more than once; 252 * - number of components specified to capture exceeds limits 253 * MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS or 254 * MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. 255 */ 256 class LinkingErrors : public deqp::TestCase 257 { 258 public: 259 LinkingErrors(deqp::Context &context); 260 ~LinkingErrors(void); 261 IterateResult iterate(void); 262 263 private: 264 deqp::Context &m_context; 265 266 static const glw::GLchar *s_fragment_shader; 267 static const glw::GLchar *s_vertex_shader_template; 268 static const glw::GLchar *s_valid_transform_feedback_varying; 269 static const glw::GLchar *s_invalid_transform_feedback_varying; 270 static const glw::GLchar *s_repeated_transform_feedback_varying[]; 271 static const glw::GLsizei s_repeated_transform_feedback_varying_count; 272 273 bool testNoVertexNoGeometry(void); 274 bool testInvalidVarying(void); 275 bool testRepeatedVarying(void); 276 bool testTooManyVaryings(void); 277 }; 278 279 /** Limits 280 * 281 * Verifies that limits reported by API are as expected. 282 * 283 * Check the following if EXT_transform_feedback is supported or context is at 284 * least 3.0: 285 * - MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS is at least 64, 286 * - MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS is at least 4, 287 * - MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS is at least 4. 288 * 289 * Check the following if ARB_transform_feedback3 is supported or context is at 290 * least 4.0: 291 * - MAX_TRANSFORM_FEEDBACK_BUFFERS is at least 4, 292 * - MAX_VERTEX_STREAMS is at least 1. 293 */ 294 class Limits : public deqp::TestCase 295 { 296 public: 297 Limits(deqp::Context &context); 298 ~Limits(void); 299 IterateResult iterate(void); 300 301 private: 302 deqp::Context &m_context; 303 304 static const glw::GLchar *s_fragment_shader; 305 static const glw::GLchar *s_vertex_shader; 306 307 static const glw::GLint s_min_value_of_max_transform_feedback_interleaved_components; 308 static const glw::GLint s_min_value_of_max_transform_feedback_separate_attribs; 309 static const glw::GLint s_min_value_of_max_transform_feedback_separate_components; 310 static const glw::GLint s_min_value_of_max_transform_feedback_buffers; 311 static const glw::GLint s_min_value_of_max_vertex_streams; 312 313 bool test_max_transform_feedback_interleaved_components(void); 314 bool test_max_transform_feedback_separate_attribs(void); 315 bool test_max_transform_feedback_separate_components(void); 316 bool test_max_transform_feedback_buffers(void); 317 bool test_max_vertex_streams(void); 318 }; 319 320 /** CaptureVertexInterleaved 321 * 322 * Verifies if geometry processed with vertex shader is captured as expected in 323 * interleaved mode. 324 * 325 * Test should be run if EXT_transform_feedback is supported or context is 326 * at least 3.0. 327 * 328 * Steps: 329 * - prepare program consisting of vertex and fragment shader; Vertex shader 330 * should assign all MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS components; 331 * One of the variables must be a position; Position should be set to one of 332 * corners, based on gl_VertexID: 0 - top left, 1 - top right, 2 - bottom left 333 * and 3 - bottom right; Rest of components should be covered with output 334 * variables of type vec4; Fragment shader should accept all outputs from 335 * vertex shader as inputs and use them to calculate non-black output color; 336 * - instruct implementation to capture all outputs defined by vertex shader; 337 * Use interleaved mode; 338 * - prepare and set buffer to store captured geometry; 339 * - prepare, set and clean frame-buffer with black color; 340 * - execute BeginTransformFeedback; 341 * - execute DrawElements; 342 * - execute EndTransformFeedback; 343 * - inspect contents of frame-buffer to check if rasterization was done 344 * correctly; 345 * - inspect TRANSFORM_FEEDBACK_BUFFER_START and 346 * TRANSFORM_FEEDBACK_BUFFER_SIZE; 347 * - inspect contents of the buffer to check if geometry was captured 348 * correctly. 349 * 350 * Test the following BindBuffer routines: 351 * - BindBufferRange - use non-zero offset, 352 * - BindBufferOffset - use non-zero offset, 353 * - BindBufferBase. 354 * 355 * Test the following primitive types: 356 * - GL_POINTS - use these indices: [0, 1, 2, 3]; All corner pixels should be 357 * set to specific colors; XFB should contain four vertices; 358 * - GL_LINES - use these indices: [0, 1, 2, 3]; Top and bottom edges should be 359 * drawn; XFB should contain four vertices; 360 * - GL_LINE_LOOP - use these indices: [0, 1, 3, 2]; All four edges should be 361 * drawn; XFB should contain eight vertices; 362 * - GL_LINE_STRIP - use these indices: [0, 1, 3, 2]; Top, right and bottom 363 * edge should be drawn; XFB should contain six vertices; 364 * - GL_TRIANGLES - use these indices: [2, 0, 1, 2, 1, 3]; Whole image should 365 * be drawn; XFB should contain six vertices; 366 * - GL_TRIANGLE_STRIP - use these indices: [0, 1, 2, 3]; Whole image should 367 * be drawn; XFB should contain six vertices; 368 * - GL_TRIANGLE_FAN - use these indices: [2, 0, 1, 3]; Whole image should 369 * be drawn; XFB should contain six vertices. 370 * 371 * Number of components that can be passed to rasterization must not exceed 372 * MAX_VARYING_COMPONENTS. 373 */ 374 class CaptureVertexInterleaved : public deqp::TestCase 375 { 376 public: 377 CaptureVertexInterleaved(deqp::Context &context, const char *test_name, const char *test_description); 378 ~CaptureVertexInterleaved(void); 379 virtual IterateResult iterate(void); 380 381 protected: 382 deqp::Context &m_context; 383 glw::GLuint m_program; 384 glw::GLuint m_framebuffer; 385 glw::GLuint m_renderbuffer; 386 glw::GLuint m_buffer; 387 glw::GLuint m_buffer_size; 388 glw::GLuint m_vertex_array_object; 389 glw::GLint m_max_transform_feedback_components; 390 glw::GLenum m_attrib_type; 391 glw::GLuint m_max_vertices_drawn; 392 393 typedef GLW_APICALL void(GLW_APIENTRY *BindBufferOffsetEXT_ProcAddress)(glw::GLenum target, glw::GLuint index, 394 glw::GLuint buffer, glw::GLintptr offset); 395 396 BindBufferOffsetEXT_ProcAddress m_glBindBufferOffsetEXT; 397 398 static const glw::GLchar *s_vertex_shader_source_code_template; 399 static const glw::GLchar *s_fragment_shader_source_code; 400 401 static const glw::GLuint s_max_element_indices_count = 6; 402 static const glw::GLuint s_element_indices[][s_max_element_indices_count]; 403 static const glw::GLuint s_primitive_cases_count; 404 static const glw::GLuint s_element_indices_counts[]; 405 static const glw::GLenum s_primitive_cases[]; 406 static const glw::GLenum s_primitive_cases_xfb[]; 407 static const glw::GLuint s_framebuffer_size; 408 static const glw::GLfloat s_rasterization_epsilon; 409 static const glw::GLuint s_max_vertex_id = 4; 410 411 enum BindBufferCase 412 { 413 BIND_BUFFER_BASE_CASE, 414 BIND_BUFFER_RANGE_CASE, 415 BIND_BUFFER_OFFSET_CASE, 416 BIND_BUFFER_CASES_COUNT 417 }; 418 419 virtual void fetchLimits(void); 420 virtual void buildProgram(void); 421 void createFramebuffer(void); 422 virtual void createTransformFeedbackBuffer(void); 423 void createVertexArrayObject(void); 424 virtual void draw(glw::GLuint primitive_case); 425 virtual bool checkFramebuffer(glw::GLuint primitive_case); 426 virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); 427 virtual void bindBuffer(BindBufferCase bind_case); 428 virtual void clean(void); 429 virtual void cleanBuffer(void); 430 }; 431 432 /** CaptureGeometryInterleaved 433 * 434 * Verifies if geometry processed with geometry shader is captured as expected 435 * in interleaved mode. 436 * 437 * Test should be run if either EXT_transform_feedback is supported or context 438 * is at least 3.0 and either ARB_geometry_shader4 is supported or context is 439 * at least 3.2. 440 * 441 * Modify CaptureVertexInterleaved test in the following aspects: 442 * - outputs definition and assignment is done in geometry instead of 443 * vertex shader; 444 * - vertex shader can be blank; 445 * - use DrawArrays instead of DrawElements, draw single vertex with GL_POINTS. 446 * 447 * Test the following output primitive types for geometry shader: 448 * - points - emit vertices as in GL_POINTS case; 449 * - line_strip - emit vertices as in GL_LINE_STRIP case; 450 * - triangle_strip - emit vertices as in GL_TRIANGLE_STRIP case. 451 * 452 * Number of components written by geometry shader must not exceed 453 * MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS. 454 */ 455 class CaptureGeometryInterleaved : virtual public CaptureVertexInterleaved 456 { 457 public: 458 CaptureGeometryInterleaved(deqp::Context &context, const char *test_name, const char *test_description); 459 ~CaptureGeometryInterleaved(void); 460 virtual IterateResult iterate(void); 461 462 protected: 463 virtual void fetchLimits(void); 464 using CaptureVertexInterleaved::buildProgram; 465 virtual void buildProgram(glw::GLuint primitive_case); 466 virtual void draw(glw::GLuint primitive_case); 467 468 static const glw::GLchar *s_geometry_shader_source_code_template; 469 static const glw::GLchar *s_blank_vertex_shader_source_code; 470 471 static const glw::GLchar *s_geometry_interleaved_primitive_cases[]; 472 static const glw::GLenum s_geometry_interleaved_primitive_cases_xfb[]; 473 static const glw::GLuint s_geometry_interleaved_primitive_cases_count; 474 }; 475 476 /** CaptureVertexSeparate 477 * 478 * Verifies if geometry processed with vertex shader is captured as expected in 479 * separate mode. 480 * 481 * Test should be run if EXT_transform_feedback is supported or context is 482 * at least 3.0. 483 * 484 * Modify CaptureVertexInterleaved test in the following aspects: 485 * - use transform feedback in separate mode. 486 * 487 * Separate mode require one buffer per captured variable. 488 * 489 * Number of attributes and components that can be captured is limited by: 490 * - MAX TRANSFORM FEEDBACK SEPARATE ATTRIBS, 491 * - MAX TRANSFORM FEEDBACK SEPARATE COMPONENTS. 492 */ 493 class CaptureVertexSeparate : virtual public CaptureVertexInterleaved 494 { 495 public: 496 CaptureVertexSeparate(deqp::Context &context, const char *test_name, const char *test_description); 497 498 protected: 499 glw::GLuint *m_buffers; 500 glw::GLint m_max_transform_feedback_separate_attribs; 501 502 virtual void fetchLimits(void); 503 virtual void createTransformFeedbackBuffer(void); 504 virtual void bindBuffer(BindBufferCase bind_case); 505 virtual void cleanBuffer(void); 506 virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); 507 }; 508 509 /** CaptureGeometrySeparate 510 * 511 * Verifies if geometry processed with geometry shader is captured as expected 512 * in separate mode. 513 * 514 * Test should be run if either EXT_transform_feedback is supported or context 515 * is at least 3.0 and either ARB_geometry_shader4 is supported or context is 516 * at least 3.2. 517 * 518 * Modify CaptureGeometryInterleaved test in the following aspects: 519 * - use transform feedback in separate mode. 520 * 521 * Separate mode require one buffer per captured variable. 522 * 523 * Number of attributes and components that can be captured is limited by: 524 * - MAX TRANSFORM FEEDBACK SEPARATE ATTRIBS, 525 * - MAX TRANSFORM FEEDBACK SEPARATE COMPONENTS. 526 */ 527 class CaptureGeometrySeparate : public CaptureGeometryInterleaved, virtual public CaptureVertexSeparate 528 { 529 public: 530 CaptureGeometrySeparate(deqp::Context &context, const char *test_name, const char *test_description); iterate(void)531 virtual IterateResult iterate(void) 532 { 533 return CaptureGeometryInterleaved::iterate(); 534 } 535 536 protected: 537 glw::GLuint *m_buffers; 538 glw::GLint m_max_transform_feedback_separate_attribs; 539 draw(glw::GLenum primitive_type)540 virtual void draw(glw::GLenum primitive_type) 541 { 542 CaptureGeometryInterleaved::draw(primitive_type); 543 } fetchLimits(void)544 virtual void fetchLimits(void) 545 { 546 CaptureVertexSeparate::fetchLimits(); 547 } createTransformFeedbackBuffer(void)548 virtual void createTransformFeedbackBuffer(void) 549 { 550 CaptureVertexSeparate::createTransformFeedbackBuffer(); 551 } bindBuffer(BindBufferCase bind_case)552 virtual void bindBuffer(BindBufferCase bind_case) 553 { 554 CaptureVertexSeparate::bindBuffer(bind_case); 555 } cleanBuffer(void)556 virtual void cleanBuffer(void) 557 { 558 CaptureVertexSeparate::cleanBuffer(); 559 } checkTransformFeedbackBuffer(BindBufferCase bind_case,glw::GLenum primitive_type)560 virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type) 561 { 562 return CaptureVertexSeparate::checkTransformFeedbackBuffer(bind_case, primitive_type); 563 } 564 }; 565 566 /** GetXFBVaryingVertexInterleaved 567 * 568 * Verifies if varyings captured from vertex stage are correctly reported in 569 * interleaved mode. 570 * 571 * Test should be run if EXT_transform_feedback is supported or context is 572 * at least 3.0. 573 * 574 * Steps: 575 * - prepare program consisting of vertex and fragment shader; Vertex shader 576 * should define and assign maximum allowed number of varyings of tested type; 577 * Fragment shader can be blank; 578 * - instruct implementation to capture all outputs defined by vertex shader; 579 * Use interleaved mode; 580 * - inspect all captured varying with GetTransformFeedbackVarying; 581 * - inspect TRANSFORM_FEEDBACK_VARYINGS; 582 * - inspect TRANSFORM_FEEDBACK_BUFFER_MODE; 583 * - inspect TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH. 584 * 585 * Test all valid types. 586 * 587 * 588 * GetXFBVaryingGeometryInterleaved 589 * 590 * Verifies if varyings captured from geometry stage are correctly reported in 591 * interleaved mode. 592 * 593 * Test should be run if either EXT_transform_feedback is supported or context 594 * is at least 3.0 and either ARB_geometry_shader4 is supported or context is 595 * at least 3.2. 596 * 597 * Modify GetXFBVaryingVertexInterleaved test in the following aspects: 598 * - outputs definition and assignment is done in geometry instead of 599 * vertex shader; 600 * - vertex shader can be blank; 601 * 602 * 603 * GetXFBVaryingVertexSeparate 604 * 605 * Verifies if varyings captured from vertex stage are correctly reported in 606 * separate mode. 607 * 608 * Test should be run if EXT_transform_feedback is supported or context is 609 * at least 3.0. 610 * 611 * Modify CaptureGeometryInterleaved test in the following aspects: 612 * - use transform feedback in separate mode. 613 * 614 * Separate mode require one buffer per captured variable. 615 * 616 * 617 * GetXFBVaryingGeometrySeparate 618 * 619 * Verifies if varyings captured from geometry stage are correctly reported in 620 * separate mode. 621 * 622 * Test should be run if either EXT_transform_feedback is supported or context 623 * is at least 3.0 and either ARB_geometry_shader4 is supported or context is 624 * at least 3.2. 625 * 626 * Modify GetXFBVaryingGeometryInterleaved test in the following aspects: 627 * - use transform feedback in separate mode. 628 * 629 * Separate mode require one buffer per captured variable. 630 */ 631 class CheckGetXFBVarying : public deqp::TestCase 632 { 633 public: 634 CheckGetXFBVarying(deqp::Context &context, const char *test_name, const char *test_description); 635 ~CheckGetXFBVarying(void); 636 virtual IterateResult iterate(void); 637 638 private: 639 deqp::Context &m_context; 640 glw::GLint m_max_xfb_interleaved_components; 641 glw::GLint m_max_xfb_separate_attributes; 642 glw::GLint m_max_xfb_separate_components; 643 glw::GLint m_max_varying_components; 644 glw::GLint m_max_varying_vectors; 645 glw::GLint m_max_geometry_total_output_components; 646 647 void fetchLimits(void); 648 glw::GLuint numberOfAttributes(glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type); 649 650 glw::GLuint buildProgram(glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type, 651 glw::GLuint number_of_attributes); 652 653 bool check(glw::GLuint program, glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type, 654 glw::GLuint number_of_attributes); 655 656 static const glw::GLchar *s_generic_fragment_shader; 657 658 static const struct ShaderCase 659 { 660 const glw::GLchar *vertex_shader; 661 const glw::GLchar *geometry_shader; 662 } s_shader_cases[]; 663 664 static const glw::GLuint s_shader_cases_count; 665 666 static const struct VaryingType 667 { 668 const glw::GLenum type; 669 const glw::GLchar *name; 670 const glw::GLuint components_count; 671 const bool float_component; 672 } s_varying_types[]; 673 674 static const glw::GLuint s_varying_types_count; 675 676 static const glw::GLenum s_capture_ways[]; 677 static const glw::GLuint s_capture_ways_count; 678 }; 679 680 /** QueryVertexInterleaved 681 * 682 * Verifies if queries are performed as expected when geometry is captured from 683 * vertex stage in interleaved mode. 684 * 685 * Test should be run if EXT_transform_feedback is supported or context is 686 * at least 3.0. 687 * 688 * Modify CaptureVertexInterleaved test in the following aspects: 689 * - buffer used as storage for captured geometry should be too small to fit 690 * all emitted vertices; 691 * - execute BeginQuery for PRIMITIVES_GENERATED and 692 * TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries 693 * after draw call. 694 * 695 * Test pass if results of queries are correct. 696 */ 697 class QueryVertexInterleaved : public CaptureVertexInterleaved 698 { 699 public: 700 QueryVertexInterleaved(deqp::Context &context, const char *test_name, const char *test_description); 701 702 protected: 703 glw::GLuint m_query_object; 704 705 virtual void createTransformFeedbackBuffer(void); 706 virtual void draw(glw::GLuint primitive_case); 707 virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); 708 virtual void clean(void); 709 }; 710 711 /** QueryGeometryInterleaved 712 * 713 * Verifies if queries are performed as expected when geometry is captured from 714 * geometry stage in interleaved mode. 715 * 716 * Test should be run if either EXT_transform_feedback is supported or context 717 * is at least 3.0 and either ARB_geometry_shader4 is supported or context is 718 * at least 3.2. 719 * 720 * Modify CaptureGeometryInterleaved test in the following aspects: 721 * - buffer used as storage for captured geometry should be too small to fit 722 * all emitted vertices; 723 * - execute BeginQuery for PRIMITIVES_GENERATED and 724 * TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries 725 * after draw call. 726 * 727 * Test pass if results of queries are correct. 728 */ 729 class QueryGeometryInterleaved : public CaptureGeometryInterleaved 730 { 731 public: 732 QueryGeometryInterleaved(deqp::Context &context, const char *test_name, const char *test_description); 733 734 protected: 735 glw::GLuint m_query_object; 736 737 virtual void createTransformFeedbackBuffer(void); 738 virtual void draw(glw::GLuint primitive_case); 739 virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); 740 virtual void clean(void); 741 }; 742 743 /** QueryVertexSeparate 744 * 745 * Verifies if queries are performed as expected when geometry is captured from 746 * vertex stage in separate mode. 747 * 748 * Test should be run if EXT_transform_feedback is supported or context is 749 * at least 3.0. 750 * 751 * Modify CaptureVertexSeparate test in the following aspects: 752 * - buffers used as storage for captured geometry should be too small to fit 753 * all emitted vertices; 754 * - execute BeginQuery for PRIMITIVES_GENERATED and 755 * TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries 756 * after draw call; 757 * - use transform feedback in separate mode. 758 * 759 * Separate mode require one buffer per captured variable. 760 * 761 * Test pass if results of queries are correct. 762 */ 763 class QueryVertexSeparate : public CaptureVertexSeparate 764 { 765 public: 766 QueryVertexSeparate(deqp::Context &context, const char *test_name, const char *test_description); 767 768 protected: 769 glw::GLuint m_query_object; 770 771 virtual void createTransformFeedbackBuffer(void); 772 virtual void draw(glw::GLuint primitive_case); 773 virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); 774 virtual void clean(void); 775 }; 776 777 /** QueryGeometrySeparate 778 * 779 * Verifies if queries are performed as expected when geometry is captured from 780 * geometry stage in separate mode. 781 * 782 * Test should be run if either EXT_transform_feedback is supported or context 783 * is at least 3.0 and either ARB_geometry_shader4 is supported or context is 784 * at least 3.2. 785 * 786 * Modify CaptureGeometrySeparate test in the following aspects: 787 * - buffers used as storage for captured geometry should be too small to fit 788 * all emitted vertices; 789 * - execute BeginQuery for PRIMITIVES_GENERATED and 790 * TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries 791 * after draw call; 792 * - use transform feedback in separate mode. 793 * 794 * Separate mode require one buffer per captured variable. 795 * 796 * Test pass if results of queries are correct. 797 */ 798 class QueryGeometrySeparate : public CaptureGeometrySeparate 799 { 800 public: 801 QueryGeometrySeparate(deqp::Context &context, const char *test_name, const char *test_description); 802 803 protected: 804 glw::GLuint m_query_object; 805 806 virtual void createTransformFeedbackBuffer(void); 807 virtual void draw(glw::GLuint primitive_case); 808 virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); 809 virtual void clean(void); 810 }; 811 812 /** DiscardVertex 813 * 814 * Verifies if rasterization is discarded when geometry is captured from vertex 815 * stage. 816 * 817 * Test should be run if EXT_transform_feedback is supported or context is 818 * at least 3.0. 819 * 820 * Modify CaptureVertexInterleaved test in the following aspects: 821 * - disable rasterization before draw call; 822 * - it is expected that framebuffer contents will not change, while XFB buffer 823 * is modified. 824 */ 825 class DiscardVertex : public CaptureVertexInterleaved 826 { 827 public: 828 DiscardVertex(deqp::Context &context, const char *test_name, const char *test_description); 829 830 protected: 831 virtual void draw(glw::GLuint primitive_case); 832 virtual bool checkFramebuffer(glw::GLuint primitive_case); 833 }; 834 835 /** DiscardGeometry 836 * 837 * Verifies if rasterization is discarded when geometry is captured from 838 * geometry stage. 839 * 840 * Test should be run if EXT_transform_feedback is supported or context is at least 3.0. 841 * Test should be run if ARB_geometry_shader4 is supported or context is at least 3.2. 842 * 843 * Modify CaptureGeometryInterleaved test in the following aspects: 844 * - disable rasterization before draw call; 845 * - it is expected that framebuffer contents will not change, while XFB buffer 846 * is modified. 847 */ 848 class DiscardGeometry : public CaptureGeometryInterleaved 849 { 850 public: 851 DiscardGeometry(deqp::Context &context, const char *test_name, const char *test_description); 852 853 protected: 854 virtual void draw(glw::GLuint primitive_case); 855 virtual bool checkFramebuffer(glw::GLuint primitive_case); 856 }; 857 858 /** DrawXFB 859 * 860 * Verifies that transform feedback objects can be used to draw. 861 * 862 * Test should be executed if ARB_transform_feedback2 is supported or context 863 * is at least 4.0. 864 * 865 * Steps: 866 * - prepare two programs consisting of vertex shader which will: 867 * * output position based on gl_VertexID: 868 * * output color by passing value of uniform; 869 * First program should use the following positions: 870 * ID | X | Y 871 * 0 | -1 | -1 872 * 1 | -1 | 1 873 * 2 | 1 | 1 874 * Second program should use the following positions: 875 * 0 | -1 | -1 876 * 1 | 1 | 1 877 * 2 | 1 | -1 878 * - prepare three XFB objects and corresponding buffers for captured geometry; 879 * Each XFB should capture position and color from both programs; 880 * - activate first program; 881 * - for each XFB object: 882 * * set uniform to color corresponding with XFB; 883 * * activate XFB; 884 * * execute DrawArrays to draw three points starting at 0; 885 * * pause XFB; 886 * - inspect TRANSFORM_FEEDBACK_BUFFER_PAUSED and 887 * TRANSFORM_FEEDBACK_BUFFER_ACTIVE; 888 * - activate second program; 889 * - for each XFB object: 890 * * set uniform to color corresponding with XFB; 891 * * resume XFB; 892 * * execute DrawArrays to draw three points starting at 0; 893 * * end XFB; 894 * - inspect TRANSFORM_FEEDBACK_BUFFER_PAUSED and 895 * TRANSFORM_FEEDBACK_BUFFER_ACTIVE; 896 * - prepare program consisting of vertex and fragment stage; Vertex shader 897 * should pass position and color; Fragment stage should pass color; 898 * - set program; 899 * - set vertex array to match layout of XFB; 900 * - for each XFB: 901 * * prepare and clean framebuffer; 902 * * execute DrawTransformFeedback to draw triangles; 903 * * inspect contents of framebuffer; 904 * 905 * It is expected that drawn images will be filled with color set via uniform 906 * variables. 907 * 908 * Repeat steps for both interleaved and separate modes. 909 */ 910 class DrawXFB : public deqp::TestCase 911 { 912 public: 913 DrawXFB(deqp::Context &context, const char *test_name, const char *test_description); 914 ~DrawXFB(void); 915 virtual IterateResult iterate(void); 916 917 protected: 918 static const glw::GLchar *s_vertex_shader_xfb; 919 static const glw::GLchar *s_vertex_shader_draw; 920 static const glw::GLchar *s_fragment_shader; 921 922 static const glw::GLuint s_xfb_varyings_count = 2; 923 static const glw::GLchar *s_xfb_varyings[s_xfb_varyings_count]; 924 static const glw::GLuint s_vertex_count = 3; 925 static const glw::GLenum s_capture_modes[]; 926 static const glw::GLuint s_capture_modes_count; 927 static const glw::GLuint s_capture_size = s_vertex_count * sizeof(glw::GLfloat) * 4 /* number of components */ * 928 s_xfb_varyings_count * 2 /* number of programs */; 929 static const glw::GLuint s_view_size = 2; 930 static const glw::GLuint s_xfb_count = 3; 931 static const glw::GLfloat s_colours[s_xfb_count][4]; 932 933 deqp::Context &m_context; 934 glw::GLuint m_program_id_xfb; 935 glw::GLuint m_program_id_draw; 936 glw::GLuint m_xfb_id[s_xfb_count]; 937 glw::GLuint m_bo_id[s_xfb_count]; 938 glw::GLuint m_fbo_id; 939 glw::GLuint m_rbo_id; 940 glw::GLuint m_vao_id; 941 942 void prepare(glw::GLenum capture_mode); 943 void bindXFB(glw::GLuint xfb_id); 944 void bindVAO(glw::GLuint vao_id); 945 void bindBOForXFB(glw::GLenum capture_mode, glw::GLuint bo_id); 946 void bindBOForDraw(glw::GLuint program_id, glw::GLenum capture_mode, glw::GLuint bo_id); 947 void useProgram(glw::GLuint program_id); 948 void useColour(glw::GLuint program_id, glw::GLfloat r, glw::GLfloat g, glw::GLfloat b, glw::GLfloat a); 949 void useGeometrySet(glw::GLuint program_id, bool invert_sign); 950 void drawForCapture(bool begin_xfb, bool pause_xfb, bool resume_xfb, bool end_xfb); 951 void drawToFramebuffer(glw::GLuint xfb_id); 952 bool checkFramebuffer(glw::GLfloat r, glw::GLfloat g, glw::GLfloat b, glw::GLfloat a); 953 bool inspectXFBState(bool shall_be_paused, bool shall_be_active); 954 void clean(); 955 }; 956 957 /** DrawXFBFeedback 958 * 959 * Verifies that data captured with XFB can be used as source for next capture. 960 * 961 * Test should be executed if ARB_transform_feedback2 is supported or context 962 * is at least 4.0. 963 * 964 * Steps: 965 * - prepare program consisting of vertex shader which pass position from input 966 * attribute to gl_Position multiplying it by 2.0; 967 * - instruct implementation to capture geometry in interleaved mode; 968 * - prepare source buffer; 969 * - prepare buffer to capture geometry; 970 * - begin transform feedback; 971 * - draw one vertex using DrawArrays; 972 * - end transform feedback; 973 * - swap buffer 974 * - begin transform feedback; 975 * - draw using DrawTransformFeedback; 976 * - end transform feedback; 977 * - swap buffer 978 * - begin transform feedback; 979 * - draw using DrawTransformFeedback; 980 * - end transform feedback; 981 * - map last captured buffer, expect position vector multiplied by value 8; 982 */ 983 class DrawXFBFeedback : public deqp::TestCase 984 { 985 public: 986 DrawXFBFeedback(deqp::Context &context, const char *test_name, const char *test_description); 987 ~DrawXFBFeedback(void); 988 virtual IterateResult iterate(void); 989 990 protected: 991 static const glw::GLchar *s_vertex_shader; 992 static const glw::GLchar *s_fragment_shader; 993 static const glw::GLchar *s_xfb_varying; 994 static const glw::GLchar *s_attrib; 995 static const glw::GLuint s_draw_vertex_count; 996 static const glw::GLfloat s_initial_data[]; 997 static const glw::GLuint s_bo_count = 2; 998 static const glw::GLuint s_bo_size; 999 1000 deqp::Context &m_context; 1001 glw::GLuint m_program_id; 1002 glw::GLuint m_vao_id[s_bo_count]; 1003 glw::GLuint m_xfb_id; 1004 glw::GLuint m_bo_id[s_bo_count]; 1005 glw::GLuint m_source_bo_index; 1006 1007 void prepareAndBind(); 1008 void draw(bool is_first_draw); 1009 void swapBuffers(); 1010 bool check(); 1011 void clean(); 1012 }; 1013 1014 /** DrawXFBStream 1015 * 1016 * Verifies that vertex stream captured with transform feedback can be used to 1017 * draw. 1018 * 1019 * Test should be executed if both ARB_transform_feedback3 and ARB_gpu_shader5 1020 * are supported or context is at least 4.0. 1021 * This test is not supported if MAX_VERTEX_STREAMS is less than 2. 1022 * 1023 * Steps: 1024 * - prepare program consisting of vertex and geometry shaders; Geometry shader 1025 * should output full-screen quad made of two triangles; First triangle should 1026 * be emitted to first vertex stream; Second triangle should be emitted to the 1027 * second vertex stream; Vertex shader can be blank; 1028 * - prepare buffers to capture geometry; 1029 * - instruct implementation to capture geometry in interleaved mode; 1030 * - begin XFB; 1031 * - begin indexed query for PRIMITIVES_GENERATED and 1032 * TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN for both vertex streams; 1033 * - draw single vertex; 1034 * - end queries; 1035 * - end XFB; 1036 * - inspect results of queries; 1037 * - prepare program consisting of vertex and fragment shaders; Vertex stage 1038 * should pass position from input to output; Fragment shader should output 1039 * white color; 1040 * - prepare and clean framebuffer; 1041 * - set vertex array layout to match data captured by XFB; 1042 * - execute DrawTransformFeedbackStream to draw triangle from first stream; 1043 * - execute DrawTransformFeedbackStream to draw triangle from second stream; 1044 * - inspect contents of framebuffer, it is expected to be filled with white 1045 * color. 1046 */ 1047 class DrawXFBStream : public deqp::TestCase 1048 { 1049 public: 1050 DrawXFBStream(deqp::Context &context, const char *test_name, const char *test_description); 1051 ~DrawXFBStream(void); 1052 virtual IterateResult iterate(void); 1053 1054 private: 1055 static const glw::GLchar *s_vertex_shader_pass; 1056 static const glw::GLchar *s_vertex_shader_blank; 1057 static const glw::GLchar *s_geometry_shader; 1058 static const glw::GLchar *s_fragment_shader; 1059 static const glw::GLchar *s_xfb_varyings[]; 1060 static const glw::GLuint s_xfb_varyings_count; 1061 static const glw::GLuint s_bo_ids_count = 2; 1062 static const glw::GLuint s_qo_ids_count = 4; 1063 static const glw::GLuint s_bo_size; 1064 static const glw::GLuint s_view_size; 1065 1066 deqp::Context &m_context; 1067 glw::GLuint m_program_id_generate; 1068 glw::GLuint m_program_id_draw; 1069 glw::GLuint m_vao_id; 1070 glw::GLuint m_xfb_id; 1071 glw::GLuint m_bo_id[s_bo_ids_count]; 1072 glw::GLuint m_fbo_id; 1073 glw::GLuint m_rbo_id; 1074 glw::GLuint m_qo_id[s_qo_ids_count]; 1075 1076 void prepareObjects(); 1077 void setupVertexArray(glw::GLuint bo_id); 1078 void useProgram(glw::GLuint program_id); 1079 void drawForXFB(); 1080 bool inspectQueries(); 1081 void drawForFramebuffer(glw::GLuint stream); 1082 bool check(); 1083 void clean(); 1084 }; 1085 1086 /** CaptureSpecialInterleaved 1087 * 1088 * Verifies that special variable names are respected. 1089 * 1090 * Test should be executed if ARB_transform_feedback3 is supported or context 1091 * is at least 4.0. 1092 * 1093 * Steps: 1094 * - prepare program consisting of vertex shader which outputs four variables; 1095 * - set up XFB to capture the following <varyings>: 1096 * * variable_1, 1097 * * gl_SkipComponents4, 1098 * * variable_2, 1099 * * gl_NextBuffer, 1100 * * variable_3, 1101 * * gl_SkipComponents4, 1102 * * variable_4; 1103 * - begin XFB; 1104 * - draw two vertices; 1105 * - end XFB; 1106 * - verify that captured geometry is correct. 1107 */ 1108 class CaptureSpecialInterleaved : public deqp::TestCase 1109 { 1110 public: 1111 CaptureSpecialInterleaved(deqp::Context &context, const char *test_name, const char *test_description); 1112 ~CaptureSpecialInterleaved(void); 1113 virtual IterateResult iterate(void); 1114 1115 private: 1116 static const glw::GLchar *s_vertex_shader; 1117 static const glw::GLchar *s_fragment_shader; 1118 static const glw::GLchar *s_xfb_varyings[]; 1119 static const glw::GLuint s_xfb_varyings_count; 1120 static const glw::GLuint s_bo_ids_count = 2; 1121 static const glw::GLuint s_bo_size; 1122 1123 deqp::Context &m_context; 1124 glw::GLuint m_program_id; 1125 glw::GLuint m_vao_id; 1126 glw::GLuint m_xfb_id; 1127 glw::GLuint m_bo_id[s_bo_ids_count]; 1128 1129 void prepareAndBind(); 1130 void draw(); 1131 bool check(); 1132 void clean(); 1133 }; 1134 1135 /** DrawXFBInstanced 1136 * 1137 * Verifies that transform feedback objects can used with instanced draws. 1138 * 1139 * Test should be executed if context is at least 3.1 and either 1140 * ARB_transform_feedback_instanced is supported or context is at least 4.2. 1141 * 1142 * Steps: 1143 * - prepare program consisting of vertex shader which outputs positions of 1144 * full-screen quad made of triangle strip based on gl_VertexID; 1145 * - instruct implementation to capture geometry in interleaved mode; 1146 * - prepare buffer to capture geometry; 1147 * - begin transform feedback; 1148 * - draw four vertices; 1149 * - end transform feedback; 1150 * - prepare program consisting of vertex and fragment shaders; Vertex stage 1151 * should calculate position as follows: 1152 * 1153 * gl_Position = in_position * uni_matrices[gl_InstanceID]; 1154 * 1155 * Fragment shader should output white color; 1156 * - prepare UNIFORM_BUFFER filled with four mat4; Select data so matrices 1157 * transforms quad [-1, -1] : [1, 1] as follows: 1158 * * 0 - [-1, 0] : [0, 1] - left top, 1159 * * 1 - [ 0, 0] : [1, 1] - right top, 1160 * * 2 - [-1, -1] : [0, 0] - left bottom, 1161 * * 3 - [ 0, -1] : [1, 0] - right bottom; 1162 * - prepare and clean framebuffer; 1163 * - set up layout of vertex data in XFB; 1164 * - execute DrawTransformFeedbackInstanced to draw four instances of quad from XFB; 1165 * - it is expected that framebuffer is filled with white color; 1166 */ 1167 class DrawXFBInstanced : public deqp::TestCase 1168 { 1169 public: 1170 DrawXFBInstanced(deqp::Context &context, const char *test_name, const char *test_description); 1171 ~DrawXFBInstanced(void); 1172 virtual IterateResult iterate(void); 1173 1174 private: 1175 static const glw::GLchar *s_vertex_shader_generate; 1176 static const glw::GLchar *s_vertex_shader_draw; 1177 static const glw::GLchar *s_fragment_shader; 1178 static const glw::GLchar *s_xfb_varying; 1179 static const glw::GLchar *s_uniform; 1180 static const glw::GLuint s_bo_xfb_size; 1181 static const glw::GLfloat s_bo_uniform_data[]; 1182 static const glw::GLuint s_bo_uniform_size; 1183 static const glw::GLuint s_view_size; 1184 1185 deqp::Context &m_context; 1186 glw::GLuint m_program_id_generate; 1187 glw::GLuint m_program_id_draw; 1188 glw::GLuint m_vao_id; 1189 glw::GLuint m_xfb_id; 1190 glw::GLuint m_bo_id_xfb; 1191 glw::GLuint m_bo_id_uniform; 1192 glw::GLuint m_fbo_id; 1193 glw::GLuint m_rbo_id; 1194 1195 void prepareObjects(); 1196 void drawForXFB(); 1197 void drawInstanced(); 1198 bool check(); 1199 void clean(); 1200 1201 typedef GLW_APICALL glw::GLuint(GLW_APIENTRY *GetUniformBlockIndex_ProcAddress)( 1202 glw::GLuint program, const glw::GLchar *uniformBlockName); 1203 typedef GLW_APICALL void(GLW_APIENTRY *UniformBlockBinding_ProcAddress)(glw::GLuint program, 1204 glw::GLuint uniformIndex, 1205 glw::GLuint uniformBlockBinding); 1206 1207 GetUniformBlockIndex_ProcAddress m_glGetUniformBlockIndex; 1208 UniformBlockBinding_ProcAddress m_glUniformBlockBinding; 1209 }; 1210 1211 /** DrawXFBStreamInstanced 1212 * 1213 * Verifies that transform feedback objects can used with instanced draws. 1214 * 1215 * Test should be executed if context is at least 3.1 and either 1216 * ARB_gpu_shader5 is supported or context is at least 4.0 and either 1217 * ARB_transform_feedback_instanced is supported or context is at least 4.2. 1218 * 1219 * Steps: 1220 * - prepare program consisting of vertex shader which based on gl_VertexID 1221 * outputs: 1222 * * to stream 0 - color, 1223 * * to stream 1 - positions 1224 * for a full-screen quad made of triangle strip; 1225 * - instruct implementation to capture geometry in interleaved mode; 1226 * - prepare buffers to capture geometry; 1227 * - begin transform feedback; 1228 * - draw four vertices; 1229 * - end transform feedback; 1230 * - prepare program consisting of vertex and fragment shaders; Vertex stage 1231 * should calculate position as follows: 1232 * 1233 * gl_Position = in_position * uni_matrices[gl_InstanceID]; 1234 * 1235 * Fragment shader should output white color; 1236 * - prepare UNIFORM_BUFFER filled with four mat4; Select data so matrices 1237 * transforms quad [-1, -1] : [1, 1] as follows: 1238 * * 0 - [-1, 0] : [0, 1] - left top, 1239 * * 1 - [ 0, 0] : [1, 1] - right top, 1240 * * 2 - [-1, -1] : [0, 0] - left bottom, 1241 * * 3 - [ 0, -1] : [1, 0] - right bottom; 1242 * - prepare and clean framebuffer; 1243 * - set up layout of vertex data in XFB; 1244 * - execute DrawTransformFeedbackStreamInstanced to draw four instances of 1245 * quad from XFB, stream 1; 1246 * - it is expected that framebuffer is filled with white color; 1247 */ 1248 class DrawXFBStreamInstanced : public deqp::TestCase 1249 { 1250 public: 1251 DrawXFBStreamInstanced(deqp::Context &context, const char *test_name, const char *test_description); 1252 ~DrawXFBStreamInstanced(void); 1253 virtual IterateResult iterate(void); 1254 1255 private: 1256 static const glw::GLchar *s_vertex_shader_blank; 1257 static const glw::GLchar *s_geometry_shader_generate; 1258 static const glw::GLchar *s_vertex_shader_draw; 1259 static const glw::GLchar *s_fragment_shader_blank; 1260 static const glw::GLchar *s_fragment_shader_draw; 1261 static const glw::GLchar *s_xfb_varyings[]; 1262 static const glw::GLuint s_xfb_varyings_count; 1263 static const glw::GLchar *s_uniform; 1264 static const glw::GLuint s_bo_xfb_size; 1265 static const glw::GLfloat s_bo_uniform_data[]; 1266 static const glw::GLuint s_bo_uniform_size; 1267 static const glw::GLuint s_view_size; 1268 1269 deqp::Context &m_context; 1270 glw::GLuint m_program_id_generate; 1271 glw::GLuint m_program_id_draw; 1272 glw::GLuint m_vao_id; 1273 glw::GLuint m_xfb_id; 1274 glw::GLuint m_bo_id_xfb_position; 1275 glw::GLuint m_bo_id_xfb_color; 1276 glw::GLuint m_bo_id_uniform; 1277 glw::GLuint m_fbo_id; 1278 glw::GLuint m_rbo_id; 1279 1280 void prepareObjects(); 1281 void drawForXFB(); 1282 void drawStreamInstanced(); 1283 bool check(); 1284 void clean(); 1285 1286 typedef GLW_APICALL glw::GLuint(GLW_APIENTRY *GetUniformBlockIndex_ProcAddress)( 1287 glw::GLuint program, const glw::GLchar *uniformBlockName); 1288 typedef GLW_APICALL void(GLW_APIENTRY *UniformBlockBinding_ProcAddress)(glw::GLuint program, 1289 glw::GLuint uniformIndex, 1290 glw::GLuint uniformBlockBinding); 1291 1292 GetUniformBlockIndex_ProcAddress m_glGetUniformBlockIndex; 1293 UniformBlockBinding_ProcAddress m_glUniformBlockBinding; 1294 }; 1295 1296 namespace Utilities 1297 { 1298 /** Build a GLSL program 1299 * 1300 * @param [in] gl OpenGL Functions Access. 1301 * @param [in] log Log outut. 1302 * @param [in] geometry_shader_source Pointer to C string of the geometry shader or NULL if not used. 1303 * @param [in] tessellation_control_shader_source Pointer to C string of the tessellation control shader or NULL if not used. 1304 * @param [in] tessellation_evaluation_shader_source Pointer to C string of the tessellation evaluation shader or NULL if not used. 1305 * @param [in] vertex_shader_source Pointer to C string of the vertex shader or NULL if not used. 1306 * @param [in] geometry_shader_source Pointer to C string of the fragment shader or NULL if not used. 1307 * @param [in] transform_feedback_varyings C array of transform feedback varyings names. 1308 * @param [in] transform_feedback_varyings_count Count of transform feedback varyings names. 1309 * @param [in] transform_feedback_varyings_mode Transform feedback capture mode - GL_SEPARATE_ATTRIBS or GL_INTERLEAVED_ATTRIBS. 1310 * @param [in] do_not_detach Do not detach shaders - default is faulse. 1311 * @param [out] linking_status Return pointer to store linking status or NULL if not needed. 1312 * 1313 * @return OpenGL program shader ID or zero if error had occured. 1314 */ 1315 glw::GLuint buildProgram(glw::Functions const &gl, tcu::TestLog &log, glw::GLchar const *const geometry_shader_source, 1316 glw::GLchar const *const tessellation_control_shader_source, 1317 glw::GLchar const *const tessellation_evaluation_shader_source, 1318 glw::GLchar const *const vertex_shader_source, glw::GLchar const *const fragment_shader_source, 1319 glw::GLchar const *const *const transform_feedback_varyings, 1320 glw::GLsizei const transform_feedback_varyings_count, 1321 glw::GLenum const transform_feedback_varyings_mode, bool const do_not_detach = false, 1322 glw::GLint *linking_status = DE_NULL); 1323 1324 /** Preprocess source string by replacing key tokens with new values. 1325 * 1326 * @param [in] source Source string. 1327 * @param [in] key Key, substring to be replaced. 1328 * @param [in] value Value, substring to be substituted in place of key. 1329 * 1330 * @return Preprocessed string. 1331 */ 1332 std::string preprocessCode(std::string source, std::string key, std::string value); 1333 1334 /** Change integer number to string 1335 * 1336 * @param [in] i Integer number. 1337 * 1338 * @return String represnting integer number. 1339 */ 1340 std::string itoa(glw::GLint i); 1341 1342 /** Change floating point number to string 1343 * 1344 * @param [in] f Floating point number. 1345 * 1346 * @return String represnting floating point number. 1347 */ 1348 std::string ftoa(glw::GLfloat f); 1349 } // namespace Utilities 1350 } // namespace TransformFeedback 1351 1352 } // namespace gl3cts 1353 1354 #endif // _GL3CTRANSFORMFEEDBACKTESTS_HPP 1355