rendy icon indicating copy to clipboard operation
rendy copied to clipboard

[BUG] texture::image::load_from_image creates invalid TextureBuilder

Open valkum opened this issue 5 years ago • 10 comments

Description

texture::image::load_from_image returns a TextureBuilder which according to the vulkan validation has unsupported parameters for some source images.

Reproduction Steps

  1. Clone https://github.com/valkum/learn-rendy/tree/image_load_bug
  2. Run instanced_cube example with vulkan
  3. Change Filename in https://github.com/valkum/learn-rendy/blob/image_load_bug/examples/instanced_cube.rs#L278-L287

What You Expected to Happen

See textured cubes for alle 3 textures in resources.

What Actually Happened

Both not_working pngs are black in rendy.

Screenshots and Logs

using not_working.png:

ERROR 2019-03-20T20:47:02Z: gfx_backend_vulkan: [Validation]  [ VUID_Undefined ] Object: VK_NULL_HANDLE (Type = 0) | vkCreateIm
age(): Format VK_FORMAT_R8G8B8_SRGB is not supported for this combination of parameters.
ERROR 2019-03-20T20:47:02Z: gfx_backend_vulkan: [Validation]  [ VUID-VkImageViewCreateInfo-None-02273 ] Object: 0x1d (Type = 10
) | vkCreateImageView(): pCreateInfo->format VK_FORMAT_R8G8B8_SRGB with tiling VK_IMAGE_TILING_OPTIMAL has no supported format
features on this physical device. The Vulkan spec states: The format features of the resultant image view must contain at least
 one bit. (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkImageViewCreateInfo-None-02273)

image

Your Environment

Windows 10 64bit AMD R9 390 Driver 19.2.3

Additional Context

For reproduction purpose I added amethyst-like image loading code to an updated version of learn-rendy.

The working original learn-rendy code uses image::load_from_memory and to_rgba but is not optimal for all texture assets.

valkum avatar Mar 20 '19 20:03 valkum

This looks like the same thing that was happening with rgb32float, and as I suspected we will need to handle this case as well. Basically at least some nvidia gpus and maybe others don’t support 3-component images in optimal tiling mode, only 4-component. So we should detect this and convert the data by adding a dummy padding component, and probably allow user configuration choice on how to resolve or to error out if needed

On Wed, Mar 20, 2019 at 1:55 PM Rudi Floren [email protected] wrote:

Description

texture::image::load_from_image returns a TextureBuilder containing a black image for some source images. Reproduction Steps

  1. Clone https://github.com/valkum/learn-rendy/tree/image_load_bug
  2. Run instanced_cube example with vulkan
  3. Change Filename in https://github.com/valkum/learn-rendy/blob/image_load_bug/examples/instanced_cube.rs#L278-L287

What You Expected to Happen

See textured cubes for alle 3 textures in resources. What Actually Happened

Both not_working pngs are black in rendy. Screenshots and Logs

using not_working.png:

ERROR 2019-03-20T20:47:02Z: gfx_backend_vulkan: [Validation] [ VUID_Undefined ] Object: VK_NULL_HANDLE (Type = 0) | vkCreateIm age(): Format VK_FORMAT_R8G8B8_SRGB is not supported for this combination of parameters. ERROR 2019-03-20T20:47:02Z: gfx_backend_vulkan: [Validation] [ VUID-VkImageViewCreateInfo-None-02273 ] Object: 0x1d (Type = 10 ) | vkCreateImageView(): pCreateInfo->format VK_FORMAT_R8G8B8_SRGB with tiling VK_IMAGE_TILING_OPTIMAL has no supported format features on this physical device. The Vulkan spec states: The format features of the resultant image view must contain at least one bit. (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkImageViewCreateInfo-None-02273)

[image: image] https://user-images.githubusercontent.com/169155/54717856-6f1f3700-4b59-11e9-8324-d8ce4d55b00a.png Additional Context

For reproduction purpose I added amethyst-like image loading code to an updated version of learn-rendy.

