реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> BF533 отрисовка на дисплей, шина EBIU
_pv
сообщение Sep 6 2017, 09:14
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 2 276
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



ну вот есть у вас 5 инструкций на пиксель, можно ещё сократить, наверное.
P0=W[P1++]
P0=P3+(P0<<1)
да и в собирании двух пикселей в одно 32х разрядное слово смысла особого нет. EBUI всё равно 16 бит.
если бы был дополнительный буфер во внутренней памяти, куда дма данные само подтаскивает, наверное, можно было бы ещё какой-нибудь один такт сэкономить, запараллелив запись одного пикселя с чтением следующего и/или P0=P3+(P0<<1), P2=P3+(P2<<1)
но всё равно чтение из sdrama в лучшем случае 1SCLK = 3-4CCLK, (если не лень встаньте, осциллографом на шину памяти и посмотрите сколько тактов реально такие одиночные чтения из sdram занимают)
а запись в дисплей по асинхронной шине 2-3SCLK = 6-12CCLK.
что толку оптимизировать эти 4 инструкции, если обращение чтение из памяти и запись в дисплей длится в несколько раз дольше 9-16 тактов.
как уже не раз говорил, заставьте дма перекладывать данные, тогда обработка палитры процессором будет идти параллельно с перекладыванием данных.

ps. у вас 16ти разрядный цвет в палитре и 16ти разрядный индекс цвета, в чем смысл?
Go to the top of the page
 
+Quote Post
__inline__
сообщение Sep 6 2017, 11:18
Сообщение #17


Частый гость
**

Группа: Участник
Сообщений: 92
Регистрация: 5-09-17
Пользователь №: 99 126



Цитата(_pv @ Sep 6 2017, 09:14) *
что толку оптимизировать эти 4 инструкции, если обращение чтение из памяти и запись в дисплей длится в несколько раз дольше 9-16 тактов.
как уже не раз говорил, заставьте дма перекладывать данные, тогда обработка палитры процессором будет идти параллельно с перекладыванием данных.


Процессор разогнан до 550 МГц. Шина CCLK/3=183 МГц. SDRAM работает на 183 МГц с CAS latency =2. Кеш включен (для кода и данных).
Дисплей 7 тактов (setup + write + hold), в эквиваленте 183/7 = 26 МГц. Шина данных 16 бит.

Цитата(_pv @ Sep 6 2017, 09:14) *
да и в собирании двух пикселей в одно 32х разрядное слово смысла особого нет. EBUI всё равно 16 бит.

Обращение к 32 битам идет подряд как 2 раза по 16 бит, адрес+1.
Но та как адресов у контроллера дисплея нет (точнее есть и висит он на самом старшем адресном бите), инкремент адреса не мешает.
Это небольшой burst из двух коротких слов sm.gif

Сделал 14 строк ассемблера на 4 пикселя.
Раньше было 11 строк на 2 пикселя.
Ппришлось попарить мозг, пока вышло так (задействовал конвеер Блекфина).
Пока не проверял в работе, но компилируется.
Эффективность кода возросла на 36%


Код
#define PIXEL \
{ \
__asm__ volatile ("                 R0=W[P0++] (Z);"); \
__asm__ volatile ("R0=R0<<1      || R1=W[P0++] (Z);"); \
__asm__ volatile ("R1=R1<<1      || R2=W[P0++] (Z);"); \
__asm__ volatile ("R2=R2<<1      || R3=W[P0++] (Z);"); \
__asm__ volatile ("P3=R3                        ;"); \
__asm__ volatile ("P3=P5+(P3<<1)                ;"); \
__asm__ volatile ("R0=R0+R5 (NS) || R1.H=W[P3]  ;"); \
__asm__ volatile ("I0=R0                        ;"); \
__asm__ volatile ("R1=R1+R5 (NS) || R0.L=W[I0]  ;"); \
__asm__ volatile ("I1=R1                        ;"); \
__asm__ volatile ("R2=R2+R5 (NS) || R0.H=W[I1]  ;"); \
__asm__ volatile ("I2=R2                        ;"); \
__asm__ volatile ("R3=R3+R5 (NS) || R1.L=W[I2] || [P1]=R0 ;"); \
__asm__ volatile ("  [P1]=R1    ;"); \
\
} \


