1 #ifndef _ESEXTCGPUSHADER5FMAPRECISION_HPP 2 #define _ESEXTCGPUSHADER5FMAPRECISION_HPP 3 /*------------------------------------------------------------------------- 4 * OpenGL Conformance Test Suite 5 * ----------------------------- 6 * 7 * Copyright (c) 2014-2016 The Khronos Group Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 */ /*! 22 * \file 23 * \brief 24 */ /*-------------------------------------------------------------------*/ 25 26 /*! 27 * \file esextcGPUShader5FmaPrecision.hpp 28 * \brief gpu_shader5 extension - fma precision Test (Test 8) 29 */ /*-------------------------------------------------------------------*/ 30 31 #include "../esextcTestCaseBase.hpp" 32 33 #include "tcuVector.hpp" 34 #include <cstdlib> 35 #include <iostream> 36 37 namespace glcts 38 { 39 /** Implementation of "Test 8" from CTS_EXT_gpu_shader5. Description follows 40 * 41 * Test whether the precision of fma() is conformant to the required 42 * precisions from Section 4.5.1 of the GLSL-ES 3.0 spec. 43 * 44 * Category: API, 45 * Functional Test. 46 * 47 * Write a vertex shader that declares three input attributes and 48 * two output variables 49 * 50 * in float a; 51 * in float b; 52 * in float c; 53 * 54 * precise out float resultStd; 55 * out float resultFma; 56 * 57 * In the vertex shader compute: 58 * 59 * resultStd = a*b+c; 60 * resultFma = fma(a,b,c); 61 * 62 * Write a boilerplate fragment shader. 63 * 64 * Create a program from the vertex shader and fragment shader and use it. resultStd 65 * must use "precise" so that number of operations for a*b+c is well defined. 66 * 67 * Initialize a set of buffer objects to be assigned as attributes data 68 * sources and fill each of them with 100 random float values from range 69 * [-100.0,100.0] generated using a consistent seed. 70 * 71 * Configure transform feedback to capture the values of resultStd and 72 * resultFma. 73 * 74 * Execute a draw call glDrawArrays(GL_POINTS, 0, 100). 75 * 76 * Copy the captured results from the buffer objects bound to transform 77 * feedback binding points to unionFloatInt resultStd[100] and 78 * unionFloatInt resultFma[100]. 79 * 80 * Compute: 81 * 82 * unionFloatInt resultCPU[100]; 83 * 84 * for(unsigned int i = 0; i < 100; ++i) 85 * { 86 * resultCPU[i].floatValue = data[i]*dataB[i] + dataC[i]; 87 * } 88 * 89 * The test is successful if 90 * 91 * abs( resultCPU.intValue - resultStd.intValue ) <= 2 && 92 * abs( resultCPU.intValue - resultFma.intValue ) <= 2 && 93 * abs( resultStd.intValue - resultFma.intValue ) <= 2 94 * 95 * for i = 0..99. 96 * 97 * This test should be run against all genTypes applicable to fma. 98 * For integers the calculations should be exact. 99 * 100 **/ 101 102 /* Define type of input data */ 103 enum INPUT_DATA_TYPE 104 { 105 IDT_FLOAT = 1, 106 IDT_VEC2 = 2, 107 IDT_VEC3 = 3, 108 IDT_VEC4 = 4, 109 }; 110 111 /* Helper for bitwise operation */ 112 union FloatConverter { 113 glw::GLfloat m_float; 114 glw::GLint m_int; 115 }; 116 117 template <INPUT_DATA_TYPE S> 118 class GPUShader5FmaPrecision : public TestCaseBase 119 { 120 public: 121 /* Public methods */ 122 GPUShader5FmaPrecision(Context& context, const ExtParameters& extParams, const char* name, const char* description); 123 ~GPUShader5FmaPrecision(void)124 virtual ~GPUShader5FmaPrecision(void) 125 { 126 } 127 128 virtual void deinit(void); 129 virtual IterateResult iterate(void); 130 131 private: 132 /* Private methods */ 133 std::string generateVertexShaderCode(); 134 const char* getFragmentShaderCode(); 135 void generateData(); 136 void initTest(void); 137 138 /* Static variables */ 139 static const glw::GLuint m_n_elements = 100; 140 141 /* Variables for general usage */ 142 const glw::GLfloat m_amplitude; 143 glw::GLfloat m_data_a[m_n_elements * S]; 144 glw::GLfloat m_data_b[m_n_elements * S]; 145 glw::GLfloat m_data_c[m_n_elements * S]; 146 glw::GLuint m_fs_id; 147 glw::GLuint m_po_id; 148 glw::GLuint m_vao_id; 149 glw::GLuint m_vbo_a_id; 150 glw::GLuint m_vbo_b_id; 151 glw::GLuint m_vbo_c_id; 152 glw::GLuint m_vbo_result_fma_id; 153 glw::GLuint m_vbo_result_std_id; 154 glw::GLuint m_vs_id; 155 }; 156 157 } // namespace glcts 158 159 #endif // _ESEXTCGPUSHADER5FMAPRECISION_HPP 160