Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Black Screen #15

Closed
jeffreyrosenbluth opened this issue Oct 14, 2021 · 12 comments
Closed

Black Screen #15

jeffreyrosenbluth opened this issue Oct 14, 2021 · 12 comments

Comments

@jeffreyrosenbluth
Copy link

When running examples, the window only contains solid black, no image.
MacOS Big Sur
iMac Pro 2017

@de-vri-es
Copy link
Member

de-vri-es commented Oct 15, 2021

Hey,

Thanks for reporting the issue. I'm afraid I can not test on MacOS myself.

Could you perhabs modify one of the examples to enable logging and post the result? wgpu has a lot of logging statements that might help debug it.

If you're not sure exactly how to do that, I can help with that.

@de-vri-es
Copy link
Member

The main branch now uses env_logger in the examples. This means you can use RUST_LOG=info cargo run --example show-image .... to enable logging.

Could you try it and share the output?

@xanecs
Copy link
Contributor

xanecs commented Oct 17, 2021

Hi, I have just experienced the same issue, also on macOS Big Sur.
When using the Scroll Wheel (which would normally be used to zoom, I assume) the image appears but very distorted.

This is the output when opening an image and then scrolling:

ImageInfo {
    pixel_format: Rgb8,
    size: UVec2(
        640,
        480,
    ),
    stride: UVec2(
        3,
        1920,
    ),
}
[2021-10-17T14:36:26Z INFO  wgpu_core::device] creating swap chain SwapChainDescriptor { usage: RENDER_ATTACHMENT, format: Bgra8Unorm, width: 800, height: 600, present_mode: Mailbox }
[2021-10-17T14:36:26Z WARN  wgpu_core::device] Surface does not support present mode: MAILBOX, falling back to FIFO
[2021-10-17T14:36:26Z INFO  gfx_backend_metal::window] build swapchain SwapchainConfig { present_mode: FIFO, composite_alpha_mode: OPAQUE, format: Bgra8Unorm, extent: Extent2D { width: 800, height: 600 }, image_count: 3, image_layers: 1, image_usage: COLOR_ATTACHMENT }
[2021-10-17T14:36:26Z INFO  wgpu_core::device] Created buffer Valid((0, 1, Metal)) with BufferDescriptor { label: None, size: 64, usage: COPY_DST | UNIFORM, mapped_at_creation: true }
[2021-10-17T14:36:26Z INFO  wgpu_core::device] Created buffer Valid((1, 1, Metal)) with BufferDescriptor { label: Some("480_uniforms_buffer"), size: 20, usage: UNIFORM, mapped_at_creation: true }
[2021-10-17T14:36:26Z INFO  wgpu_core::device] Created buffer Valid((2, 1, Metal)) with BufferDescriptor { label: Some("480_image_buffer"), size: 921600, usage: STORAGE, mapped_at_creation: true }
[2021-10-17T14:36:26Z INFO  wgpu_core::device] Created buffer Valid((3, 1, Metal)) with BufferDescriptor { label: None, size: 64, usage: COPY_SRC, mapped_at_creation: true }
[2021-10-17T14:36:26Z INFO  wgpu_core::device] Buffer (3, 1, Metal) is dropped
[2021-10-17T14:36:28Z INFO  wgpu_core::device] Created buffer Valid((4, 1, Metal)) with BufferDescriptor { label: None, size: 64, usage: COPY_SRC, mapped_at_creation: true }
[2021-10-17T14:36:28Z INFO  wgpu_core::device] Buffer (4, 1, Metal) is dropped
[2021-10-17T14:36:28Z INFO  wgpu_core::device] Created buffer Valid((3, 2, Metal)) with BufferDescriptor { label: None, size: 64, usage: COPY_SRC, mapped_at_creation: true }
[2021-10-17T14:36:28Z INFO  wgpu_core::device] Buffer (3, 2, Metal) is dropped
[2021-10-17T14:36:29Z INFO  wgpu_core::device] Created buffer Valid((4, 2, Metal)) with BufferDescriptor { label: None, size: 64, usage: COPY_SRC, mapped_at_creation: true }
[2021-10-17T14:36:29Z INFO  wgpu_core::device] Buffer (4, 2, Metal) is dropped
[2021-10-17T14:36:29Z INFO  wgpu_core::device] Created buffer Valid((3, 3, Metal)) with BufferDescriptor { label: None, size: 64, usage: COPY_SRC, mapped_at_creation: true }
[2021-10-17T14:36:29Z INFO  wgpu_core::device] Buffer (3, 3, Metal) is dropped
[2021-10-17T14:36:29Z INFO  wgpu_core::device] Created buffer Valid((4, 3, Metal)) with BufferDescriptor { label: None, size: 64, usage: COPY_SRC, mapped_at_creation: true }
[2021-10-17T14:36:29Z INFO  wgpu_core::device] Buffer (4, 3, Metal) is dropped
[2021-10-17T14:36:29Z INFO  wgpu_core::device] Created buffer Valid((3, 4, Metal)) with BufferDescriptor { label: None, size: 64, usage: COPY_SRC, mapped_at_creation: true }
[2021-10-17T14:36:29Z INFO  wgpu_core::device] Buffer (3, 4, Metal) is dropped
[2021-10-17T14:36:30Z INFO  wgpu_core::device] Created buffer Valid((4, 4, Metal)) with BufferDescriptor { label: None, size: 64, usage: COPY_SRC, mapped_at_creation: true }
[2021-10-17T14:36:30Z INFO  wgpu_core::device] Buffer (4, 4, Metal) is dropped
[2021-10-17T14:36:30Z INFO  wgpu_core::device] Created buffer Valid((3, 5, Metal)) with BufferDescriptor { label: None, size: 64, usage: COPY_SRC, mapped_at_creation: true }
[2021-10-17T14:36:30Z INFO  wgpu_core::device] Buffer (3, 5, Metal) is dropped
[2021-10-17T14:36:30Z INFO  wgpu_core::device] Created buffer Valid((4, 5, Metal)) with BufferDescriptor { label: None, size: 64, usage: COPY_SRC, mapped_at_creation: true }
[2021-10-17T14:36:30Z INFO  wgpu_core::device] Buffer (4, 5, Metal) is dropped
[2021-10-17T14:36:33Z INFO  wgpu_core::device] Buffer (0, 1, Metal) is dropped
[2021-10-17T14:36:33Z INFO  wgpu_core::device] Buffer (1, 1, Metal) is dropped
[2021-10-17T14:36:33Z INFO  wgpu_core::device] Buffer (2, 1, Metal) is dropped

