Thimbleberry's WebGPU demo doesn't work yet
Categories
(Core :: Graphics: WebGPU, defect, P3)
Tracking
()
People
(Reporter: bugz, Unassigned)
References
(Blocks 1 open bug, )
Details
Attachments
(1 file)
392.32 KB,
application/zip
|
Details |
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0
Steps to reproduce:
visit thimbleberry.dev
Actual results:
the demo app makes more progress after the fix for after 1825186 (thanks!), but still fails quickly because:
createTexture() returns undefined.
src here: https://github.com/mighdoll/thimbleberry/blob/main/src/shader-util/ImageToTexture.ts
Expected results:
(works on chrome)
Comment 1•2 years ago
|
||
The severity field is not set for this bug.
:jimb, could you have a look please?
For more information, please visit auto_nag documentation.
Comment 2•2 years ago
|
||
mighdoll: AFAICT, createTexture
is working, but I am running into bug 1830762 when visiting https://thimbleberry.dev/, where the GPUTexture.format
attribute of the returned texture isn't being populated, i.e.:
Uncaught (in promise) TypeError: GPUDevice.createRenderPipeline: Missing required 'format' member of GPUColorTargetState.
createMosaicPipeline MosaicPipeline.ts:86
memoMemo MemoMemo.ts:44
memoizeWithDevice CacheKeyWithDevice.ts:33
get pipeline MosaicShader.ts:101
Is this what you were referring to, mighdoll?
Updated•2 years ago
|
Updated•2 years ago
|
Comment 3•2 years ago
|
||
This should be making more progress now, though in my latest testing, I still see these blockages in the JS console for the tab:
15:30:44.997 Invalid URI. Load of media resource failed. thimbleberry.dev
15:30:45.828 In a draw command, indexed:false indirect:false, caused by: The pipeline layout, associated with the current render pipeline, contains a bind group layout at index 0 which is incompatible with the bind group layout associated with the bind group at 0
15:30:45.828 Command encoder is invalid
Updated•2 years ago
|
Comment 4•2 years ago
|
||
The problem I found with comment 3 is blocked on bug 1611425.
Updated•2 years ago
|
Updated•2 years ago
|
Comment 5•1 year ago
•
|
||
This trace allows us to reproduce the bind group mismatch error in wgpu's replay tool. As can be seen in the .ron file copied below, a pipeline layout is created with a bind group layout, and later a render pass uses the pipeline without setting a compatible bind group.
Erich found out that we are (incorrectly) discarding the set_bind_group before it gets a chance to be recorded in the command buffer.
[
Init(
desc: (
label: None,
features: 2,
limits: (
maxTextureDimension1D: 8192,
maxTextureDimension2D: 8192,
maxTextureDimension3D: 2048,
maxTextureArrayLayers: 256,
maxBindGroups: 4,
maxBindingsPerBindGroup: 1000,
maxDynamicUniformBuffersPerPipelineLayout: 8,
maxDynamicStorageBuffersPerPipelineLayout: 4,
maxSampledTexturesPerShaderStage: 16,
maxSamplersPerShaderStage: 16,
maxStorageBuffersPerShaderStage: 8,
maxStorageTexturesPerShaderStage: 4,
maxUniformBuffersPerShaderStage: 12,
maxUniformBufferBindingSize: 65536,
maxStorageBufferBindingSize: 134217728,
maxVertexBuffers: 8,
maxBufferSize: 268435456,
maxVertexAttributes: 16,
maxVertexBufferArrayStride: 2048,
minUniformBufferOffsetAlignment: 256,
minStorageBufferOffsetAlignment: 256,
maxInterStageShaderComponents: 60,
maxComputeWorkgroupStorageSize: 16384,
maxComputeInvocationsPerWorkgroup: 256,
maxComputeWorkgroupSizeX: 256,
maxComputeWorkgroupSizeY: 256,
maxComputeWorkgroupSizeZ: 64,
maxComputeWorkgroupsPerDimension: 65535,
maxPushConstantSize: 256,
maxNonSamplerBindings: 10000,
),
),
backend: Vulkan,
),
CreateTexture(Id(0, 1, Vulkan), (
label: Some("placeholder texture"),
size: (
width: 50,
height: 50,
depthOrArrayLayers: 1,
),
mip_level_count: 1,
sample_count: 1,
dimension: r#2d,
format: "rgba8unorm",
usage: 23,
view_formats: [],
)),
CreateTexture(Id(1, 1, Vulkan), (
label: Some("bird.jpg"),
size: (
width: 400,
height: 400,
depthOrArrayLayers: 1,
),
mip_level_count: 1,
sample_count: 1,
dimension: r#2d,
format: "bgra8unorm",
usage: 23,
view_formats: [],
)),
WriteTexture(
to: (
texture: Id(1, 1, Vulkan),
mip_level: 0,
origin: (
x: 0,
y: 0,
z: 0,
),
aspect: all,
),
data: "data1.bin",
layout: (
offset: 0,
bytes_per_row: Some(1600),
rows_per_image: Some(400),
),
size: (
width: 400,
height: 400,
depthOrArrayLayers: 1,
),
),
CreateTexture(Id(2, 1, Vulkan), (
label: None,
size: (
width: 1200,
height: 900,
depthOrArrayLayers: 1,
),
mip_level_count: 1,
sample_count: 1,
dimension: r#2d,
format: "bgra8unorm",
usage: 19,
view_formats: [],
)),
CreateTexture(Id(3, 1, Vulkan), (
label: None,
size: (
width: 400,
height: 900,
depthOrArrayLayers: 1,
),
mip_level_count: 1,
sample_count: 1,
dimension: r#2d,
format: "bgra8unorm",
usage: 19,
view_formats: [],
)),
CreateTexture(Id(4, 1, Vulkan), (
label: None,
size: (
width: 400,
height: 400,
depthOrArrayLayers: 1,
),
mip_level_count: 1,
sample_count: 1,
dimension: r#2d,
format: "bgra8unorm",
usage: 19,
view_formats: [],
)),
CreateTextureView(
id: Id(0, 1, Vulkan),
parent_id: Id(4, 1, Vulkan),
desc: (
label: Some("view-canvas current texture 0"),
format: None,
dimension: None,
range: (
aspect: all,
base_mip_level: 0,
mip_level_count: None,
base_array_layer: 0,
array_layer_count: None,
),
),
),
CreateBindGroupLayout(Id(0, 1, Vulkan), (
label: Some("mosaic layout"),
entries: [
(
binding: 0,
visibility: 3,
ty: Buffer(
ty: Uniform,
has_dynamic_offset: false,
min_binding_size: None,
),
count: None,
),
(
binding: 1,
visibility: 1,
ty: Texture(
sample_type: Float(
filterable: false,
),
view_dimension: r#2d,
multisampled: false,
),
count: None,
),
(
binding: 11,
visibility: 2,
ty: Buffer(
ty: Storage(
read_only: false,
),
has_dynamic_offset: false,
min_binding_size: None,
),
count: None,
),
],
)),
CreateShaderModule(
id: Id(0, 1, Vulkan),
desc: (
label: None,
shader_bound_checks: (
runtime_checks: true,
),
),
data: "data2.wgsl",
),
CreatePipelineLayout(Id(0, 1, Vulkan), (
label: None,
bind_group_layouts: [
Id(0, 1, Vulkan),
],
push_constant_ranges: [],
)),
CreateRenderPipeline(
id: Id(0, 1, Vulkan),
desc: (
label: Some("Mosaic Pipeline"),
layout: Some(Id(0, 1, Vulkan)),
vertex: (
stage: (
module: Id(0, 1, Vulkan),
entry_point: "vertMain",
),
buffers: [
(
arrayStride: 8,
stepMode: vertex,
attributes: [
(
format: float32x2,
offset: 0,
shaderLocation: 0,
),
],
),
(
arrayStride: 8,
stepMode: instance,
attributes: [
(
format: float32x2,
offset: 0,
shaderLocation: 1,
),
],
),
],
),
primitive: (
topology: r#triangle-strip,
stripIndexFormat: None,
frontFace: ccw,
cullMode: None,
unclippedDepth: false,
polygonMode: fill,
conservative: false,
),
depth_stencil: None,
multisample: (
count: 1,
mask: 4294967295,
alphaToCoverageEnabled: false,
),
fragment: Some((
stage: (
module: Id(0, 1, Vulkan),
entry_point: "fragMain",
),
targets: [
Some((
format: "bgra8unorm",
blend: Some((
color: (
srcFactor: one,
dstFactor: r#one-minus-src-alpha,
operation: add,
),
alpha: (
srcFactor: zero,
dstFactor: one,
operation: add,
),
)),
writeMask: 15,
)),
],
)),
multiview: None,
),
implicit_context: None,
),
CreateBuffer(Id(30, 1, Vulkan), (
label: None,
size: 32,
usage: 40,
mapped_at_creation: false,
)),
WriteBuffer(
id: Id(30, 1, Vulkan),
data: "data3.bin",
range: (
start: 0,
end: 32,
),
queued: true,
),
CreateBuffer(Id(31, 1, Vulkan), (
label: None,
size: 5456,
usage: 40,
mapped_at_creation: false,
)),
WriteBuffer(
id: Id(31, 1, Vulkan),
data: "data4.bin",
range: (
start: 0,
end: 5456,
),
queued: true,
),
CreateTextureView(
id: Id(1, 1, Vulkan),
parent_id: Id(1, 1, Vulkan),
desc: (
label: Some("view "),
format: None,
dimension: None,
range: (
aspect: all,
base_mip_level: 0,
mip_level_count: None,
base_array_layer: 0,
array_layer_count: None,
),
),
),
CreateBuffer(Id(32, 1, Vulkan), (
label: None,
size: 32,
usage: 72,
mapped_at_creation: false,
)),
CreateBuffer(Id(33, 1, Vulkan), (
label: None,
size: 64,
usage: 132,
mapped_at_creation: false,
)),
Submit(1, [
RunRenderPass(
base: (
label: Some("Mosaic shader render pass"),
commands: [
SetPipeline(Id(0, 1, Vulkan)),
SetVertexBuffer(
slot: 0,
buffer_id: Id(30, 1, Vulkan),
offset: 0,
size: None,
),
SetVertexBuffer(
slot: 1,
buffer_id: Id(31, 1, Vulkan),
offset: 0,
size: None,
),
Draw( // the error happens here, we set a pipeline that requires a bind group but did not set the bind group.
vertex_count: 4,
instance_count: 682,
first_vertex: 0,
first_instance: 0,
),
],
dynamic_offsets: [],
string_data: [],
push_constant_data: [],
),
target_colors: [
Some((
view: Id(0, 1, Vulkan),
resolve_target: None,
channel: (
load_op: clear,
store_op: store,
clear_value: (
r: 0.1,
g: 0.3,
b: 0.4,
a: 1.0,
),
read_only: false,
),
)),
],
target_depth_stencil: None,
timestamp_writes: None,
occlusion_query_set_id: None,
),
]),
CreateBuffer(Id(29, 1, Vulkan), (
label: None,
size: 716800,
usage: 9,
mapped_at_creation: false,
)),
Submit(2, [
CopyTextureToBuffer(
src: (
texture: Id(4, 1, Vulkan),
mip_level: 0,
origin: (
x: 0,
y: 0,
z: 0,
),
aspect: all,
),
dst: (
buffer: Id(29, 1, Vulkan),
layout: (
offset: 0,
bytes_per_row: Some(1792),
rows_per_image: None,
),
),
size: (
width: 400,
height: 400,
depthOrArrayLayers: 1,
),
),
]),
DestroyTexture(Id(3, 1, Vulkan)),
DestroyTexture(Id(2, 1, Vulkan)),
DestroyShaderModule(Id(0, 1, Vulkan)),
DestroyTextureView(Id(1, 1, Vulkan)),
]
Comment 6•1 year ago
|
||
And now that I attached all of this information to the bug I realize that the trace is merely a product of the issue but does not really reproduce it because it is recorded after we incorrectly discard the setBindGroup from the commands.
Comment 7•1 year ago
|
||
So at least two bad things happening here:
- When we create a pipeline, we don't populate the list of implicit bind group layouts in all cases (source) which causes us to fail to create a valid bind group layout when calling
pipeline.getBindGroupLayout(0)
later. We try to create a bind group from the invalid layout and get an invalid one as a result. - The invalid bind groups and bind group layouts are represented by both an invalid ID (value zero) and an mValid = false flag. On the rust side of things the Id types are NonZero, so it is pretty bad to pass zero ids through the ffi boundary without checking. This is what is happening when we do
setBindGroup
in the render pass.
At this point I think that we should not be able to express invalid objects on the content side. Every object should have a valid ID and a spot in the registry on the parent side. The validity of the object must always be managed by the parent side. The spec has been specifically designed for thing to work this way and straying away from this structure is sure to create lots of unexpected bugs and undefined behavior.
Updated•1 year ago
|
Description
•