4.基于BLE SoC芯片GR5526开发GPU 3D图形效果(4) - 解析第一个GPU工程

 系列文章:

1.基于BLE SoC芯片GR5526开发GPU 3D图形效果(1) - 概览

2.基于BLE SoC芯片GR5526开发GPU 3D图形效果(2) - 先看Demo效果

3.基于BLE SoC芯片GR5526开发GPU 3D图形效果(3) - GPU知识概念梳理

4.基于BLE SoC芯片GR5526开发GPU 3D图形效果(4) - 解析第一个GPU工程

5.基于BLE SoC芯片GR5526开发GPU 3D图形效果(5) - 理解图形学中的矩阵变换

6.基于BLE SoC芯片GR5526开发GPU 3D图形效果(6) - 开发炫酷新动画

前言: 通过上一篇文章对GR5526 GPU知识基础和接口的梳理, 对基本原理有了一定认知, 可以阅读分析 SDK 提供的GPU示例工程了.

一、 GPU应用典型代码结构

GPU应用典型的代码结构主要分为四个部分:Graphics外设初始化、缓冲区配置、渲染任务与屏幕刷新、外设反初始化(可选)。

  1. Graphics外设初始化
    • 初始化OSPI、PSRAM外设模块(默认使用OSPI访问内部PSRAM,若不使用内部PSRAM可不初始化相关外设)
    • 初始化GPU模块
    • 初始化DC模块
    • 初始化QSPI模块
  2. 缓冲区配置
    • Graphics内存管理初始化
    • 根据需求,初始化合适的帧缓冲区
      • 为GPU配置全局Framebuffer参数
      • 为DC配置全局Framebuffer参数
  3. 根据需求,申请适当的Texture Memory存储纹理图案
  4. 初始化环形缓冲区,为命令列表提供缓冲空间
    • 渲染任务与屏幕刷新
    • 构建GPU的命令列表,并提交至GPU进行渲染
    • 进入核心的渲染逻辑执行渲染任务,并实时将渲染结果刷新至屏幕上显示
      • 根据GPU中断获取渲染结果
      • 根据DC中断获取刷屏结果
  5. 外设反初始化(可选)
    • 任务结束时反初始化Graphics相关外设模块
    • 释放任务过程中申请的内存

Graphics 涉及几个重要的外设模块需要初始化, 分别是GPU、OSPI&PSRAM、DC和QSPI Flash, GPU 提供图形化渲染的算力,OSPI&PSRAM 提供足够的缓存运算空间, QSPI Flash是图片资源的持久化存储介质, DC模块要初始化好屏幕配置,同时负责将GPU渲染好的帧缓冲区, 刷新到屏幕进行显示.

二、基于 graphics_animation_effects 工程的说明

1. 宏配置graphics_defs.h

        graphics_defs.h头文件属于工程配置文件,每个示例工程独立,其位于:SDK_Folder\projects\peripheral\graphics\示例工程名\Src\application

/* Set current screen configuration */

#define LCD_RES_CURRENT LCD_RES_454

 

/* Set display enable */

#define HAL_GDC_DISPLAY_ENABLE 1u

 

/* Set TSCx compressed format enable */

#define TSCx_ENABLE 1u

 

/* Set image show area */

#define SHOW_AREA_X 240u

#define SHOW_AREA_Y 240u

 

/* Set pixel depth size in byte (Determined by color format) */

#define PIXEL_DEPTH_BYTES 4u

 

/* Set pixel show size in byte (Determined by color format) */

#define PIXEL_SHOW_BYTES 3u

 

/* Set screen display area */

#define DISPLAY_LCD_RES_X 454u

#define DISPLAY_LCD_RES_Y 454u

配置主要是配置显示屏幕参数, 显示区域参数和 Framebuffer参数. 注意屏幕分辨率和显示区域的区别,前者是屏幕物理上的分辨率尺寸,后者是实际显示区域, 小于等于前者, 意味着可能不会用所有区域进行显示

上述配置属于工程配置, 各个工程内容可能是不一致的

2. 宏配置 graphics_sys_defs.h

        graphics_sys_defs.h头文件属于graphics系统配置文件,其位于:SDK_Folder\components\graphics\gfx\porting

/**< The GPU RING BUFFER SIZE. */

#define HAL_GFX_RING_BUFFER_SIZE 1024u

/**< The same to Pool id */

#define HAL_GFX_MEM_POOL_ASSETS 0

/**< Pool id, only set to 0 currently */

#define HAL_GFX_MEM_POOL_FB 0

