FNA-XNA / FNA3D

FNA3D - 3D Graphics Library for FNA
http://fna-xna.github.io/
Other
287 stars 48 forks source link

Vulkan texture uploads for mipped compressed textures produce validation errors #184

Closed kg closed 1 year ago

kg commented 1 year ago

Just recording this here: If you perform uploads to mips of a compressed texture where the base level's size is just so, some of the mips will have sizes that are not multiples of 4, which will produce validator errors from inside FNA3D. From what I can tell, the D3D11 backend internally rounds the width/height up to a multiple of 4 to fix this. I tried doing the same in the Vulkan driver myself but I got new and more exciting validator errors when doing so.

VUID-VkBufferImageCopy-None-01735(ERROR / SPEC): msgNum: -191671466 - Validation Error: [ VUID-VkBufferImageCopy-None-01735 ] Object 0: handle = 0x129e7d0000001ea6, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf4935356 | vkCmdCopyBufferToImage(): pRegion[0] bufferRowLength (43) must be a multiple of the compressed image's texel width (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferRowLength must be a multiple of the compressed texel block width (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01735)
    Objects: 1
        [0] 0x129e7d0000001ea6, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01735(ERROR / SPEC): msgNum: -191671466 - Validation Error: [ VUID-VkBufferImageCopy-None-01735 ] Object 0: handle = 0x129e7d0000001ea6, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf4935356 | vkCmdCopyBufferToImage(): pRegion[0] bufferRowLength (86) must be a multiple of the compressed image's texel width (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferRowLength must be a multiple of the compressed texel block width (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01735)
    Objects: 1
        [0] 0x129e7d0000001ea6, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01735(ERROR / SPEC): msgNum: -191671466 - Validation Error: [ VUID-VkBufferImageCopy-None-01735 ] Object 0: handle = 0x129e7d0000001ea6, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf4935356 | vkCmdCopyBufferToImage(): pRegion[0] bufferRowLength (21) must be a multiple of the compressed image's texel width (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferRowLength must be a multiple of the compressed texel block width (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01735)
    Objects: 1
        [0] 0x129e7d0000001ea6, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01735(ERROR / SPEC): msgNum: -191671466 - Validation Error: [ VUID-VkBufferImageCopy-None-01735 ] Object 0: handle = 0x129e7d0000001ea6, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf4935356 | vkCmdCopyBufferToImage(): pRegion[0] bufferRowLength (10) must be a multiple of the compressed image's texel width (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferRowLength must be a multiple of the compressed texel block width (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01735)
    Objects: 1
        [0] 0x129e7d0000001ea6, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01736(ERROR / SPEC): msgNum: 1409501487 - Validation Error: [ VUID-VkBufferImageCopy-None-01736 ] Object 0: handle = 0x129e7d0000001ea6, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x5403492f | vkCmdCopyBufferToImage(): pRegion[0] bufferImageHeight (5) must be a multiple of the compressed image's texel height (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferImageHeight must be a multiple of the compressed texel block height (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01736)
    Objects: 1
        [0] 0x129e7d0000001ea6, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01735(ERROR / SPEC): msgNum: -191671466 - Validation Error: [ VUID-VkBufferImageCopy-None-01735 ] Object 0: handle = 0x129e7d0000001ea6, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf4935356 | vkCmdCopyBufferToImage(): pRegion[0] bufferRowLength (5) must be a multiple of the compressed image's texel width (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferRowLength must be a multiple of the compressed texel block width (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01735)
    Objects: 1
        [0] 0x129e7d0000001ea6, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01736(ERROR / SPEC): msgNum: 1409501487 - Validation Error: [ VUID-VkBufferImageCopy-None-01736 ] Object 0: handle = 0x129e7d0000001ea6, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x5403492f | vkCmdCopyBufferToImage(): pRegion[0] bufferImageHeight (10) must be a multiple of the compressed image's texel height (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferImageHeight must be a multiple of the compressed texel block height (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01736)
    Objects: 1
        [0] 0x129e7d0000001ea6, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01735(ERROR / SPEC): msgNum: -191671466 - Validation Error: [ VUID-VkBufferImageCopy-None-01735 ] Object 0: handle = 0x768fda0000001eb5, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf4935356 | vkCmdCopyBufferToImage(): pRegion[0] bufferRowLength (42) must be a multiple of the compressed image's texel width (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferRowLength must be a multiple of the compressed texel block width (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01735)
    Objects: 1
        [0] 0x768fda0000001eb5, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01736(ERROR / SPEC): msgNum: 1409501487 - Validation Error: [ VUID-VkBufferImageCopy-None-01736 ] Object 0: handle = 0x768fda0000001eb5, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x5403492f | vkCmdCopyBufferToImage(): pRegion[0] bufferImageHeight (82) must be a multiple of the compressed image's texel height (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferImageHeight must be a multiple of the compressed texel block height (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01736)
    Objects: 1
        [0] 0x768fda0000001eb5, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01735(ERROR / SPEC): msgNum: -191671466 - Validation Error: [ VUID-VkBufferImageCopy-None-01735 ] Object 0: handle = 0x768fda0000001eb5, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf4935356 | vkCmdCopyBufferToImage(): pRegion[0] bufferRowLength (10) must be a multiple of the compressed image's texel width (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferRowLength must be a multiple of the compressed texel block width (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01735)
    Objects: 1
        [0] 0x768fda0000001eb5, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01735(ERROR / SPEC): msgNum: -191671466 - Validation Error: [ VUID-VkBufferImageCopy-None-01735 ] Object 0: handle = 0x768fda0000001eb5, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf4935356 | vkCmdCopyBufferToImage(): pRegion[0] bufferRowLength (21) must be a multiple of the compressed image's texel width (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferRowLength must be a multiple of the compressed texel block width (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01735)
    Objects: 1
        [0] 0x768fda0000001eb5, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01736(ERROR / SPEC): msgNum: 1409501487 - Validation Error: [ VUID-VkBufferImageCopy-None-01736 ] Object 0: handle = 0x768fda0000001eb5, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x5403492f | vkCmdCopyBufferToImage(): pRegion[0] bufferImageHeight (41) must be a multiple of the compressed image's texel height (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferImageHeight must be a multiple of the compressed texel block height (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01736)
    Objects: 1
        [0] 0x768fda0000001eb5, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01735(ERROR / SPEC): msgNum: -191671466 - Validation Error: [ VUID-VkBufferImageCopy-None-01735 ] Object 0: handle = 0x768fda0000001eb5, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf4935356 | vkCmdCopyBufferToImage(): pRegion[0] bufferRowLength (170) must be a multiple of the compressed image's texel width (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferRowLength must be a multiple of the compressed texel block width (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01735)
    Objects: 1
        [0] 0x768fda0000001eb5, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01735(ERROR / SPEC): msgNum: -191671466 - Validation Error: [ VUID-VkBufferImageCopy-None-01735 ] Object 0: handle = 0x768fda0000001eb5, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf4935356 | vkCmdCopyBufferToImage(): pRegion[0] bufferRowLength (85) must be a multiple of the compressed image's texel width (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferRowLength must be a multiple of the compressed texel block width (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01735)
    Objects: 1
        [0] 0x768fda0000001eb5, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01736(ERROR / SPEC): msgNum: 1409501487 - Validation Error: [ VUID-VkBufferImageCopy-None-01736 ] Object 0: handle = 0x768fda0000001eb5, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x5403492f | vkCmdCopyBufferToImage(): pRegion[0] bufferImageHeight (5) must be a multiple of the compressed image's texel height (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferImageHeight must be a multiple of the compressed texel block height (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01736)
    Objects: 1
        [0] 0x768fda0000001eb5, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01735(ERROR / SPEC): msgNum: -191671466 - Validation Error: [ VUID-VkBufferImageCopy-None-01735 ] Object 0: handle = 0x768fda0000001eb5, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xf4935356 | vkCmdCopyBufferToImage(): pRegion[0] bufferRowLength (5) must be a multiple of the compressed image's texel width (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferRowLength must be a multiple of the compressed texel block width (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01735)
    Objects: 1
        [0] 0x768fda0000001eb5, type: 10, name: NULL
