sasamy 0 Posted Monday at 03:52 PM (edited) · Report post On 6/27/2022 at 1:44 PM, repstosw said: А что по адресу 0x7010000 хранится? судя по DTS диапазон адресов 0x07010000 - 0x07010240 относится к одному из блоков управления тактированием https://github.com/Tina-Linux/tina-t113-linux-5.4/blob/150c69d4f2b0886db269cc7883f007e2cdcd839c/arch/arm/boot/dts/sun8iw20p1.dtsi#L419 Quote r_ccu: [email protected] { compatible = "allwinner,sun8iw20-r-ccu"; reg = <0x0 0x07010000 0x0 0x240>; clocks = <&dcxo24M>, <&rtc_ccu CLK_OSC32K>, <&rtc_ccu CLK_IOSC>, <&ccu CLK_PLL_PERIPH0>; clock-names = "hosc", "losc", "iosc", "pll-periph0"; #clock-cells = <1>; #reset-cells = <1>; }; драйвер тут https://github.com/Tina-Linux/tina-t113-linux-5.4/blob/150c69d4f2b0886db269cc7883f007e2cdcd839c/drivers/clk/sunxi-ng/ccu-sun8iw20-r.c#L131 Edited Monday at 04:24 PM by sasamy Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
repstosw 0 Posted 16 hours ago (edited) · Report post Успешно запустил G2D. Проверил на отрисовке прямоугольников и BitBlt. Над прозрачностью и порядком отрисовки пришлось поломать голову, но сделал. На картинке - Blt с учётом альфы. Цветовое представление: ARGB. Прикрутил декодер PNG-файлов. (по краям изображение хорошо сглаживается). Есть некоторые моменты: 1) GD2 не может одновременно использовать Mixer и Rotator. Либо смешиваем, либо поворачиваем 2) Отсутствует отсечение: если изображение выходит за пределы рабочей области - повисает 3) Критичны размеры. Например, прямоугольник размером 1x1 пиксель он не выведет. Минимальный - 2x1 пиксел Edited 15 hours ago by repstosw Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
mantech 1 Posted 16 hours ago (edited) · Report post В 28.06.2022 в 14:10, repstosw сказал: Например, прямоугольник размером 1x1 пиксель он не выведет. Больше интересует производительность, сколько по времени рисует закрашенный квадрат во весь экран НЕОНом и этим g2d? В 28.06.2022 в 14:10, repstosw сказал: если изображение выходит за пределы рабочей области - повисает Эт как-то не радует, конечно.. Виснет ускоритель или вся система? Edited 16 hours ago by mantech Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
repstosw 0 Posted 15 hours ago (edited) · Report post On 6/28/2022 at 9:23 PM, mantech said: Больше интересует производительность, сколько по времени рисует закрашенный квадрат во весь экран НЕОНом и этим g2d? Скоро об этом напишу. Какой клок ставить ускорителю? По поводу производительности - даже если будет одинаково или чуть-медленее - не смертельно. Главное, что параллельно. CPU может делать другие вещи, в то время когда G2D рисует. Заложить буферизацию. Ну например - время отрисовки CPU 10 мкс, а время отрисовки G2D - 15 мкс, время процессора на выполнение остального кода - 10 мкс. Здесь CPU шустрее рисует в 1,5 раза. Но один он всё сделает за: 10 + 10 = 20 мкс А вместе с GPU на всё уйдёт MAX(15, 10) =15 мкс В этом примере выигрыш в производительности 20/15 = 1,333 (на 30% что неплохо) On 6/28/2022 at 9:23 PM, mantech said: Эт как-то не радует, конечно.. Виснет ускоритель или вся система? Скорее всего ускоритель. У меня пока программный поллинг (опрос занятости ускорителя перед отрисовкой следующего элемента). Уточню позже. Edited 15 hours ago by repstosw Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
mantech 1 Posted 15 hours ago (edited) · Report post В 28.06.2022 в 14:36, repstosw сказал: даже если будет одинаково или чуть-медленее - не смертельно. Главное, что параллельно. CPU может делать другие вещи, в то время когда G2D рисует. Заложить буферизацию. В моем случае это не имеет значения, т.к. надо нарисовать кучу квадратов, затем текст и только потом переключится на другое дело - один фиг ждать надо завершения, но использование подобных корок накладывает ограничения на переносимость, НЕОН-то во всех армах есть, а вот g2d только в Т113, в v3s, например его нет, так что перенести не получится, и если скорость примерно одинаковая, то смысла большого не вижу,ИМХО... ЗЫ. Кстати, хотел спросить, как вы делаете синхронизацию рисования картинок или прямоугольников с обновлением экрана. Допустим, частота 50Гц, и вам надо нарисовать картинку, ждете прерывания окончания очередного обновления экрана и начинаете рисовать? А если оно уже началось, то надо снова 1\50 сек ждать? Долго ведь получается... Или это только для крупных фигур, а мелкие можно рисовать в любое время? Edited 14 hours ago by mantech Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
repstosw 0 Posted 13 hours ago (edited) · Report post On 6/28/2022 at 10:25 PM, mantech said: ЗЫ. Кстати, хотел спросить, как вы делаете синхронизацию рисования картинок или прямоугольников с обновлением экрана. Допустим, частота 50Гц, и вам надо нарисовать картинку, ждете прерывания окончания очередного обновления экрана и начинаете рисовать? А если оно уже началось, то надо снова 1\50 сек ждать? Долго ведь получается... Или это только для крупных фигур, а мелкие можно рисовать в любое время? Я рисую в заднем буфере. Когда всё отрисовано - скидываю весь буфер на экран. В этом случае синхронизация с экраном нужна только 1 раз - когда скидываю буфер целиком на экран. Синхронизация самая простая - опрос регистра LCD_GINT0_REG и сброс ему бита: void VSync(void) { LCD_GINT0_REG&=~(1<<15); //clear LCD_VB_INT_FLAG while(!(LCD_GINT0_REG&(1<<15))); //wait LCD_VB_INT_FLAG } Перед этим, нужно разрешить VB: LCD_GINT0_REG|=(1<<31); //Enable the Vertical Blank interrupt Можно также через прерывание TCON . Оба способа работают. Но так как на прерывании у меня обновление DMA для звука, то использую опрос VSync() перед отправкой данных на экран. Всё очень плавно и гладко движется. Причем даже сбрасывать с кеша не нужно. Экранная память буферизована, но не кеширована, также бит 12 (TEX) установлен. Память заднего буфера - обычная: кеширована и буферизована. Это режим с наибольшей производительностью, когда задний буфер надо и читать и писать процессором. А экранная память только читается TCON/DE, и пересылка NEON'ом (запись) 1 раз. У C6745 есть PRU, там можно этот VSync заставить ждать сопроцессором, основной CPU идёт дальше... Возвращаясь к G2D: он работает на любом участке DDR: для каждой картинки можно назначить свой адрес источника, или сделать один общий атлас картинок в памяти, а потом вырезать нужную и показывать. G2D это всё может! Edited 13 hours ago by repstosw Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
GenaSPB 0 Posted 12 hours ago · Report post Я попытался сделать: В dbuff ставится младший бит и ждем пока снимется. Но судя по иногда промаргивающему изображению, это не то... write32((uintptr_t) & glb->dbuff, 0x01uL); // 1: register value be ready for update (self-cleaning bit) while ((read32((uintptr_t) & glb->dbuff) & 0x01uL) != 0) ; // Allwinner_DE2.0_Spec_V1.0 // 5.10.3.4 Blender // GLB struct de_glb_t { uint32_t ctl; /** Offset 0x000 Global control register */ uint32_t status; /** Offset 0x004 Global status register */ uint32_t dbuff; /** Offset 0x008 Global double buffer control register */ uint32_t size; /** Offset 0x00C Global size register */ }; Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
mantech 1 Posted 11 hours ago (edited) · Report post В 28.06.2022 в 16:52, repstosw сказал: Когда всё отрисовано - скидываю весь буфер на экран. В смысле? Копируете весь теневой буфер в экранный или перекидываете адреса DE с активной экранной области на теневую во время обратного хода? ЗЫ. Хотя, если теневая область закэширована, то походу только копирование... Edited 11 hours ago by mantech Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
GenaSPB 0 Posted 10 hours ago · Report post On 6/28/2022 at 5:59 PM, GenaSPB said: В dbuff ставится младший бит и ждем пока снимется. Это как раз надеюсь на синхронизацию с vsync Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
GenaSPB 0 Posted 10 hours ago (edited) · Report post оставил своё и добавил ваше - помогло. Но вообще где-то должен быть способ по настоящему синхронизироваться, не в ручную ловить момент. Т.е. как в STM32 LTDC и Renessas VD5: выставил в регистр новый адрес страницы, дождался когда дисплей на него перейдет - и все, поехал заполнять старый буфер. Edited 10 hours ago by GenaSPB Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
repstosw 0 Posted 3 hours ago (edited) · Report post On 6/29/2022 at 12:59 AM, GenaSPB said: Я попытался сделать: В dbuff ставится младший бит и ждем пока снимется. Но судя по иногда промаргивающему изображению, это не то... Рисовалки типа G2D и DE отставить... Тут только TCON, без вариантов. Обновлять изображение нужно в те моменты, когда TCON не сканирует память. Иначе артефакты на экране будут визуально ощутимы. О вкусах не спорят: Double Buffering vs. Page Flipping : https://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html Для моих целей (игры) более подходит двойная буферизация, чем переключение страниц. Потому что не всегда надо перерисовывать всё полностью. Перед переключением страницы тоже нужно ждать VSync: void DE_SwitchBuffer(u8 channel,u8 buffer) //channel = 0,1,2 ; buffer = 0,1 { int j; switch(channel) { case 0: //CH0 for(j=0;j<3;j++)writel(buffer?CH0_BUFFER1:CH0_BUFFER0,&de_vi_regs0->cfg[0].top_laddr[j]); //CH0 LAYMB_LADD break; case 1: //CH1 for(j=0;j<3;j++)writel(buffer?CH1_BUFFER1:CH1_BUFFER0,&de_vi_regs1->cfg[0].top_laddr[j]); //CH1 LAYMB_LADD break; case 2: //CH2 writel(buffer?CH2_BUFFER1:CH2_BUFFER0,&de_ui_regs->cfg[0].top_laddr); //CH2 LAYMB_LADD break; } } void DE_ComposerApply(void) { writel(1,&de_glb_regs->dbuff); //composer enable } void main(void) { //... u8 page=0; while(1) { //... VSync(); DE_SwitchBuffer(0,page); DE_ComposerApply(); page^=1; Draw_Scene(page); //... } //... } On 6/29/2022 at 3:08 AM, GenaSPB said: оставил своё и добавил ваше - помогло. Но вообще где-то должен быть способ по настоящему синхронизироваться, не в ручную ловить момент. Разрешить прерывание от TCON. В обработчике переключать страницу. Чтобы вручную не ловить момент - можно задействовать второе ядро у T113-s3 или его HiFi-DSP. И сделать отложенную отрисовку на экран: дать команду сопроцессору, а тот будет ждать VSync, а main CPU пойдёт дальше. Я так делал на C6745, у него есть пара сопроцессоров, как раз один из них рисовал на экран и ждал VSync. Ну или чисто софт-вариант: потоки (threads). Создать поток и в нём проверять. Edited 3 hours ago by repstosw Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...
repstosw 0 Posted 2 hours ago · Report post On 6/28/2022 at 10:25 PM, mantech said: Допустим, частота 50Гц, и вам надо нарисовать картинку, ждете прерывания окончания очередного обновления экрана и начинаете рисовать? А если оно уже началось, то надо снова 1\50 сек ждать? Долго ведь получается... Не долго. 50 Гц это 20 мс. За эти 20 мс процессор может горы свернуть. Не уверен, что оставшаяся часть вашей программы займёт больше времени. Долго может быть только первая итерация цикла. Затем система входит в синхрон и на эти 20 мс успевает ещё не только выполнить код, но и дождаться следующего VSync. Но если вдруг 20 мс не хватит, тогда да, очередной VSync будет пропущен и придётся ждать следующего. В этом случае уже будет не 50 FPS, а в 2 раза меньше. А если программа требует более 40 мс, то уже 2 VSync будут пропущены. FPS тут просядет уже в 3 раза... Это в любом учебнике по игрострою расписано. Quote Ответить с цитированием Share this post Link to post Share on other sites More sharing options...