/**< the graphics (video) memory base address. */

#define VMEM_BASEADDR ((uint32_t)(&s_graphics_memory_buffer[0]))

/**< The GPU max memory size for frame buffer. */

#ifndef VMEM_SIZE

#define VMEM_SIZE (20*1024u)

#endif

/**< If enable, use the memory management of GPU. */

#ifndef USE_TSI_MALLOC

#define USE_TSI_MALLOC

#endif

/**< if HAL_GFX_MULTI_MEM_POOLS is defined, use HAL_GFX_MULTI_MEM_POOLS_CNT pools must be equal or less than 4. */

#ifndef HAL_GFX_MULTI_MEM_POOLS_CNT

#define HAL_GFX_MULTI_MEM_POOLS_CNT 1

#endif

这些配置主要配置 命令列表缓冲区和GPU 库所引用的内存池等,一般不用修改

注释上述配置是公共路径的通用配置, 其修改会影响所有引用这个文件的工程

3. 工程目录

graphics_animation_effects示例的源代码和工程文件位于:SDK_Folder\projects\peripheral\graphics\graphics_animation_effects,其中工程文件位于Keil_5文件夹。

双击打开graphics_animation_effects.uvprojx工程文件,在Keil中查看示例graphics_animation_effects工程目录结构

4. 应用代码介绍

graphics_animation_effects示例工程主要展现GPU的图像过渡效果。

该工程已适配FreeRTOS,通过FreeRTOS的系统心跳可计算图像的FPS。开发者可以通过禁用ENV_USE_FREERTOS宏来禁用FreeRTOS,通过自定义函数来计算图像的FPS。

路径:工程目录下的Src\application\graphics_animation_effects.c

名称:int graphics_animation_effects_main(void)

该函数为graphics_animation_effects示例工程GPU应用程序的主体代码入口,该函数完成外设初始化、缓冲区配置、渲染任务与屏幕刷新等。

int graphics_animation_effects_main(void)

{

/* Peripheral Initialization and Buffer Configuration */

int ret = init();

if (ret)

{

app_graphics_mem_free(s_fb.bo.base_virt);

return ret;

}

/* Rendering Tasks and Screen Refresh */

animation_effects_loop();

/* Destroy Command List and Memory Release */

hal_gfx_cl_destroy(&cl);

app_graphics_mem_free(s_fb.bo.base_virt);

return 0;

}

1. 外设初始化与缓冲区配置

路径:工程目录下的Src\application\graphics_animation_effects.c

名称:static int init(void)

该函数主要完成外设初始化与缓冲区配置,包括:

• 初始化OSPI、PSRAM外设模块(可选)

• 初始化GPU、DC外设模块

• 初始化帧缓冲区,申请合适的Texture Memory存储Texture Image(可选),并完成绑定工作

• 初始化CL所需的环形缓冲区

static int init(void)

{

/* Initialize OSPI, PSRAM Peripheral Modules */

app_graphics_ospi_params_t params = PSRAM_INIT_PARAMS_Default;

app_graphics_ospi_init(&params);

/* Initialize GPU, DC Peripheral Modules */

graphics_gpu_init(NULL);

graphics_dc_rm69330_qspi_lcd_init(LCD_RES_CURRENT, LCD_PIXEL_mode_24bit,GDC_MIPICFG_QSPI_RGB888_OPT0);

/* Initialize Graphics Memory Management */

app_graphics_mem_init((uint8_t*)GFX_MEM_BASE, GFX_MEM_SIZE);

/* Buffer Configuration */

load_objects();

/* Create Command List */

cl = hal_gfx_cl_create();

/* Bind Command List */

hal_gfx_cl_bind(&cl);

/* Set Clipping Rectangle */

hal_gfx_set_clip(0, 0, SHOW_AREA_X, SHOW_AREA_Y);

/* Bind Texture to HAL_GFX_TEX1 Slot (Foreground) */

hal_gfx_bind_src_tex(screen0.bo.base_phys,screen0.w, screen0.h,(hal_gfx_tex_format_t)(screen0.format),screen0.stride,(hal_gfx_tex_mode_t)(HAL_GFX_FILTER_BL |HAL_GFX_TEX_BORDER));

/* Bind Texture to HAL_GFX_TEX2 Slot (Background) */

hal_gfx_bind_src2_tex(screen1.bo.base_phys,screen1.w, screen1.h,(hal_gfx_tex_format_t)(screen1.format),screen1.stride,(hal_gfx_tex_mode_t)(HAL_GFX_FILTER_BL |HAL_GFX_TEX_BORDER));

/* Set Texture Default Color */

hal_gfx_set_tex_color(0);

/* Submit Current CL and Wait */

hal_gfx_cl_submit(&cl);

hal_gfx_cl_wait(&cl);

return 0;

}

