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