Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: conformance/resources/glsl-generator.js

Issue 8342021: Add webgl conformance tests r15841. (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/webgl/sdk/tests/
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « conformance/resources/glsl-feature-tests.css ('k') | conformance/resources/gray-ramp.png » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:executable
+ *
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 GLSLGenerator = (function() {
2
3 var vertexShaderTemplate = [
4 "attribute vec4 aPosition;",
5 "",
6 "varying vec4 vColor;",
7 "",
8 "$(extra)",
9 "$(emu)",
10 "",
11 "void main()",
12 "{",
13 " gl_Position = aPosition;",
14 " vec2 texcoord = vec2(aPosition.xy * 0.5 + vec2(0.5, 0.5));",
15 " vec4 color = vec4(",
16 " texcoord,",
17 " texcoord.x * texcoord.y,",
18 " (1.0 - texcoord.x) * texcoord.y * 0.5 + 0.5);",
19 " $(test)",
20 "}"
21 ].join("\n");
22
23 var fragmentShaderTemplate = [
24 "#if defined(GL_ES)",
25 "precision mediump float;",
26 "#endif",
27 "",
28 "varying vec4 vColor;",
29 "",
30 "$(extra)",
31 "$(emu)",
32 "",
33 "void main()",
34 "{",
35 " $(test)",
36 "}"
37 ].join("\n");
38
39 var baseVertexShader = [
40 "attribute vec4 aPosition;",
41 "",
42 "varying vec4 vColor;",
43 "",
44 "void main()",
45 "{",
46 " gl_Position = aPosition;",
47 " vec2 texcoord = vec2(aPosition.xy * 0.5 + vec2(0.5, 0.5));",
48 " vColor = vec4(",
49 " texcoord,",
50 " texcoord.x * texcoord.y,",
51 " (1.0 - texcoord.x) * texcoord.y * 0.5 + 0.5);",
52 "}"
53 ].join("\n");
54
55 var baseFragmentShader = [
56 "#if defined(GL_ES)",
57 "precision mediump float;",
58 "#endif",
59 "varying vec4 vColor;",
60 "",
61 "void main()",
62 "{",
63 " gl_FragColor = vColor;",
64 "}"
65 ].join("\n");
66
67 var types = [
68 { type: "float",
69 code: [
70 "float $(func)_emu($(args)) {",
71 " return $(func)_base($(baseArgs));",
72 "}"].join("\n")
73 },
74 { type: "vec2",
75 code: [
76 "vec2 $(func)_emu($(args)) {",
77 " return vec2(",
78 " $(func)_base($(baseArgsX)),",
79 " $(func)_base($(baseArgsY)));",
80 "}"].join("\n")
81 },
82 { type: "vec3",
83 code: [
84 "vec3 $(func)_emu($(args)) {",
85 " return vec3(",
86 " $(func)_base($(baseArgsX)),",
87 " $(func)_base($(baseArgsY)),",
88 " $(func)_base($(baseArgsZ)));",
89 "}"].join("\n")
90 },
91 { type: "vec4",
92 code: [
93 "vec4 $(func)_emu($(args)) {",
94 " return vec4(",
95 " $(func)_base($(baseArgsX)),",
96 " $(func)_base($(baseArgsY)),",
97 " $(func)_base($(baseArgsZ)),",
98 " $(func)_base($(baseArgsW)));",
99 "}"].join("\n")
100 }
101 ];
102
103 var bvecTypes = [
104 { type: "bvec2",
105 code: [
106 "bvec2 $(func)_emu($(args)) {",
107 " return bvec2(",
108 " $(func)_base($(baseArgsX)),",
109 " $(func)_base($(baseArgsY)));",
110 "}"].join("\n")
111 },
112 { type: "bvec3",
113 code: [
114 "bvec3 $(func)_emu($(args)) {",
115 " return bvec3(",
116 " $(func)_base($(baseArgsX)),",
117 " $(func)_base($(baseArgsY)),",
118 " $(func)_base($(baseArgsZ)));",
119 "}"].join("\n")
120 },
121 { type: "bvec4",
122 code: [
123 "vec4 $(func)_emu($(args)) {",
124 " return bvec4(",
125 " $(func)_base($(baseArgsX)),",
126 " $(func)_base($(baseArgsY)),",
127 " $(func)_base($(baseArgsZ)),",
128 " $(func)_base($(baseArgsW)));",
129 "}"].join("\n")
130 }
131 ];
132
133 var replaceRE = /\$\((\w+)\)/g;
134
135 var replaceParams = function(str, params) {
136 return str.replace(replaceRE, function(str, p1, offset, s) {
137 if (params[p1] === undefined) {
138 throw "unknown string param '" + p1 + "'";
139 }
140 return params[p1];
141 });
142 };
143
144 var generateReferenceShader = function(
145 shaderInfo, template, params, typeInfo, test) {
146 var input = shaderInfo.input;
147 var output = shaderInfo.output;
148 var feature = params.feature;
149 var testFunc = params.testFunc;
150 var emuFunc = params.emuFunc || "";
151 var extra = params.extra || '';
152 var args = params.args || "$(type) value";
153 var type = typeInfo.type;
154 var typeCode = typeInfo.code;
155
156 var baseArgs = params.baseArgs || "value$(field)";
157 var baseArgsX = replaceParams(baseArgs, {field: ".x"});
158 var baseArgsY = replaceParams(baseArgs, {field: ".y"});
159 var baseArgsZ = replaceParams(baseArgs, {field: ".z"});
160 var baseArgsW = replaceParams(baseArgs, {field: ".w"});
161 var baseArgs = replaceParams(baseArgs, {field: ""});
162
163 test = replaceParams(test, {
164 input: input,
165 output: output,
166 func: feature + "_emu"
167 });
168 emuFunc = replaceParams(emuFunc, {
169 func: feature
170 });
171 args = replaceParams(args, {
172 type: type
173 });
174 typeCode = replaceParams(typeCode, {
175 func: feature,
176 type: type,
177 args: args,
178 baseArgs: baseArgs,
179 baseArgsX: baseArgsX,
180 baseArgsY: baseArgsY,
181 baseArgsZ: baseArgsZ,
182 baseArgsW: baseArgsW
183 });
184 var shader = replaceParams(template, {
185 extra: extra,
186 emu: emuFunc + "\n\n" + typeCode,
187 test: test
188 });
189 return shader;
190 };
191
192 var generateTestShader = function(
193 shaderInfo, template, params, test) {
194 var input = shaderInfo.input;
195 var output = shaderInfo.output;
196 var feature = params.feature;
197 var testFunc = params.testFunc;
198 var extra = params.extra || '';
199
200 test = replaceParams(test, {
201 input: input,
202 output: output,
203 func: feature
204 });
205 var shader = replaceParams(template, {
206 extra: extra,
207 emu: '',
208 test: test
209 });
210 return shader;
211 };
212
213 var makeImage = function(canvas) {
214 var img = document.createElement('img');
215 img.src = canvas.toDataURL();
216 return img;
217 };
218
219 var runFeatureTest = function(params) {
220 if (window.initNonKhronosFramework) {
221 window.initNonKhronosFramework(false);
222 }
223
224 var wtu = WebGLTestUtils;
225 var gridRes = params.gridRes;
226 var tolerance = params.tolerance || 0;
227
228 description("Testing GLSL feature: " + params.feature);
229
230 var width = 32;
231 var height = 32;
232
233 var console = document.getElementById("console");
234 var canvas = document.createElement('canvas');
235 canvas.width = width;
236 canvas.height = height;
237 var gl = wtu.create3DContext(canvas);
238 if (!gl) {
239 testFailed("context does not exist");
240 finishTest();
241 return;
242 }
243
244 var canvas2d = document.createElement('canvas');
245 canvas2d.width = width;
246 canvas2d.height = height;
247 var ctx = canvas2d.getContext("2d");
248 var imgData = ctx.getImageData(0, 0, width, height);
249
250 var shaderInfos = [
251 { type: "vertex",
252 input: "color",
253 output: "vColor",
254 vertexShaderTemplate: vertexShaderTemplate,
255 fragmentShaderTemplate: baseFragmentShader
256 },
257 { type: "fragment",
258 input: "vColor",
259 output: "gl_FragColor",
260 vertexShaderTemplate: baseVertexShader,
261 fragmentShaderTemplate: fragmentShaderTemplate
262 }
263 ];
264 for (var ss = 0; ss < shaderInfos.length; ++ss) {
265 var shaderInfo = shaderInfos[ss];
266 var tests = params.tests;
267 var testTypes = params.emuFuncs || (params.bvecTest ? bvecTypes : types);
268 // Test vertex shaders
269 for (var ii = 0; ii < tests.length; ++ii) {
270 var type = testTypes[ii];
271 if (params.simpleEmu) {
272 type = {
273 type: type.type,
274 code: params.simpleEmu
275 };
276 }
277 debug("");
278 var str = replaceParams(params.testFunc, {
279 func: params.feature,
280 type: type.type,
281 arg0: type.type
282 });
283 debug("Testing: " + str + " in " + shaderInfo.type + " shader");
284
285 var referenceVertexShaderSource = generateReferenceShader(
286 shaderInfo,
287 shaderInfo.vertexShaderTemplate,
288 params,
289 type,
290 tests[ii]);
291 var referenceFragmentShaderSource = generateReferenceShader(
292 shaderInfo,
293 shaderInfo.fragmentShaderTemplate,
294 params,
295 type,
296 tests[ii]);
297 var testVertexShaderSource = generateTestShader(
298 shaderInfo,
299 shaderInfo.vertexShaderTemplate,
300 params,
301 tests[ii]);
302 var testFragmentShaderSource = generateTestShader(
303 shaderInfo,
304 shaderInfo.fragmentShaderTemplate,
305 params,
306 tests[ii]);
307
308 debug("");
309 addShaderSource(
310 "reference vertex shader", referenceVertexShaderSource);
311 addShaderSource(
312 "reference fragment shader", referenceFragmentShaderSource);
313 addShaderSource(
314 "test vertex shader", testVertexShaderSource);
315 addShaderSource(
316 "test fragment shader", testFragmentShaderSource);
317 debug("");
318
319 var refData = draw(
320 canvas, referenceVertexShaderSource, referenceFragmentShaderSource);
321 var refImg = makeImage(canvas);
322 if (ss == 0) {
323 var testData = draw(
324 canvas, testVertexShaderSource, referenceFragmentShaderSource);
325 } else {
326 var testData = draw(
327 canvas, referenceVertexShaderSource, testFragmentShaderSource);
328 }
329 var testImg = makeImage(canvas);
330
331 reportResults(refData, refImg, testData, testImg);
332 }
333 }
334
335 finishTest();
336
337 function addShaderSource(label, source) {
338 var div = document.createElement("div");
339 var s = document.createElement("pre");
340 s.className = "shader-source";
341 s.style.display = "none";
342 var ol = document.createElement("ol");
343 //s.appendChild(document.createTextNode(source));
344 var lines = source.split("\n");
345 for (var ii = 0; ii < lines.length; ++ii) {
346 var line = lines[ii];
347 var li = document.createElement("li");
348 li.appendChild(document.createTextNode(line));
349 ol.appendChild(li);
350 }
351 s.appendChild(ol);
352 var l = document.createElement("a");
353 l.href = "show-shader-source";
354 l.appendChild(document.createTextNode(label));
355 l.addEventListener('click', function(event) {
356 if (event.preventDefault) {
357 event.preventDefault();
358 }
359 s.style.display = (s.style.display == 'none') ? 'block' : 'none';
360 return false;
361 }, false);
362 div.appendChild(l);
363 div.appendChild(s);
364 console.appendChild(div);
365 }
366
367 function reportResults(refData, refImage, testData, testImage) {
368 var same = true;
369 for (var yy = 0; yy < height; ++yy) {
370 for (var xx = 0; xx < width; ++xx) {
371 var offset = (yy * width + xx) * 4;
372 var imgOffset = ((height - yy - 1) * width + xx) * 4;
373 imgData.data[imgOffset + 0] = 0;
374 imgData.data[imgOffset + 1] = 0;
375 imgData.data[imgOffset + 2] = 0;
376 imgData.data[imgOffset + 3] = 255;
377 if (Math.abs(refData[offset + 0] - testData[offset + 0]) > tolerance ||
378 Math.abs(refData[offset + 1] - testData[offset + 1]) > tolerance ||
379 Math.abs(refData[offset + 2] - testData[offset + 2]) > tolerance ||
380 Math.abs(refData[offset + 3] - testData[offset + 3]) > tolerance) {
381 imgData.data[imgOffset] = 255;
382 same = false;
383 }
384 }
385 }
386
387 var diffImg = null;
388 if (!same) {
389 ctx.putImageData(imgData, 0, 0);
390 diffImg = makeImage(canvas2d);
391 }
392
393 var div = document.createElement("div");
394 div.className = "testimages";
395 insertImg(div, "ref", refImg);
396 insertImg(div, "test", testImg);
397 if (diffImg) {
398 insertImg(div, "diff", diffImg);
399 }
400 div.appendChild(document.createElement('br'));
401
402 function insertImg(element, caption, img) {
403 var div = document.createElement("div");
404 div.appendChild(img);
405 var label = document.createElement("div");
406 label.appendChild(document.createTextNode(caption));
407 div.appendChild(label);
408 element.appendChild(div);
409 }
410
411 console.appendChild(div);
412
413 if (!same) {
414 testFailed("images are different");
415 } else {
416 testPassed("images are the same");
417 }
418
419 console.appendChild(document.createElement('hr'));
420 }
421
422 function draw(canvas, vsSource, fsSource) {
423 var program = wtu.loadProgram(gl, vsSource, fsSource, testFailed);
424
425 var posLoc = gl.getAttribLocation(program, "aPosition");
426 WebGLTestUtils.setupQuad(gl, gridRes, posLoc);
427
428 gl.useProgram(program);
429 gl.clearColor(0, 0, 1, 1);
430 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
431 gl.drawElements(gl.TRIANGLES, gridRes * gridRes * 6, gl.UNSIGNED_SHORT, 0);
432 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors from draw");
433
434 var img = new Uint8Array(width * height * 4);
435 gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, img);
436 return img;
437 }
438
439 };
440
441 return {
442 /**
443 * runs a bunch of GLSL tests using the passed in parameters
444 * The parameters are:
445 *
446 * feature:
447 * the name of the function being tested (eg, sin, dot,
448 * normalize)
449 *
450 * testFunc:
451 * The prototype of function to be tested not including the
452 * return type.
453 *
454 * emuFunc:
455 * A base function that can be used to generate emulation
456 * functions. Example for 'ceil'
457 *
458 * float $(func)_base(float value) {
459 * float m = mod(value, 1.0);
460 * return m != 0.0 ? (value + 1.0 - m) : value;
461 * }
462 *
463 * args:
464 * The arguments to the function
465 *
466 * baseArgs: (optional)
467 * The arguments when a base function is used to create an
468 * emulation function. For example 'float sign_base(float v)'
469 * is used to implemenent vec2 sign_emu(vec2 v).
470 *
471 * simpleEmu:
472 * if supplied, the code that can be used to generate all
473 * functions for all types.
474 *
475 * Example for 'normalize':
476 *
477 * $(type) $(func)_emu($(args)) {
478 * return value / length(value);
479 * }
480 *
481 * gridRes: (optional)
482 * The resolution of the mesh to generate. The default is a
483 * 1x1 grid but many vertex shaders need a higher resolution
484 * otherwise the only values passed in are the 4 corners
485 * which often have the same value.
486 *
487 * tests:
488 * The code for each test. It is assumed the tests are for
489 * float, vec2, vec3, vec4 in that order.
490 */
491 runFeatureTest: runFeatureTest,
492
493 none: false
494 };
495
496 }());
497
OLDNEW
« no previous file with comments | « conformance/resources/glsl-feature-tests.css ('k') | conformance/resources/gray-ramp.png » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698