名称:static void load_objects(void)

该函数主要完成缓冲区配置,包括初始化帧缓冲区,为GPU和DC配置全局Framebuffer参数,申请合适的Texture Memory存储Texture Image(可选)

static void load_objects(void)

{

/* Configure Framebuffer for GPU */

s_fb.bo = hal_gfx_fb_create(s_fb.w*s_fb.h*PIXEL_DEPTH_BYTES);

hal_gfx_buffer_map(&s_fb.bo);

/* Configure Framebuffer for DC */

#if HAL_GDC_DISPLAY_ENABLE >0u

s_dc_layer.resolution_x = s_fb.w;

s_dc_layer.resolution_y = s_fb.h;

#if TSCx_ENABLE > 0u

s_dc_layer.data_format = GDC_DATA_FORMAT_RGBA8888 ;

#else

s_dc_layer.data_format = GDC_DATA_FORMAT_RGBA8888 ;

#endif

s_dc_layer.row_stride = s_dc_layer.resolution_x*PIXEL_DEPTH_BYTES;

s_dc_layer.blendmode = HAL_GDC_BL_SIMPLE;

s_dc_layer.start_x = 0;

s_dc_layer.start_y = 0;

s_dc_layer.size_x = s_dc_layer.resolution_x;

s_dc_layer.size_y = s_dc_layer.resolution_y;

s_dc_layer.alpha = 0x80;

s_dc_layer.frame_baseaddr = (void*)s_fb.bo.base_phys;

#endif

printf("FB: V:%p P:0x%08x\n", (void *)s_fb.bo.base_virt,

(uint32_t)s_fb.bo.base_phys);

}

5. 渲染任务与屏幕刷新

路径:工程目录下的Src\application\graphics_animation_effects.c

名称:static void animation_effects_loop(void)

该函数主要构建GPU渲染任务的命令列表,包含GPU的各种图像过渡效果。最终通过DC外设模块,实时将图像刷新至屏幕。

static void animation_effects_loop(void)

{

float step = 0.f;

float step_step = ANIMATION_STEP_0_1;

float start_time = hal_gfx_get_time();

int frame = 0;

while (1)

{

/* Build GPU Rendering Tasks and Refresh Screen */

display(step, HAL_GFX_BL_SRC);

/* Realize Image Transition Effect of GPU */

if (step <= 0.f)

{

step = 0.f;

step_step = ANIMATION_STEP_0_1;

next_effect();

}

else if (step >= 1.f)

{

step = 1.f;

step_step = -ANIMATION_STEP_0_1;

next_effect();

}

step += step_step;

frame++;

/* Calculate FPS */

hal_gfx_calculate_fps_ext(start_time, frame);

}

}

名称:static void display(float step, uint32_t blendmode)

该函数主要构建GPU渲染任务的命令列表和通过DC外设模块实时将图像刷新至屏幕

static void display(float step, uint32_t blendmode)

{

/* Reset Position of Next Command to be Written to the Beginning */

hal_gfx_cl_rewind(&cl);

/* Bind Framebuffer to HAL_GFX_TEX0 Slot */

hal_gfx_bind_dst_tex((uint32_t)s_fb.bo.base_phys, s_fb.w, s_fb.h, (hal_gfx_tex_format_t)(s_fb.format), s_fb.stride);

/* GPU Image Transition Effect */

hal_gfx_transition(s_effect, HAL_GFX_TEX1, HAL_GFX_TEX2, blendmode, step, s_fb.w, s_fb.h);

/* Submit Current CL and Wait */

hal_gfx_cl_submit(&cl);

(void)hal_gfx_cl_wait(&cl);

/* Refresh Image to Screen via DC */

#if HAL_GDC_DISPLAY_ENABLE > 0u

app_graphics_dc_set_power_state(GDC_POWER_STATE_ACTIVE);

graphics_dc_rm69330_qspi_send_frame(s_dc_layer, DISPLAY_LCD_RES_X,DISPLAY_LCD_RES_Y);

#endif

}

三、结语

本文通过 GR5526 SDK 提供的 graphics_animation_effects 工程解析了 GPU使用的基本流程, 涉及的外设模块, 对代码进行了初步的注解解释.可以比较简单的就把 GPU 效果先玩起来, 再看看这个工程的编译和烧录到SK的效果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值