repstosw 18 12 февраля Опубликовано 12 февраля (изменено) · Жалоба 2 hours ago, mantech said: Данные могут приходить от программного PNG декодера, поэтому сброс кэша нужен, и выходной поток тоже может быть использован в постобработке. В таком случае, использую инвалидацию кеша, когда процессор использует данные от декодера. И сброс с кеша, когда процессор готовит данные для энкодера. 2 hours ago, mantech said: Вот тут чет затупил, что это такое? first_dimension - это ширина источника, или что? Или это высота*ширину источника? Длина и ширина источника. 2 hours ago, mantech said: Вот здесь, я так понял, что нужно поставить G2D_FMT_ABGR_AVUY8888, т.к. плоскость RGB ? Да. Константа с нужным порядком следования компонент RGB. 2 hours ago, mantech said: Тут как понимаю 2 адреса из-за плоскости Y\C в RGB нужен только первый? Да. Для RGB нужен только с индексом [0]. остальные не нужны. 2 hours ago, mantech said: Ну и вот тут бы пояснительную бригаду))) Это координаты левого верхнего угла вывода изображения в финальном видеобуфере. Изменено 12 февраля пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 12 февраля Опубликовано 12 февраля (изменено) · Жалоба Собственно инициализация блока для поворота вот так (в этом тексте поворот на 0 градусов - используется как копирование) /* Коприрование с применением блока G2D_ROT */ static void hwaccel_rotcopy( uintptr_t saddr, unsigned sstride, uint_fast32_t ssizehw, uintptr_t taddr, unsigned tstride, uint_fast32_t tsizehw ) { ASSERT((G2D_ROT->ROT_CTL & (UINT32_C(1) << 31)) == 0); G2D_ROT->ROT_CTL = 0; G2D_ROT->ROT_IFMT = VI_ImageFormat; G2D_ROT->ROT_ISIZE = ssizehw; G2D_ROT->ROT_IPITCH0 = sstride; // G2D_ROT->ROT_IPITCH1 = sstride; // G2D_ROT->ROT_IPITCH2 = sstride; G2D_ROT->ROT_ILADD0 = ptr_lo32(saddr); G2D_ROT->ROT_IHADD0 = ptr_hi32(saddr) & 0xff; // G2D_ROT->ROT_ILADD1 = ptr_lo32(saddr); // G2D_ROT->ROT_IHADD1 = ptr_hi32(saddr) & 0xff; // G2D_ROT->ROT_ILADD2 = ptr_lo32(saddr); // G2D_ROT->ROT_IHADD2 = ptr_hi32(saddr) & 0xff; G2D_ROT->ROT_OPITCH0 = tstride; // G2D_ROT->ROT_OPITCH1 = tstride; // G2D_ROT->ROT_OPITCH2 = tstride; G2D_ROT->ROT_OSIZE = tsizehw; G2D_ROT->ROT_OLADD0 = ptr_lo32(taddr); G2D_ROT->ROT_OHADD0 = ptr_hi32(taddr) & 0xff; // G2D_ROT->ROT_OLADD1 = ptr_lo32(taddr); // G2D_ROT->ROT_OHADD1 = ptr_hi32(taddr) & 0xff; // G2D_ROT->ROT_OLADD2 = ptr_lo32(taddr); // G2D_ROT->ROT_OHADD2 = ptr_hi32(taddr) & 0xff; //G2D_ROT->ROT_CTL |= (UINT32_C(1) << 7); // flip horisontal //G2D_ROT->ROT_CTL |= (UINT32_C(1) << 6); // flip vertical //G2D_ROT->ROT_CTL |= (UINT32_C(1) << 4); // rotate (0: 0deg, 1: 90deg, 2: 180deg, 3: 270deg) G2D_ROT->ROT_CTL |= (UINT32_C(1) << 0); // ENABLE awxx_g2d_rot_startandwait(); /* Запускаем и ждём завершения обработки */ } Остальные функции можно у меня в репо посмотреть. stride - шаг строк в памяти в байтах. const unsigned tstride = GXADJ(tdx) * PIXEL_SIZE; const unsigned sstride = GXADJ(sdx) * PIXEL_SIZE; const uintptr_t taddr = (uintptr_t) dst; const uintptr_t saddr = (uintptr_t) src; const uint_fast32_t ssizehw = ((sh - 1) << 16) | ((sw - 1) << 0); const uint_fast32_t tsizehw = ((sh - 1) << 16) | ((sw - 1) << 0); /* размер совпадающий с источником - просто для удобства */ Изменено 12 февраля пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 49 12 февраля Опубликовано 12 февраля · Жалоба 1 час назад, GenaSPB сказал: Собственно инициализация Всем спасибо, буду разбираться. Кстати, этот g2d может ресайзинг делать из меньшей в большую и наоборот? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 12 февраля Опубликовано 12 февраля (изменено) · Жалоба Да, умеет. В том числе и с color key. Смотреть у меня - https://github.com/ua1arn/hftrx/blob/develop/src/display/framebuf.c исходники теста искать по словам Hello! Изменено 12 февраля пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 49 13 февраля Опубликовано 13 февраля (изменено) · Жалоба 22 часа назад, GenaSPB сказал: Да, умеет. Чет не едет этот поворот, может он вообще только квадратные объекты поворачивает? Сделал так: int G2D_ImageRotate(uint32_t *img_src,uint32_t *img_dest,uint16_t *width,uint16_t *height) { g2d_blt G2D_Rot; uint32_t w=width; uint32_t h=height; G2D_Rot.flag=G2D_BLT_ROTATE270; G2D_Rot.src_image.w=w;//Длина и ширина источника. G2D_Rot.src_image.h=h; G2D_Rot.src_rect.w=w; G2D_Rot.src_rect.h=h; G2D_Rot.src_image.format=G2D_FMT_ABGR_AVUY8888; G2D_Rot.src_image.pixel_seq=G2D_SEQ_NORMAL; G2D_Rot.src_image.addr[0]=(u32)(TMPIMG_BASE); //Y G2D_Rot.src_image.addr[1]=0; //UV G2D_Rot.src_rect.x=0; G2D_Rot.src_rect.y=0; G2D_Rot.dst_image.addr[0]=(u32)(SAVEFG_BASE); //Y G2D_Rot.dst_image.addr[1]=0; //UV G2D_Rot.dst_image.w=w; G2D_Rot.dst_image.h=h; G2D_Rot.dst_image.format=G2D_FMT_ABGR_AVUY8888; G2D_Rot.dst_image.pixel_seq=G2D_SEQ_NORMAL; G2D_Rot.dst_x=0;//координаты левого верхнего угла вывода изображения в финальном видеобуфере. G2D_Rot.dst_y=0; G2D_Rot.color=0x000000; G2D_Rot.alpha=0xFF; g2d_blit(&G2D_Rot); cache_flush_range((uint32_t)SAVEFG_BASE ,(uint32_t)(SAVEFG_BASE+0x800000)); //инвалидация кеша - декодер записал в память *width=h; *height=w; } Нужно просто заменить софтовый аналог: void ImageRotate(uint32_t *img_src,uint32_t *img_dest,uint16_t *width,uint16_t *height) { uint16_t i=0,q; uint32_t w; uint16_t lenx=*width; uint16_t leny=*height; uint32_t *src=(u32)(TMPIMG_BASE);//img_src; uint32_t *dests=(u32)SAVEFG_BASE;//img_dest; uint32_t *dest=dests; while (i<leny) { q=0; w=leny*(lenx-1); while (q<lenx) { q++;dest=dests+w;w=w-leny;*dest=*src; src++; } i++;dests=img_dest+i; } *width=leny; *height=lenx; } Жалко нет аналога на НЕОНе, каждый раз мозги выпаривать с этими корками... Задача просто повернуть на 270 картинку с исходным разрешением 1080х1920 в вид 1920х1080. Изменено 13 февраля пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 13 февраля Опубликовано 13 февраля (изменено) · Жалоба Масштабирование это отдельная операция, поворот отдельная. 35 minutes ago, mantech said: 1080х1920 в вид 1920х1080 Это к ROT cache_flush_range - а зачем ПОСЛЕ работы аппаратуры? Изменено 13 февраля пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 49 13 февраля Опубликовано 13 февраля (изменено) · Жалоба 2 часа назад, GenaSPB сказал: cache_flush_range - а зачем ПОСЛЕ работы аппаратуры? Пока проверяю НЕОНовским копировщиком в экранную область 2 часа назад, GenaSPB сказал: Это к ROT Вы проверяли как поворачивается прямоугольник размером с весь экран? Если да, можете привести значения для вашего разрешения экрана для этих параметров? И какой режим экрана используете, у меня ABGR8888 sstride, ssizehw, tstride, tsizehw Единственное, чего я добился - это поворот квадратной области 1080х1080, полный прямоугольник не хочет ни в какую... Изменено 13 февраля пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vasilius 1 13 февраля Опубликовано 13 февраля · Жалоба Кому инетерсно как запустить DSP с имиджа Xtensa в линкере выделяем память - я выделил последние 4М для ДСП __DSP_BASE = 0x47C00000; __DSP_SIZE = 4M; /* Step 1M */ __RAM_SIZE = 128M - __DSP_SIZE; MEMORY { RAM (rwx) : ORIGIN = 0x40000000, LENGTH = __RAM_SIZE DSP (rwx) : ORIGIN = __DSP_BASE, LENGTH = __DSP_SIZE } настраиваем MMU для этого региона MMU_TTSection((uint32_t*)tbbArea, __dsp_base, sizeDSP, Sect_Device_RW); собираем приложение для дсп, там настраиваем LSP для нашего региона MEMORY { iram0_0_seg : org = 0x00400000, len = 0x660 iram0_1_seg : org = 0x00400660, len = 0x9A0 iram0_2_seg : org = 0x00401000, len = 0x17C iram0_3_seg : org = 0x0040117C, len = 0x20 iram0_4_seg : org = 0x0040119C, len = 0x20 iram0_5_seg : org = 0x004011BC, len = 0x20 iram0_6_seg : org = 0x004011DC, len = 0x20 iram0_7_seg : org = 0x004011FC, len = 0x20 iram0_8_seg : org = 0x0040121C, len = 0x20 iram0_9_seg : org = 0x0040123C, len = 0xEDC4 dram0_0_seg : org = 0x00420000, len = 0x8000 dram1_0_seg : org = 0x00440000, len = 0x8000 ddr1_0_seg : org = 0x37C00000, len = 0x400000 } настраиваем _cache_config(); в board_init(); собираем получаем ELF. Бинарник в голом виде там не получится, поэтому с эльфа надо данные выдирать самим ельф можно потрошить с сдк линукса : там в драйверах есть файл dsp.c, так как у меня нет задачи запускать имидж с линукса я oemhead не добавлялю... я написал свою выдиралку, она дает хидер в таком виде прямо с эльфа #ifndef DSPIMAGE_H #define DSPIMAGE_H typedef struct { unsigned int RAM; unsigned int Offset; unsigned int Length; } dspImgMapStruct; const unsigned char dspImgData[] = { ....... }; const unsigned int dspImageBlocksCount = 11; const unsigned int dspImageDataLength = 4680; const unsigned int dspEntryPoint = 0x00400660; const dspImgMapStruct dspImgMap[11] = { {0x00400660, 0x00000000, 0x0000016C}, ... }; #endif В итоге данные хранятся как RO в прошивке, занимают минимум места. После этого запускается это все красиво таким образом #include "dsp.h" #include "dspImg.h" void DSP_LoadImage(void) { for(int i = 0; i < dspImageBlocksCount; i++) { memcpy((uint8_t*)dspImgMap[i].RAM, &dspImgData[dspImgMap[i].Offset], dspImgMap[i].Length); } } void DSP_Setup(void) { CCU_SetDSP(CCU_DSP_SRC_PERI2X, 1); BIT_SET(SYS_CFG->DSP_BOOT_RAMMAP_REG, BIT_SRAM_REMAP_ENABLE); BIT_CLEAR(CCU->DSP_BGR_REG, BIT_DSP0_RST); // DSP Reset Assert DSP0_CFG->DSP_ALT_RESET_VEC_REG = dspEntryPoint; BIT_SET(DSP0_CFG->DSP_CTRL_REG0, BIT_START_VEC_SEL); BIT_SET(DSP0_CFG->DSP_CTRL_REG0, BIT_RUN_STALL); BIT_SET(DSP0_CFG->DSP_CTRL_REG0, BIT_DSP_CLKEN); BIT_SET(CCU->DSP_BGR_REG, BIT_DSP0_RST); // DSP Reset De-assert DSP_LoadImage(); BIT_CLEAR(SYS_CFG->DSP_BOOT_RAMMAP_REG, BIT_SRAM_REMAP_ENABLE); BIT_CLEAR(DSP0_CFG->DSP_CTRL_REG0, BIT_RUN_STALL); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 13 февраля Опубликовано 13 февраля · Жалоба А попробуйтье указать у выходного прямоунольника ражмеры оиличающиеся от входного? В моем же случае прворота нет. И stride чскорее всего другой Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 49 13 февраля Опубликовано 13 февраля (изменено) · Жалоба 7 минут назад, GenaSPB сказал: А попробуйтье указать у выходного прямоунольника ражмеры оиличающиеся от входного? Пробовал, все полосит и вообще мусор не экране, иногда в хардфаулт вылетает, видимо лезет за пределы экранного буфера. 7 минут назад, GenaSPB сказал: В моем же случае прворота нет. И не проверяли его вообще? ЗЫ. У вас случаем НЕОНовского варианта ротатора нет, чет в инете на эту тему совсем тускло... Нашел только на 90град и однобайтовая матрица. Изменено 13 февраля пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 13 февраля Опубликовано 13 февраля (изменено) · Жалоба 8 minutes ago, mantech said: хардфаулт вылетает, видимо лезет за пределы экранного буфера. Ну это точно пепепутали со stridе. Осоьенно полосит. При возмлжгости на днях поворот пррверю. Зы: буферы не перекрываются у вас? Изменено 13 февраля пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vasilius 1 13 февраля Опубликовано 13 февраля (изменено) · Жалоба 12 минут назад, mantech сказал: ЗЫ. У вас случаем НЕОНовского варианта ротатора нет, чет в инете на эту тему совсем тускло... https://www.linkedin.com/pulse/using-simd-arm-neon-speed-up-applications-salvatore-c-chieppa https://stackoverflow.com/questions/11259596/128-bit-rotation-using-arm-neon-intrinsics Изменено 13 февраля пользователем vasilius Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 49 13 февраля Опубликовано 13 февраля · Жалоба 8 минут назад, GenaSPB сказал: буферы не перекрываются у вас? Нет, источник и получатель разные буферы по 8 мбайт, выровненные по 0х1000 5 минут назад, vasilius сказал: https://stackoverflow.com/questions/11259596/128-bit-rotation-using-arm-neon-intrinsics первую не могу открыть, надо снова впн ставить, а во воторой что там делается, не понял, там походу в пределах вектора что-то вращают... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vasilius 1 13 февраля Опубликовано 13 февраля · Жалоба 18 минут назад, mantech сказал: первую не могу открыть, надо снова впн ставить, а во воторой что там делается, не понял, там походу в пределах вектора что-то вращают... Using SIMD ARM NEON to speed up applications.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 13 февраля Опубликовано 13 февраля (изменено) · Жалоба 8 hours ago, mantech said: разные буферы по 8 мбайт, выровненные по 0х1000 то что я говорил - stride - шаг строк - разное? Хотя не обязано... в вашем случае хоть по восемь килобайт на строку h & w - разное? Изменено 13 февраля пользователем GenaSPB Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться