← 输入框|github.com|刷新
Skip to content

Add reference Web GPU Spinning Cube Demo and glMatrix - #209

Merged
JusSn merged 10 commits into
gpuweb:masterfrom
JusSn:CubeDemoRef
Jul 1, 2019
Merged

JusSn merged 10 commits into
gpuweb:masterfrom
JusSn:CubeDemoRef

Conversation

@JusSn

@JusSn JusSn commented Feb 11, 2019

Copy link
Copy Markdown
Contributor

This demo serves as a reference for a Web GPU implementation. It reflects the current API as well as approved pull requests.

Also included is the glMatrix matrix math library by Brandon Jones.

Comment thread samples/hello-cube.html Resolved
Comment thread samples/hello-cube.html Outdated

const verticesBufferDescriptor = {
size: vertexArray.byteLength,
usage: GPUBufferUsage.VERTEX | GPUBufferUsage.TRANSFER_DST

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's kind of unfortunate that setSubData requires TRANSFER_DST and nothing else. On UMA, setSubData might be able to write directly into the buffer (if the stars align correctly).

Comment thread samples/hello-cube.html Resolved
Comment thread samples/hello-cube.html Outdated
depthCompare: "less"
};

/* Render Pipeline */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd move this comment to above line 150.

Comment thread samples/hello-cube.html
clearColor: { r: 0.5, g: 1.0, b: 1.0, a: 1.0 }
};

// GPUExtent3D

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish we could do something more type-safe here. It seems silly to attach a 3D size to a 2D texture.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, maybe we need GPUSize2D and GPUSize3D (I prefer both of them over "Extent")

Comment thread samples/hello-cube.html Outdated
mipLevelCount: 1,
sampleCount: 1,
dimension: "2d",
format: "d32-float-s8-uint",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At a glance, this looks like a UUID. 🤮

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should at least make them consistent with the other texture formats.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I missed this one when updating the names.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you forgot to include depth and stencil formats when you updated the list of texture formats in the IDL. I'll make a PR in a bit to add them.

Comment thread samples/hello-cube.html Outdated
clearDepth: 1.0
};

renderPassDescriptor = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of writing into globals, it's probably better style to return a collection of all the variables.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds very functional indeed.

Comment thread samples/hello-cube.html Outdated
};
}

class MappedBufferBindGroup {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we're going to add classes as helpers, we could do the same for the transform array matrix. e.g. a class that holds the mappedGroup and exposes the arrayBuffer.

Comment thread samples/hello-cube.html
queue.submit([commandEncoder.finish()]);

// Ready the current buffer for update after GPU is done with it.
mappedGroup.buffer.mapWriteAsync().then((arrayBuffer) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The right thing will happen here, but we might not wants apps to rely on the specific timeline that the mapWriteAsync promise resolves. It may be better to explicitly handle the dependency of "the mapping should happen after the command buffer finishes" by using fences. I'm not sure which behavior we want to promote.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this does the right thing, it's probably more readable than barriers.

The thing that I think is a bit weird is that mappedGroups could grow infinitely (if some other part of the code appends to it outside this loop). It's a shame we can't attach the group to the queue or something.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have this example working with my mapWriteAsync() prototype. I could use a class to control access to the mappedGroups queue, if that's what you mean?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I understand what you're saying now. Shouldn't mapWriteAsync only resolve after the GPU is done with the buffer?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but it means that we don't have any pipelining here based on how I understand it. We cannot upload the data for the second frame until the GPU is done with the data for the first. Our example should support double-buffering.

Comment thread samples/hello-cube.html Outdated
mappedGroup.buffer.unmap();

const commandEncoder = device.createCommandEncoder();
renderPassDescriptor.colorAttachments[0].attachment = swapChain.getTexture().createDefaultTextureView();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've got a single render pass descriptor that every render pass uses. This implicitly requires that beginRenderPass copy the contents of the descriptor so that the next frame doesn't clobber the current frame's execution. This might be okay, but it might not be. If it isn't okay, the group should decide on a mechanism to make it obvious to authors what is going wrong when they write the same code you have here.

Comment thread samples/hello-cube.html Outdated

const vertexSize = 4 * 8;
const colorOffset = 4 * 4;
const vertexArray = new Float32Array([

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea whether this giant array is correct. Can't you compute it at runtime?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fairly standard in all spinning cube demos. I don't think it is a big deal. Computing it at runtime would probably be an equally confusing set of for loops.

Maybe the best thing to do would be to name the variables cubeVertices, and provide comments for the 4 * 8 and 4 * 4 values.

Comment thread samples/hello-cube.html
<script src="gl-matrix-min.js"></script>
</head>
<body>
<canvas height=1000 width=1000></canvas>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You set a 600px viewport above, so 1000x1000 would be mostly offscreen.

Comment thread samples/hello-cube.html Outdated

vertex FragmentData vertex_main(float4 position : attribute(0),
float4 color : attribute(1),
constant float4x4* modelViewProjectionMatrix : register(b0)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the input a pointer to a float4x4?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean as opposed to a reference or copy?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As opposed to the more normal HLSL mechanism of defining a cbuffer/ConstantBuffer with your input variables.

Comment thread samples/hello-cube.html

const depthTexture = device.createTexture(depthTextureDescriptor);

// GPURenderPassDepthStencilAttachmentDescriptor

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this comment.

Comment thread samples/hello-cube.html Outdated
this.bindGroup = bindGroup;
}
}
const mappedGroups = [];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably go at the top.

Comment thread samples/hello-cube.html Outdated
const { buffer, arrayBuffer } = device.createMappedBuffer(transformBufferDescriptor);
const bindGroup = device.createBindGroup(createTransformBindGroupDescriptor(buffer));

mappedGroup = new MappedBufferBindGroup(buffer, arrayBuffer, bindGroup);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since a MappedBufferBindGroup doesn't have anything other than a constructor, it's basically equivalent to an anonymous object. i.e. you could omit the class and just say:

mappedGroup = { buffer, arrayBuffer, bindGroup };

Comment thread samples/hello-cube.html Resolved
Comment thread samples/hello-cube.html Outdated
init();
</script>
</body>
</html> No newline at end of file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a newline.

Comment thread samples/hello-cube.html Outdated
} else
mappedGroup = mappedGroups.shift();

updateTransformArray(mappedGroup.arrayBuffer);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving myself a note here to fix: updateTransformArray takes a Float32Array, not an ArrayBuffer.

@kdashg kdashg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we link to an external source for the library?
https://cdnjs.com/libraries/gl-matrix

@JusSn

JusSn commented Jul 1, 2019 •

Copy link
Copy Markdown
Contributor Author

I've updated the file to match our API changes and removed the library file in favor of an external source. It does not work in current Safari since WHLSL is not the default ingestion format yet.

Feel free to make a PR after merging to feature-detect and use SPIR-V shaders, or other API updates I may have missed @kainino0x @austinEng

@JusSn
JusSn merged commit 627d096 into gpuweb:master Jul 1, 2019
Kangz pushed a commit to Kangz/gpuweb that referenced this pull request Jul 9, 2019
* Add reference demo files

* Add shading language notice

* Addressed basic review issues

* Small fixes

* Add some clarifying comments

* Update to IDL commit e137ea9

* Attempt to get WHLSL shaders working

* whoops

* Update reference for submission

* Delete gl-matrix-min.js
ben-clayton pushed a commit to ben-clayton/gpuweb that referenced this pull request Sep 6, 2022
Using npm slightly reduces unnecessary dependencies of the project.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants