2 * Copyright 2014 VMware, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 * Test resource limits given the maximum supported by the implementation.
27 * Each component of the fragment output is derived using the following
28 * expression (indexed at the scalar level):
30 * result[i] = texture[i] * texture[i] * ... * attrib[i + l * numOutputs]
32 * Depending on the limits for vertex/fragment image units, the texture
33 * contribution will vary. See the generation of g_expected at the end of
36 * Since the scalar inputs are primes, multiplication will yield a unique
37 * result. Results can be diagnosed by evaluating for their missing factor(s).
43 #include "piglit-util-gl.h"
45 PIGLIT_GL_TEST_CONFIG_BEGIN
47 config
.supports_gl_compat_version
= 30;
48 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGBA
;
49 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
51 PIGLIT_GL_TEST_CONFIG_END
55 * Definitions for the runtime behavior.
57 #define GLSL_VERSION "#version 130"
58 #define BUFFER_WIDTH 32
59 #define BUFFER_HEIGHT 32
60 #define MAX_SHADER_LINE_CHARS 256
61 #define MAX_SHADER_TEXT_CHARS 16*1024
62 #define MAX_COMPONENTS 4
63 #define MAX_EXPRESSION_OUTPUTS 1
64 #define MAX_EXPRESSION_ARGUMENTS 2
65 #define MAX_EXPRESSION_TEMPS 1
66 #define TEMP_TEXT_SIZE (MAX_EXPRESSION_OUTPUTS + \
67 MAX_EXPRESSION_ARGUMENTS + \
68 MAX_EXPRESSION_ARGUMENTS)
70 #define NUM_PRIMES 512
71 #define NUM_VERTICES 3
73 #define DEBUG_INPUT 0x01
74 #define DEBUG_READBACK 0x02
75 #define DEBUG_SHADERS 0x04
76 #define DEBUG_DRAW 0x08
77 #define DEBUG_DONT_CLAMP_MAX_VARYINGS 0x10
80 * Type definitions for our working set.
84 DRAW_ELEMENTS_VBO
= 1,
88 typedef struct MyVector4
{
92 typedef struct PackedTypeDesc
{
94 unsigned numComponents
;
95 char *componentNames
[MAX_COMPONENTS
];
99 typedef struct PackedDesc
{
104 const PackedTypeDesc
*typeDesc
;
109 * Global variables for the test's state.
111 static GLint g_maxVaryingFloats
= 0;
112 static GLint g_maxVertexAttribs
= 0;
113 static GLint g_maxVertexTextureImageUnits
= 0;
114 static GLint g_maxTextureImageUnits
= 0;
115 static GLint g_maxCombinedTextureImageUnits
= 0;
117 static GLint g_maxAuxBuffers
= 0;
118 static GLint g_maxDrawBuffers
= 0;
119 static GLint g_maxColorAttachments
= 0;
121 static GLint g_debugMask
= 0x0;
122 static GLint g_drawMode
= DRAW_IMMEDIATE
;
124 static char *g_fragColor
= "gl_FragColor";
125 static char *g_fragData
= "gl_FragData";
127 static const GLfloat g_primes
[NUM_PRIMES
] = {
128 2.0, 3.0, 5.0, 7.0, 11.0, 13.0, 17.0, 19.0,
129 23.0, 29.0, 31.0, 37.0, 41.0, 43.0, 47.0, 53.0,
130 59.0, 61.0, 67.0, 71.0, 73.0, 79.0, 83.0, 89.0,
131 97.0, 101.0, 103.0, 107.0, 109.0, 113.0, 127.0, 131.0,
132 137.0, 139.0, 149.0, 151.0, 157.0, 163.0, 167.0, 173.0,
133 179.0, 181.0, 191.0, 193.0, 197.0, 199.0, 211.0, 223.0,
134 227.0, 229.0, 233.0, 239.0, 241.0, 251.0, 257.0, 263.0,
135 269.0, 271.0, 277.0, 281.0, 283.0, 293.0, 307.0, 311.0,
136 313.0, 317.0, 331.0, 337.0, 347.0, 349.0, 353.0, 359.0,
137 367.0, 373.0, 379.0, 383.0, 389.0, 397.0, 401.0, 409.0,
138 419.0, 421.0, 431.0, 433.0, 439.0, 443.0, 449.0, 457.0,
139 461.0, 463.0, 467.0, 479.0, 487.0, 491.0, 499.0, 503.0,
140 509.0, 521.0, 523.0, 541.0, 547.0, 557.0, 563.0, 569.0,
141 571.0, 577.0, 587.0, 593.0, 599.0, 601.0, 607.0, 613.0,
142 617.0, 619.0, 631.0, 641.0, 643.0, 647.0, 653.0, 659.0,
143 661.0, 673.0, 677.0, 683.0, 691.0, 701.0, 709.0, 719.0,
144 727.0, 733.0, 739.0, 743.0, 751.0, 757.0, 761.0, 769.0,
145 773.0, 787.0, 797.0, 809.0, 811.0, 821.0, 823.0, 827.0,
146 829.0, 839.0, 853.0, 857.0, 859.0, 863.0, 877.0, 881.0,
147 883.0, 887.0, 907.0, 911.0, 919.0, 929.0, 937.0, 941.0,
148 947.0, 953.0, 967.0, 971.0, 977.0, 983.0, 991.0, 997.0,
149 1009.0, 1013.0, 1019.0, 1021.0, 1031.0, 1033.0, 1039.0, 1049.0,
150 1051.0, 1061.0, 1063.0, 1069.0, 1087.0, 1091.0, 1093.0, 1097.0,
151 1103.0, 1109.0, 1117.0, 1123.0, 1129.0, 1151.0, 1153.0, 1163.0,
152 1171.0, 1181.0, 1187.0, 1193.0, 1201.0, 1213.0, 1217.0, 1223.0,
153 1229.0, 1231.0, 1237.0, 1249.0, 1259.0, 1277.0, 1279.0, 1283.0,
154 1289.0, 1291.0, 1297.0, 1301.0, 1303.0, 1307.0, 1319.0, 1321.0,
155 1327.0, 1361.0, 1367.0, 1373.0, 1381.0, 1399.0, 1409.0, 1423.0,
156 1427.0, 1429.0, 1433.0, 1439.0, 1447.0, 1451.0, 1453.0, 1459.0,
157 1471.0, 1481.0, 1483.0, 1487.0, 1489.0, 1493.0, 1499.0, 1511.0,
158 1523.0, 1531.0, 1543.0, 1549.0, 1553.0, 1559.0, 1567.0, 1571.0,
159 1579.0, 1583.0, 1597.0, 1601.0, 1607.0, 1609.0, 1613.0, 1619.0,
160 1621.0, 1627.0, 1637.0, 1657.0, 1663.0, 1667.0, 1669.0, 1693.0,
161 1697.0, 1699.0, 1709.0, 1721.0, 1723.0, 1733.0, 1741.0, 1747.0,
162 1753.0, 1759.0, 1777.0, 1783.0, 1787.0, 1789.0, 1801.0, 1811.0,
163 1823.0, 1831.0, 1847.0, 1861.0, 1867.0, 1871.0, 1873.0, 1877.0,
164 1879.0, 1889.0, 1901.0, 1907.0, 1913.0, 1931.0, 1933.0, 1949.0,
165 1951.0, 1973.0, 1979.0, 1987.0, 1993.0, 1997.0, 1999.0, 2003.0,
166 2011.0, 2017.0, 2027.0, 2029.0, 2039.0, 2053.0, 2063.0, 2069.0,
167 2081.0, 2083.0, 2087.0, 2089.0, 2099.0, 2111.0, 2113.0, 2129.0,
168 2131.0, 2137.0, 2141.0, 2143.0, 2153.0, 2161.0, 2179.0, 2203.0,
169 2207.0, 2213.0, 2221.0, 2237.0, 2239.0, 2243.0, 2251.0, 2267.0,
170 2269.0, 2273.0, 2281.0, 2287.0, 2293.0, 2297.0, 2309.0, 2311.0,
171 2333.0, 2339.0, 2341.0, 2347.0, 2351.0, 2357.0, 2371.0, 2377.0,
172 2381.0, 2383.0, 2389.0, 2393.0, 2399.0, 2411.0, 2417.0, 2423.0,
173 2437.0, 2441.0, 2447.0, 2459.0, 2467.0, 2473.0, 2477.0, 2503.0,
174 2521.0, 2531.0, 2539.0, 2543.0, 2549.0, 2551.0, 2557.0, 2579.0,
175 2591.0, 2593.0, 2609.0, 2617.0, 2621.0, 2633.0, 2647.0, 2657.0,
176 2659.0, 2663.0, 2671.0, 2677.0, 2683.0, 2687.0, 2689.0, 2693.0,
177 2699.0, 2707.0, 2711.0, 2713.0, 2719.0, 2729.0, 2731.0, 2741.0,
178 2749.0, 2753.0, 2767.0, 2777.0, 2789.0, 2791.0, 2797.0, 2801.0,
179 2803.0, 2819.0, 2833.0, 2837.0, 2843.0, 2851.0, 2857.0, 2861.0,
180 2879.0, 2887.0, 2897.0, 2903.0, 2909.0, 2917.0, 2927.0, 2939.0,
181 2953.0, 2957.0, 2963.0, 2969.0, 2971.0, 2999.0, 3001.0, 3011.0,
182 3019.0, 3023.0, 3037.0, 3041.0, 3049.0, 3061.0, 3067.0, 3079.0,
183 3083.0, 3089.0, 3109.0, 3119.0, 3121.0, 3137.0, 3163.0, 3167.0,
184 3169.0, 3181.0, 3187.0, 3191.0, 3203.0, 3209.0, 3217.0, 3221.0,
185 3229.0, 3251.0, 3253.0, 3257.0, 3259.0, 3271.0, 3299.0, 3301.0,
186 3307.0, 3313.0, 3319.0, 3323.0, 3329.0, 3331.0, 3343.0, 3347.0,
187 3359.0, 3361.0, 3371.0, 3373.0, 3389.0, 3391.0, 3407.0, 3413.0,
188 3433.0, 3449.0, 3457.0, 3461.0, 3463.0, 3467.0, 3469.0, 3491.0,
189 3499.0, 3511.0, 3517.0, 3527.0, 3529.0, 3533.0, 3539.0, 3541.0,
190 3547.0, 3557.0, 3559.0, 3571.0, 3581.0, 3583.0, 3593.0, 3607.0,
191 3613.0, 3617.0, 3623.0, 3631.0, 3637.0, 3643.0, 3659.0, 3671.0,
194 static const PackedTypeDesc g_rgbaDesc
= {
195 "vec4", 4, { ".r", ".g", ".b", ".a" },
196 "vec4(1.0, 1.0, 1.0, 1.0)"
199 static const PackedTypeDesc g_vec4Desc
= {
200 "vec4", 4, { ".x", ".y", ".z", ".w" },
201 "vec4(1.0, 1.0, 1.0, 1.0)"
204 static const PackedTypeDesc g_floatDesc
= {
209 static const PackedTypeDesc g_sampler2DDesc
= {
210 "sampler2D", 4, { "" },
211 "vec4(1.0, 1.0, 1.0, 1.0)"
214 static const char *g_vectorComponents
[MAX_COMPONENTS
] = {
215 ".x", ".y", ".z", ".w"
218 //static const MyVector4 one = { 1.0f, 1.0f, 1.0f, 1.0f };
219 //static const MyVector4 zero = { 0.0f, 0.0f, 0.0f, 0.0f };
221 static const MyVector4 g_positionBuffer
[NUM_VERTICES
] = {
222 { -1.0, -1.0, 0.0, 0.0 },
223 { -1.0, 1.0, 0.0, 0.0 },
224 { 1.0, 1.0, 0.0, 0.0 }
227 static GLuint g_elementVBO
;
228 static const GLushort g_elementBuffer
[NUM_VERTICES
] = { 0, 1, 2 };
229 static const char *g_vertexShaderText
=
234 " gl_Position = gl_Vertex; \n"
237 //static char *g_geometryShaderText = NULL;
239 static const char *g_fragmentShaderText
=
244 " gl_FragData[0] = vec4(1.0, 2.0, 3.0, 4.0);\n"
245 " gl_FragData[1] = vec4(5.0, 6.0, 7.0, 8.0);\n"
248 static GLuint g_program
= 0;
249 static GLfloat
*g_expected
;
253 * Format a string which contains the requested declaration for the variable.
254 * The desc structure will describe the variable, i.e. type, if it is an array,
255 * and how large the array is.
257 * \param desc Descriptor of the variable referenced. See PackedDesc.
258 * \param tmpStrSize Temporary string size for safe string formatting.
259 * \param tmpStr Temporary staging string.
260 * \param strSize Size of the formatted string.
261 * \param str An allocated temporary string for this function to populate with
262 * the reference expression.
263 * \return Pointer to str.
267 get_packed_decl(const PackedDesc
*desc
,
268 const unsigned tmpStrSize
,
270 const unsigned strSize
,
280 snprintf(tmpStr
, tmpStrSize
,
283 desc
->typeDesc
->typeName
,
285 desc
->isArray
? "[" : "",
287 desc
->isArray
? "]" : "");
288 strncat(str
, tmpStr
, strSize
- strlen(str
));
289 } else if (desc
->count
> 1) {
290 for (i
= 0; i
< desc
->count
; i
++) {
291 snprintf(tmpStr
, tmpStrSize
,
294 desc
->typeDesc
->typeName
,
295 desc
->variableName
, i
);
296 strncat(str
, tmpStr
, strSize
- strlen(str
));
299 snprintf(tmpStr
, tmpStrSize
,
302 desc
->typeDesc
->typeName
,
304 strncat(str
, tmpStr
, strSize
- strlen(str
));
312 * Format a string which contains the requested referenced value. The desc
313 * structure will describe the variable which is sub-indexed by arrayIndex.
314 * To address individual components, a componentIndex translated to (x,y,z,w)
315 * is applied to the textual representation.
317 * \param desc Descriptor of the variable referenced. See PackedDesc.
318 * \param arrayIndex Sub-index into the variable described by desc.
319 * \param componentIndex Component of the variable, depends on the desc
320 * configuration for the variable.
321 * \param str An allocated temporary string for this function to populate with
322 * the reference expression.
323 * \return Pointer to str.
327 get_packed_reference(const PackedDesc
*desc
,
328 const unsigned arrayIndex
,
329 const unsigned componentIndex
,
330 const unsigned strSize
,
333 if (g_debugMask
& DEBUG_INPUT
) {
334 printf("desc=%p componentIndex=%u\n", desc
, componentIndex
);
335 printf("desc->typeDesc=%p\n", desc
->typeDesc
);
336 printf("desc->typeDesc->componentNames=%p\n",
337 desc
->typeDesc
->componentNames
);
340 if (componentIndex
> desc
->typeDesc
->numComponents
) {
341 snprintf(str
, strSize
, "%s", g_floatDesc
.defaultValue
);
345 if (arrayIndex
> desc
->count
) {
346 snprintf(str
, strSize
, "%s%s",
347 desc
->typeDesc
->defaultValue
,
348 desc
->typeDesc
->componentNames
[componentIndex
]);
352 if (desc
->count
> 1) {
353 snprintf(str
, strSize
, "%s%s%u%s%s",
355 desc
->isArray
? "[" : "",
357 desc
->isArray
? "]" : "",
358 desc
->typeDesc
->componentNames
[componentIndex
]);
360 snprintf(str
, strSize
, "%s%s",
362 desc
->typeDesc
->componentNames
[componentIndex
]);
370 * Set up an FBO for the test.
372 * \param colorTarget Color attachment index relative to GL_COLOR_ATTACHMENT0
373 * \param internalFormat Internal GL format for the pixel data.
374 * \param format GL format for the pixel data.
375 * \param formatType Data type for the pixel data.
376 * \param width Width of the requested FBO backing store.
377 * \param height Height of the requested FBO backing store.
378 * \param fbo FBO object allocated to bind with this texture.
379 * \param pTexture A pointer to the GLuint identifier storage for the allocated
381 * \return true if the setup succeeded without error
386 setup_fbo_2d(const GLuint colorTarget
,
387 const GLenum internalFormat
,
389 const GLenum formatType
,
397 glGenTextures(1, pTexture
);
398 glBindTexture(GL_TEXTURE_2D
, *pTexture
);
399 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
400 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
401 glTexImage2D(GL_TEXTURE_2D
, 0, internalFormat
, width
, height
, 0,
402 format
, formatType
, NULL
);
405 * Framebuffer object is implied to be bound.
407 glFramebufferTexture2D(GL_FRAMEBUFFER
,
408 GL_COLOR_ATTACHMENT0
+ colorTarget
,
409 GL_TEXTURE_2D
, *pTexture
, 0);
411 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
412 fprintf(stderr
, "Failed to create FBO %u.\n", colorTarget
);
413 piglit_report_result(PIGLIT_FAIL
);
417 status
= glCheckFramebufferStatus(GL_FRAMEBUFFER
);
418 if (status
!= GL_FRAMEBUFFER_COMPLETE
) {
419 fprintf(stderr
, "Incomplete fbo for format %s.%s (status %s)\n",
420 piglit_get_gl_enum_name(internalFormat
),
421 piglit_get_gl_enum_name(format
),
422 piglit_get_gl_enum_name(status
));
423 piglit_report_result(PIGLIT_FAIL
);
432 * Set up the vertex buffer objects and element buffer objects for the
433 * test. To ensure constant values across the primitive, populate the same
434 * prime attribute value in each vertex.
436 * \return true if the setup succeeded without error
441 setup_vertex_element_buffers(void)
443 MyVector4 attrib
[NUM_VERTICES
];
449 * Setup the gl_Position attribute buffer.
451 glGenBuffers(1, &buf
);
452 glBindBuffer(GL_ARRAY_BUFFER
, buf
);
453 glBufferData(GL_ARRAY_BUFFER
, NUM_VERTICES
*sizeof(MyVector4
),
454 g_positionBuffer
, GL_STATIC_DRAW
);
456 attribLoc
= glGetAttribLocation(g_program
, "InPosition");
457 glEnableVertexAttribArray(attribLoc
);
458 glVertexAttribPointer(attribLoc
, 4, GL_FLOAT
, GL_FALSE
, 0, 0);
459 glBindBuffer(GL_ARRAY_BUFFER
, 0);
462 * Setup the vertex buffer objects.
464 for (i
= 0; i
< g_maxVertexAttribs
- 1; i
++) {
467 if ((i
+ 1) * MAX_COMPONENTS
< NUM_PRIMES
) {
468 attrib
[0].x
= attrib
[1].x
=
469 attrib
[2].x
= g_primes
[i
*MAX_COMPONENTS
+ 0];
470 attrib
[0].y
= attrib
[1].y
=
471 attrib
[2].y
= g_primes
[i
*MAX_COMPONENTS
+ 1];
472 attrib
[0].z
= attrib
[1].z
=
473 attrib
[2].z
= g_primes
[i
*MAX_COMPONENTS
+ 2];
474 attrib
[0].w
= attrib
[1].w
=
475 attrib
[2].w
= g_primes
[i
*MAX_COMPONENTS
+ 3];
477 attrib
[0].x
= attrib
[1].x
= attrib
[2].x
= 1.0;
478 attrib
[0].y
= attrib
[1].y
= attrib
[2].y
= 1.0;
479 attrib
[0].z
= attrib
[1].z
= attrib
[2].z
= 1.0;
480 attrib
[0].w
= attrib
[1].w
= attrib
[2].w
= 1.0;
483 glGenBuffers(1, &buf
);
484 glBindBuffer(GL_ARRAY_BUFFER
, buf
);
485 glBufferData(GL_ARRAY_BUFFER
, sizeof(MyVector4
)*NUM_VERTICES
,
486 attrib
, GL_STATIC_DRAW
);
488 snprintf(strTemp
, sizeof(strTemp
), "InValue%u", i
);
489 attribLoc
= glGetAttribLocation(g_program
, strTemp
);
490 glEnableVertexAttribArray(attribLoc
);
491 glVertexAttribPointer(attribLoc
, 4, GL_FLOAT
, GL_FALSE
, 0, 0);
492 glBindBuffer(GL_ARRAY_BUFFER
, 0);
494 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
495 fprintf(stderr
, "Failed to create VBO %u.\n", i
);
496 piglit_report_result(PIGLIT_FAIL
);
502 * Setup the element buffers.
504 glGenBuffers(1, &g_elementVBO
);
505 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, g_elementVBO
);
506 glBufferData(GL_ELEMENT_ARRAY_BUFFER
, sizeof(g_elementBuffer
),
507 g_elementBuffer
, GL_STATIC_DRAW
);
508 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, 0);
510 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
511 fprintf(stderr
, "Failed to create IBO.\n");
512 piglit_report_result(PIGLIT_FAIL
);
521 * Build a GLSL shader for the given packedInput, packedUniform, packedOutput
522 * descriptors. Each GLSL shader will have inputs, uniforms, and outputs. To
523 * ensure all bound resources are made resident, this shader must use all the
524 * inputs, uniforms, and outputs requested by the describing PackedDesc
525 * structures. If the number of outputs are smaller than the number of inputs,
526 * the inputs will map as follows:
528 * outputs[0] = uniforms[0] inputs[0] * ... * inputs[(i % numOutputs == 0)]
530 * where i >= numOutputs and represents a subsequent pass of inputs up
531 * until i == numInputs.
533 * If the number of outputs is larger than the number of inputs, the inputs
534 * and uniforms are referenced until exhausted. Once exhausted, an input
535 * or uniform will default to 1.0 to provide a multiplicative identity.
537 * \param packedInput A descriptor of the type and number of inputs to this
539 * \param packedUniform A descriptor of the type and number of uniforms bound
541 * \param packedOutput A descriptor of the type and number of outputs for this
543 * \param outputDefaultSystemValue A required output for the GLSL shader.
544 * i.e. gl_Position for a vertex shader.
545 * \param defaultSystemValueDecl Pre-defined output declaration.
546 * \param defaultSystemValue Pre-defined output value.
547 * \param pShaderText Output pointer for the allocated and generated shader
549 * \return true if the setup succeeded without error
554 build_reduce_glsl_shader(const PackedDesc
*packedInput
,
555 const PackedDesc
*packedUniform
,
556 const PackedDesc
*packedOutput
,
557 const char *outputDefaultSystemValue
,
558 const char *defaultSystemValueDecl
,
559 const char *defaultSystemValue
,
562 char *shaderTempText
[TEMP_TEXT_SIZE
];
563 char *shaderText
= NULL
;
564 unsigned shaderTextFree
= 0;
565 unsigned numScalarInputs
=
566 packedInput
->count
* packedInput
->typeDesc
->numComponents
;
567 unsigned numScalarUniforms
=
568 packedUniform
->count
* packedUniform
->typeDesc
->numComponents
;
569 unsigned numScalarOutputs
=
570 packedOutput
->count
* packedOutput
->typeDesc
->numComponents
;
572 /* Prepare for reduction of input contributions to the output slots */
573 unsigned di_do
= numScalarInputs
/ numScalarOutputs
;
574 unsigned r
= numScalarInputs
% numScalarOutputs
;
577 if (g_debugMask
& DEBUG_INPUT
) {
578 printf("di_do=%u r=%u\n", di_do
, r
);
581 for (i
= 0; i
< sizeof(shaderTempText
) / sizeof(char *); i
++) {
582 shaderTempText
[i
] = calloc(MAX_SHADER_LINE_CHARS
, sizeof(char));
584 if (NULL
== shaderTempText
[i
]) {
586 "Failed to allocate shader temporary text area\n");
587 piglit_report_result(PIGLIT_FAIL
);
592 shaderText
= calloc(MAX_SHADER_TEXT_CHARS
, sizeof(char));
593 if (NULL
== shaderText
) {
594 fprintf(stderr
, "Failed to allocate space for shader text\n");
595 piglit_report_result(PIGLIT_FAIL
);
599 shaderTextFree
= MAX_SHADER_TEXT_CHARS
- 1;
601 snprintf(shaderTempText
[0], MAX_SHADER_LINE_CHARS
,
602 "%s\n", GLSL_VERSION
);
603 strncat(shaderText
, shaderTempText
[0], shaderTextFree
);
604 shaderTextFree
-= strlen(shaderTempText
[0]);
607 * Declare the default system value input.
609 if (outputDefaultSystemValue
) {
610 snprintf(shaderTempText
[0], MAX_SHADER_LINE_CHARS
,
611 "%s\n", defaultSystemValueDecl
);
612 strncat(shaderText
, shaderTempText
[0], shaderTextFree
);
613 shaderTextFree
-= strlen(defaultSystemValueDecl
);
617 * Declare the input attributes.
619 get_packed_decl(packedInput
,
620 MAX_SHADER_LINE_CHARS
, shaderTempText
[0],
621 MAX_SHADER_TEXT_CHARS
, shaderText
);
624 * Declare the uniform samplers using the vertex texture functionality.
626 get_packed_decl(packedUniform
,
627 MAX_SHADER_LINE_CHARS
, shaderTempText
[0],
628 MAX_SHADER_TEXT_CHARS
, shaderText
);
631 * Declare the outputs.
633 if (packedOutput
->semanticName
) {
634 get_packed_decl(packedOutput
,
635 MAX_SHADER_LINE_CHARS
, shaderTempText
[0],
636 MAX_SHADER_TEXT_CHARS
, shaderText
);
639 shaderTextFree
= MAX_SHADER_TEXT_CHARS
- strlen(shaderText
);
642 * Begin main program block.
644 snprintf(shaderTempText
[0], MAX_SHADER_LINE_CHARS
,
646 strncat(shaderText
, shaderTempText
[0], shaderTextFree
);
647 shaderTextFree
-= strlen(shaderTempText
[0]);
649 snprintf(shaderTempText
[0], MAX_SHADER_LINE_CHARS
,
651 strncat(shaderText
, shaderTempText
[0], shaderTextFree
);
652 shaderTextFree
-= strlen(shaderTempText
[0]);
655 * Passthru the attributes to the outputs.
659 while (i
< numScalarOutputs
) {
660 char *resultStr
= " ", *srcStr
= " ";
662 if ((i
< packedUniform
->count
*packedUniform
->typeDesc
->numComponents
) &&
663 (j
% packedUniform
->typeDesc
->numComponents
) == 0) {
664 snprintf(shaderTempText
[0], MAX_SHADER_LINE_CHARS
,
665 " texel = texture2D(Texture[%u], vec2(0.0, 0.0));\n",
666 i
/ packedUniform
->typeDesc
->numComponents
);
667 strncat(shaderText
, shaderTempText
[0], shaderTextFree
);
668 shaderTextFree
-= strlen(shaderTempText
[0]);
672 * Iterate through the contents of the texel
674 resultStr
= get_packed_reference(packedOutput
,
675 (i
/ packedOutput
->typeDesc
->numComponents
),
676 (i
% packedOutput
->typeDesc
->numComponents
),
677 MAX_SHADER_LINE_CHARS
,
680 /* Reset the temp string to avoid cumulative contributions. */
681 memset(shaderTempText
[2], 0, MAX_SHADER_LINE_CHARS
);
683 if (k
< numScalarInputs
) {
684 /* Reduce the scalar multiple of the input contributions. */
685 for (l
= 0; l
< di_do
; l
++) {
686 srcStr
= get_packed_reference(packedInput
,
687 (i
+ (l
* numScalarOutputs
)) /
688 packedInput
->typeDesc
->numComponents
,
689 (i
+ (l
* numScalarOutputs
)) %
690 packedInput
->typeDesc
->numComponents
,
691 MAX_SHADER_LINE_CHARS
,
695 strncat(shaderTempText
[2], " * ",
696 MAX_SHADER_LINE_CHARS
- strlen(shaderTempText
[2]));
698 strncat(shaderTempText
[2], srcStr
,
699 MAX_SHADER_LINE_CHARS
- strlen(shaderTempText
[2]));
704 /* Reduce the remaining scalar contributions until exhausted */
706 srcStr
= get_packed_reference(packedInput
,
707 (i
+ (l
* numScalarOutputs
)) /
708 packedInput
->typeDesc
->numComponents
,
709 (i
+ (l
* numScalarOutputs
)) %
710 packedInput
->typeDesc
->numComponents
,
711 MAX_SHADER_LINE_CHARS
,
714 strncat(shaderTempText
[2], " * ",
715 MAX_SHADER_LINE_CHARS
- strlen(shaderTempText
[2]));
717 strncat(shaderTempText
[2], srcStr
,
718 MAX_SHADER_LINE_CHARS
- strlen(shaderTempText
[2]));
722 srcStr
= shaderTempText
[2];
724 snprintf(shaderTempText
[2], MAX_SHADER_LINE_CHARS
,
725 "%s", g_floatDesc
.defaultValue
);
726 srcStr
= shaderTempText
[2];
729 if (j
< numScalarUniforms
) {
730 if ((g_debugMask
& DEBUG_INPUT
) && outputDefaultSystemValue
) {
731 snprintf(shaderTempText
[0], MAX_SHADER_LINE_CHARS
,
732 " %s = texel%s;\n", resultStr
,
733 g_vectorComponents
[j
%
734 packedUniform
->typeDesc
->numComponents
]);
736 snprintf(shaderTempText
[0], MAX_SHADER_LINE_CHARS
,
737 " %s = texel%s * %s;\n", resultStr
,
738 g_vectorComponents
[j
%
739 packedUniform
->typeDesc
->numComponents
],
742 strncat(shaderText
, shaderTempText
[0], shaderTextFree
);
743 shaderTextFree
-= strlen(shaderTempText
[0]);
746 snprintf(shaderTempText
[0], MAX_SHADER_LINE_CHARS
,
747 " %s = %s%s * %s;\n", resultStr
,
748 packedUniform
->typeDesc
->defaultValue
,
749 g_vectorComponents
[0],
751 strncat(shaderText
, shaderTempText
[0], shaderTextFree
);
752 shaderTextFree
-= strlen(shaderTempText
[0]);
755 /* Increment to the next output. */
760 * End the main program block.
762 if (outputDefaultSystemValue
) {
763 snprintf(shaderTempText
[0], MAX_SHADER_LINE_CHARS
,
765 outputDefaultSystemValue
, defaultSystemValue
);
766 strncat(shaderText
, shaderTempText
[0], shaderTextFree
);
767 shaderTextFree
-= strlen(shaderTempText
[0]);
770 snprintf(shaderTempText
[0], MAX_SHADER_LINE_CHARS
, "}\n");
771 strncat(shaderText
, shaderTempText
[0], shaderTextFree
);
772 shaderTextFree
-= strlen(shaderTempText
[0]);
774 for (i
= 0; i
< sizeof(shaderTempText
) / sizeof(char *); i
++) {
775 if (shaderTempText
[i
]) {
776 free(shaderTempText
[i
]);
780 *pShaderText
= shaderText
;
786 * Core piglit_display callback. This function will bind the FBOs, Textures,
787 * VBOs, IBOs, and draw a primitive using the GLSL shader generated by
788 * build_reduce_glsl_shader.
790 * Once rendered, a pixel from each of the color attachments is read back and
791 * compared to the final expression value stored in g_expected given the
792 * associated color attachment index.
794 * \return PIGLIT_PASS if the setup succeeded without error
795 * PIGLIT_FAIL otherwise.
803 GLuint
*fboTextures
= NULL
;
804 GLenum
*colorBuffers
= NULL
;
810 * Reserve memory for the FBO texture objects.
812 fboTextures
= calloc(g_maxColorAttachments
, sizeof(GLuint
));
814 if (NULL
== fboTextures
) {
815 fprintf(stderr
, "Failed to create FBO texture object container.\n");
820 * Build the color attachments
822 colorBuffers
= calloc(g_maxColorAttachments
, sizeof(GLenum
));
824 if (NULL
== colorBuffers
) {
825 fprintf(stderr
, "Failed to create draw buffers descriptor.\n");
830 * Generate an FBO container to hold the color attachment hierarchy.
832 glGenFramebuffers(1, &fbo
);
833 glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
835 for (i
= 0; i
< g_maxColorAttachments
; i
++) {
836 setup_fbo_2d(i
, GL_RGBA32F
, GL_RGBA
, GL_FLOAT
,
837 BUFFER_WIDTH
, BUFFER_HEIGHT
,
838 fbo
, &fboTextures
[i
]);
839 colorBuffers
[i
] = GL_COLOR_ATTACHMENT0
+ i
;
843 * Build the textures sampled by the shaders
845 for (i
= 0; i
< g_maxCombinedTextureImageUnits
; i
++) {
850 glGenTextures(1, &tex
);
851 glActiveTexture(GL_TEXTURE0
+ i
);
852 glBindTexture(GL_TEXTURE_2D
, tex
);
853 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
854 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
856 if (((i
+1) * MAX_COMPONENTS
) > sizeof(g_primes
)) {
857 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA32F
, 1, 1, 0,
858 GL_RGBA
, GL_UNSIGNED_BYTE
, NULL
);
860 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA32F
, 1, 1, 0,
862 &g_primes
[i
* MAX_COMPONENTS
]);
865 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
866 fprintf(stderr
, "Failed to create texture %u.\n", i
);
870 snprintf(strTemp
, sizeof(strTemp
), "Texture[%u]", i
);
871 uniformLoc
= glGetUniformLocation(g_program
, strTemp
);
872 glUniform1i(uniformLoc
, i
);
874 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
875 fprintf(stderr
, "Unable to assign texture %u uniform.\n", i
);
881 * Setup the vertex and element buffers for drawing our points.
883 if (g_drawMode
!= DRAW_IMMEDIATE
) {
884 glGenVertexArrays(1, &vao
);
885 glBindVertexArray(vao
);
887 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
888 fprintf(stderr
, "Unable to create VAO.\n");
892 setup_vertex_element_buffers();
896 * Setup the raster state.
898 glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
899 glDrawBuffers(g_maxColorAttachments
, colorBuffers
);
901 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
902 fprintf(stderr
, "Unable to assign draw buffers.\n");
906 glClearColor(0.0, 1.0, 0.0, 0.0);
907 glClear(GL_COLOR_BUFFER_BIT
);
910 * Bind the vertex array and enable each attribute.
912 if (g_drawMode
!= DRAW_IMMEDIATE
) {
913 glBindVertexArray(vao
);
914 attribLoc
= glGetAttribLocation(g_program
, "InPosition");
915 glEnableVertexAttribArray(attribLoc
);
917 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
919 "Unable to enable vertex array attribute %u.\n",
925 * Enable the rest of the attributes.
927 for (i
= 0; i
< g_maxVertexAttribs
- 1; i
++) {
930 snprintf(strTemp
, sizeof(strTemp
), "InValue%u", i
);
931 attribLoc
= glGetAttribLocation(g_program
, strTemp
);
932 glEnableVertexAttribArray(attribLoc
);
934 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
936 "Unable to enable vertex array attribute %u.\n",
942 if (g_drawMode
== DRAW_ARRAYS_VBO
) {
943 if (g_debugMask
& DEBUG_DRAW
) {
944 fprintf(stderr
, "Draw mode DRAW_ARRAYS_VBO\n");
946 glDrawArrays(GL_TRIANGLES
, 0, NUM_VERTICES
);
949 if (g_drawMode
== DRAW_ELEMENTS_VBO
) {
950 if (g_debugMask
& DEBUG_DRAW
) {
952 "Draw mode DRAW_ELEMENTS_VBO\n");
954 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, g_elementVBO
);
955 glDrawElements(GL_TRIANGLES
, NUM_VERTICES
,
956 GL_UNSIGNED_SHORT
, 0);
957 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, 0);
961 * Blindly reset all the attributes.
963 for (i
= 0; i
< g_maxVertexAttribs
; i
++) {
964 glDisableVertexAttribArray(i
);
967 glBegin(GL_TRIANGLES
);
968 glVertex3f(-1.0, -1.0, 0.0);
969 glVertex3f(-1.0, 1.0, 0.0);
970 glVertex3f(1.0, 1.0, 0.0);
974 if (!piglit_check_gl_error(GL_NO_ERROR
))
978 * Read back the FBO contents.
982 * Disable color clamping so we don't encounter result
983 * collisions attempting to use a normalized color space.
985 * Requires OpenGL 3.0
987 glClampColor(GL_CLAMP_READ_COLOR
, GL_FALSE
);
989 for (i
= 0; i
< g_maxColorAttachments
; i
++) {
990 if (g_debugMask
& DEBUG_READBACK
) {
991 printf("GL_READ_FRAMEBUFFER <- fbo=%u\n", fbo
);
994 glBindFramebuffer(GL_READ_FRAMEBUFFER
, fbo
);
996 if (!piglit_check_gl_error(GL_NO_ERROR
))
999 glFramebufferTexture2D(GL_READ_FRAMEBUFFER
,
1000 GL_COLOR_ATTACHMENT0
,
1005 if (!piglit_check_gl_error(GL_NO_ERROR
))
1008 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
1009 glReadBuffer(GL_COLOR_ATTACHMENT0
);
1011 if (!piglit_check_gl_error(GL_NO_ERROR
))
1014 glReadPixels(0, BUFFER_HEIGHT
- 1,
1015 1, 1, GL_RGBA
, GL_FLOAT
, result
);
1017 if ((g_expected
[(i
* MAX_COMPONENTS
) + 0] != result
[0]) ||
1018 (g_expected
[(i
* MAX_COMPONENTS
) + 1] != result
[1]) ||
1019 (g_expected
[(i
* MAX_COMPONENTS
) + 2] != result
[2]) ||
1020 (g_expected
[(i
* MAX_COMPONENTS
) + 3] != result
[3])) {
1021 fprintf(stderr
, "GL_COLOR_ATTACHMENT%u: expected "
1022 "(%f, %f, %f, %f) != (%f, %f, %f, %f)\n",
1023 i
, g_expected
[(i
* MAX_COMPONENTS
) + 0],
1024 g_expected
[(i
* MAX_COMPONENTS
) + 1],
1025 g_expected
[(i
* MAX_COMPONENTS
) + 2],
1026 g_expected
[(i
* MAX_COMPONENTS
) + 3],
1027 result
[0], result
[1], result
[2], result
[3]);
1033 piglit_present_results();
1036 * Cleanup the allocations.
1041 piglit_report_result(PIGLIT_PASS
);
1053 piglit_report_result(PIGLIT_FAIL
);
1060 * Core piglit_init callback. This function will query the implementation for
1061 * the maximum number of supported resources. We attempt to create a GLSL
1062 * shader which references all supported resources bindable within the GL 3.0
1065 * Each resource will be populated with a unique prime value. This function is
1066 * also responsible for calculating the expected value and storing this in
1067 * the g_expected array.
1069 * Note: If the number of primes is insufficient to assign a unique prime to
1070 * each resource, we will exit with PIGLIT_SKIP.
1072 * Results: PIGLIT_PASS if the setup succeeded without error
1073 * PIGLIT_FAIL otherwise.
1077 piglit_init(int argc
, char **argv
)
1080 PackedDesc vsInput
= { "in", "InValue", false, 0, &g_vec4Desc
};
1081 PackedDesc vsUniform
= { "uniform", "Texture", true, 0, &g_sampler2DDesc
};
1082 PackedDesc vsOutput
= { "out", "Variable", true, 0, &g_floatDesc
};
1083 PackedDesc fsInput
= { "in", "Variable", true, 0, &g_floatDesc
};
1084 PackedDesc fsUniform
= { "uniform", "Texture", true, 0, &g_sampler2DDesc
};
1085 PackedDesc fsOutput
= { NULL
, g_fragData
, true, 0, &g_rgbaDesc
};
1086 char shaderTempText
[MAX_SHADER_LINE_CHARS
];
1087 char *vertexShaderText
= (char *)g_vertexShaderText
;
1088 char *fragmentShaderText
= (char *)g_fragmentShaderText
;
1091 piglit_require_gl_version(30);
1093 for (i
= 1; i
< argc
; i
++) {
1094 if (strcmp(argv
[i
], "-drawArraysVBO") == 0) {
1095 g_drawMode
= DRAW_ARRAYS_VBO
;
1097 if (strcmp(argv
[i
], "-drawElementsVBO") == 0) {
1098 g_drawMode
= DRAW_ELEMENTS_VBO
;
1100 if (strcmp(argv
[i
], "-drawImmediate") == 0) {
1101 g_drawMode
= DRAW_IMMEDIATE
;
1103 if (strcmp(argv
[i
], "-debugInput") == 0) {
1104 g_debugMask
|= DEBUG_INPUT
;
1106 if (strcmp(argv
[i
], "-debugReadback") == 0) {
1107 g_debugMask
|= DEBUG_READBACK
;
1109 if (strcmp(argv
[i
], "-debugShaders") == 0) {
1110 g_debugMask
|= DEBUG_SHADERS
;
1112 if (strcmp(argv
[i
], "-debugDraw") == 0) {
1113 g_debugMask
|= DEBUG_DRAW
;
1115 if (strcmp(argv
[i
], "-dontClampMaxVaryings") == 0) {
1116 g_debugMask
|= DEBUG_DONT_CLAMP_MAX_VARYINGS
;
1121 * Query the sampler capabilities.
1123 glGetIntegerv(GL_MAX_VARYING_FLOATS
, &g_maxVaryingFloats
);
1124 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS
, &g_maxVertexAttribs
);
1125 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
,
1126 &g_maxVertexTextureImageUnits
);
1127 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS
,
1128 &g_maxTextureImageUnits
);
1129 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
,
1130 &g_maxCombinedTextureImageUnits
);
1132 printf("GL_MAX_VARYING_FLOATS: %d\n", g_maxVaryingFloats
);
1133 printf("GL_MAX_VERTEX_ATTRIBS: %d\n", g_maxVertexAttribs
);
1134 printf("GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: %d\n",
1135 g_maxVertexTextureImageUnits
);
1136 printf("GL_MAX_TEXTURE_IMAGE_UNITS: %d\n",
1137 g_maxTextureImageUnits
);
1138 printf("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %d\n",
1139 g_maxCombinedTextureImageUnits
);
1142 * Query the render target capabilities.
1144 glGetIntegerv(GL_AUX_BUFFERS
, &g_maxAuxBuffers
);
1145 glGetIntegerv(GL_MAX_DRAW_BUFFERS
, &g_maxDrawBuffers
);
1146 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS
, &g_maxColorAttachments
);
1148 if (g_maxColorAttachments
== 1) {
1149 fsOutput
.variableName
= g_fragColor
;
1152 printf("GL_AUX_BUFFERS: %d\n", g_maxAuxBuffers
);
1153 printf("GL_MAX_DRAW_BUFFERS: %d\n", g_maxDrawBuffers
);
1154 printf("GL_MAX_COLOR_ATTACHMENTS: %d\n", g_maxColorAttachments
);
1156 if ((g_maxColorAttachments
* MAX_COMPONENTS
> NUM_PRIMES
) ||
1157 (g_maxVaryingFloats
> NUM_PRIMES
) ||
1158 (g_maxVertexAttribs
* MAX_COMPONENTS
> NUM_PRIMES
) ||
1159 (g_maxVertexTextureImageUnits
* MAX_COMPONENTS
> NUM_PRIMES
) ||
1160 (g_maxTextureImageUnits
* MAX_COMPONENTS
> NUM_PRIMES
)) {
1161 fprintf(stderr
, "Unable to uniquely represent a result path.\n");
1162 piglit_report_result(PIGLIT_SKIP
);
1166 * Clamp the max varyings by default to work around large array
1167 * issues with some GLSL implementations.
1169 if ((g_debugMask
& DEBUG_DONT_CLAMP_MAX_VARYINGS
) == 0) {
1170 g_maxVaryingFloats
= MIN2(g_maxVaryingFloats
, 32);
1171 fprintf(stderr
, "Clamped max varying floats to %u.\n",
1172 g_maxVaryingFloats
);
1175 if (g_drawMode
== DRAW_IMMEDIATE
) {
1176 g_maxVertexAttribs
= 1;
1178 "Immediate mode selected, using only one vertex attrib.\n");
1182 * Build the shaders based upon the queried limits.
1184 vsInput
.count
= g_maxVertexAttribs
- 1;
1185 vsUniform
.count
= g_maxVertexTextureImageUnits
;
1186 vsOutput
.count
= g_maxVaryingFloats
;
1187 if (!build_reduce_glsl_shader(&vsInput
,
1191 "in vec4 InPosition;",
1193 &vertexShaderText
)) {
1194 fprintf(stderr
, "Failed to build GLSL vertex shader\n");
1195 piglit_report_result(PIGLIT_SKIP
);
1198 if (g_debugMask
& DEBUG_SHADERS
) {
1199 printf("vertexShaderText:\n%s", vertexShaderText
);
1202 fsInput
.count
= g_maxVaryingFloats
;
1203 fsUniform
.count
= g_maxTextureImageUnits
;
1204 fsOutput
.count
= g_maxColorAttachments
;
1205 if (!build_reduce_glsl_shader(&fsInput
,
1211 &fragmentShaderText
)) {
1212 fprintf(stderr
, "Failed to build GLSL vertex shader\n");
1213 piglit_report_result(PIGLIT_SKIP
);
1216 if (g_debugMask
& DEBUG_SHADERS
) {
1217 printf("fragmentShaderText:\n%s", fragmentShaderText
);
1221 * Build the vertex and fragment shaders.
1223 g_program
= piglit_build_simple_program(vertexShaderText
,
1224 fragmentShaderText
);
1226 fprintf(stderr
, "Failed to compile/link program\n");
1227 piglit_report_result(PIGLIT_SKIP
);
1230 snprintf(shaderTempText
, sizeof(shaderTempText
), "InPosition");
1231 glBindAttribLocation(g_program
, 0, shaderTempText
);
1233 for (i
= 0; i
< g_maxVertexAttribs
- 1; i
++) {
1234 snprintf(shaderTempText
, sizeof(shaderTempText
), "InValue%u", i
);
1235 glBindAttribLocation(g_program
, i
+1, shaderTempText
);
1238 if (g_debugMask
& DEBUG_SHADERS
) {
1239 printf("Linking program...\n");
1242 glLinkProgram(g_program
);
1243 glUseProgram(g_program
);
1245 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
1246 fprintf(stderr
, "Failure to link shaders\n");
1247 fprintf(stderr
, "vertexShaderText:\n%s", vertexShaderText
);
1248 fprintf(stderr
, "fragmentShaderText:\n%s", fragmentShaderText
);
1249 free(vertexShaderText
);
1250 free(fragmentShaderText
);
1251 piglit_report_result(PIGLIT_FAIL
);
1254 if (g_debugMask
& DEBUG_SHADERS
) {
1255 printf("Using program %u...\n", g_program
);
1258 /* Delete the interim copies generated by build_reduce_glsl_shader */
1259 free(vertexShaderText
);
1260 free(fragmentShaderText
);
1263 * Calculate the expected results for the bound resource limits.
1265 var
= calloc(g_maxVaryingFloats
, sizeof(GLfloat
));
1269 "Failed to allocate temporary array for expected calculation.\n");
1270 piglit_report_result(PIGLIT_FAIL
);
1273 g_expected
= calloc(g_maxColorAttachments
, sizeof(GLfloat
)*MAX_COMPONENTS
);
1275 if (NULL
== g_expected
) {
1276 fprintf(stderr
, "Failed to allocate array for expected calculation.\n");
1277 piglit_report_result(PIGLIT_FAIL
);
1281 * Sampler coverage up to the total number of varying floats.
1283 for (i
= 0; i
< g_maxVaryingFloats
; i
++) {
1284 if ((i
< g_maxVertexTextureImageUnits
*MAX_COMPONENTS
) &&
1286 var
[i
] = g_primes
[i
];
1293 * Multiply in all vertex attributes.
1296 while (i
< (g_maxVertexAttribs
-1)*MAX_COMPONENTS
) {
1297 if (i
< NUM_PRIMES
) {
1298 var
[i
% g_maxVaryingFloats
] *= g_primes
[i
];
1300 var
[i
% g_maxVaryingFloats
] *= 1.0;
1306 * Calculate the expected values for the FS stage.
1308 * Sampler cover up to the total number of varying floats.
1310 for (i
= 0; i
< g_maxColorAttachments
*MAX_COMPONENTS
; i
++) {
1311 if ((i
< g_maxVertexTextureImageUnits
*MAX_COMPONENTS
) &&
1313 g_expected
[i
] = g_primes
[i
];
1315 g_expected
[i
] = 1.0;
1320 * Multiply in all the varying contributions generated by the VS.
1323 while (i
< g_maxVaryingFloats
) {
1324 g_expected
[i
% (g_maxColorAttachments
*MAX_COMPONENTS
)] *= var
[i
];
1328 for (i
= 0; i
< g_maxColorAttachments
; i
++) {
1329 printf("g_expected[%u]=(%f, %f, %f, %f)\n", i
,
1330 g_expected
[(i
* MAX_COMPONENTS
) + 0],
1331 g_expected
[(i
* MAX_COMPONENTS
) + 1],
1332 g_expected
[(i
* MAX_COMPONENTS
) + 2],
1333 g_expected
[(i
* MAX_COMPONENTS
) + 3]);