Skip to content

Commit 23f932e

Browse files
committed
Upload triangles tests for 3D suite in MotionMark
https://bugs.webkit.org/show_bug.cgi?id=201606 Reviewed by Simon Fraser. PerformanceTests: * MotionMark/resources/debug-runner/motionmark.css: * MotionMark/resources/debug-runner/tests.js: * MotionMark/tests/3d/resources/webgl.js: * MotionMark/tests/3d/resources/webgpu.js: Added. * MotionMark/tests/3d/triangles-webgl.html: Renamed from Websites/browserbench.org/MotionMark1.1/tests/3d/webgl.html. * MotionMark/tests/3d/triangles-webgpu.html: Copied from PerformanceTests/MotionMark/tests/3d/webgl.html. Websites/browserbench.org: * MotionMark1.1/resources/debug-runner/tests.js: * MotionMark1.1/tests/3d/resources/webgl.js: * MotionMark1.1/tests/3d/resources/webgpu.js: Added. * MotionMark1.1/tests/3d/triangles-webgl.html: Copied from PerformanceTests/MotionMark/tests/3d/webgl.html. * MotionMark1.1/tests/3d/triangles-webgpu.html: Renamed from PerformanceTests/MotionMark/tests/3d/webgl.html. Canonical link: https://commits.webkit.org/215249@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249657 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 1e19315 commit 23f932e

File tree

5 files changed

+392
-4
lines changed

5 files changed

+392
-4
lines changed

