Как я могу использовать «сжатую текстуру» в openGL? - PullRequest
0 голосов
/ 27 февраля 2020

В нашем проекте мы загружаем так много изображений 4K одновременно. мы хотим сократить время загрузки, при котором текстура передается в графический процессор.

Мой графический процессор - GTX 1080 ti.

Я вижу, что использование сжатых текстур ускоряет загрузку.

Сначала я пытаюсь «AST C (адаптивное масштабируемое сжатие текстур)», сжатие с помощью «инструмента сжатия текстур Mali». я получаю «сжатый» файл. 1 ~ 2 МБ jpg файла (2048 * 2048 изображений) go до 456 КБ.

ниже - моя функция загрузчика.

  struct astc_header
{
    uint8_t magic[4];
    uint8_t blockdim_x;
    uint8_t blockdim_y;
    uint8_t blockdim_z;
    uint8_t xsize[3];           // x-size = xsize[0] + xsize[1] + xsize[2]
    uint8_t ysize[3];           // x-size, y-size and z-size are given in texels;
    uint8_t zsize[3];           // block count is inferred
};


int suppress_progress_counter = 0;
int perform_srgb_transform = 0;

#define MAGIC_FILE_CONSTANT 0x5CA1AB13

float load_astc_file(const char *filename)
{
    FILE *f = fopen(filename, "rb");
    if (!f)
    {
        printf("Failed to open file %s\n", filename);
        exit(1);
    }
    astc_header hdr;
    size_t hdr_bytes_read = fread(&hdr, 1, sizeof(astc_header), f);
    if (hdr_bytes_read != sizeof(astc_header))
    {
        fclose(f);
        printf("Failed to read file %s\n", filename);
        exit(1);
    }

    uint32_t magicval = hdr.magic[0] + 256 * (uint32_t)(hdr.magic[1]) + 65536 * (uint32_t)(hdr.magic[2]) + 16777216 * (uint32_t)(hdr.magic[3]);

    if (magicval != MAGIC_FILE_CONSTANT)
    {
        fclose(f);
        printf("File %s not recognized\n", filename);
        exit(1);
    }

    int xdim = hdr.blockdim_x;
    int ydim = hdr.blockdim_y;
    int zdim = hdr.blockdim_z;

    if (xdim < 3 || xdim > 12 || ydim < 3 || ydim > 12 || (zdim < 3 && zdim != 1) || zdim > 12)
    {
        fclose(f);
        printf("File %s not recognized %d %d %d\n", filename, xdim, ydim, zdim);
        exit(1);
    }

    int xsize = hdr.xsize[0] + 256 * hdr.xsize[1] + 65536 * hdr.xsize[2];
    int ysize = hdr.ysize[0] + 256 * hdr.ysize[1] + 65536 * hdr.ysize[2];
    int zsize = hdr.zsize[0] + 256 * hdr.zsize[1] + 65536 * hdr.zsize[2];

    int xblocks = (xsize + xdim - 1) / xdim;
    int yblocks = (ysize + ydim - 1) / ydim;
    int zblocks = (zsize + zdim - 1) / zdim;
    int size = xblocks * yblocks * zblocks * 16;
    uint8_t *buffer = (uint8_t *)malloc(size);
    if (!buffer)
    {
        fclose(f);
        printf("Ran out of memory\n");
        exit(1);
    }
    size_t bytes_to_read = xblocks * yblocks * zblocks * 16;
    size_t bytes_read = fread(buffer, 1, bytes_to_read, f);
    fclose(f);
    if (bytes_read != bytes_to_read)
    {
        printf("Failed to read file %s\n", filename);
        exit(1);
    }
    float compute_time;



    glFinish();
    CHECK_TIME_START;
    if (xdim == 12 && ydim == 12) {
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_ASTC_12x12_KHR, xsize, ysize, 0, size, buffer);
    }
    else if (xdim == 10 && ydim == 10) {
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_ASTC_10x10_KHR, xsize, ysize, 0, size, buffer);
    }
    else if (xdim == 8 && ydim == 8) {
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_ASTC_8x8_KHR, xsize, ysize, 0, size, buffer);
    }
    else if (xdim == 6 && ydim == 6) {
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_ASTC_6x6_KHR, xsize, ysize, 0, size, buffer);
    }
    else if (xdim == 5 && ydim == 5) {
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_ASTC_5x5_KHR, xsize, ysize, 0, size, buffer);
    }
    else if (xdim == 4 && ydim == 4) {
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_ASTC_4x4_KHR, xsize, ysize, 0, size, buffer);
    }
    glFinish();
    CHECK_TIME_END(compute_time);

    free(buffer);
    return compute_time;
}

к сожалению, она отлично работает, но время загрузки составляет 40 раз больше, чем просто загрузить файл JPG. jpg - 112 мс, ast c - 4124 мс ...

ниже - это часть функции загрузки jpg.

    glFinish();
    CHECK_TIME_START;
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);

    glFinish();
    CHECK_TIME_END(compute_time);

на некоторых страницах ast c быстрее, чем без сжатия образ. это не правильно? я думаю, что glCompressedTexImage2D медленнее, чем glTexImage2D. это правильно?

Далее я попробую ARB с этим документом. https://www.oldunreal.com/editing/s3tc/ARB_texture_compression.pdf

но он совершенно не работает .... сохраненный файл (сжатый файл) занимает всего 4 КБ. оригинал имеет размер 16 МБ ... конечно, не работает.

Я не могу описать пример или руководство по использованию сжатой текстуры. пожалуйста, помогите мне!

1 Ответ

1 голос
/ 04 марта 2020

Сжатая нагрузка должна быть заметно быстрее, а не значительно медленнее из-за гораздо меньшего объема данных, передаваемых в графический процессор.

Скорее всего, проблема заключается в том, что синхронизация указанного вызова c GL выдает ошибку , По какой-то причине водитель может блокировать / уступать. Попробуйте синхронизировать весь раздел загрузки только с изменением кода. Ваш объект буфера может означать, что в одном случае есть некоторая синхронизация в другом?

Другая возможная проблема заключается в том, есть ли какая-либо функция преобразования формата / другая активная функция, которая вызывает его распаковку. Так что проверьте, выполняет ли он также автоматическую генерацию mipmap или переключает координаты из верхнего левого в нижний левый [0,0], или какую-либо опцию качества в вашем драйвере (убедитесь, что все отключено / управляется приложением в вашем контроле NVidia панель).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...