The working original learn-rendy code uses image::load_from_memory and to_rgba but is not optimal for all texture assets.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/omni-viral/rendy/issues/80, or mute the thread https://github.com/notifications/unsubscribe-auth/AA2Ln63Y9lYQNFz5NMy82843X_Vz-z0sks5vYqBKgaJpZM4cAP87 .

fu5ha avatar Mar 21 '19 00:03 fu5ha

So best to call PhysicalDevice ::image_format_properties during TextureBuilder::build and have the user choose from a couple of different approaches to resolve or error out? If I find time and a solution tomorrow I will hand in a WIP PR.

valkum avatar Mar 21 '19 02:03 valkum

For the record here is a list of unsupported formats of my AMD r9 390 (19.2.3). It would be really nice if there would be a website with supported/unsupported vulkan formats/features in relation to e.g. the steam hardware stats. Like it is done for web features across browsers.

FORMAT_UNDEFINED
FORMAT_R8G8B8_UNORM
FORMAT_R8G8B8_SNORM
FORMAT_R8G8B8_USCALED
FORMAT_R8G8B8_SSCALED
FORMAT_R8G8B8_UINT
FORMAT_R8G8B8_SINT
FORMAT_R8G8B8_SRGB
FORMAT_B8G8R8_UNORM
FORMAT_B8G8R8_SNORM
FORMAT_B8G8R8_USCALED
FORMAT_B8G8R8_SSCALED
FORMAT_B8G8R8_UINT
FORMAT_B8G8R8_SINT
FORMAT_B8G8R8_SRGB
FORMAT_R16G16B16_UNORM
FORMAT_R16G16B16_SNORM
FORMAT_R16G16B16_USCALED
FORMAT_R16G16B16_SSCALED
FORMAT_R16G16B16_UINT
FORMAT_R16G16B16_SINT
FORMAT_R16G16B16_SFLOAT
FORMAT_X8_D24_UNORM_PACK32
FORMAT_D24_UNORM_S8_UINT
FORMAT_ETC2_R8G8B8_UNORM_BLOCK
FORMAT_ETC2_R8G8B8_SRGB_BLOCK
FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK
FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK
FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK
FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK
FORMAT_EAC_R11_UNORM_BLOCK
FORMAT_EAC_R11_SNORM_BLOCK
FORMAT_EAC_R11G11_UNORM_BLOCK
FORMAT_EAC_R11G11_SNORM_BLOCK
FORMAT_ASTC_4x4_UNORM_BLOCK
FORMAT_ASTC_4x4_SRGB_BLOCK
FORMAT_ASTC_5x4_UNORM_BLOCK
FORMAT_ASTC_5x4_SRGB_BLOCK
FORMAT_ASTC_5x5_UNORM_BLOCK
FORMAT_ASTC_5x5_SRGB_BLOCK
FORMAT_ASTC_6x5_UNORM_BLOCK
FORMAT_ASTC_6x5_SRGB_BLOCK
FORMAT_ASTC_6x6_UNORM_BLOCK
FORMAT_ASTC_6x6_SRGB_BLOCK
FORMAT_ASTC_8x5_UNORM_BLOCK
FORMAT_ASTC_8x5_SRGB_BLOCK
FORMAT_ASTC_8x6_UNORM_BLOCK
FORMAT_ASTC_8x6_SRGB_BLOCK
FORMAT_ASTC_8x8_UNORM_BLOCK
FORMAT_ASTC_8x8_SRGB_BLOCK
FORMAT_ASTC_10x5_UNORM_BLOCK
FORMAT_ASTC_10x5_SRGB_BLOCK
FORMAT_ASTC_10x6_UNORM_BLOCK
FORMAT_ASTC_10x6_SRGB_BLOCK
FORMAT_ASTC_10x8_UNORM_BLOCK
FORMAT_ASTC_10x8_SRGB_BLOCK
FORMAT_ASTC_10x10_UNORM_BLOCK
FORMAT_ASTC_10x10_SRGB_BLOCK
FORMAT_ASTC_12x10_UNORM_BLOCK
FORMAT_ASTC_12x10_SRGB_BLOCK
FORMAT_ASTC_12x12_UNORM_BLOCK
FORMAT_ASTC_12x12_SRGB_BLOCK
FORMAT_G8B8G8R8_422_UNORM
FORMAT_B8G8R8G8_422_UNORM
FORMAT_G8_B8_R8_3PLANE_420_UNORM
FORMAT_G8_B8R8_2PLANE_420_UNORM
FORMAT_G8_B8_R8_3PLANE_422_UNORM
FORMAT_G8_B8R8_2PLANE_422_UNORM
FORMAT_G8_B8_R8_3PLANE_444_UNORM
FORMAT_R10X6_UNORM_PACK16
FORMAT_R10X6G10X6_UNORM_2PACK16
FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16
FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16
FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16
FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16
FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16
FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16
FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16
FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16
FORMAT_R12X4_UNORM_PACK16
FORMAT_R12X4G12X4_UNORM_2PACK16
FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16
FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16
FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16
FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16
FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16
FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16
FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16
FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16
FORMAT_G16B16G16R16_422_UNORM
FORMAT_B16G16R16G16_422_UNORM
FORMAT_G16_B16_R16_3PLANE_420_UNORM
FORMAT_G16_B16R16_2PLANE_420_UNORM
FORMAT_G16_B16_R16_3PLANE_422_UNORM
FORMAT_G16_B16R16_2PLANE_422_UNORM
FORMAT_G16_B16_R16_3PLANE_444_UNORM

