aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <jara@hensl.cz>2024-07-27 18:51:09 +0200
committerJaroslav Hensl <jara@hensl.cz>2024-07-27 18:51:09 +0200
commitc8b19a5217ea94727626ad08ce2acae6cc4b8540 (patch)
tree96c6f8ad65712060663e97b601286712aa0e955a
parent6ce40234ffeddfc716389c8e89d336b9ff8a838b (diff)
downloadvmdisp9x-c8b19a5217ea94727626ad08ce2acae6cc4b8540.tar.gz
fix: garbage in fifo, optimized async commands
-rw-r--r--3d_accel.h14
-rw-r--r--makefile2
-rw-r--r--vxd_lib.c43
-rw-r--r--vxd_lib.h1
-rw-r--r--vxd_main.c95
-rw-r--r--vxd_strings.h12
-rw-r--r--vxd_svga.c21
-rw-r--r--vxd_svga.h9
-rw-r--r--vxd_svga_cb.c306
-rw-r--r--vxd_svga_mem.c149
10 files changed, 447 insertions, 205 deletions
diff --git a/3d_accel.h b/3d_accel.h
index 1d9fcec..06ec786 100644
--- a/3d_accel.h
+++ b/3d_accel.h
@@ -250,12 +250,14 @@ BOOL SVGA_init_hw();
BOOL SVGA_valid();
-#define SVGA_CB_USE_CONTEXT_DEVICE 0x80000000UL
-#define SVGA_CB_SYNC 0x40000000UL
-#define SVGA_CB_FORCE_FIFO 0x20000000UL
-#define SVGA_CB_FORCE_FENCE 0x10000000UL
-#define SVGA_CB_PRESENT_ASYNC 0x08000000UL
-#define SVGA_CB_PRESENT_GPU 0x04000000UL
+#define SVGA_CB_USE_CONTEXT_DEVICE 0x80000000UL /* CB control command */
+#define SVGA_CB_SYNC 0x40000000UL /* wait to command complete */
+#define SVGA_CB_FORCE_FIFO 0x20000000UL /* insert this command to FIFO, event the CB is working */
+#define SVGA_CB_FORCE_FENCE 0x10000000UL /* force insert fence */
+#define SVGA_CB_PRESENT 0x08000000UL /* this is 'present' command: WAIT for previous 'present' and 'render' to complete */
+#define SVGA_CB_DIRTY_SURFACE 0x04000000UL /* need reread GPU SURFACE first, can combine with SVGA_CB_PRESENT */
+#define SVGA_CB_RENDER 0x02000000UL /* this is 'render' cmd, WAIT for 'present', 'update' */
+#define SVGA_CB_UPDATE 0x01000000UL /* this is 'update' cmd, updates screen on HOST, WAIT for 'update', 'present' */
// SVGA_CB_FLAG_DX_CONTEXT
diff --git a/makefile b/makefile
index f8bb043..67836e8 100644
--- a/makefile
+++ b/makefile
@@ -12,7 +12,7 @@ OBJS += &
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
-VER_BUILD = 67
+VER_BUILD = 68
FLAGS = -DDRV_VER_BUILD=$(VER_BUILD)
diff --git a/vxd_lib.c b/vxd_lib.c
index cff6666..9be9cdc 100644
--- a/vxd_lib.c
+++ b/vxd_lib.c
@@ -37,6 +37,8 @@ THE SOFTWARE.
#include "code32.h"
+#include "vxd_strings.h"
+
/* some CRT */
void memset(void *dst, int c, unsigned int size)
{
@@ -153,20 +155,49 @@ DWORD Get_VMM_Version()
return ver;
}
+static DWORD cs_count = 0;
+
volatile void __cdecl Begin_Critical_Section(ULONG Flags)
{
static ULONG sFlags;
sFlags = Flags;
- _asm push ecx
- _asm mov ecx, [sFlags]
- VMMCall(Begin_Critical_Section);
- _asm pop ecx
+ if(cs_count == 0)
+ {
+ _asm push ecx
+ _asm mov ecx, [sFlags]
+ VMMCall(Begin_Critical_Section);
+ _asm pop ecx
+ }
+ cs_count++;
}
-volatile void __cdecl End_Critical_Section()
+volatile void __cdecl End_Critical_Section()
{
- VMMCall(End_Critical_Section);
+ if(cs_count == 0)
+ {
+ dbg_printf(dbg_cs_underflow);
+ return;
+ }
+
+ --cs_count;
+ if(cs_count == 0)
+ {
+ VMMCall(End_Critical_Section);
+ }
+}
+
+void Cleanup_Critical_Section()
+{
+ if(cs_count > 0)
+ {
+ dbg_printf(dbg_cs_active);
+
+ while(cs_count != 0)
+ {
+ End_Critical_Section();
+ }
+ }
}
ULONG __cdecl Create_Semaphore(ULONG TokenCount)
diff --git a/vxd_lib.h b/vxd_lib.h
index 96453e5..f385422 100644
--- a/vxd_lib.h
+++ b/vxd_lib.h
@@ -43,6 +43,7 @@ DWORD __cdecl _RegCloseKey(DWORD hKey);
DWORD __cdecl _RegQueryValueEx(DWORD hKey, char *lpszValueName, DWORD *lpdwReserved, DWORD *lpdwType, BYTE *lpbData, DWORD *lpcbData);
volatile void __cdecl Begin_Critical_Section(ULONG Flags);
volatile void __cdecl End_Critical_Section();
+void Cleanup_Critical_Section();
ULONG __cdecl Create_Semaphore(ULONG TokenCount);
void __cdecl Destroy_Semaphore(ULONG SemHandle);
void __cdecl Wait_Semaphore(ULONG semHandle, ULONG flags);
diff --git a/vxd_main.c b/vxd_main.c
index dfd56dd..7de327b 100644
--- a/vxd_main.c
+++ b/vxd_main.c
@@ -48,6 +48,7 @@ THE SOFTWARE.
#ifdef SVGA
# include "svga_all.h"
+# include "vxd_svga.h"
#endif
#include "version.h"
@@ -368,6 +369,8 @@ WORD __stdcall VXD_API_Proc(PCRS_32 state)
}
+ Cleanup_Critical_Section();
+
if(rc == 0xFFFF)
{
state->Client_EFlags |= 0x1; // set carry
@@ -492,6 +495,7 @@ DWORD __stdcall Device_IO_Control_proc(DWORD vmhandle, struct DIOCParams *params
{
DWORD *inBuf = (DWORD*)params->lpInBuffer;
DWORD *outBuf = (DWORD*)params->lpOutBuffer;
+ DWORD rc = 1;
// dbg_printf(dbg_deviceiocontrol, params->dwIoControlCode);
@@ -501,58 +505,74 @@ DWORD __stdcall Device_IO_Control_proc(DWORD vmhandle, struct DIOCParams *params
case DIOC_OPEN:
case DIOC_CLOSEHANDLE:
dbg_printf(dbg_dic_system, params->dwIoControlCode);
- return 0;
+ rc = 0;
+ break;
case OP_FBHDA_SETUP:
outBuf[0] = (DWORD)FBHDA_setup();
- return 0;
+ rc = 0;
+ break;
case OP_FBHDA_ACCESS_BEGIN:
FBHDA_access_begin(inBuf[0]);
- return 0;
+ rc = 0;
+ break;
case OP_FBHDA_ACCESS_END:
FBHDA_access_end(inBuf[0]);
- return 0;
+ rc = 0;
+ break;
case OP_FBHDA_ACCESS_RECT:
FBHDA_access_rect(inBuf[0], inBuf[1], inBuf[2], inBuf[3]);
- return 0;
+ rc = 0;
+ break;
case OP_FBHDA_SWAP:
outBuf[0] = FBHDA_swap(inBuf[0]);
- return 0;
+ rc = 0;
+ break;
case OP_FBHDA_CLEAN:
FBHDA_clean();
- return 0;
+ rc = 0;
+ break;
case OP_FBHDA_PALETTE_SET:
FBHDA_palette_set(inBuf[0], inBuf[1]);
- return 0;
+ rc = 0;
+ break;
case OP_FBHDA_PALETTE_GET:
outBuf[0] = FBHDA_palette_get(inBuf[0]);
- return 0;
+ rc = 0;
+ break;
#ifdef SVGA
case OP_SVGA_VALID:
outBuf[0] = SVGA_valid();
- return 0;
+ rc = 0;
+ break;
case OP_SVGA_CMB_ALLOC:
outBuf[0] = (DWORD)SVGA_CMB_alloc();
- return 0;
+ rc = 0;
+ break;
case OP_SVGA_CMB_FREE:
SVGA_CMB_free((DWORD*)inBuf[0]);
- return 0;
+ rc = 0;
+ break;
case OP_SVGA_CMB_SUBMIT:
{
SVGA_CMB_submit_io_t *inio = (SVGA_CMB_submit_io_t*)inBuf;
SVGA_CMB_status_t *status = (SVGA_CMB_status_t*)outBuf;
SVGA_CMB_submit(inio->cmb, inio->cmb_size, status, inio->flags, inio->DXCtxId);
- return 0;
+ rc = 0;
+ break;
}
case OP_SVGA_FENCE_GET:
outBuf[0] = SVGA_fence_get();
- return 0;
+ rc = 0;
+ break;
case OP_SVGA_FENCE_QUERY:
SVGA_fence_query(&outBuf[0], &outBuf[1]);
- return 0;
+ rc = 0;
+ break;
case OP_SVGA_FENCE_WAIT:
SVGA_fence_wait(inBuf[0]);
- return 0;
+ rc = 0;
+ break;
case OP_SVGA_REGION_CREATE:
{
SVGA_region_info_t *inio = (SVGA_region_info_t*)inBuf;
@@ -567,50 +587,65 @@ DWORD __stdcall Device_IO_Control_proc(DWORD vmhandle, struct DIOCParams *params
SVGA_flushcache();
SVGA_region_create(outio);
}
- return 0;
+ rc = 0;
+ break;
}
case OP_SVGA_REGION_FREE:
{
SVGA_region_info_t *inio = (SVGA_region_info_t*)inBuf;
SVGA_region_free(inio);
- return 0;
+ rc = 0;
+ break;
}
case OP_SVGA_QUERY:
outBuf[0] = SVGA_query(inBuf[0], inBuf[1]);
- return 0;
+ rc = 0;
+ break;
case OP_SVGA_QUERY_VECTOR:
SVGA_query_vector(inBuf[0], inBuf[1], inBuf[2], outBuf);
- return 0;
+ rc = 0;
+ break;
case OP_SVGA_DB_SETUP:
outBuf[0] = (DWORD)SVGA_DB_setup();
- return 0;
+ rc = 0;
+ break;
case OP_SVGA_OT_SETUP:
outBuf[0] = (DWORD)SVGA_OT_setup();
- return 0;
+ rc = 0;
+ break;
case OP_SVGA_FLUSHCACHE:
SVGA_flushcache();
- return 0;
+ rc = 0;
+ break;
case OP_SVGA_VXDCMD:
outBuf[0] = (DWORD)SVGA_vxdcmd(inBuf[0]);
- return 0;
+ rc = 0;
+ break;
#ifdef DBGPRINT
/* export some mouse function for debuging */
case OP_MOUSE_MOVE:
mouse_move(inBuf[0], inBuf[1]);
- return 0;
+ rc = 0;
+ break;
case OP_MOUSE_SHOW:
mouse_show();
- return 0;
+ rc = 0;
+ break;
case OP_MOUSE_HIDE:
mouse_hide();
- return 0;
+ rc = 0;
+ break;
#endif /*DBGPRINT */
#endif /* SVGA */
+ default:
+ dbg_printf(dbg_dic_unknown, params->dwIoControlCode);
+ break;
}
-
- dbg_printf(dbg_dic_unknown, params->dwIoControlCode);
- return 1;
+ Cleanup_Critical_Section();
+// dbg_printf(dbg_deviceiocontrol_leave);
+
+ return rc;
}
void Device_Init_proc()
diff --git a/vxd_strings.h b/vxd_strings.h
index 88188dd..5db428e 100644
--- a/vxd_strings.h
+++ b/vxd_strings.h
@@ -67,7 +67,8 @@ DSTR(dbg_cmd_on, "SVGA_CMB_submit: ptr=%X, first cmd=%X, flags=%X, size=%d\n");
DSTR(dbg_cmd_off, "SVGA_CMB_submit: end - cmd: %X\n");
DSTR(dbg_cmd_error, "CB error: %d, first cmd %X (error at %d)\n");
-DSTR(dbg_deviceiocontrol, "DeviceIoControl(%x);\n");
+DSTR(dbg_deviceiocontrol, "DeviceIoControl(%x)\n");
+DSTR(dbg_deviceiocontrol_leave, "DeviceIoControl Leave\n");
DSTR(dbg_gmr, "GMR: %ld at %X\n");
DSTR(dbg_gmr_succ, "GMR ALLOC: %ld (size: %ld)\n");
@@ -150,7 +151,7 @@ DSTR(dbg_irq_install_fail, "IRQ(%d) found, but cannot be traped\n");
DSTR(dbg_no_irq, "No IRQ enabled\n");
-DSTR(dbg_disable, "HW disable");
+DSTR(dbg_disable, "HW disable\n");
DSTR(dbg_pt_build, "PT_build(%ld): BASE=%lX TYPE=%ld USER=%lp\n");
DSTR(dbg_pt_build_2, "PT_build(%ld): pt1_entries=%ld, pt2_entries=%ld\n");
@@ -162,6 +163,13 @@ DSTR(dbg_region_2, "SVGA_region_create #2: %ld\n");
DSTR(dbg_cb_error, "Error (%ld): offset %ld, error command: %ld\n");
+DSTR(dbg_cs_underflow, "WARNING: closing inactive CS!\n");
+DSTR(dbg_cs_active, "WARNING: CS is still active!\n");
+
+DSTR(dbg_fence_wait, "SVGA_fence_wait(%lu) from line %ld\n");
+
+DSTR(dbg_queue_check, "CB_queue_check\n");
+
#undef DSTR
#endif
diff --git a/vxd_svga.c b/vxd_svga.c
index 7b5b44e..befc82e 100644
--- a/vxd_svga.c
+++ b/vxd_svga.c
@@ -81,7 +81,7 @@ void *ctlbuf = NULL;
/* guest frame buffer is dirty */
BOOL ST_FB_invalid = FALSE;
-DWORD present_fence = 0;
+//DWORD present_fence = 0;
/*
* strings
*/
@@ -255,8 +255,14 @@ BOOL SVGA_fence_is_passed(DWORD fence_id)
return FALSE;
}
+#ifndef DBGPRINT
void SVGA_fence_wait(DWORD fence_id)
+#else
+void SVGA_fence_wait_dbg(DWORD fence_id, int line)
+#endif
{
+// dbg_printf(dbg_fence_wait, fence_id, line);
+
for(;;)
{
if(SVGA_fence_is_passed(fence_id))
@@ -264,6 +270,7 @@ void SVGA_fence_wait(DWORD fence_id)
break;
}
+#if 1
if(cb_support && cb_context0)
{
if(CB_queue_check(NULL))
@@ -273,6 +280,7 @@ void SVGA_fence_wait(DWORD fence_id)
return;
}
}
+#endif
SVGA_Sync();
}
}
@@ -1071,12 +1079,7 @@ void FBHDA_access_rect(DWORD left, DWORD top, DWORD right, DWORD bottom)
if(fb_lock_cnt++ == 0)
{
BOOL readback = FALSE;
-
- if(present_fence != 0)
- {
- SVGA_fence_wait(present_fence);
-// readback = TRUE;
- }
+ SVGA_CMB_wait_update();
if(ST_FB_invalid)
{
@@ -1173,7 +1176,7 @@ void FBHDA_access_end(DWORD flags)
stupdate->rect.w = w;
stupdate->rect.h = h;
- submit_cmdbuf(cmd_offset, SVGA_CB_PRESENT_ASYNC, 0);
+ submit_cmdbuf(cmd_offset, SVGA_CB_UPDATE, 0);
}
else if(hda->bpp == 32)
{
@@ -1188,7 +1191,7 @@ void FBHDA_access_end(DWORD flags)
cmd_update->width = hda->width;
cmd_update->height = hda->height;
- submit_cmdbuf(cmd_offset, SVGA_CB_PRESENT_ASYNC, 0);
+ submit_cmdbuf(cmd_offset, SVGA_CB_UPDATE, 0);
}
} // fb_lock_cnt == 0
diff --git a/vxd_svga.h b/vxd_svga.h
index 299089a..9e4eadf 100644
--- a/vxd_svga.h
+++ b/vxd_svga.h
@@ -25,6 +25,14 @@ BOOL SVGA_fence_is_passed(DWORD fence_id);
DWORD SVGA_fence_passed();
DWORD SVGA_GetDevCap(DWORD search_id);
+#ifdef DBGPRINT
+void SVGA_fence_wait_dbg(DWORD fence_id, int line);
+
+#define SVGA_fence_wait(_fence) SVGA_fence_wait_dbg(_fence, __LINE__)
+
+#endif
+
+
/* screen target */
extern BOOL st_used;
extern DWORD st_flags;
@@ -63,5 +71,6 @@ void SVGA_CMB_free(DWORD *cmb);
void SVGA_CB_start();
void SVGA_CB_stop();
void SVGA_CB_restart();
+void SVGA_CMB_wait_update();
#endif /* __VXD_SVGA_H__INCLUDED__ */
diff --git a/vxd_svga_cb.c b/vxd_svga_cb.c
index 27d41fa..17df34f 100644
--- a/vxd_svga_cb.c
+++ b/vxd_svga_cb.c
@@ -44,6 +44,10 @@ THE SOFTWARE.
* types
*/
+#define CBQ_PRESENT 0x01
+#define CBQ_RENDER 0x02
+#define CBQ_UPDATE 0x04
+
#pragma pack(push)
#pragma pack(1)
typedef struct _cb_enable_t
@@ -75,7 +79,7 @@ extern BOOL gb_support;
extern BOOL cb_support;
extern BOOL cb_context0;
-extern DWORD present_fence;
+//extern DWORD present_fence;
extern BOOL ST_FB_invalid;
BOOL CB_queue_check(SVGACBHeader *tracked);
@@ -90,7 +94,6 @@ static uint64 cb_next_id = {0, 0};
/*
* Macros
*/
-
#define WAIT_FOR_CB(_cb, _forcesync) \
do{ \
/*dbg_printf(dbg_wait_cb, __LINE__);*/ \
@@ -264,14 +267,36 @@ inline BOOL CB_queue_check_inline(SVGACBHeader *tracked)
BOOL CB_queue_check(SVGACBHeader *tracked)
{
+// dbg_printf(dbg_queue_check);
return CB_queue_check_inline(tracked);
}
-void CB_queue_insert(SVGACBHeader *cb)
+static BOOL CB_queue_is_flags_set(DWORD flags)
+{
+ cb_queue_t *item = cb_queue_info.first;
+
+ if(flags == 0) return FALSE;
+
+ while(item != NULL)
+ {
+ if((item->flags & flags) != 0)
+ {
+ return TRUE;
+ }
+
+ item = item->next;
+ }
+
+ return FALSE;
+}
+
+void CB_queue_insert(SVGACBHeader *cb, DWORD flags)
{
cb_queue_t *item = (cb_queue_t*)(cb-1);
item->next = NULL;
-
+ item->flags = flags;
+ item->data_size = cb->length;
+
if(cb_queue_info.last != NULL)
{
cb_queue_info.last->next = item;
@@ -300,14 +325,112 @@ void CB_queue_erase()
cb_queue_info.last = NULL;
}
+static DWORD flags_to_cbq(DWORD cb_flags)
+{
+ DWORD r = 0;
+
+ if((cb_flags & SVGA_CB_PRESENT) != 0)
+ {
+ r |= CBQ_PRESENT;
+ }
+
+ if((cb_flags & SVGA_CB_RENDER) != 0)
+ {
+ r |= CBQ_RENDER;
+ }
+
+ if((cb_flags & SVGA_CB_UPDATE) != 0)
+ {
+ r |= SVGA_CB_UPDATE;
+ }
+
+ return r;
+}
+
+static DWORD flags_to_cbq_check(DWORD cb_flags)
+{
+ DWORD r = 0;
+
+ if((cb_flags & SVGA_CB_PRESENT) != 0)
+ {
+ r |= CBQ_PRESENT | CBQ_RENDER;
+ }
+
+ if((cb_flags & SVGA_CB_RENDER) != 0)
+ {
+ r |= CBQ_RENDER | SVGA_CB_UPDATE;
+ }
+
+ if((cb_flags & SVGA_CB_UPDATE) != 0)
+ {
+ r |= CBQ_RENDER | SVGA_CB_UPDATE;
+ }
+
+ return r;
+}
+
+static uint32 fence_present = 0;
+static uint32 fence_render = 0;
+static uint32 fence_update = 0;
+
+static void flags_fence_check(DWORD cb_flags)
+{
+ DWORD to_check = flags_to_cbq_check(cb_flags);
+
+ if((to_check & CBQ_PRESENT) != 0)
+ {
+ if(fence_present)
+ {
+ SVGA_fence_wait(fence_present);
+ fence_present = 0;
+ }
+ }
+
+ if((to_check & CBQ_RENDER) != 0)
+ {
+ if(fence_render)
+ {
+ SVGA_fence_wait(fence_render);
+ fence_render = 0;
+ }
+ }
+
+ if((to_check & CBQ_UPDATE) != 0)
+ {
+ if(fence_update)
+ {
+ SVGA_fence_wait(fence_update);
+ fence_update = 0;
+ }
+ }
+}
+
+static void flags_fence_insert(DWORD cb_flags, uint32 fence)
+{
+ if((cb_flags & SVGA_CB_PRESENT) != 0)
+ {
+ fence_present = fence;
+ }
+
+ if((cb_flags & SVGA_CB_RENDER) != 0)
+ {
+ fence_render = fence;
+ }
+
+ if((cb_flags & SVGA_CB_UPDATE) != 0)
+ {
+ fence_update = fence;
+ }
+}
+
+#define flags_fifo_fence_need(_flags) (((_flags) & (SVGA_CB_SYNC | SVGA_CB_FORCE_FENCE | SVGA_CB_PRESENT | SVGA_CB_RENDER | SVGA_CB_UPDATE)) != 0)
+#define flags_cb_fence_need(_flags) (((_flags) & (SVGA_CB_FORCE_FENCE)) != 0)
static void SVGA_CMB_submit_critical(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_status_t FBPTR status, DWORD flags, DWORD DXCtxId)
{
DWORD fence = 0;
SVGACBHeader *cb = ((SVGACBHeader *)cmb)-1;
- CB_queue_check_inline(NULL);
-
if(status)
{
cb->status = SVGA_CB_STATUS_NONE;
@@ -320,43 +443,28 @@ static void SVGA_CMB_submit_critical(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_s
// debug_cmdbuf_trace(cmb, cmb_size, SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN);
// debug_draw(cmb, cmb_size);
#endif
-
- if(flags & SVGA_CB_PRESENT_ASYNC)
- {
- if(present_fence != 0)
- {
- SVGA_fence_wait(present_fence);
- }
-
- flags |= SVGA_CB_FORCE_FENCE;
- }
- else if(present_fence)
- {
- if(SVGA_fence_is_passed(present_fence))
- {
- present_fence = 0;
- }
- }
- if(flags & SVGA_CB_PRESENT_GPU)
+ if(flags & SVGA_CB_DIRTY_SURFACE)
{
ST_FB_invalid = TRUE;
}
-
+
if( /* CB are supported and enabled */
- cb_support &&
- (cb_context0 || (flags & SVGA_CB_USE_CONTEXT_DEVICE)) &&
+ cb_support && cb_context0 &&
(flags & SVGA_CB_FORCE_FIFO) == 0
)
{
+ /***
+ *
+ * COMMAND BUFFER procesing
+ *
+ ***/
DWORD cbhwctxid = SVGA_CB_CONTEXT_0;
+ DWORD cbq_check = flags_to_cbq_check(flags);
- if(flags & SVGA_CB_USE_CONTEXT_DEVICE)
- {
- cbhwctxid = SVGA_CB_CONTEXT_DEVICE;
- }
+ //if(flags & SVGA_CB_USE_CONTEXT_DEVICE) cbhwctxid = SVGA_CB_CONTEXT_DEVICE;
- if(flags & SVGA_CB_FORCE_FENCE)
+ if(flags_cb_fence_need(flags))
{
DWORD dwords = cmb_size/sizeof(DWORD);
fence = SVGA_fence_get();
@@ -365,6 +473,12 @@ static void SVGA_CMB_submit_critical(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_s
cmb_size += sizeof(DWORD)*2;
}
+ /* wait */
+ do
+ {
+ CB_queue_check_inline(NULL);
+ } while(CB_queue_is_flags_set(cbq_check));
+
if(cmb_size == 0)
{
cb->status = SVGA_PROC_COMPLETED;
@@ -377,10 +491,10 @@ static void SVGA_CMB_submit_critical(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_s
}
else
{
- cb->status = SVGA_CB_STATUS_NONE;
+ cb->status = SVGA_CB_STATUS_NONE;
cb->errorOffset = 0;
- cb->offset = 0; /* VMware modified this, needs to be clear */
- cb->flags = SVGA_CB_FLAG_NO_IRQ;
+ cb->offset = 0; /* VMware modified this, needs to be clear */
+ cb->flags = SVGA_CB_FLAG_NO_IRQ;
if(flags & SVGA_CB_FLAG_DX_CONTEXT)
{
@@ -392,11 +506,11 @@ static void SVGA_CMB_submit_critical(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_s
cb->dxContext = 0;
}
- cb->id.low = cb_next_id.low;
- cb->id.hi = cb_next_id.hi;
- cb->length = cmb_size;
+ cb->id.low = cb_next_id.low;
+ cb->id.hi = cb_next_id.hi;
+ cb->length = cmb_size;
- CB_queue_insert(cb);
+ CB_queue_insert(cb, flags_to_cbq(flags));
SVGA_WriteReg(SVGA_REG_COMMAND_HIGH, 0); // high part of 64-bit memory address...
SVGA_WriteReg(SVGA_REG_COMMAND_LOW, (cb->ptr.pa.low - sizeof(SVGACBHeader)) | cbhwctxid);
@@ -417,10 +531,10 @@ static void SVGA_CMB_submit_critical(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_s
fence = SVGA_fence_passed();
}
}
- else
+ /*else
{
dbg_printf(dbg_cb_suc);
- }
+ }*/
if(status)
{
@@ -440,45 +554,30 @@ static void SVGA_CMB_submit_critical(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_s
}
}
}
- else /* copy to FIFO */
+ else
{
+ /***
+ *
+ * FIFO procesing
+ *
+ ***/
DWORD *ptr = cmb;
DWORD dwords = cmb_size/sizeof(DWORD);
DWORD nextCmd, max, min;
/* insert fence CMD */
- fence = SVGA_fence_get();
- ptr[dwords] = SVGA_CMD_FENCE;
- ptr[dwords+1] = fence;
-
- dwords += 2;
-
- //SVGA_Flush();
-
- nextCmd = gSVGA.fifoMem[SVGA_FIFO_NEXT_CMD];
- max = gSVGA.fifoMem[SVGA_FIFO_MAX];
- min = gSVGA.fifoMem[SVGA_FIFO_MIN];
-
- /* copy to fifo */
- while(dwords > 0)
+ if(flags_fifo_fence_need(flags))
{
- gSVGA.fifoMem[nextCmd/sizeof(DWORD)] = *ptr;
- ptr++;
-
- nextCmd += sizeof(uint32);
- if (nextCmd >= max)
- {
- nextCmd = min;
- }
- gSVGA.fifoMem[SVGA_FIFO_NEXT_CMD] = nextCmd;
- dwords--;
+ fence = SVGA_fence_get();
+ ptr[dwords++] = SVGA_CMD_FENCE;
+ ptr[dwords++] = fence;
}
- //SVGA_Sync();
+ flags_fence_check(flags);
- if(flags & SVGA_CB_SYNC)
+ if(dwords == 0)
{
- SVGA_fence_wait(fence);
+ cb->status = SVGA_PROC_COMPLETED;
if(status)
{
status->sStatus = SVGA_PROC_COMPLETED;
@@ -488,15 +587,49 @@ static void SVGA_CMB_submit_critical(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_s
}
else
{
- if(status)
+ nextCmd = gSVGA.fifoMem[SVGA_FIFO_NEXT_CMD];
+ max = gSVGA.fifoMem[SVGA_FIFO_MAX];
+ min = gSVGA.fifoMem[SVGA_FIFO_MIN];
+
+ /* copy to fifo */
+ while(dwords > 0)
{
- status->sStatus = SVGA_PROC_FENCE;
- status->qStatus = NULL;
- status->fifo_fence_used = fence;
+ gSVGA.fifoMem[nextCmd/sizeof(DWORD)] = *ptr;
+ ptr++;
+
+ nextCmd += sizeof(uint32);
+ if (nextCmd >= max)
+ {
+ nextCmd = min;
+ }
+ gSVGA.fifoMem[SVGA_FIFO_NEXT_CMD] = nextCmd;
+ dwords--;
}
- }
-
- cb->status = SVGA_PROC_COMPLETED;
+
+ if(flags & SVGA_CB_SYNC)
+ {
+ SVGA_fence_wait(fence);
+ if(status)
+ {
+ status->sStatus = SVGA_PROC_COMPLETED;
+ status->qStatus = NULL;
+ status->fifo_fence_used = 0;
+ }
+ }
+ else
+ {
+ flags_fence_insert(flags, fence);
+
+ if(status)
+ {
+ status->sStatus = SVGA_PROC_FENCE;
+ status->qStatus = NULL;
+ status->fifo_fence_used = fence;
+ }
+ }
+
+ cb->status = SVGA_PROC_COMPLETED;
+ } // size > 0
} /* FIFO */
if(status)
@@ -504,11 +637,6 @@ static void SVGA_CMB_submit_critical(DWORD FBPTR cmb, DWORD cmb_size, SVGA_CMB_s
status->fifo_fence_last = SVGA_fence_passed();
}
- if(flags & SVGA_CB_PRESENT_ASYNC)
- {
- present_fence = fence;
- }
-
//dbg_printf(dbg_cmd_off, cmb[0]);
}
@@ -627,7 +755,6 @@ void SVGA_CB_stop()
SVGA_Sync();
CB_queue_erase();
- present_fence = 0; // remove waiting fence
dbg_printf(dbg_cb_stop_status, status);
}
@@ -643,3 +770,18 @@ void SVGA_CB_restart()
SVGA_CB_start();
}
+
+void SVGA_CMB_wait_update()
+{
+ if(cb_support && cb_context0)
+ {
+ do
+ {
+ CB_queue_check_inline(NULL);
+ } while(CB_queue_is_flags_set(CBQ_UPDATE | CBQ_UPDATE));
+ }
+ else
+ {
+ flags_fence_check(SVGA_CB_UPDATE);
+ }
+}
diff --git a/vxd_svga_mem.c b/vxd_svga_mem.c
index fb1d87b..16c3820 100644
--- a/vxd_svga_mem.c
+++ b/vxd_svga_mem.c
@@ -714,94 +714,104 @@ BOOL SVGA_region_create(SVGA_region_info_t *rinfo)
ULONG blk_pages_raw = 0;
/* allocate user block */
- maddr = _PageAllocate(nPages+pt_pages, pa_type, pa_vm, pa_align, 0x0, 0x100000, NULL, pa_flags);
-
- if(!maddr)
+ if(!rinfo->mobonly)
{
- End_Critical_Section();
- return FALSE;
+ maddr = _PageAllocate(nPages+pt_pages, pa_type, pa_vm, pa_align, 0x0, 0x100000, NULL, pa_flags);
}
-
- laddr = maddr + pt_pages*P_SIZE;
-
- /* determine how many physical continuous blocks we have */
- base_ppn = getPPN(laddr);
- base_cnt = 1;
- blocks = 1;
- for(pgi = 1; pgi < nPages; pgi++)
+ else
{
- taddr = laddr + pgi*P_SIZE;
- tppn = getPPN(taddr);
-
- if(tppn != base_ppn + base_cnt)
- {
- base_ppn = tppn;
- base_cnt = 1;
- blocks++;
- }
- else
- {
- base_cnt++;
- }
+ maddr = _PageAllocate(nPages+pt_pages, pa_type, pa_vm, 0, 0x0, 0x100000, NULL, PAGEFIXED);
}
- // number of pages to store regions information
- blk_pages_raw = (blocks + MDONPAGE - 1)/MDONPAGE;
-
- // number of pages including pages-cross descriptors
- blk_pages = (blocks + blk_pages_raw + MDONPAGE - 1)/MDONPAGE;
-
- dbg_printf(dbg_region_1, blocks+blk_pages_raw, SVGA_ReadReg(SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH));
-
- /* allocate memory for GMR descriptor */
- pgblk = _PageAllocate(blk_pages, pa_type, pa_vm, pa_align, 0x0, 0x100000, NULL, pa_flags);
- if(!pgblk)
+ if(!maddr)
{
- _PageFree((PVOID)laddr, 0);
End_Critical_Section();
return FALSE;
}
- desc = (SVGAGuestMemDescriptor*)pgblk;
- memset(desc, 0, blk_pages*P_SIZE);
-
- blocks = 1;
- desc->ppn = getPPN(laddr);
- desc->numPages = 1;
- /* fill GMR physical structure */
- for(pgi = 1; pgi < nPages; pgi++)
+ laddr = maddr + pt_pages*P_SIZE;
+
+ if(!rinfo->mobonly)
{
- taddr = laddr + pgi*P_SIZE;
- tppn = getPPN(taddr);
-
- if(tppn == desc->ppn + desc->numPages)
+ /* determine how many physical continuous blocks we have */
+ base_ppn = getPPN(laddr);
+ base_cnt = 1;
+ blocks = 1;
+ for(pgi = 1; pgi < nPages; pgi++)
{
- desc->numPages++;
+ taddr = laddr + pgi*P_SIZE;
+ tppn = getPPN(taddr);
+
+ if(tppn != base_ppn + base_cnt)
+ {
+ base_ppn = tppn;
+ base_cnt = 1;
+ blocks++;
+ }
+ else
+ {
+ base_cnt++;
+ }
}
- else
+
+ // number of pages to store regions information
+ blk_pages_raw = (blocks + MDONPAGE - 1)/MDONPAGE;
+
+ // number of pages including pages-cross descriptors
+ blk_pages = (blocks + blk_pages_raw + MDONPAGE - 1)/MDONPAGE;
+
+ dbg_printf(dbg_region_1, blocks+blk_pages_raw, SVGA_ReadReg(SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH));
+
+ /* allocate memory for GMR descriptor */
+ pgblk = _PageAllocate(blk_pages, pa_type, pa_vm, pa_align, 0x0, 0x100000, NULL, pa_flags);
+ if(!pgblk)
+ {
+ _PageFree((PVOID)laddr, 0);
+ End_Critical_Section();
+ return FALSE;
+ }
+
+ desc = (SVGAGuestMemDescriptor*)pgblk;
+ memset(desc, 0, blk_pages*P_SIZE);
+
+ blocks = 1;
+ desc->ppn = getPPN(laddr);
+ desc->numPages = 1;
+ /* fill GMR physical structure */
+ for(pgi = 1; pgi < nPages; pgi++)
{
- /* the next descriptor is on next page page */
- if(((blocks+1) % MDONPAGE) == 0)
+ taddr = laddr + pgi*P_SIZE;
+ tppn = getPPN(taddr);
+
+ if(tppn == desc->ppn + desc->numPages)
{
+ desc->numPages++;
+ }
+ else
+ {
+ /* the next descriptor is on next page page */
+ if(((blocks+1) % MDONPAGE) == 0)
+ {
+ desc++;
+ desc->numPages = 0;
+ desc->ppn = getPPN((DWORD)(desc+1));
+ blocks++;
+ }
+
desc++;
- desc->numPages = 0;
- desc->ppn = getPPN((DWORD)(desc+1));
+ desc->ppn = tppn;
+ desc->numPages = 1;
blocks++;
}
-
- desc++;
- desc->ppn = tppn;
- desc->numPages = 1;
- blocks++;
}
+
+ desc++;
+ desc->ppn = 0;
+ desc->numPages = 0;
+
+ dbg_printf(dbg_region_2, blocks);
}
- desc++;
- desc->ppn = 0;
- desc->numPages = 0;
-
- dbg_printf(dbg_region_2, blocks);
-
rinfo->mob_address = (void*)maddr;
rinfo->mob_ppn = 0;
rinfo->mob_pt_depth = 0;
@@ -837,7 +847,7 @@ BOOL SVGA_region_create(SVGA_region_info_t *rinfo)
SVGA_WriteReg(SVGA_REG_GMR_DESCRIPTOR, rinfo->region_ppn);
SVGA_Sync(); // notify register change
- SVGA_Flush_CB_critical();
+ //SVGA_Flush_CB_critical();
}
else
{
@@ -859,6 +869,7 @@ BOOL SVGA_region_create(SVGA_region_info_t *rinfo)
mob->sizeInBytes = rinfo->size;
submit_cmdbuf(cmdoff, SVGA_CB_SYNC, 0);
+ SVGA_Sync();
rinfo->is_mob = 1;
}
@@ -871,7 +882,7 @@ BOOL SVGA_region_create(SVGA_region_info_t *rinfo)
End_Critical_Section();
- //dbg_printf(dbg_gmr_succ, rinfo->region_id, rinfo->size);
+ dbg_printf(dbg_gmr_succ, rinfo->region_id, rinfo->size);
return TRUE;
}