Цитата(_pv @ Sep 6 2017, 09:14) *
если бы был дополнительный буфер во внутренней памяти, куда дма данные само подтаскивает, наверное, можно было бы ещё какой-нибудь один такт сэкономить, запараллелив запись одного пикселя с чтением следующего


К сожалению объем графических данных не позволяет сделать буфер на строку во внутренней памяти + DMA. Потому что программу писал не я.

Цитата(_pv @ Sep 6 2017, 09:14) *
ps. у вас 16ти разрядный цвет в палитре и 16ти разрядный индекс цвета, в чем смысл?


Это эмуляция аркадных автоматов Capcom Play System 1/2, там палитра больше 256 цветов sm.gif

Вот это детище портировал на BF533:
https://osdn.net/projects/mamespi/releases/2046 / https://www.zophar.net/mame/caname.html

Сообщение отредактировал __inline__ - Sep 6 2017, 11:20
Go to the top of the page
 
+Quote Post
_pv
сообщение Sep 6 2017, 11:44
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 2 276
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



буфер не обязательно на всю строку делать, 8-16-32 пикселя возможно уже вполне хватит чтобы успеть и данные пережевать и дма перенастроить.
главное чтобы не процессор занимался перекладыванием данных из регистра/внутренней памяти наружу.

Цитата(__inline__ @ Sep 6 2017, 18:18) *
Это эмуляция аркадных автоматов Capcom Play System 1/2, там палитра больше 256 цветов sm.gif

раз это память никак не экономит, делайте конверсию в цвет по палитре при записи в буфер, а не при чтении, и выводите тогда просто направив дма из внешней памяти на экран вообще без участия процессора.
Go to the top of the page
 
+Quote Post
__inline__
сообщение Sep 6 2017, 14:09
Сообщение #19


Частый гость
**

Группа: Участник
Сообщений: 92
Регистрация: 5-09-17
Пользователь №: 99 126



Цитата(_pv @ Sep 6 2017, 11:44) *
раз это память никак не экономит, делайте конверсию в цвет по палитре при записи в буфер, а не при чтении, и выводите тогда просто направив дма из внешней памяти на экран вообще без участия процессора.


Там очень хитрый буфер. И он "грязный", потому что по-очереди отрисовываются несколько спрайтовых плоскостей (видеосистема Capcom PlaySystem 1/2). Если преобразовывать палитру там, то боюсь всё замедлится в число раз, равное числу плоскостей.

Цитата(_pv @ Sep 6 2017, 11:44) *
буфер не обязательно на всю строку делать, 8-16-32 пикселя возможно уже вполне хватит чтобы успеть и данные пережевать и дма перенастроить.
главное чтобы не процессор занимался перекладыванием данных из регистра/внутренней памяти наружу.


Процессор к сожалению будет конвертить палитру, а DMA так же занимать шину во время транзакций.
И можно будет авансом заранее сделать не более 1 цикла эмуляции, до того как экран будет полностью не отрисован, иначе пропуск кадра будет что плохо.

Проверил работу процедуры. На практике вышло чуть-лучше. Но ненамного.

Вот код всей процедуры - пока не вычесал, затронут только внутренний цикл.

Код
.section/DOUBLE32 program;

.extern _current_display;
.extern _palette_16bit_lookup

.global _dib_draw_window_asm;

_dib_draw_window_asm:
    [--SP] = (P5:3);
    P1.L = _current_display+4;
    P1.H = _current_display+4;
    P1 = [P1];
    P2 = 17600;
    P0 = 224;
    I0 = 0;
    I0.H = 8193;
    P1 = [P1 + 16];
    P5.L = _palette_16bit_lookup;
    P5.H = _palette_16bit_lookup;
    P4 = 4;
    P1 = P1 + P2;
    [SP + 12] = P1;
    LOOP CycleYL LC1 = P0;
CycleY:
    LOOP_BEGIN CycleYL;
    P1 = [SP + 12];
    P0 = 80;

    P3 = [P5];
        R5=P3;

    LOOP CycleXL LC0 = P0;
