2022-05-27 11:57:55 +02:00
|
|
|
#include <vhex/display/stack.h>
|
|
|
|
#include <vhex/display/shader.h>
|
2022-06-20 16:29:28 +02:00
|
|
|
#include <vhex/display/interface.h>
|
2022-05-27 11:57:55 +02:00
|
|
|
#include <vhex/driver.h>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
struct {
|
|
|
|
struct dstack_action *action;
|
|
|
|
int slots;
|
|
|
|
int idx;
|
|
|
|
} pool;
|
|
|
|
struct dstack_drv_interface driver;
|
|
|
|
} dstack_info = {
|
|
|
|
.pool = {
|
|
|
|
.action = NULL,
|
|
|
|
.slots = 0,
|
|
|
|
.idx = 0
|
|
|
|
},
|
|
|
|
.driver = {
|
|
|
|
.frame_start = NULL,
|
|
|
|
.frame_frag_next = NULL,
|
|
|
|
.frame_frag_send = NULL,
|
|
|
|
.frame_end = NULL,
|
2022-05-28 21:55:48 +02:00
|
|
|
.display_width = 0,
|
|
|
|
.display_height = 0
|
2022-05-27 11:57:55 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-06-19 20:11:52 +02:00
|
|
|
//---
|
2022-05-27 11:57:55 +02:00
|
|
|
// Kernel API
|
2022-06-19 20:11:52 +02:00
|
|
|
//---
|
2022-05-27 11:57:55 +02:00
|
|
|
|
|
|
|
/* dstack_init() : Initialise the draw stack (should not be involved) */
|
2022-06-20 16:29:28 +02:00
|
|
|
int dstack_init(void)
|
2022-05-27 11:57:55 +02:00
|
|
|
{
|
|
|
|
dstack_info.pool.action = calloc(
|
2022-06-20 16:29:28 +02:00
|
|
|
16,
|
2022-06-10 21:28:51 +02:00
|
|
|
sizeof(struct dstack_action)
|
2022-05-27 11:57:55 +02:00
|
|
|
);
|
|
|
|
dstack_info.pool.idx = -1;
|
2022-06-20 16:29:28 +02:00
|
|
|
dstack_info.pool.slots = 16;
|
|
|
|
|
2022-05-27 11:57:55 +02:00
|
|
|
for (int i = 0; i < dstack_info.pool.slots; ++i) {
|
2022-06-10 21:28:51 +02:00
|
|
|
dstack_info.pool.action[i].shader.table = calloc(
|
2022-06-20 16:29:28 +02:00
|
|
|
4,
|
2022-06-21 18:43:11 +02:00
|
|
|
sizeof(dshader_call_t)
|
2022-05-27 11:57:55 +02:00
|
|
|
);
|
2022-06-20 16:29:28 +02:00
|
|
|
dstack_info.pool.action[i].shader.number = 4;
|
2022-06-10 21:28:51 +02:00
|
|
|
dstack_info.pool.action[i].shader.idx = -1;
|
2022-05-27 11:57:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
struct vhex_driver *driver = vhex_driver_table();
|
|
|
|
for (int i = 0; i < vhex_driver_count(); ++i) {
|
|
|
|
if (driver[i].flags.DISPLAY) {
|
|
|
|
memcpy(
|
|
|
|
&dstack_info.driver,
|
|
|
|
driver[i].module_data,
|
|
|
|
sizeof(struct dstack_drv_interface)
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* dstack_quit() : Uninit the draw stack */
|
|
|
|
int dstack_quit(void)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < dstack_info.pool.slots; ++i) {
|
|
|
|
free(dstack_info.pool.action[i].shader.table);
|
|
|
|
dstack_info.pool.action[i].shader.number = 0;
|
2022-06-10 21:28:51 +02:00
|
|
|
dstack_info.pool.action[i].shader.idx = -1;
|
2022-05-27 11:57:55 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-06-21 18:43:11 +02:00
|
|
|
//---
|
2022-05-27 11:57:55 +02:00
|
|
|
// Internal API
|
2022-06-21 18:43:11 +02:00
|
|
|
//---
|
|
|
|
|
|
|
|
/* dstack_action_add_shader() : add a shader in action */
|
|
|
|
static void dstack_action_add_shader(
|
|
|
|
struct dstack_action *action,
|
|
|
|
dshader_call_t *shader
|
|
|
|
) {
|
|
|
|
action->shader.idx += 1;
|
|
|
|
if (action->shader.idx >= action->shader.number) {
|
|
|
|
action->shader.number += action->shader.number;
|
|
|
|
action->shader.table = reallocarray(
|
|
|
|
action->shader.table,
|
|
|
|
action->shader.number,
|
|
|
|
sizeof(dshader_call_t)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
memcpy(
|
|
|
|
&action->shader.table[action->shader.idx],
|
|
|
|
shader,
|
|
|
|
sizeof(dshader_call_t)
|
|
|
|
);
|
|
|
|
}
|
2022-05-27 11:57:55 +02:00
|
|
|
|
2022-06-21 18:43:11 +02:00
|
|
|
/* dstack_action_alloc() : allocate a new dstack action with shader */
|
2022-05-28 21:55:48 +02:00
|
|
|
static did_t dstack_action_alloc(
|
|
|
|
dstack_call_t *call,
|
|
|
|
dshader_call_t *shader,
|
|
|
|
void (*quit)(uint32_t *arg)
|
|
|
|
) {
|
2022-05-27 11:57:55 +02:00
|
|
|
struct dstack_action *action;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
dstack_info.pool.idx += 1;
|
|
|
|
if (dstack_info.pool.idx >= dstack_info.pool.slots) {
|
|
|
|
dstack_info.pool.slots += dstack_info.pool.slots;
|
2022-06-10 21:28:51 +02:00
|
|
|
dstack_info.pool.action = reallocarray(
|
2022-05-27 11:57:55 +02:00
|
|
|
dstack_info.pool.action,
|
2022-06-10 21:28:51 +02:00
|
|
|
dstack_info.pool.slots,
|
|
|
|
sizeof(struct dstack_action)
|
2022-05-27 11:57:55 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
action = &dstack_info.pool.action[dstack_info.pool.idx];
|
|
|
|
memcpy(&action->call, call, sizeof(dstack_call_t));
|
2022-06-02 10:16:25 +02:00
|
|
|
action->shader.idx = -1;
|
2022-05-27 11:57:55 +02:00
|
|
|
if (shader != NULL) {
|
|
|
|
for (i = 0; shader[i].routine != NULL; ++i) {
|
2022-06-21 18:43:11 +02:00
|
|
|
dstack_action_add_shader(action, &shader[i]);
|
2022-05-27 11:57:55 +02:00
|
|
|
}
|
|
|
|
}
|
2022-06-10 21:28:51 +02:00
|
|
|
action->quit = quit;
|
2022-05-27 11:57:55 +02:00
|
|
|
return dstack_info.pool.idx;
|
|
|
|
}
|
|
|
|
|
2022-06-21 18:43:11 +02:00
|
|
|
/* dstack_action_get() : return the display action using its dislay ID */
|
|
|
|
struct dstack_action *dstack_action_get(did_t did)
|
|
|
|
{
|
|
|
|
if (did > dstack_info.pool.idx)
|
|
|
|
return NULL;
|
|
|
|
return &dstack_info.pool.action[did];
|
|
|
|
}
|
|
|
|
|
2022-05-28 21:55:48 +02:00
|
|
|
//---
|
2022-05-27 11:57:55 +02:00
|
|
|
// Public API
|
2022-05-28 21:55:48 +02:00
|
|
|
//---
|
2022-05-27 11:57:55 +02:00
|
|
|
|
|
|
|
/* dstack_add_action() : add a new action in the draw stack */
|
2022-05-28 21:55:48 +02:00
|
|
|
did_t dstack_add_action(
|
|
|
|
dstack_call_t *call,
|
|
|
|
dshader_call_t *shader,
|
|
|
|
void (*quit)(uint32_t *arg)
|
|
|
|
) {
|
2022-06-21 18:43:11 +02:00
|
|
|
return dstack_action_alloc(call, shader, quit);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* dstack_add_shader() : add shader on particular action */
|
|
|
|
int dstack_add_shader(did_t did, dshader_call_t *call)
|
|
|
|
{
|
|
|
|
struct dstack_action *action;
|
|
|
|
|
|
|
|
if (call == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
action = dstack_action_get(did);
|
|
|
|
if (action == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
dstack_action_add_shader(action, call);
|
|
|
|
return 0;
|
2022-05-27 11:57:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* dstack_render(): render a frame */
|
|
|
|
void dstack_render(void)
|
|
|
|
{
|
2022-06-20 16:29:28 +02:00
|
|
|
dsurface_t surface;
|
2022-05-27 11:57:55 +02:00
|
|
|
struct dstack_action *action;
|
|
|
|
|
|
|
|
action = dstack_info.pool.action;
|
2022-05-28 21:55:48 +02:00
|
|
|
|
2022-05-27 11:57:55 +02:00
|
|
|
dstack_info.driver.frame_start(&surface);
|
|
|
|
do {
|
|
|
|
for (int i = 0; i <= dstack_info.pool.idx; ++i) {
|
|
|
|
action[i].call.routine(&surface, action[i].call.args);
|
2022-06-02 10:16:25 +02:00
|
|
|
for (int j = 0; j <= action[i].shader.idx; j++) {
|
2022-05-27 11:57:55 +02:00
|
|
|
action[i].shader.table[j].routine(
|
|
|
|
&surface,
|
|
|
|
action[i].call.args,
|
VxKernel 0.6.0-13 : Add keyboard API + update timer API
@add
<> include/vhex/driver/mpu/sh/sh7305/keysc
| add internal driver primitives
<> include/vhex/driver/mpu/sh/sh7305/tmu
| add internal driver primitives
<> include/vhex/keyboard
| add getkey* (high-level) API
| add key event API
| add key status API
| add keycode information
| add keyboard driver interface
@update
<> include/vhex/driver
| add KEYBOARD driver flags
<> include/vhex/keyboard
| isolate each part of the keyboard module
| link the keycache part with the driver-provided keycache information
<> src/drivers/mpu/sh/sh7305/keysc
| use the new keycache API (high-level interrupt handler)
| update keycache API
| link the new API in the driver device
<> src/drivers/mpu/sh/sh7305/tmu
| add timer reservation (WIP)
| use a "reservation" cache to known which timer is free instead of hardware
| rename internal functions
<> src/module/display
| Now, by default, DSTACK_CALL() create a pointer on a dstack_call_t
| use dsubimage dstack primitive in dimage()
@fix
<> board/fxcg50/fxcg50.ld
| remove the IL-memory and allow only the X-memory area. This because the
bootloader uses the IL-memory for DMA transfer and other "low-level"
routine used by Gint.
Moreover, I originally try to move each "display-driver" in this place,
but after some profiling and tests, the dclear()/dupdate() combo went from
9155us up to 33250us (for many reason). So, I keep this area free, but I
moved-back from RAM display routines.
<> board/fxcg50/initialize
| remove "section" copy. This role has been delegated to the bootload (vxBoot)
because, in the final ELF file generated by GCC, many relocalization
information for the IL/X memory has been set and the bootloader cannot
performs general relocalization.
So, all "special section/memory" displacement has been moved in the
bootloader and we don't have to worrying about the section copy.
<> src/drivers/mpu/sh/sh7305/tmu
| fix delay calculation in timer reload primitive
| disable interruption for profiling timer
<> src/module/dislay/
| fix shader index used during the dstack_render()
| fix many errors in dimage() shadow render (WIP)
2022-06-24 15:33:36 +02:00
|
|
|
action[i].shader.table[j].args
|
2022-05-27 11:57:55 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dstack_info.driver.frame_frag_send(&surface);
|
|
|
|
} while (dstack_info.driver.frame_frag_next(&surface) == 0);
|
|
|
|
dstack_info.driver.frame_end(&surface);
|
2022-06-10 21:28:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* dstack_invalidate() : Invalidate the draw stack (reset) */
|
|
|
|
int dstack_invalidate(void)
|
|
|
|
{
|
|
|
|
struct dstack_action *action;
|
2022-05-28 21:55:48 +02:00
|
|
|
|
2022-06-10 21:28:51 +02:00
|
|
|
action = dstack_info.pool.action;
|
2022-05-28 21:55:48 +02:00
|
|
|
for (int i = 0; i <= dstack_info.pool.idx; ++i) {
|
|
|
|
if (action[i].quit != NULL)
|
|
|
|
action[i].quit(action[i].call.args);
|
|
|
|
}
|
2022-06-10 21:28:51 +02:00
|
|
|
dstack_info.pool.idx = -1;
|
2022-05-27 11:57:55 +02:00
|
|
|
}
|
2022-05-28 21:55:48 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* dstack_display_width() : return the display width */
|
2022-06-02 10:16:25 +02:00
|
|
|
size_t dstack_display_width(void)
|
2022-05-28 21:55:48 +02:00
|
|
|
{
|
|
|
|
return dstack_info.driver.display_width;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* dstack_display_height() : return the display height */
|
2022-06-02 10:16:25 +02:00
|
|
|
size_t dstack_display_height(void)
|
2022-05-28 21:55:48 +02:00
|
|
|
{
|
|
|
|
return dstack_info.driver.display_height;
|
|
|
|
}
|