VUID-VkBufferImageCopy-None-01736(ERROR / SPEC): msgNum: 1409501487 - Validation Error: [ VUID-VkBufferImageCopy-None-01736 ] Object 0: handle = 0x768fda0000001eb5, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x5403492f | vkCmdCopyBufferToImage(): pRegion[0] bufferImageHeight (10) must be a multiple of the compressed image's texel height (4).. The Vulkan spec states: If the calling command's VkImage parameter is a compressed image, or a single-plane, "_422" image format, bufferImageHeight must be a multiple of the compressed texel block height (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-None-01736)
    Objects: 1
        [0] 0x768fda0000001eb5, type: 10, name: NULL
VUID-VkBufferImageCopy-bufferOffset-00194(ERROR / SPEC): msgNum: -934325023 - Validation Error: [ VUID-VkBufferImageCopy-bufferOffset-00194 ] Object 0: handle = 0xda655600000011e4, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0xc84f54e1 | vkCmdCopyImageToBuffer(): pRegion[0] bufferOffset 0x90e62 must be a multiple of 4. The Vulkan spec states: bufferOffset must be a multiple of 4 (https://vulkan.lunarg.com/doc/view/1.2.141.0/windows/1.2-extensions/vkspec.html#VUID-VkBufferImageCopy-bufferOffset-00194)
    Objects: 1
        [0] 0xda655600000011e4, type: 10, name: NULL

In this case I'm calling SetData without passing a Rect, so everything on my end is default. A 196x196 DXT texture is sufficient to repro this, because its level 1 has a size that isn't a multiple of 4. All the data is there, so the driver seems to be happy to round the size up for us and the upload is successful.

flibitijibibo commented 1 year ago

Did #186 fix this?

kg commented 1 year ago

Yeah I think it's fixed now.