CycleX:
    LOOP_BEGIN CycleXL;
                     R0=W[P1 + 2] (Z)     ;
    R0=R0<<1      || R1=W[P1 ++ P4] (Z)   ;
    R1=R1<<1      || R2=W[P1 + 2] (Z)     ;
    R2=R2<<1      || R3=W[P1 ++ P4] (Z)   ;
    P0=R3                                 ;
    P0=P3+(P0<<1)                         ; //Preg read after write which requires 4 extra cycles
    R0=R0+R5 (NS) || R7.L=W[P0]           ;
    I1=R0                                 ;
    R1=R1+R5 (NS) || R6.H=W[I1]           ; //Dagreg read after write which requires 4 extra cycles
    I1=R1                                 ;
    R2=R2+R5 (NS) || R6.L=W[I1]           ; //Dagreg read after write which requires 4 extra cycles
    I1=R2                                 ;
    R3=R3+R5 (NS) || R7.H=W[I1] || [I0]=R6; //Dagreg read after write which requires 4 extra cycles
    [I0]=R7                               ;
    LOOP_END CycleXL;
.P35L13:
    P0 = [SP + 12];
    P1 = 1088;
    P1 = P0 + P1;                            //Preg read after write which requires 3 extra cycles
    [SP + 12] = P1;
    LOOP_END CycleYL;
.P35L14:
    (P5:3) = [SP++];
    RTS;


А вот это разочаровало:
//Preg read after write which requires 3 extra cycles
//Dagreg read after write which requires 4 extra cycles

Выходит вся оптимизация и конвеер лесом?? wacko.gif

Пока получилось 35 - 40 FPS, в идеале должно быть 60 FPS (частота смены кадров NTSC)
Go to the top of the page
 
+Quote Post
_pv
сообщение Sep 6 2017, 15:24
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 2 276
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(__inline__ @ Sep 6 2017, 20:09) *
Там очень хитрый буфер. И он "грязный", потому что по-очереди отрисовываются несколько спрайтовых плоскостей (видеосистема Capcom PlaySystem 1/2). Если преобразовывать палитру там, то боюсь всё замедлится в число раз, равное числу плоскостей.

когда данные не во внешней памяти, а уже в регистре то это преобразование занимает два такта.
ну и если взять в среднем, пиксель всё таки читается каждый кадр, а вот пишется думаю далеко не каждый.
правда исходное разрешение наверное больше чем выходное 320х240, тогда пожалуй да, лучше конвертировать при выводе.

Цитата(__inline__ @ Sep 6 2017, 20:09) *
Процессор к сожалению будет конвертить палитру, а DMA так же занимать шину во время транзакций.
И можно будет авансом заранее сделать не более 1 цикла эмуляции, до того как экран будет полностью не отрисован, иначе пропуск кадра будет что плохо.
Пока получилось 35 - 40 FPS, в идеале должно быть 60 FPS (частота смены кадров NTSC)

ну у процессора-то не отберёт, там приоритет вроде как поставить можно кто главней процессор или дма если оба наружу хотят обратиться.
что такое цикл эмуляции?
вот есть у вас 15мс между кадрами при 60Гц, за это время надо успеть наэмулировать 15мс тактов приставки и отрисовать экран. какая разница в каком порядке.
320*240 / 26МГц = 3мс, это время в течении которого шина всё равно будет просто занята отрисовкой на экран, чтение из памяти гораздо быстрее можно не учитывать, так почему бы в эти 3мс процессору не заняться конвертированием цветов, ПАРАЛЛЕЛЬНО с выдачей, а не последовательно как сейчас. потому что ничего другого он всё равно без внешней шины делать не сможет.
Go to the top of the page
 
+Quote Post
__inline__
сообщение Sep 6 2017, 15:37
Сообщение #21


Частый гость
**

Группа: Участник
Сообщений: 92
Регистрация: 5-09-17
Пользователь №: 99 126



Цитата(_pv @ Sep 6 2017, 15:24) *
когда данные не во внешней памяти, а уже в регистре то это преобразование занимает два такта.
ну и если взять в среднем, пиксель всё таки читается каждый кадр, а вот пишется думаю далеко не каждый.
правда исходное разрешение наверное больше чем выходное 320х240, тогда пожалуй да, лучше конвертировать при выводе.


ну у процессора-то не отберёт, там приоритет вроде как поставить можно кто главней процессор или дма если оба наружу хотят обратиться.
что такое цикл эмуляции?
вот есть у вас 15мс между кадрами при 60Гц, за это время надо успеть наэмулировать 15мс тактов приставки и отрисовать экран. какая разница в каком порядке.
320*240 / 26МГц = 3мс, это время в течении которого шина всё равно будет просто занята отрисовкой на экран, чтение из памяти гораздо быстрее можно не учитывать, так почему бы в эти 3мс процессору не заняться конвертированием цветов, ПАРАЛЛЕЛЬНО с выдачей, а не последовательно как сейчас. потому что ничего другого он всё равно без внешней шины делать не сможет.


