-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
mipgen succeeds but OpenGlDriver::setCompressedTextureData() fails on assert #1966
Comments
The assert might have been only for ETC textures, I don't remember if ASTC has the same size constraints. |
Hmm even when the resolution is a multiple of 4 I'm running into this same issue:
I had a quick look at mipgen, and this might be related: filament/libs/image/src/ImageSampler.cpp Lines 357 to 358 in a4a1bf0
As quick test, I resized all my images to a multiple of 4 and made sure that the width and height were the same to make sure that it's not related to the resolution and/or alignment. After resizing it passes asserts in
Any ideas what might cause this? Update
|
Thanks for these bug reports, we like them, believe it or not. :) I think the Command-related SIGABRT is quite distinct from the texture compression problem, do you mind filing a separate bug for that? Might be useful to let us know how many objects you're drawing too. |
Just ran into a similar issue. Tested with both dxt5 and astc compression. How can I figure out what image is causing this issue, then I can share it.
|
See #2057 |
You're triggering an assert so it could be you're asking to use an unsupported compression format (astc on desktop?). |
I tested both astc and dxt5 and both triggered the same assert. |
Here are the assertions in that code path:
Could be an issue with the dimensions or offsets or mip levels you pass? |
I looked into this a bit more closely and I found two things that are maybe related to this issue. 1. Multiples of 4 When using DXT5 we are limited to image resolutions that are multiples of 4 or at least some compressors seem to be limited to this. The image that I was testing with has a resolution of 160x90. I used mipgen to compress with DXT5 and didn't see any error messages which might tell us that it's OK to use image resolutions which are not a multipe of 4. Maybe the image is resized internally. The output I got when using mipgen:
2. Mipmap Count The other thing that might cause this is because the getMipmapCount() will return the maximum mipmap that would be possible for either the width OR the height. In my case the maximum mipmap for the width is 7 and the height is 6 until we reach an image of 1x1 pix. I created this test case to log some info, see below. Output of the test: getMipmapCount, shifted height: 45, width: 80, count: 1.
getMipmapCount, shifted height: 22, width: 40, count: 2.
getMipmapCount, shifted height: 11, width: 20, count: 3.
getMipmapCount, shifted height: 5, width: 10, count: 4.
getMipmapCount, shifted height: 2, width: 5, count: 5.
getMipmapCount, shifted height: 1, width: 2, count: 6.
getMipmapCount, shifted height: 0, width: 1, count: 7.
texture_width: 160
texture_height: 90
height_shifted_level: 0
width_shifted_level: 1.
mipmap count: 7 Code used to produce the above output: #include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <algorithm>
/* -------------------------------------------------------------------------------------- */
/*
Copied `getMipmapCount()` and changed it a bit that allows us
to pass a width and height instead of a `LinearImage` so that
we can create this standalone test case.
Original version:
https://github.com/google/filament/blob/master/libs/image/src/ImageSampler.cpp#L351
*/
static uint32_t getMipmapCount(uint32_t width, uint32_t height);
/* -------------------------------------------------------------------------------------- */
int main(int argc, char* argv[]) {
printf("\nmipgen crash test\n");
/*
The asserts in OpenGLDriver.cpp, setCompressedTextureData() are:
assert(xoffset + width <= t->width >> level);
assert(yoffset + height <= t->height >> level);
assert(zoffset + depth <= t->depth);
assert(t->samples <= 1);
The one that fails is:
assert(yoffset + height <= t->height >> level);
When the values are:
yoffset = 0
height = 1
t->height = 90
level = 7
*/
uint32_t texture_width = 160;
uint32_t texture_height = 90;
uint32_t level = 7;
uint32_t height = 1;
uint32_t height_shifted_level = (texture_height >> level);
uint32_t width_shifted_level = (texture_width >> level);
uint32_t mipmap_count = getMipmapCount(texture_width, texture_height);
printf("texture_width: %u\n", texture_width);
printf("texture_height: %u\n", texture_height);
printf("height_shifted_level: %u\n", height_shifted_level);
printf("width_shifted_level: %u.\n", width_shifted_level);
printf("mipmap count: %u\n", mipmap_count);
printf("\n");
return 0;
}
/* -------------------------------------------------------------------------------------- */
static uint32_t getMipmapCount(uint32_t width, uint32_t height){
uint32_t count = 0;
while (width > 1 || height > 1) {
++count;
printf("getMipmapCount, shifted height: %u, width: %u, count: %u.\n", (height >> 1), (width >> 1), count);
width = std::max(width >> 1u, 1u);
height = std::max(height >> 1u, 1u);
}
return count;
}
/* -------------------------------------------------------------------------------------- */
|
I just resized all my assets so that both width and height fit into the same mipmap level. When I debug my app I'm not running into that assert anymore. |
@pixelflinger, @romainguy running into this issue again; can we remove the assert in question? See my comment above where I created a test app which shows that the check is wrong. I just ran into this when using an 512 x 2048 image. mipgen: $ mipgen --compress=s3tc_rgba_dxt5 img/trees-bark-diffuse.png
Generating miplevels...
Writing KTX file to disk...
Starting compression for trees-bark-diffuse.png (512x2048)
Starting compression for trees-bark-diffuse.png (256x1024)
Starting compression for trees-bark-diffuse.png (128x512)
Starting compression for trees-bark-diffuse.png (64x256)
Starting compression for trees-bark-diffuse.png (32x128)
Starting compression for trees-bark-diffuse.png (16x64)
Starting compression for trees-bark-diffuse.png (8x32)
Starting compression for trees-bark-diffuse.png (4x16)
Starting compression for trees-bark-diffuse.png (2x8)
Starting compression for trees-bark-diffuse.png (1x4)
Starting compression for trees-bark-diffuse.png (1x2)
Starting compression for trees-bark-diffuse.png (1x1) This fails: assert(xoffset + width <= t->width >> level);
// checks: assert(0 + 1 <= 512 >> 10) GDB values: this = 0x7fffe4395870
t = 0x7fffe8af9800
t->width = 512
level = 10
xoffset = 0
yoffset = 0
zoffset = 0
width = 1
height = 2
depth = 1 |
I think the assert() is wrong. Will get to it today. |
I'm using
mipgen
to generate .ktx files using--compress=astc_fast_ldr_4x4
and for certain sizes e.g. 446 x 602 the mipgen succeeds but when loading the image data usingOpenGDriver::setCompressedTextureData()
an assert is triggered:assert(xoffset + width <= t->width >> level);
.This is probably caused because the width and height aren't multiples of 4?
Would it make sense to trigger an error in mipgen when this occurs?
And what would be an approriate way to deal with this?
Output of mipgen:
Values in
OpenGLDriver::setCompressedTextureData()
The text was updated successfully, but these errors were encountered: