版主
最后登录1970-1-1
在线时间 小时
注册时间2015-12-2
|
先上游戏效果视频,回复可见:
野火i.MX RT1052 EVK Pro跑超级玛丽演示效果,帧率53帧 :
野火i.MX RT1052 EVK Pro跑超级玛丽大屏演示效果:
1、什么PXP?在RT1052中PXP是用于在数据发送到LCD显示器或TV编码器之前的一个图像处理缓冲器。
就是一个简易的2D图像加速器,在显示之前做一些简单操作,比如缩放,颜色域转换,旋转。
通过集成多个模块,可以消除对外部存储器的中间缓冲操作,从而减少外部存储器带宽、功耗和软件控制的复杂性。 看起来性能相当不错,PXP框图如下所示:
2、之前一直没机会用到PXP,鉴于上面说到PXP的优点,这次移植InfoNES立马尝试PXP,是驴是马测试一番就知道结果,
这次实验主要针对PXP缩放性能测试,InfoNES的移植过程在这里不做展开。
实验平台:
野火i.MX RT1052 EVK Pro开发板
显示:
5寸屏,分辨率为800x480
10.1寸屏,分辨率为1280x800(LVDS接口)
3、 InfoNES的默认输出分辨率是256x224,格式为RGB565,因此液晶显示首选RGB565输出,避免不必要的转换,
在SDRAM中开辟一个显存空间给液晶屏使用,这里使用AT_NONCACHEABLE_SECTION_ALIGN修饰即显存放在非cache的区域,
双缓冲,APP_IMG_HEIGHT、APP_IMG_WIDTH分别是液晶屏的长和宽,FRAME_BUFFER_ALIGN缓冲帧对齐。
- AT_NONCACHEABLE_SECTION_ALIGN(static uint16_t s_psBufferLcd[2][APP_IMG_HEIGHT][APP_IMG_WIDTH], FRAME_BUFFER_ALIGN);
复制代码 初始化液晶屏
- void APP_ELCDIF_Init(void)
- {
- const elcdif_rgb_mode_config_t config = {
- .panelWidth = APP_IMG_WIDTH,/*液晶参数设置*/
- .panelHeight = APP_IMG_HEIGHT,
- .hsw = APP_HSW,
- .hfp = APP_HFP,
- .hbp = APP_HBP,
- .vsw = APP_VSW,
- .vfp = APP_VFP,
- .vbp = APP_VBP,
- .polarityFlags = APP_POL_FLAGS,/*极性设置*/
- .bufferAddr = (uint32_t)s_psBufferLcd[0],/*显存首地址*/
- .pixelFormat = kELCDIF_PixelFormatRGB565,/*像素格式为RGB565*/
- .dataBus = APP_LCDIF_DATA_BUS,/*液晶输出位宽为16bit*/
- };
- ELCDIF_RgbModeInit(APP_ELCDIF, &config);/*初始化液晶屏*/
- ELCDIF_RgbModeStart(APP_ELCDIF);/*启动显示*/
- }
复制代码 在内部OCRAM申请一个RAM空间作为PXP处理缓冲区,这里NES_DISP_HEIGHT,NES_DISP_WIDTH分别是显示NES的图像高度和宽度。
- static uint16_t s_psBufferPxp[NES_DISP_HEIGHT][NES_DISP_WIDTH] __attribute__ ((at(0x20200000)));
复制代码 初始化PXP代码
- static void APP_InitPxp(void)
复制代码
4、缩放测试代码- void NES_PIC_Scale(void)
- {
- static int t0=0;
- static int t1=0;
- int time;
- uint8_t curLcdBufferIdx = 1U;
-
- /* 启动计时器 */
- t0=CPU_TS_TmrRd();
- outputBufferConfig.buffer0Addr = (uint32_t)s_psBufferLcd[curLcdBufferIdx];
- /* 配置PXP输出缓冲区 */
- PXP_SetOutputBufferConfig(APP_PXP, &outputBufferConfig);
- /* 启动PXP传输,如果要循环启动必须要每次都重新启动 */
- PXP_Start(APP_PXP);
- /* 等待PXP处理完成 */
- while(!(kPXP_CompleteFlag & PXP_GetStatusFlags(APP_PXP)))
- {
- }
- /* 清除PXP完成标志位 */
- PXP_ClearStatusFlags(APP_PXP, kPXP_CompleteFlag);
-
- /* 停止计时器 */
- t1=CPU_TS_TmrRd();
- /* 计算缩放一帧图像所耗费时间(单位us) */
- time =(t1-t0)/528;
- PRINTF("PXP Scale Time=%d us\r\n",time);
- /* 新一帧已经准备好传递给LCDIF. */
- ELCDIF_SetNextBufferAddr(APP_ELCDIF, (uint32_t)s_psBufferLcd[curLcdBufferIdx]);
- /* 切换LCD另一个缓冲区 */
- curLcdBufferIdx ^= 1U;
- }
复制代码
5、代码全部放在ITCM,DATA放在DTCM
- #define m_flash_config_start 0x60000000
- #define m_flash_config_size 0x00001000
- #define m_ivt_start 0x60001000
- #define m_ivt_size 0x00001000
- #define m_interrupts_start 0x60002000
- #define m_interrupts_size 0x00000400
- #define m_text_start 0x60002400
- #define m_text_size 0x03FFDC00
- #define m_text1_start 0x00000400
- #define m_text1_size 0x0001FC00//ITCM 127KB
- #define m_data_start 0x20000000
- #define m_data_size 0x00020000//DTCM 128KB
- #define m_ncache_start 0x81000000
- #define m_ncache_size 0x01000000
- /* Sizes */
- #if (defined(__stack_size__))
- #define Stack_Size __stack_size__
- #else
- #define Stack_Size 0x0400
- #endif
- #if (defined(__heap_size__))
- #define Heap_Size __heap_size__
- #else
- #define Heap_Size 0x15000
- #endif
- LR_m_rom_config m_flash_config_start m_flash_config_size { ; load region size_region
- RW_m_config_text m_flash_config_start m_flash_config_size { ; load address = execution address
- * (.boot_hdr.conf, +FIRST)
- }
- }
- LR_m_rom_ivt m_ivt_start m_ivt_size { ; load region size_region
- RW_m_ivt_text m_ivt_start m_ivt_size { ; load address = execution address
- * (.boot_hdr.ivt, +FIRST)
- * (.boot_hdr.boot_data)
- * (.boot_hdr.dcd_data)
- }
- }
- LR_m_text m_interrupts_start m_text_start+m_text_size-m_interrupts_size { ; load region size_region
- VECTOR_ROM m_interrupts_start m_interrupts_size { ; load address = execution address
- * (RESET,+FIRST)
- }
- ER_m_text m_text_start m_text_size { ; load address = execution address
- * (InRoot$Sections)
- startup_mimxrt1052.o(+RO)
- system_mimxrt1052.o(+RO)
- }
- ER_m_text1 m_text1_start m_text1_size { ; load address = execution address
- .ANY (+RO)
- }
- RW_m_data m_data_start m_data_size-Stack_Size-Heap_Size { ; RW data
- .ANY (+RW +ZI)
- *(m_usb_dma_init_data)
- *(m_usb_dma_noninit_data)
- }
- ARM_LIB_HEAP +0 EMPTY Heap_Size { ; Heap region growing up
- }
- ARM_LIB_STACK m_data_start+m_data_size EMPTY -Stack_Size { ; Stack region growing down
- }
- RW_m_ncache m_ncache_start m_ncache_size { ; ncache RW data
- * (NonCacheable.init)
- * (NonCacheable)
- }
- }
复制代码
6、测试结果
A、5寸液晶屏全屏显示,分辨率800x480,SDRAM工作在163.8MHz,耗时为10.49ms,图像刷新率53帧/秒(不显示图像,PXP缩放耗时为9.04ms)
B、10.1寸液晶屏全屏显示,分辨率1280x800,SDRAM工作在163.8MHz,耗时为28.93ms,图像刷新率26帧/秒 (不显示图像,PXP缩放耗时为24.491ms)
代码在QSPI flash运行时测试结果如下:
C、5寸液晶屏全屏显示,分辨率800x480,SDRAM工作在163.8MHz,耗时为10.53ms,图像刷新率53帧/秒
D、10.1寸液晶屏全屏显示,分辨率1280x800,SDRAM工作在163.8MHz,耗时为29.01ms,图像刷新率26帧/秒
7、以上测试结果显示代码在QSPI执行与否对PXP硬件加速是没有影响,PXP的主要瓶颈在于SDRAM的带宽,实际应用选择800x480比较合适,效果相当不错。
|
|