Весь цикл программы можно упрощенно представить так:

Код
while(!Quit)
{
эмулируем...
рисуем...
}


Если запустить DMA и отрисовывать построчно, то всеравно прийдется ждать окончания работы DMA чтобы подсунуть ему новую линию с декодированной палитрой при передаче.
В момент работы ДМА, процессор всеравно будет брать индексы из SDRAM, а это снова шина.
В итоге процессор и ДМА будут рвать шину по кускам.
Go to the top of the page
 
+Quote Post
_pv
сообщение Sep 6 2017, 16:05
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 2 276
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(__inline__ @ Sep 6 2017, 21:37) *
Если запустить DMA и отрисовывать построчно, то всеравно прийдется ждать окончания работы DMA чтобы подсунуть ему новую линию с декодированной палитрой при передаче.
В момент работы ДМА, процессор всеравно будет брать индексы из SDRAM, а это снова шина.
В итоге процессор и ДМА будут рвать шину по кускам.

для этого и нужен небольшой буфер во внутренней памяти чтобы процессору было с чем работать пока шина занята отрисовкой.
и не обязательно буфер на всю строку.
0) завели два буфера по 64 байта.

1)настроили ДМА, чтобы забрать 32 точки из сдрама(ну или забрали руками, тут без разницы) в буфер №1
2)курим бамбук, так как без шины заняться нечем.
3)по получении данных отправили предыдущий буфер№2 из 32 точек на отрисовку через дма
4)пока дма перекладывает данные в дисплей, обрабатываем только что полученные данные в буфере№1.
5)как только старые данные ушли (обработка вроде бы должна закончиться гораздо быстрее, дисплею надо 21ССLK на пиксель, а процессор за 3-5 управиться должен из внутренней памяти), поменяли местами указатели на буферы
GOTO 1
Go to the top of the page
 
+Quote Post
__inline__
сообщение Sep 7 2017, 09:04
Сообщение #23


Частый гость
**

Группа: Участник
Сообщений: 92
Регистрация: 5-09-17
Пользователь №: 99 126



Цитата(_pv @ Sep 6 2017, 16:05) *
0) завели два буфера по 64 байта.
1)настроили ДМА, чтобы забрать 32 точки из сдрама(ну или забрали руками, тут без разницы) в буфер №1
2)курим бамбук, так как без шины заняться нечем.
3)по получении данных отправили предыдущий буфер№2 из 32 точек на отрисовку через дма
4)пока дма перекладывает данные в дисплей, обрабатываем только что полученные данные в буфере№1.
5)как только старые данные ушли (обработка вроде бы должна закончиться гораздо быстрее у дисплею надо 21ССLK на пиксель, а процессор за 3-5 управиться должен из внутренней памяти), поменяли местами указатели на буферы
GOTO 1


Всё сделал как написали, работает исправно, но прироста скорости всёравно нет. Пробовал убрать dma_wait, скорость повышается, но экран отрисовывается на 1/4 и весь трясётся (что и понятно почему).

Попробую не ждать, а в обработчик прерывания засунуть вывод на дисплей через DMA.

Рабочий код ниже:

Код
#ifndef __DMA_H__
#define __DMA_H__

//0xFF800000..0xFF803FFF //L1_DATA_A

#define NB 32

#define buf0 (0xFF803FC0-(NB<<1))
#define buf1 (0xFF803FE0- NB    )

#define DMA_INIT                         \
{                                        \
*pMDMA_S1_PERIPHERAL_MAP=0x0040;        \
*pMDMA_S1_X_COUNT=(NB>>1);              \
*pMDMA_S1_X_MODIFY=2;                   \
*pMDMA_S1_Y_COUNT=1;                    \
*pMDMA_S1_Y_MODIFY=0;                   \
*pMDMA_D1_PERIPHERAL_MAP=0x0040;        \
*pMDMA_D1_START_ADDR=(void*)&OLED_Data; \
*pMDMA_D1_X_COUNT=(NB>>1);              \
*pMDMA_D1_X_MODIFY=0;                   \
*pMDMA_D1_Y_COUNT=1;                    \
*pMDMA_D1_Y_MODIFY=0;                   \
}                                        \