Bildschirmfoto 2021-10-17 um 16 35 22

@xanecs
Copy link
Contributor

xanecs commented Oct 17, 2021

After poking around a bit, I think the problem is how the transform matrix is transferred to the vertex shader. (Maybe because macOS, unlike other platforms, uses Metal). The scale value ends up in transform[0][0] and transform[2][1] while the translation value does not seem to be in the mat3x2 at all.

However I could not figure out why the matrix is messed up like that. (Printing the value from the CPU side returns a correct looking matrix)

@de-vri-es
Copy link
Member

de-vri-es commented Oct 17, 2021

Interesting, that's very useful information. It would have taken a while before I would start suspecting that the transformation.

I will have to investigate more, but maybe metal has different padding on matrices. You could try playing with the alignment values here:

#[repr(C, align(16))]

Maybe just remove the alignas to remove all internal padding in the matrix. If that turns out to be the problem, we'll have to pass the matrix in a more portable form.

@xanecs
Copy link
Contributor

xanecs commented Oct 17, 2021

I have suspected the alignment to be a problem as well, as the metal specifications say that float3x2 (which should be the mat3x2 equivalent) is 8 byte aligned by default. (https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf, page 28).

Simply changing the Mat3x2 struct to use Vec2A8 or setting Vec2A16 to be align(8) results in an error from wgpu:

thread 'main' panicked at 'Unhandled WGPU error: Validation Error

Caused by:
    In Device::create_render_pipeline
      note: label = `show-image-pipeline`
    error matching VERTEX shader requirements against the pipeline
    shader global ResourceBinding { group: 0, binding: 0 } is not available in the layout pipeline layout
    buffer structure size 56, added to one element of an unbound array, if it's the last field, ended up greater than the given `min_binding_size`
', src/backend/context.rs:122:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

This makes me think that the spir-v shader specifies 16 byte alignment, but the metal translation layer of wgpu somehow does not correctly handle this.

When using naga (the shader cross-compiler from wgpu) to convert the spir-v to metal it does indeed give an incorrect format for the uniform buffer:

struct WindowUniforms {
    metal::float3x2 transform;
    char _pad1[24];
    metal::float2 image_size;
};

I'll open an issue for naga

Edit: There is ongoing discussion about incorrect matrix strides at naga here: gfx-rs/naga#1400

@de-vri-es
Copy link
Member

Hmm, I wonder if this can be easily solved by naga. Maybe they can tell metal it's a 3x3 matrix and inject code to slice it into a 2x3 when used.

In the mean time, a simple solution for show-image is to do that manually. It appears that 3x3 matrices have the same layout in metal and glsl. I'll try to get round to this soon, unless someone wants to put it in a PR.

@xanecs
Copy link
Contributor

xanecs commented Oct 17, 2021

I have just figured out it's possible to use std430 alignment in the current glsl shader which emits 8 byte alignment in the spirv. Together with changing Mat3x2 to use Vec2A8 this works for me. Unfortunately I can't validate this solution with anything else than Metal right now, but I'll submit it as a PR.

@de-vri-es
Copy link
Member

Hmm, I'm a little worried that std430 layout may not work for all older systems. I'm not 100% sure any-more, but I think I had a laptop that didn't support it.

If std430 is widely supported on older hardware too, then it sounds good. But otherwise I would prefer to go with a mat3x3.

@xanecs
Copy link
Contributor

xanecs commented Oct 17, 2021

You might be right on that one. Naga seems to ignore the MatrixStride when outputting GLSL as well, so this might break the OpenGL backend

@de-vri-es
Copy link
Member

Fixed by #17 and released as 0.9.4 🚀

Thank again @xanecs for debugging and fixing this, and @jeffreyrosenbluth for reporting it :)

@jeffreyrosenbluth
Copy link
Author

jeffreyrosenbluth commented Oct 18, 2021 via email

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

No branches or pull requests

3 participants