valkum avatar Mar 21 '19 02:03 valkum

Hmm, I'm not sure whether I think it shouldn't happen in build... I kinda think that if the user is manually building up a TextureBuilder then they should query for this and handle it themselves. Certainly, if they are using something like load_from_image then automatic loading strategies should be presented... I have something like this going in #69 for HDR images, but without any configuration really.

Thoughts @Frizi @omni-viral ?

fu5ha avatar Mar 21 '19 02:03 fu5ha

I see there are formats with compressions and formats with size not multiple of 4 bytes. So this makes sense for them to be not supported in optimal tiling. I agree with @termhn that load_from_image should handle that by converting into supported format.

zakarumych avatar Mar 21 '19 06:03 zakarumych

I think that we could do two things in those automatic loaders:

  • make sure that whatever is loaded by default always is converted to one of the optimal compatible formats
  • allow overriding the output format manually by specifying it in ImageTextureConfig.

I'm not exactly sure about the need for the second one though. It might be useful if somebody is doing some image copying manually later, but that's about it probably.

Frizi avatar Mar 22 '19 11:03 Frizi

Well actually after thinking about it for a while, I realised that amethyst's biggest usage for those methods will be in asset pipeline, which doesn't have the context of specific GPU device available. Any kind of "cross-compilation"-like system will have that problem. That means that any automatic features also have to be either optional or not depend on device as well. If we can't guarantee that a specific format will cut it for all devices, having the option to manually override the chosen format seems like a must.

On the other hand, it would be a shame to force conversion when original format is just fine for it's intended usage. That's why automatic choosing should still be possible, just has to be optional.

Frizi avatar Mar 22 '19 12:03 Frizi

On the other hand, it would be a shame to force conversion when original format is just fine for it's intended usage.

What other options do you have if the (regarding use) optimal format is not supported by the driver?

Some question to figure out the place for the conversion:

  1. When doing it in the asset pipeline (during build): Would we need statistics about support for different formats, for the different backends and drivers, to provide a copy of each in the install bundle?

  2. When doing it during runtime: When modifying the assets (e.g. padding) should amethyst/"crate that uses rendy" cache those? Or should this be done every start? If cached: Can a driver update add support for other formats? Should we recheck periodically if the supported formats changed?

  3. When doing it during install: Should this be done by the installer (To avoid overhead during startup and duplicate files on your disc (cached))?

valkum avatar Mar 22 '19 18:03 valkum

You can also change hardware

zakarumych avatar Mar 22 '19 18:03 zakarumych

If cached: Can a driver update add support for other formats? Should we recheck periodically if the supported formats changed?

Yes it can change, and you can and should query every time the driver to see if it supports the requested format

fu5ha avatar Mar 22 '19 21:03 fu5ha