#define DMA_SEND(buf)                  \
{                                      \
*pMDMA_S1_START_ADDR=(void*)buf;      \
*pMDMA_S1_CONFIG=WDSIZE_16|DMAEN;     \
*pMDMA_D1_CONFIG=WDSIZE_16|WNR|DMAEN; \
}                                      \

#define DMA_WAIT while(*pMDMA_D1_IRQ_STATUS&DMA_RUN);

#define MEMORY_COPY(dst,src)       \
{                                  \
register u16 i;                   \
register u32* d=(u32*)dst;        \
register u32* s=(u32*)src;        \
for(i=0;i<(NB>>2);i++) *d++=*s++; \
}                                  \

#define PALETTE_CONVERT(buf)                          \
{                                                     \
register u16 i;                                      \
register u16* c=(u16*)buf;                           \
for(i=0;i<(NB>>1);i++)*c++=palette_16bit_lookup[*c]; \
}                                                     \
#endif


Код
void dib_draw_window_DMA(void)
{
register u16* src=(u16*)(((u32)current_display.game_bitmap->base)+17536+64);
register u16 y=DST_HEIGHT;

while(y--)
{
  register u16 x=(u16)SCR_WIDTH/(u16)NB;

  MEMORY_COPY(buf1,src)
  PALETTE_CONVERT(buf1)
  src+=(NB>>1);

  while(x--)
  {
   MEMORY_COPY(buf0,src)
   DMA_SEND(buf1)
   PALETTE_CONVERT(buf0)
   src+=(NB>>1);
   DMA_WAIT

   MEMORY_COPY(buf1,src)
   DMA_SEND(buf0)
   PALETTE_CONVERT(buf1)
   src+=(NB>>1);
   DMA_WAIT
  }

  src+=(SRC_PITCH-SCR_WIDTH-(NB>>1));
}
}
Go to the top of the page
 
+Quote Post
_pv
сообщение Sep 7 2017, 09:23
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 2 276
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(__inline__ @ Sep 7 2017, 16:04) *
Всё сделал как написали, работает исправно, но прироста скорости всёравно нет. Пробовал убрать dma_wait, скорость повышается, но экран отрисовывается на 1/4 и весь трясётся (что и понятно почему).

Core Timer в руки и смотрите сколько тактов что исполняется. тормозит где-то ещё.
вы же понимаете что тут быстрее уже вывод не сделать, так как в данном случае всё упирается в скорость перекладывания данных в дисплей.
ну разве что только на PPI или SPORT какой-нибудь его перевесить, чтобы внешнюю шину не занимал.

зы уже говорили про макросы.
inline void DMA_INIT(){
*pMDMA_S1_PERIPHERAL_MAP=0x0040;
...
}
ну вот абсолютно ничем не отличается, но выглядит не так безобразно.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 7 2017, 19:29
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 3 833
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(__inline__ @ Sep 7 2017, 12:04) *
Всё сделал как написали, работает исправно, но прироста скорости всёравно нет.

И не будет. Я писал выше почему.

Цитата(_pv @ Sep 7 2017, 12:23) *
зы уже говорили про макросы.

Да. Похоже - не в коня корм... smile3046.gif

Цитата(__inline__ @ Sep 6 2017, 17:09) *
//Preg read after write which requires 3 extra cycles
//Dagreg read after write which requires 4 extra cycles
Выходит вся оптимизация и конвеер лесом?? wacko.gif

Чтобы что-то оптимизировать, нужно сначала досконально изучить процессор. А у Вас знания - поверхностные.
Я тут уже несколько раз писал по stall-ы в c55x и почему они возникают. И вот именно в этих же точках c55xx вставил бы stall-ы, и похоже, что конвеер Blackfin работает аналогично.
На ядре C55xx нельзя вычислить значение на основном АЛУ (D-unit АЛУ) и тут же использовать его для вычисления адреса, так как действия эти выполняются на разных фазах конвеера (причём: вычисление адреса - на более ранней фазе). Если так сделать, то ядро вставит необходимое число stall-ов (остановок конвеера) для синхронизции фаз, что у Вас похоже и наблюдается.
Кроме этой, есть есть куча причин для вставки stall-ов. Пока не изучите полностью - не напишите ничего путнего. DSP-ядра - это не ARM, они в разы сложнее ARM-а.
Да и операций у Вас куча лишних - какие-то пересылки - зачем они? Надо изучать систему команд и искать решения с меньшим их кол-вом.
Вобщем оптимизации там - кот наплакал. Никакой скорости выполнения от такого кода ждать не приходится.
Go to the top of the page
 
