lavapipe: do not stumble on overly large textures
LLVMpipe doesn't support using textures larger than 2GB, due to using signed offsets.
But this leads to some problems for Zink + Lavapipe:
- When we create a vkImage that would have been larger than 2GB, we end up creating an image with a required size of zero.
- Then when we try to create a zero-sized allocation, we return a
VK_NULL_HANDLE
instead. - Finally, Zink will happily try to
vkBindImageMemory
than NULL handle, which Lavapipe crashes on.
Instead, I think the right thing to do would be to calculate the right required size, and then fail to bind that. So here's a MR that does this.
But in order to not make things blow up, there's a few details that needs to be fixed first:
- The state-tracker in some cases tries to check if a negative-sized texture can be created, and it gets the max-level for that wrong. We were previously saved by the texture-size being calculated as too big, but we'll start writing out-of-bounds instead if we don't fix this.
-
p_screen::resource_bind_backing
doesn't support reporting an error, and it's LLVMpipe that knows about the max-texture size, not lavapipe. So let's add an error-code here; this also let's us report another potential problem.
The rest of this series just shuffles around the error-checking in what I believe to be a robust way, and finally reports an unlikely error-case that would previously have gone unnoticed.
There's one detail that might not be 100% kosher: We report VK_ERROR_OUT_OF_DEVICE_MEMORY
from vkBindImageMemory
even though that's not really what happened. This is because it's the closest error-code the spec allows for this function, so I think it's the best we can reasonably do.
If we really, really, really want to fix this properly, the fix would be to remove the LP_MAX_TEXTURE_SIZE
-limitation. That's not something I'm ready to take a stab at now, though.