aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <jara@hensl.cz>2024-09-30 23:12:54 +0200
committerJaroslav Hensl <jara@hensl.cz>2024-09-30 23:12:54 +0200
commitc5f1ce22501a3bfb3879bee2f46c7b00ad6a4bba (patch)
treeda416b950080ec97d7283e0eccb2ff935b2f469d
parent8a688f4a16be99c75ed910d032330405d7a346cf (diff)
downloadvmdisp9x-c5f1ce22501a3bfb3879bee2f46c7b00ad6a4bba.tar.gz
Alternative cleanup for W95
-rw-r--r--3d_accel.h3
-rw-r--r--makefile2
-rw-r--r--vxd_main.c17
-rw-r--r--vxd_svga.c106
-rw-r--r--vxd_svga.h1
5 files changed, 124 insertions, 5 deletions
diff --git a/3d_accel.h b/3d_accel.h
index 9de1464..f96e90a 100644
--- a/3d_accel.h
+++ b/3d_accel.h
@@ -366,8 +366,9 @@ SVGA_OT_info_entry_t *SVGA_OT_setup();
void SVGA_flushcache();
-BOOL SVGA_vxdcmd(DWORD cmd);
+BOOL SVGA_vxdcmd(DWORD cmd, DWORD arg);
#define SVGA_CMD_INVALIDATE_FB 1
+#define SVGA_CMD_CLEANUP 2
#endif /* SVGA */
diff --git a/makefile b/makefile
index ca0a280..af30dcd 100644
--- a/makefile
+++ b/makefile
@@ -12,7 +12,7 @@ OBJS += &
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
-VER_BUILD = 86
+VER_BUILD = 87
FLAGS = -DDRV_VER_BUILD=$(VER_BUILD)
diff --git a/vxd_main.c b/vxd_main.c
index 0e0bf95..b17cfe4 100644
--- a/vxd_main.c
+++ b/vxd_main.c
@@ -574,6 +574,8 @@ void Device_Init_proc(DWORD VM)
#undef VDDFUNC
#undef VDDNAKED
+static DWORD io_open_cnt = 0;
+
/* process user space (PM32, RING-3) call */
DWORD __stdcall Device_IO_Control_proc(DWORD vmhandle, struct DIOCParams *params)
{
@@ -589,8 +591,19 @@ DWORD __stdcall Device_IO_Control_proc(DWORD vmhandle, struct DIOCParams *params
{
/* DX */
case DIOC_OPEN:
+ dbg_printf("DIOC_OPEN\n");
+ io_open_cnt++;
+ rc = 0;
+ break;
case DIOC_CLOSEHANDLE:
- dbg_printf(dbg_dic_system, params->dwIoControlCode);
+ io_open_cnt--;
+#ifdef SVGA
+ if(io_open_cnt == 0)
+ {
+ dbg_printf("Zero reference, do ALL cleanup!\n");
+ SVGA_AllProcessCleanup();
+ }
+#endif
rc = 0;
break;
case OP_FBHDA_SETUP:
@@ -716,7 +729,7 @@ DWORD __stdcall Device_IO_Control_proc(DWORD vmhandle, struct DIOCParams *params
rc = 0;
break;
case OP_SVGA_VXDCMD:
- outBuf[0] = (DWORD)SVGA_vxdcmd(inBuf[0]);
+ outBuf[0] = (DWORD)SVGA_vxdcmd(inBuf[0], inBuf[1]);
rc = 0;
break;
#ifdef DBGPRINT
diff --git a/vxd_svga.c b/vxd_svga.c
index 14bb300..e958183 100644
--- a/vxd_svga.c
+++ b/vxd_svga.c
@@ -337,12 +337,15 @@ void __declspec(naked) SVGA_IRQ_entry()
}
#endif
-BOOL SVGA_vxdcmd(DWORD cmd)
+BOOL SVGA_vxdcmd(DWORD cmd, DWORD arg)
{
switch(cmd)
{
case SVGA_CMD_INVALIDATE_FB:
return TRUE;
+ case SVGA_CMD_CLEANUP:
+ SVGA_ProcessCleanup(arg);
+ return TRUE;
}
return FALSE;
@@ -1691,3 +1694,104 @@ void SVGA_ProcessCleanup(DWORD pid)
End_Critical_Section();
}
+void SVGA_AllProcessCleanup()
+{
+ DWORD id;
+
+ /* some process are terminated when SVGA is disabled, clean not possible */
+ if(!svga_saved_state.enabled)
+ return;
+
+ Begin_Critical_Section(0);
+ if(svga_db != NULL)
+ {
+ /* clean surfaces */
+ for(id = 0; id < svga_db->surfaces_cnt; id++)
+ {
+ SVGA_DB_surface_t *sinfo = &svga_db->surfaces[id];
+ if(sinfo->pid != 0)
+ {
+ dbg_printf("Cleaning surface: %d\n", id);
+ if(sinfo->gmrId) // GB surface
+ {
+ DWORD cmd_offset = 0;
+ SVGA3dCmdBindGBSurface *unbind;
+ SVGA3dCmdDestroySurface *destgb;
+
+ wait_for_cmdbuf();
+ unbind = SVGA_cmd3d_ptr(cmdbuf, &cmd_offset, SVGA_3D_CMD_BIND_GB_SURFACE, sizeof(SVGA3dCmdBindGBSurface));
+ unbind->sid = id+1;
+ unbind->mobid = SVGA3D_INVALID_ID;
+
+ destgb = SVGA_cmd3d_ptr(cmdbuf, &cmd_offset, SVGA_3D_CMD_DESTROY_GB_SURFACE, sizeof(SVGA3dCmdDestroySurface));
+ destgb->sid = id+1;
+
+ submit_cmdbuf(cmd_offset, SVGA_CB_SYNC, 0);
+ }
+ else
+ {
+ DWORD cmd_offset = 0;
+ SVGA3dCmdDestroySurface *dest;
+
+ wait_for_cmdbuf();
+ dest = SVGA_cmd3d_ptr(cmdbuf, &cmd_offset, SVGA_3D_CMD_SURFACE_DESTROY, sizeof(SVGA3dCmdDestroySurface));
+ dest->sid = id+1;
+
+ submit_cmdbuf(cmd_offset, SVGA_CB_SYNC, 0);
+ }
+
+ sinfo->pid = 0;
+ map_reset(svga_db->surfaces_map, id);
+ }
+ } // for
+
+ /* clean contexts */
+ for(id = 0; id < svga_db->contexts_cnt; id++)
+ {
+ SVGA_DB_context_t *cinfo = &svga_db->contexts[id];
+
+ if(cinfo->pid != 0)
+ {
+ DWORD cmd_offset = 0;
+ dbg_printf("Cleaning context: %d\n", id);
+
+ wait_for_cmdbuf();
+ if(cinfo->gmrId != 0) /* GB Context */
+ {
+ SVGA3dCmdDXDestroyContext *dest_ctx_gb =
+ SVGA_cmd3d_ptr(cmdbuf, &cmd_offset, SVGA_3D_CMD_DX_DESTROY_CONTEXT, sizeof(SVGA3dCmdDXDestroyContext));
+ dest_ctx_gb->cid = id+1;
+ submit_cmdbuf(cmd_offset, SVGA_CB_SYNC, 0);
+ }
+ else
+ {
+ SVGA3dCmdDestroyContext *dest_ctx =
+ SVGA_cmd3d_ptr(cmdbuf, &cmd_offset, SVGA_3D_CMD_CONTEXT_DESTROY, sizeof(SVGA3dCmdDestroyContext));
+ dest_ctx->cid = id+1;
+ submit_cmdbuf(cmd_offset, SVGA_CB_SYNC, 0);
+ }
+
+ cinfo->pid = 0;
+ map_reset(svga_db->contexts_map, id);
+ }
+ } // for
+
+ /* clean region */
+ for(id = 0; id < svga_db->regions_cnt; id++)
+ {
+ SVGA_DB_region_t *rinfo = &svga_db->regions[id];
+ if(rinfo->pid != 0)
+ {
+ dbg_printf("Cleaning regions: %d\n", id);
+
+ SVGA_region_free(&rinfo->info);
+ rinfo->pid = 0;
+ map_reset(svga_db->regions_map, id);
+ }
+ } // for
+
+ dbg_printf("Cleanup: used memory: %ld\n", svga_db->stat_regions_usage);
+ } // db != NULL
+
+ End_Critical_Section();
+}
diff --git a/vxd_svga.h b/vxd_svga.h
index 93f525c..2bd487e 100644
--- a/vxd_svga.h
+++ b/vxd_svga.h
@@ -40,6 +40,7 @@ void update_pm16(DWORD vm, DWORD oldmap, DWORD linear, DWORD size);
void SVGA_Sync();
void SVGA_Flush_CB();
void SVGA_ProcessCleanup(DWORD pid);
+void SVGA_AllProcessCleanup();
/* mouse */
BOOL SVGA_mouse_hw();