+Quote Post
_pv
сообщение Sep 7 2017, 21:38
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 2 276
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(jcxz @ Sep 8 2017, 02:29) *
И не будет. Я писал выше почему.
Вобщем оптимизации там - кот наплакал. Никакой скорости выполнения от такого кода ждать не приходится.

дело не в оптимизации этого куска, его можно и как угодно криво написать,
на перекладывание точки в дисплей уходит 21 такт, который сейчас выполняется параллельно с вычислением палитры, а процессор потом почти всё время сидит сидит и ждёт while(*pMDMA_D1_IRQ_STATUS&DMA_RUN);
ну а то что fpsов мало получается - надо смотреть чем там ещё процессор занят.
переслать 320*240 при 26МГц это 3мс всего.
Go to the top of the page
 
+Quote Post
__inline__
сообщение Sep 8 2017, 15:49
Сообщение #27


Частый гость
**

Группа: Участник
Сообщений: 92
Регистрация: 5-09-17
Пользователь №: 99 126



Сделал DMA по прерываниям. Буфер - 320 пикселов (одна строка) 640 байт в L1, уже сконверченная палитрой(тоже в L1). Даём DMA команду на отрисовку строки, а сами делаем дальше остальные вещи. Прерывание по окончанию пересылки строки снова запускает DMA для новой строки. И так пока экран не отрисуется весь.

Код что ниже - рабочий, удаось поднять общую скорость (отрисовка экрана + вся программа) на 15 FPS !!! rolleyes.gif
Получается, что отрисовка экрана и работа процессора немного распараллелились.

Макросы использую, потому что 100% гарантия что с-инлайнится.

Код
#define SRC_PITCH  544
#define DST_HEIGHT 224

#define SCR_WIDTH  320
#define SCR_HEIGHT 240

//0xFF800000..0xFF803FFF //L1_DATA_A

#define NB (SCR_WIDTH<<1)

#define L1_MEMORY 0xFF804000

#define L1_BUF (L1_MEMORY-NB)

#define DMA_INIT                         \
{                                        \
*pMDMA_S1_PERIPHERAL_MAP=0x0040;        \
*pMDMA_S1_START_ADDR=(void*)L1_BUF;     \
*pMDMA_S1_X_COUNT=(NB>>1);              \
*pMDMA_S1_X_MODIFY=2;                   \
*pMDMA_S1_Y_COUNT=1;                    \
*pMDMA_S1_Y_MODIFY=0;                   \
*pMDMA_D1_PERIPHERAL_MAP=0x0040;        \
*pMDMA_D1_START_ADDR=(void*)&OLED_Data; \
*pMDMA_D1_X_COUNT=(NB>>1);              \
*pMDMA_D1_X_MODIFY=0;                   \
*pMDMA_D1_Y_COUNT=1;                    \
*pMDMA_D1_Y_MODIFY=0;                   \
}                                        \

#define DMA_START                            \
{                                            \
*pMDMA_S1_CONFIG=WDSIZE_16|DMAEN;           \
*pMDMA_D1_CONFIG=WDSIZE_16|WNR|DMAEN|DI_EN; \
}                                            \

#define DMA_STOP                       \
{                                      \
*pMDMA_S1_CONFIG=0;                   \
*pMDMA_D1_CONFIG=0;                   \
}                                      \


extern struct mame_display current_display;

u16* src;

EX_INTERRUPT_HANDLER(DMA_ISR)
{
static u16 y=DST_HEIGHT;
*pMDMA_D1_IRQ_STATUS=1;
y--;
if(y)
{
  register u16* buf=(u16*)L1_BUF;
  register u16 i;
  for(i=0;i<(NB>>1);i++)*buf++=palette_16bit_lookup[*src++];
  src+=(SRC_PITCH-SCR_WIDTH);
  DMA_START
}
else
{
  y=DST_HEIGHT;
  DMA_STOP
}
}

void DMA_Init_Interrupt(void)
{
*pSIC_IMASK&=0xFFBFFFFF;                       //Disable MDMA1 interrupt
*pSIC_IAR2=(*pSIC_IAR2&0xF0FFFFFF)|0x06000000;
register_handler(ik_ivg13,DMA_ISR);
*pSIC_IMASK|=0x00400000;                       //Enable MDMA1 interrupt
}

