blob: 34d02ab17e905a4b78a02655049ae28db3310871 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
if (window.internals)
window.internals.settings.setWebGPUEnabled(true);
const renderPipelineSource = `
vertex float4 vertexShader(float4 position : attribute(0), float i : attribute(1)) : SV_Position {
return position;
}
fragment float4 fragmentShader(float4 position : SV_Position) : SV_Target 0 {
return position;
}
`;
let device = null;
let shaderModule = null;
async function createRenderPipeline() {
if (!device) {
let adapter = await navigator.gpu.requestAdapter();
device = await adapter.requestDevice();
}
if (!shaderModule)
shaderModule = device.createShaderModule({code: renderPipelineSource});
// Copied from webgpu/whlsl/whlsl.html.
const vertexStage = {module: shaderModule, entryPoint: "vertexShader"};
const fragmentStage = {module: shaderModule, entryPoint: "fragmentShader"};
const primitiveTopology = "triangle-strip";
const rasterizationState = {frontFace: "cw", cullMode: "none"};
const alphaBlend = {};
const colorBlend = {};
const colorStates = [{format: "rgba8unorm", alphaBlend, colorBlend, writeMask: 15}]; // GPUColorWrite.ALL
const depthStencilState = null;
const attribute0 = {shaderLocation: 0, format: "float4"};
const attribute1 = {shaderLocation: 1, format: "float"};
const input0 = {stride: 16, attributeSet: [attribute0]};
const input1 = {stride: 4, attributeSet: [attribute1]};
const inputs = [input0, input1];
const vertexInput = {vertexBuffers: inputs};
const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]};
const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
device.createRenderPipeline({vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout});
}
function test() {
let suite = InspectorTest.createAsyncSuite("Canvas.updateShader.WebGPU.SharedVertexFragment");
async function awaitProgramCreated() {
InspectorTest.log("Creating render pipeline...");
let evalutePromise = InspectorTest.evaluateInPage(`createRenderPipeline()`);
if (!WI.canvasManager.canvases.length)
await WI.canvasManager.awaitEvent(WI.CanvasManager.Event.CanvasAdded);
let canvas = WI.canvasManager.canvases[0];
InspectorTest.assert(canvas.contextType === WI.Canvas.ContextType.WebGPU, "Canvas should be WebGPU.");
let itemAddedEvent = await canvas.shaderProgramCollection.awaitEvent(WI.Collection.Event.ItemAdded);
let shaderProgram = itemAddedEvent.data.item;
InspectorTest.assert(shaderProgram.programType === WI.ShaderProgram.ProgramType.Render, "Shader program should be a render pipeline.");
InspectorTest.assert(shaderProgram.sharesVertexFragmentShader, "Shader program should have a shared vertex and fragment module.");
await evalutePromise;
return shaderProgram;
}
suite.addTestCase({
name: "Canvas.updateShader.WebGPU.SharedVertexFragment.SinglePipeline",
description: "Check that updating the vertex/fragment shader will also affect the fragment/vertex shader if they both use the same module.",
async test() {
let shaderProgram = await awaitProgramCreated();
let [originalVertexSource, originalFragmentSource] = await Promise.all([
CanvasAgent.requestShaderSource(shaderProgram.identifier, WI.ShaderProgram.ShaderType.Vertex),
CanvasAgent.requestShaderSource(shaderProgram.identifier, WI.ShaderProgram.ShaderType.Fragment),
]);
InspectorTest.expectShallowEqual(originalVertexSource, originalFragmentSource, "Vertex and Fragment shader sources should be the same.");
InspectorTest.log("Updating vertex shader source...");
await CanvasAgent.updateShader(shaderProgram.identifier, WI.ShaderProgram.ShaderType.Vertex, "// MODIFIED VERTEX\n\n" + originalVertexSource.source);
let [vertexSourceAfterUpdatingVertex, fragmentSourceAfterUpdatingVertex] = await Promise.all([
CanvasAgent.requestShaderSource(shaderProgram.identifier, WI.ShaderProgram.ShaderType.Vertex),
CanvasAgent.requestShaderSource(shaderProgram.identifier, WI.ShaderProgram.ShaderType.Fragment),
]);
InspectorTest.expectShallowEqual(vertexSourceAfterUpdatingVertex, fragmentSourceAfterUpdatingVertex, "Vertex and Fragment shader sources should be the same.");
InspectorTest.expectNotShallowEqual(vertexSourceAfterUpdatingVertex, originalVertexSource, "Vertex source should have changed.");
InspectorTest.log("Updating fragment shader source...");
await CanvasAgent.updateShader(shaderProgram.identifier, WI.ShaderProgram.ShaderType.Fragment, "// MODIFIED FRAGMENT\n\n" + originalFragmentSource.source);
let [vertexSourceAfterUpdatingFragment, fragmentSourceAfterUpdatingFragment] = await Promise.all([
CanvasAgent.requestShaderSource(shaderProgram.identifier, WI.ShaderProgram.ShaderType.Vertex),
CanvasAgent.requestShaderSource(shaderProgram.identifier, WI.ShaderProgram.ShaderType.Fragment),
]);
InspectorTest.expectShallowEqual(vertexSourceAfterUpdatingFragment, fragmentSourceAfterUpdatingFragment, "Vertex and Fragment shader sources should be the same.");
InspectorTest.expectNotShallowEqual(fragmentSourceAfterUpdatingFragment, originalFragmentSource, "Fragment source should have changed.");
}
});
suite.addTestCase({
name: "Canvas.updateShader.WebGPU.SharedVertexFragment.MultiplePipelines",
description: "Check that updating one pipeline won't affect any other pipelines if they share the same module.",
async test() {
let shaderProgram1 = await awaitProgramCreated();
let shaderProgram2 = await awaitProgramCreated();
let [originalVertexSource1, originalVertexSource2] = await Promise.all([
CanvasAgent.requestShaderSource(shaderProgram1.identifier, WI.ShaderProgram.ShaderType.Vertex),
CanvasAgent.requestShaderSource(shaderProgram2.identifier, WI.ShaderProgram.ShaderType.Vertex),
]);
InspectorTest.expectShallowEqual(originalVertexSource1, originalVertexSource2, "Both pipelines should have the same source.");
InspectorTest.log("Updating pipeline 1 vertex source...");
await CanvasAgent.updateShader(shaderProgram1.identifier, WI.ShaderProgram.ShaderType.Vertex, "// MODIFIED VERTEX\n\n" + originalVertexSource1.source);
let [newVertexSource1, newVertexSource2] = await Promise.all([
CanvasAgent.requestShaderSource(shaderProgram1.identifier, WI.ShaderProgram.ShaderType.Vertex),
CanvasAgent.requestShaderSource(shaderProgram2.identifier, WI.ShaderProgram.ShaderType.Vertex),
]);
InspectorTest.expectNotShallowEqual(originalVertexSource1, newVertexSource1, "Source of pipeline 1 should have changed.");
InspectorTest.expectNotShallowEqual(newVertexSource1, newVertexSource2, "Both pipelines should have different sources.");
}
});
suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>WebGPU tests for Canvas.updateShader command when the vertex and fragment shaders of a render pipeline share the same module.</p>
</body>
</html>