MotionMark1.1/resources/debug-runner/tests.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,12 @@ Suites.push(new Suite("Suits suite",
354354
Suites.push(new Suite("3D Graphics",
355355
[
356356
{
357-
url: "3d/webgl.html",
358-
name: "WebGL"
357+
url: "3d/triangles-webgl.html",
358+
name: "Triangles (WebGL)"
359+
},
360+
{
361+
url: "3d/triangles-webgpu.html",
362+
name: "Triangles (WebGPU)"
359363
},
360364
]
361365
));

MotionMark1.1/tests/3d/resources/webgl.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ WebGLStage = Utilities.createSubclass(Stage,
4141
this._gl = this.element.getContext("webgl");
4242
var gl = this._gl;
4343

44-
gl.clearColor(0.5, 0.5, 0.5, 1);
44+
gl.clearColor(0, 0, 0, 1);
4545

4646
// Create the vertex shader object.
4747
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
/*
2+
* Copyright (C) 2019 Apple Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15+
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
* THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
const whlslShaders = `
27+
struct VertexOutput {
28+
float4 position : SV_Position;
29+
float4 color : attribute(1);
30+
}
31+
32+
vertex VertexOutput vertexMain(float4 position : attribute(0),
33+
float4 color : attribute(1),
34+
constant float[] timeUniform : register(b0, space0),
35+
constant float[] uniforms : register(b0, space1)) {
36+
float scale = uniforms[0];
37+
float offsetX = uniforms[1];
38+
float offsetY = uniforms[2];
39+
float scalar = uniforms[3];
40+
float scalarOffset = uniforms[4];
41+
float time = timeUniform[0];
42+
43+
float fade = fmod(scalarOffset + time * scalar / 10.0, 1.0);
44+
if (fade < 0.5) {
45+
fade = fade * 2.0;
46+
} else {
47+
fade = (1.0 - fade) * 2.0;
48+
}
49+
float xpos = position.x * scale;
50+
float ypos = position.y * scale;
51+
float angle = 3.14159 * 2.0 * fade;
52+
float xrot = xpos * cos(angle) - ypos * sin(angle);
53+
float yrot = xpos * sin(angle) + ypos * cos(angle);
54+
xpos = xrot + offsetX;
55+
ypos = yrot + offsetY;
56+
57+
VertexOutput out;
58+
out.position = float4(xpos, ypos, 0.0, 1.0);
59+
out.color = float4(fade, 1.0 - fade, 0.0, 1.0) + color;
60+
return out;
61+
}
62+
63+
fragment float4 fragmentMain(float4 inColor : attribute(1)) : SV_Target 0 {
64+
return inColor;
65+
}
66+
`;
67+
68+
(function() {
69+
70+
WebGLStage = Utilities.createSubclass(Stage,
71+
function(element, options)
72+
{
73+
Stage.call(this);
74+
},
75+
{
76+
initialize: function(benchmark, options)
77+
{
78+
Stage.prototype.initialize.call(this, benchmark, options);
79+
80+
this._numTriangles = 0;
81+
82+
const gpuContext = this.element.getContext('gpu');
83+
84+
navigator.gpu.requestAdapter({ powerPreference: "low-power" }).then(adapter => {
85+
return adapter.requestDevice().then(device => {
86+
this._device = device;
87+
88+
const swapChainFormat = "bgra8unorm";
89+
this._swapChain = gpuContext.configureSwapChain({
90+
device: device,
91+
format: swapChainFormat,
92+
usage: GPUTextureUsage.OUTPUT_ATTACHMENT
93+
});
94+
95+
this._timeBindGroupLayout = device.createBindGroupLayout({
96+
bindings: [
97+
{ binding: 0, visibility: GPUShaderStageBit.VERTEX, type: "uniform-buffer" },
98+
],
99+
});
100+
101+
this._bindGroupLayout = device.createBindGroupLayout({
102+
bindings: [
103+
{ binding: 0, visibility: GPUShaderStageBit.VERTEX, type: "uniform-buffer" },
104+
],
105+
});
106+
107+
const vec4Size = 4 * Float32Array.BYTES_PER_ELEMENT;
108+
109+
const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [this._timeBindGroupLayout, this._bindGroupLayout] });
110+
const shaderModule = device.createShaderModule({ code: whlslShaders, isWHLSL: true });
111+
112+
const pipelineDesc = {
113+
layout: pipelineLayout,
114+
vertexStage: {
115+
module: shaderModule,
116+
entryPoint: "vertexMain",
117+
},
118+
fragmentStage: {
119+
module: shaderModule,
120+
entryPoint: "fragmentMain"
121+
},
122+
123+
primitiveTopology: "triangle-list",
124+
125+
vertexInput: {
126+
indexFormat: "uint32",
127+
vertexBuffers: [{
128+
// vertex buffer
129+
stride: 2 * vec4Size,
130+
stepMode: "vertex",
131+
attributeSet: [{
132+
// vertex positions
133+
shaderLocation: 0,
134+
offset: 0,
135+
format: "float4"
136+
}, {
137+
// vertex colors
138+
shaderLocation: 1,
139+
offset: vec4Size,
140+
format: "float4"
141+
}],
142+
}],
143+
},
144+
145+
rasterizationState: {
146+
frontFace: 'ccw',
147+
cullMode: 'none',
148+
},
149+
150+
colorStates: [{
151+
format: swapChainFormat,
152+
alphaBlend: {},
153+
colorBlend: {},
154+
}],
155+
};
156+
157+
this._pipeline = device.createRenderPipeline(pipelineDesc);
158+
159+
const [vertexBuffer, vertexArrayBuffer] = device.createBufferMapped({
160+
size: 2 * 3 * vec4Size,
161+
usage: GPUBufferUsage.VERTEX
162+
});
163+
const vertexWriteBuffer = new Float32Array(vertexArrayBuffer);
164+
vertexWriteBuffer.set([
165+
// position data /**/ color data
166+
0, 0.1, 0, 1, /**/ 1, 0, 0, 1,
167+
-0.1, -0.1, 0, 1, /**/ 0, 1, 0, 1,
168+
0.1, -0.1, 0, 1, /**/ 0, 0, 1, 1,
169+
]);
170+
vertexBuffer.unmap();
171+
172+
this._vertexBuffer = vertexBuffer;
173+
this._timeMappedBuffers = [];
174+
175+
this._resetIfNecessary();
176+
177+
benchmark._initPromise.resolve();
178+
});
179+
});
180+
},
181+
182+
_getFunctionSource: function(id)
183+
{
184+
return document.getElementById(id).text;
185+
},
186+
187+
_resetIfNecessary: function()
188+
{
189+
if (this._bindGroups != undefined && this._numTriangles <= this._bindGroups.length)
190+
return;
191+
192+
const numTriangles = this._numTriangles;
193+
194+
const device = this._device;
195+
196+
// Minimum buffer offset alignment is 256 bytes.
197+
const uniformBytes = 5 * Float32Array.BYTES_PER_ELEMENT;
198+
const alignedUniformBytes = Math.ceil(uniformBytes / 256) * 256;
199+
const alignedUniformFloats = alignedUniformBytes / Float32Array.BYTES_PER_ELEMENT;
200+
201+
const [uniformBuffer, uniformArrayBuffer] = device.createBufferMapped({
202+
size: numTriangles * alignedUniformBytes + Float32Array.BYTES_PER_ELEMENT,
203+
usage: GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.UNIFORM
204+
});
205+
const uniformWriteArray = new Float32Array(uniformArrayBuffer);
206+
207+
this._bindGroups = new Array(numTriangles);
208+
for (let i = 0; i < numTriangles; ++i) {
209+
uniformWriteArray[alignedUniformFloats * i + 0] = Stage.random(0.2, 0.4); // scale
210+
uniformWriteArray[alignedUniformFloats * i + 1] = Stage.random(-0.9, 0.9); // offsetX
211+
uniformWriteArray[alignedUniformFloats * i + 2] = Stage.random(-0.9, 0.9); // offsetY
212+
uniformWriteArray[alignedUniformFloats * i + 3] = Stage.random(0.5, 2); // scalar
213+
uniformWriteArray[alignedUniformFloats * i + 4] = Stage.random(0, 10); // scalarOffset
214+
215+
this._bindGroups[i] = device.createBindGroup({
216+
layout: this._bindGroupLayout,
217+
bindings: [{
218+
binding: 0,
219+
resource: {
220+
buffer: uniformBuffer,
221+
offset: i * alignedUniformBytes,
222+
size: 6 * Float32Array.BYTES_PER_ELEMENT,
223+
}
224+
}]
225+
});
226+
}
227+
228+
uniformBuffer.unmap();
229+
230+
this._timeOffset = numTriangles * alignedUniformBytes;
231+
this._timeBindGroup = device.createBindGroup({
232+
layout: this._timeBindGroupLayout,
233+
bindings: [{
234+
binding: 0,
235+
resource: {
236+
buffer: uniformBuffer,
237+
offset: this._timeOffset,
238+
size: Float32Array.BYTES_PER_ELEMENT,
239+
}
240+
}]
241+
});
242+
243+
this._uniformBuffer = uniformBuffer;
244+
},
245+
246+
tune: function(count)
247+
{
248+
if (!count)
249+
return;
250+
251+
this._numTriangles += count;
252+
this._numTriangles = Math.max(this._numTriangles, 0);
253+
254+
this._resetIfNecessary();
255+
},
256+
257+
animate: function(timeDelta)
258+
{
259+
const device = this._device;
260+
261+
if (!this._startTime)
262+
this._startTime = Stage.dateCounterValue(1000);
263+
264+
const elapsedTimeData = new Float32Array([Stage.dateCounterValue(1000) - this._startTime]);
265+
266+
// Update time uniform
267+
let mappedBuffer;
268+
269+
if (this._timeMappedBuffers.length === 0) {
270+
mappedBuffer = device.createBufferMapped({
271+
size: Float32Array.BYTES_PER_ELEMENT,
272+
usage: GPUBufferUsage.TRANSFER_SRC | GPUBufferUsage.MAP_WRITE
273+
});
274+
} else
275+
mappedBuffer = this._timeMappedBuffers.shift();
276+
277+
const [timeStagingBuffer, timeStagingArrayBuffer] = mappedBuffer;
278+
279+
const writeArray = new Float32Array(timeStagingArrayBuffer);
280+
writeArray.set(elapsedTimeData);
281+
timeStagingBuffer.unmap();
282+
283+
const commandEncoder = device.createCommandEncoder({});
284+
commandEncoder.copyBufferToBuffer(timeStagingBuffer, 0, this._uniformBuffer, this._timeOffset, elapsedTimeData.byteLength);
285+
286+
const renderPassDescriptor = {
287+
colorAttachments: [{
288+
loadOp: "clear",
289+
storeOp: "store",
290+
clearColor: { r: 1, g: 1, b: 1, a: 1.0 },
291+
attachment: this._swapChain.getCurrentTexture().createDefaultView(),
292+
}],
293+
};
294+
295+
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
296+
passEncoder.setPipeline(this._pipeline);
297+
passEncoder.setVertexBuffers(0, [this._vertexBuffer], [0]);
298+
passEncoder.setBindGroup(0, this._timeBindGroup);
299+
for (let i = 0; i < this._numTriangles; ++i) {
300+
passEncoder.setBindGroup(1, this._bindGroups[i]);
301+
passEncoder.draw(3, 1, 0, 0);
302+
}
303+
passEncoder.endPass();
304+
305+
device.getQueue().submit([commandEncoder.finish()]);
306+
307+
timeStagingBuffer.mapWriteAsync().then(arrayBuffer => {
308+
mappedBuffer[1] = arrayBuffer;
309+
this._timeMappedBuffers.push(mappedBuffer);
310+
});
311+
},
312+
313+
complexity: function()
314+
{
315+
return this._numTriangles;
316+
}
317+
}
318+
);
319+
320+
WebGLBenchmark = Utilities.createSubclass(Benchmark,
321+
function(options)
322+
{
323+
Benchmark.call(this, new WebGLStage(), options);
324+
}, {
325+
326+
waitUntilReady: function() {
327+
this._initPromise = new SimplePromise;
328+
return this._initPromise;
329+
},
330+
});
331+
332+
window.benchmarkClass = WebGLBenchmark;
333+
334+
})();

MotionMark1.1/tests/3d/webgl.html renamed to MotionMark1.1/tests/3d/triangles-webgl.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
Copyright (C) 2015-2017 Apple Inc. All rights reserved.
2+
Copyright (C) 2015-2019 Apple Inc. All rights reserved.
33
44
Redistribution and use in source and binary forms, with or without
55
modification, are permitted provided that the following conditions
@@ -27,6 +27,11 @@
2727
<head>
2828
<meta charset="utf-8">
2929
<link rel="stylesheet" type="text/css" href="../resources/stage.css">
30+
<style>
31+
#stage {
32+
background-color: #000;
33+
}
34+
</style>
3035
</head>
3136
<body>
3237
<canvas id="stage"></canvas>

0 commit comments

Comments
 (0)