denebopetukius 0 8 апреля, 2009 Опубликовано 8 апреля, 2009 (изменено) · Жалоба к BF532 на EBIU (банк 0) подсоединён TFT LCD шина 16 бит в SDRAM есть буфер 512x512 точек. Одна точка - байт (индекс палитры) в той же SDRAM есть массив палитры из 256 цветов (индекс палитры из буфера - номер цвета) часть буфера 512x512 надо отрисовать в дисплей прямоугольником 320x240 код: #pragma align 64 u8 BUFFER[512*512]; //байт - индекс цвета #pragma align 64 u16 PALETTE[256]; //слово - код цвета отправляемый в LCD в формате 5:6:5 (номер ячейки - код цвета(cодержимое BUFFER)) #define Pixel4 \ o=*(u32*)B; \ TFT_Data=PALETTE[ o &0xFF]; \ TFT_Data=PALETTE[(o>> 8)&0xFF]; \ TFT_Data=PALETTE[(o>>16)&0xFF]; \ TFT_Data=PALETTE[(o>>24) ]; \ B+=4; void update_video(void) { int width =320; int height =240; u8* B=(u8*)(BUFFER+0x20); register u32 x,y,o,o0=width>>6,o1=(512-width); for(y=0;y<height;y++) { for(x=0;x<o0;x++) { Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 Pixel4 } B+=o1; } } В асм-листинге это даёт(для одного Pixel4): // line 223 R1 = [P1++]; R0 = R1.b (Z); P5 = R0; R0 = R1 >> 8; R0 = R0.b (Z); P4 = R0; R0 = R1 >> 16; R0 = R0.b (Z); P3 = R0; R0 = R1 >> 24; P5 = P2 + (P5<<1); [SP + 60] = R0; R0.L = W[P5]; W[P0] = R0.L; // Use of volatile in loops precludes optimizations. P5 = P2 + (P4<<1); R0.L = W[P5]; W[P0] = R0.L; // Use of volatile in loops precludes optimizations. P5 = P2 + (P3<<1); R0.L = W[P5]; W[P0] = R0.L; // Use of volatile in loops precludes optimizations. P5 = [SP + 60]; // -- 3 stalls -- P5 = P2 + (P5<<1); R0.L = W[P5]; W[P0] = R0.L; // Use of volatile in loops precludes optimizations. DMA имхо тут не прокатит, так как на дисплей идет не содержимое буфера (i), а палитра PALETTE вопрос, можно ли быстрее сделать отрисовку на экран? Изменено 8 апреля, 2009 пользователем denebopetukius Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Itch 0 8 апреля, 2009 Опубликовано 8 апреля, 2009 · Жалоба Как минимум перенести u16 PALETTE[256] в SRAM. Опять же читать и писать в SDRAM лучше не по байтовому указателю 2 раза по байту, а один раз по слову. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
denebopetukius 0 8 апреля, 2009 Опубликовано 8 апреля, 2009 (изменено) · Жалоба Как минимум перенести u16 PALETTE[256] в SRAM. Опять же читать и писать в SDRAM лучше не по байтовому указателю 2 раза по байту, а один раз по слову. у меня кэш данных включен на 32 кб ( A+B ) а скрэтчпад для стека в итоге внутреней срамы нет уже. может что-нибуть выкинуть надо? например стек в SDRAM перенести? а в скрэтчпад PALETTE толкнуть... в том куске кода который я дал - идет чтение по 4 байта - далее индексы идут на палитру подскажите что не так? возможно я вас не понял. если можно то псевдокодом... может в кешируемых страницах надо поменять? у меня биты PLB_DIRTY и CPLB_LOCK установлены во всех страницах памяти write-back включен для секции переменных и кода а образ игры работает на чтение с write-throug кэшем дисплей не кеширован кстати, можно как-нибудь буферизовать дисплей? (как это в АРМ9 делалось) Изменено 8 апреля, 2009 пользователем denebopetukius Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
boombox 0 8 апреля, 2009 Опубликовано 8 апреля, 2009 (изменено) · Жалоба Очень жаль, что TFT не подключен к PPI. Было бы просче. А так можно поробовть сделать два видеобуффера. В один буффер пишет процессор уже подготовленные данные с учётом палитры, из второго DMA кидает данные на TFT, затем меняются местами. Качели так сказать. А можно поставить BF533 в таком же корпусе. Всё отличие это дополнительно два DATASRAM по 16k без возможности задания как кэш. Тогда все буфера влезут во внутреннюю память SRAM. Цена чуть больше. У нас примерно на 3$ Изменено 8 апреля, 2009 пользователем boom Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vik0 0 8 апреля, 2009 Опубликовано 8 апреля, 2009 · Жалоба может что-нибуть выкинуть надо? например стек в SDRAM перенести? а в скрэтчпад PALETTE толкнуть... Урежьте стек до 3.5К, и разместите PALETTE в скрэтчпаде или разместите PALETTE и BUFFER в разных банках SDRAM и сделайте банк с PALETTE некешируемым Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
boombox 0 8 апреля, 2009 Опубликовано 8 апреля, 2009 (изменено) · Жалоба Основные потери производительности происходят именно из-за приведения буфера к палитре, так вот ставить его в другой банк SDRAM наверно не совсем поможет. Лучше действительно использовать 1 вариант с уменьщением стека или отключить один банк кэш и сделать его SRAM и разместить там палитру и какие нибудь ещё данные. Также попробовать с тем что есть. Оптимизитровать количество обращений к памяти например, защёт увеличения разрадности обращения. Наверно лучше так #define Pixel4 \ o=*(u32*)B; \ (u32*)TFT_Data=((PALETTE[ o &0xFF]) | (PALETTE[(o>> 8)&0xFF] << 16)); \ (u32*)TFT_Data=((PALETTE[ (o>>16)&0xFF]) | (PALETTE[(o>> 24)&0xFF] << 16)); \ B+=4; что сократит количество обращений при записи в TFT_Data в два раза. а также сделать u32 PALETTE[65536]; o=*(u32*)B; \ (u32*)TFT_Data=(PALETTE[ o &0xFFFF]); \ (u32*)TFT_Data=(PALETTE[ (o>>16)&0xFFFF]); \ B+=4; что ещё уменьшит количество обращений к памяти PALETTE, но увеличит размер таблицы. Код сделан исходя из того, что (моё предположение) шина TFT 16 бит и TFT_Data это адрес асинхронной памяти к которому привязан дисплей. Зависит от того как подключен TFT, если ему существенны изменения адреса, то такой вариант не прокатит, т.к. A1 = 0 при записи младшей части 32 битного слова, а А1 = 1 при записи старшей части. Если же Адрес А1 не существенен, то такой код должен работать, проверял ). Изменено 8 апреля, 2009 пользователем boom Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
boombox 0 8 апреля, 2009 Опубликовано 8 апреля, 2009 (изменено) · Жалоба Исходя из описания на DT, которое я скачал с сайта автора, приведённый мной код должен работать, т.к. порт комманд и данных TFT лежит далеко друг от друга и адрес А1 не внесёт никакого влияния. Изменено 8 апреля, 2009 пользователем boom Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vik0 0 8 апреля, 2009 Опубликовано 8 апреля, 2009 · Жалоба Основные потери производительности происходят именно из-за приведения буфера к палитре, так вот ставить его в другой банк SDRAM наверно не совсем поможет. Лучше действительно использовать 1 вариант с уменьщением стека или отключить один банк кэш и сделать его SRAM и разместить там палитру и какие нибудь ещё данные. Первый вариант безусловно лучше. Но и второй должен дать прирост производительности - как минимум, за счет экономии на постоянном activate/precharge (и связанной с этим латентностью). Палитра ведь как раз помещается в одну строку SDRAM. denebopetukius, для второго варианта также необходимо выравнять палитру по 512-байтовой границе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
denebopetukius 0 8 апреля, 2009 Опубликовано 8 апреля, 2009 (изменено) · Жалоба Очень жаль, что TFT не подключен к PPI. Было бы просче. спорный вопрос. поставив дисплей на PPI, мы лишимся FIO (практически всех, ибо шина 16 бит) а они нужны на Joystick и чипселекты SPI-устройств мультиплексоры городить не хотелось бы. да и не факт что быстрее было бы. Тем более отвлекаться через каждые 50/60 Гц в моем случае отрисовка идет в произвольные моменты времени, что иногда очень выгодно Наверно лучше так #define Pixel4 \ o=*(u32*)B; \ (u32*)TFT_Data=((PALETTE[ o &0xFF]) | (PALETTE[(o>> 8)&0xFF] << 16)); \ (u32*)TFT_Data=((PALETTE[ (o>>16)&0xFF]) | (PALETTE[(o>> 24)&0xFF] << 16)); \ B+=4; что сократит количество обращений при записи в TFT_Data в два раза. Вариант дал прирост +11% на работу всей программы Теперь звук "в особо тяжких играх" идет без хрипа Но медленный темп сохранился (опять же - в некоторых играх) а также сделать u32 PALETTE[65536]; o=*(u32*)B; \ (u32*)TFT_Data=(PALETTE[ o &0xFFFF]); \ (u32*)TFT_Data=(PALETTE[ (o>>16)&0xFFFF]); \ B+=4; что ещё уменьшит количество обращений к памяти PALETTE, но увеличит размер таблицы. Вариант оказался самым медленным!!! Полагаю из-за того что PALETTE раздулась, выбор индекса зависит от картинки и близок к случайному. Сильно засоряет кеш данных Код сделан исходя из того, что (моё предположение) шина TFT 16 бит и TFT_Data это адрес асинхронной памяти к которому привязан дисплей. Зависит от того как подключен TFT, если ему существенны изменения адреса, то такой вариант не прокатит, т.к. A1 = 0 при записи младшей части 32 битного слова, а А1 = 1 при записи старшей части. Если же Адрес А1 не существенен, то такой код должен работать, проверял ). Ваши предположения абсолютно верные. Адресный бит LCD завешан на A16 Но и второй должен дать прирост производительности - как минимум, за счет экономии на постоянном activate/precharge (и связанной с этим латентностью). Палитра ведь как раз помещается в одну строку SDRAM. denebopetukius, для второго варианта также необходимо выравнять палитру по 512-байтовой границе. Чуть не забыл сказать, для второго варианта палитру располагал в отдельном банке сдрам пробовал WT и WB - нет разницы кстати, во время работы, палитра может меняться! (запись) палитра была выровнена на начало банка сдрам. почему оказалось хуже? что делать с битами CPLB: dirty и lock ? --- пока оставил первый вариант, палитру толкнул в скрэтчпад, стек урезал на всякий случай добавлю - что у приложения стартапа нет, в ldf-файле делается RESOLVE(main,0x4) вместо RESOLVE(start,0x4); KEEP(main) u32 PALETTE[65536]; ещё непонятка: как и чем заполнять такую палитру? в u16 PALETTE[256] всё просто PALETTE[i]=f( R,G,B ), а тут как? циклы гонять, каждый раз когда идет запись в палитру (она может меняться во время игры) Изменено 8 апреля, 2009 пользователем denebopetukius Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
boombox 0 9 апреля, 2009 Опубликовано 9 апреля, 2009 (изменено) · Жалоба в u16 PALETTE[256] всё просто PALETTE=f( R,G,B ), а тут как? циклы гонять, каждый раз когда идет запись в палитру (она может меняться во время игры) u32 PALETTE[65536] формируется сразу на 2 пикселя. В старших 16 бит лежит один пиксель, в младших второй. PALETTE=(f( R,G,B ) << 16) | (f( R,G,B )); поэтому и 65536 значений. В итоге (u32*)TFT_Data=(PALETTE[ o &0xFFFF]); забирается из палитры 2 пикселя и передаётся в LCD. И если эту палитру ставить в SDRAM, то как говорил vik0 отключить кэш в данной области. Можно попробовать подготовить несколько вариантов палитры и тупо менять, когда надо, указатель оной. Благо памяти много. Но это самый простой вариант и жрущий много памяти. Изменено 9 апреля, 2009 пользователем boom Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_pv 79 9 апреля, 2009 Опубликовано 9 апреля, 2009 · Жалоба к BF532 на EBIU (банк 0) подсоединён TFT LCD шина 16 бит в SDRAM есть буфер 512x512 точек. Одна точка - байт (индекс палитры) в той же SDRAM есть массив палитры из 256 цветов (индекс палитры из буфера - номер цвета) часть буфера 512x512 надо отрисовать в дисплей прямоугольником 320x240 DMA имхо тут не прокатит, так как на дисплей идет не содержимое буфера (i), а палитра PALETTE вопрос, можно ли быстрее сделать отрисовку на экран? как тут уже подсказали перенести палитру в SRAM, и может быть завести буфер 320х240, в него сначала писать правильные цвета, а затем уже с помощью MDMA копировать в дисплей. Ну а, наверное, совсем быстрый способ, это завести в SRAMe пару буферов размером на строку (512) и пару размером 320 слов, в первый из низ читать из SDRAMA через MDMA, в это время пересчитывать данные цветов из второго буфера который был заполнен ранее, и складывать в третий буфер (320 слов), который затем также через MDMA отправлять в дисплей, и пока он будет отправляться, работать с четвёртым. Во как. Радость от этого всего в том, что все операции будут проводиться в быстром SRAMe, без медленных вылазок на внешнюю шину, а одновременно с этим, будет трудиться и MDMA, занимаясь перекладыванием данных, не отвлекая процессор. спорный вопрос. поставив дисплей на PPI, мы лишимся FIO (практически всех, ибо шина 16 бит) а они нужны на Joystick и чипселекты SPI-устройств мультиплексоры городить не хотелось бы. да и не факт что быстрее было бы. Тем более отвлекаться через каждые 50/60 Гц Было бы быстрее, так как сейчас и дисплей и SDRAM делят одну шину, и соответственно она занята сначала при чтении из SDRAM а потом при записи в дисплей. в случае с PPI это было бы только последовательное чтение SDRAMA. и отвлекаться надо было бы на всего несоклько тактов, перезаписать пару регистров ДМА. а недостаток ног можно было скомпенсировать добавив на spi какой-нибудь мелкий AVR. Хотя вопрос действительно спорный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
denebopetukius 0 10 апреля, 2009 Опубликовано 10 апреля, 2009 (изменено) · Жалоба начал копать с другой стороны. расковырял функцию рендеринга эмулятора - в тот самый буфер 512x512 оказалось что рендерится по строчкам сделал так что отрендерённая строка посылается сразу на дисплей (рендерятся все слои - спрайты/фон итп...) буфер естественно уже 512x1 - расположил в скрэтчпаде! скорость поднялась, но незначительно. пробовал выводить без палитры напрямую - тоже не изменилось. пробовал не выводить на дисплей ничего - слегка ускорилось но ненамного. вывод - сам эмулятор CPU/coCPU/VDP/Sound уже хавает много ресурсов - более чем отрисовка экрана. в настоящее время буфер 512x1 и палитра - в скрэтчпаде и не кешированы Изменено 10 апреля, 2009 пользователем denebopetukius Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться