• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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