int win_init_window(void)
{
        // disable win_old_scanlines if a win_blit_effect is active
        if (win_blit_effect != 0)
                win_old_scanlines = 0;

DMA_Init_Interrupt();
DMA_INIT

OLED_Clear(0x0000);

return 0;
}

void dib_draw_window_DMA(void)
{
OLED_Rectangle(0,(SCR_HEIGHT-DST_HEIGHT)>>1,SCR_WIDTH-1,((SCR_HEIGHT+DST_HEIGHT)>>1)-1);

src=(u16*)(((u32)current_display.game_bitmap->base)+17536+64);

register u16* buf=(u16*)L1_BUF;
register u16 i;
for(i=0;i<(NB>>1);i++)*buf++=palette_16bit_lookup[*src++];
src+=(SRC_PITCH-SCR_WIDTH);
DMA_START
}
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 8 2017, 19:01
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 3 833
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(__inline__ @ Sep 8 2017, 22:49) *
Код что ниже - рабочий, удаось поднять общую скорость (отрисовка экрана + вся программа) на 15 FPS !!! rolleyes.gif
Получается, что отрисовка экрана и работа процессора немного распараллелились.

И сколько получилось? 40+15 FPS? И это по 16-битной шине?? Это всё равно очень медленно.
Для справки: у меня в одном проекте тоже используется 320*240 LCD в режиме 16 бит/пиксел.
Вот только подключен он по SPI на SCLK=45МГц. И частота CPU гораздо ниже - 180МГц.
Картинка у меня изначально нарисована в формате 4 бит/пиксел. А процедура отображения фрагментами преобразует содержимое в 16-битные пикселы (тоже с помощью палитры) в промежуточный буфер и передаёт через DMA-SPI. И исходная картинка и промежуточный буфер у меня находятся во внутренней памяти МК.
Так вот - преобразование следующего фрагмента (процессором) успевает закончится до завершения передачи (через DMA-SPI) предыдущего фрагмента. И ещё процессору остаётся время успеть заняться другими делами между преобразованиями фрагментов.
Т.е. - если бы я непрерывно только гнал кадры на LCD с высоким приоритетом, то у меня получилось бы: 45000000/(320*240*16) ~ 36FPS
И это по однобитному SPI!
И никаких ухищрений по оптимизации в цикле преобразования точек через таблицу палитры я не делалал - простой цикл на си, без каких-либо разворачиваний чего-либо.
А у Вас вроде 16-битная шина и процессор гораздо мощнее - у Вас скорость передачи картинки должна быть во много раз выше чем у меня. А почему-то получается сравнимая скорость с моей. Как будто по SPI картинку передаёте.
Да и вообще если просто посчитать: 550МГц/(320*240) - получается, что каждую секунду у процессора есть > 7100 тактов CPU на обработку одной точки экрана. Т.е. - даже при частоте FPS=60ГЦ будет около 120тактов CPU на точку! Это не просто много, это очень много - процессор должен просто почти всё время просто отдыхать. А у Вас он ещё и не успевает. wacko.gif
Какая-то у Вас там глобальная проблема в коде....

Цитата(_pv @ Sep 8 2017, 04:38) *
переслать 320*240 при 26МГц это 3мс всего.

Не понял - что за 26МГц?
Go to the top of the page
 
+Quote Post
_pv
сообщение Sep 8 2017, 19:17
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 2 276
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата(jcxz @ Sep 9 2017, 02:01) *
Не понял - что за 26МГц?

системная частота SCLK = частота ядра CCLK / 3 = 550/3 = 180МГц.
цикл асинхронной шины 7 тактов со всеми setup/holdами или 26МГц.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Sep 8 2017, 19:49
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 3 833
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(_pv @ Sep 9 2017, 02:17) *
системная частота SCLK = частота ядра CCLK / 3 = 550/3 = 180МГц.
цикл асинхронной шины 7 тактов со всеми setup/holdами или 26МГц.

А почему так много - 7 тактов/пересылка?
Если действительно такая тормозная шина, то тогда пожалуй Вы правы, что нужно преобразовывать через промежуточный буфер во внутреннем ОЗУ с последующей передачей его через DMA уже по этой тормозной шине.
Даже в этом случае у процессора автора должно быть просто море времени на эту работу и преобразование должно занимать меньше времени чем передача кадра за 3мсек.
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 13th December 2017 - 15:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.01404 секунд с 7
ELECTRONIX ©2004-2016