aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaroslav Hensl <jara@hensl.cz>2023-08-05 14:48:32 +0200
committerJaroslav Hensl <jara@hensl.cz>2023-08-05 14:48:32 +0200
commit20d064159fb3dabf6d2bfee123d2ce5432edc90d (patch)
treef3ea13ae38ddb4dcbe0be07d5b33383daaf0f2d3
parent8aa9201551d08e98ff00654f5d232912316f679d (diff)
downloadvmdisp9x-20d064159fb3dabf6d2bfee123d2ce5432edc90d.tar.gz
VGPU10 + QEMU fixes
-rw-r--r--boxv.c2
-rw-r--r--makefile25
-rw-r--r--minivdd.c381
-rw-r--r--minivdd_func.h18
-rw-r--r--minivdd_qemu.c2
-rw-r--r--minivdd_svga.c327
-rw-r--r--modes.c4
-rw-r--r--qemuvxd.c403
-rw-r--r--version.h2
-rw-r--r--vmdisp9x.inf5
-rw-r--r--vmware/svga3d_dx.h1562
-rw-r--r--vmware/svga3d_limits.h106
-rw-r--r--vmware/svga3d_reg.h5
-rw-r--r--vmware/svga_all.h1
-rw-r--r--vmware/svga_reg.h168
-rw-r--r--vmwsvxd.c435
-rw-r--r--vmwsvxd.h4
17 files changed, 3016 insertions, 434 deletions
diff --git a/boxv.c b/boxv.c
index 1f2387f..01dbb80 100644
--- a/boxv.c
+++ b/boxv.c
@@ -85,7 +85,7 @@ int BOXV_ext_mode_set( void *cx, int xres, int yres, int bpp, int v_xres, int v_
/* Enable the extended display registers. */
vid_outw( cx, VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE );
#ifdef QEMU
- vid_outw( cx, VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_8BIT_DAC | VBE_DISPI_LFB_ENABLED );
+ vid_outw( cx, VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_8BIT_DAC | VBE_DISPI_LFB_ENABLED | VBE_DISPI_NOCLEARMEM );
#else
vid_outw( cx, VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_8BIT_DAC );
#endif
diff --git a/makefile b/makefile
index 826ca92..6ee55f0 100644
--- a/makefile
+++ b/makefile
@@ -4,7 +4,7 @@ OBJS = dibthunk.obj dibcall.obj enable.obj init.obj palette.obj &
scrsw_svga.obj control_svga.obj modes_svga.obj palette_svga.obj &
pci.obj svga.obj svga3d.obj svga32.obj pci32.obj dddrv.obj &
enable_svga.obj dibcall_svga.obj boxv_qemu.obj modes_qemu.obj &
- init_qemu.obj init_svga.obj
+ init_qemu.obj init_svga.obj qemuvxd.obj minivdd_qemu.obj
INCS = -I$(%WATCOM)\h\win -Iddk -Ivmware
@@ -42,7 +42,7 @@ CC32 = wcc386
CFLAGS32 += -DCOM2
!endif
-all : boxvmini.drv vmwsmini.drv qemumini.drv vmwsmini.vxd
+all : boxvmini.drv vmwsmini.drv qemumini.drv vmwsmini.vxd qemumini.vxd
# Object files
drvlib.obj : drvlib.c .autodepend
@@ -134,10 +134,16 @@ scrsw_svga.obj : scrsw_svga.c .autodepend
vmwsvxd.obj : vmwsvxd.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
+qemuvxd.obj : qemuvxd.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
minivdd_svga.obj : minivdd_svga.c .autodepend
$(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+minivdd_qemu.obj : minivdd_qemu.c .autodepend
+ $(CC32) $(CFLAGS32) $(INCS) $(FLAGS) $<
+
dddrv.obj : dddrv.c .autodepend
$(CC) $(CFLAGS) -zW $(INCS) $(FLAGS) $<
@@ -388,7 +394,7 @@ file vmwsvxd.obj
file minivdd_svga.obj
file pci32.obj
file svga32.obj
-segment '_LTEXT' PRELOAD NONDISCARDABLE
+segment '_LTEXT' PRELOAD NONDISCARDABLE
segment '_TEXT' PRELOAD NONDISCARDABLE
segment '_DATA' PRELOAD NONDISCARDABLE
export VMWS_DDB.1
@@ -397,6 +403,19 @@ export VMWS_DDB.1
# not working now
# wrc -q vmws_vxd.res $@
+qemumini.vxd : $(OBJS) vmws_vxd.res
+ wlink op quiet $(DBGFILE32) @<<qemumini.lnk
+system win_vxd dynamic
+option map=qemuvxd.map
+option nodefaultlibs
+name qemumini.vxd
+file qemuvxd.obj
+file minivdd_qemu.obj
+segment '_LTEXT' PRELOAD NONDISCARDABLE
+segment '_TEXT' PRELOAD NONDISCARDABLE
+segment '_DATA' PRELOAD NONDISCARDABLE
+export QEMU_DDB.1
+<<
# Cleanup
clean : .symbolic
diff --git a/minivdd.c b/minivdd.c
new file mode 100644
index 0000000..fdaa832
--- /dev/null
+++ b/minivdd.c
@@ -0,0 +1,381 @@
+/*****************************************************************************
+
+Copyright (c) 2023 Jaroslav Hensl <emulator@emulace.cz>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*****************************************************************************/
+#include "winhack.h"
+#include "vmm.h"
+#include "vmwsvxd.h"
+
+#include "minivdd32.h"
+
+#ifdef SVGA
+#include "svga_all.h"
+#endif
+
+/* code and data is same segment */
+#include "code32.h"
+
+#ifdef SVGA
+extern Bool svga_init_success;
+#endif
+
+/*
+You can implement all the VESA support entirely in your mini-VDD. Doing so will
+cause VESA applications to run more efficiently since all of the VESA support is
+done at Ring 0. You can expect a 20% speed increase by implementing VESA
+unctionality in your mini-VDD over using a real mode VESA driver.
+Following are the VESA functions you can implement in your mini-VDD:
+ CHECK_HIRES_MODE
+ CHECK_SCREEN_SWITCH_OK
+ GET_BANK_SIZE
+ GET_CURRENT_BANK_READ
+ GET_CURRENT_BANK_WRITE
+ GET_TOTAL_VRAM_SIZE
+ POST_HIRES_SAVE_RESTORE
+ PRE_HIRES_SAVE_RESTORE
+ SET_BANK
+ SET_HIRES_MODE
+ VESA_CALL_POST_PROCESSING
+ VESA_SUPPORT
+*/
+
+
+/**
+REGISTER_DISPLAY_DRIVER (Function 0)
+Call With
+EBX: Contains the Windows VM handle.
+EBP: Contains the Windows VM's Client Registers.
+All other registers are via agreement between the display driver and the mini-VDD.
+Return Values
+Whatever is agreed upon by the display driver and mini-VDD.
+Remarks
+This function is called in response to a display driver call to the Main VDD function VDD_REGISTER_DISPLAY_DRIVER_INFO.
+See also VDD_REGISTER_DISPLAY_DRIVER_INFO.
+
+**/
+VDDPROC(REGISTER_DISPLAY_DRIVER, register_display_driver)
+{
+ VDD_NC;
+}
+
+/**
+GET_CHIP_ID (Function 42)
+Call With
+EBX: Contains the VM handle (always the Windows VM).
+EBP: Points to the Windows VM's Client Registers.
+Return Values
+Save everything that you use. EAX contains the ChipID.
+Remarks
+Several mini-VDD's support multiple chipsets that utilize different display drivers.
+For example, ATI's mini-VDD supports the VGA Wonder which uses SUPERVGA.DRV, the Mach8
+which uses ATIM8.DRV, the Mach32 which uses ATIM32.DRV, and the Mach64 which uses ATIM64.DRV.
+Therefore, the detection for each of these chipsets is included in the ATI mini-VDD.
+GET_CHIP_ID is the only way the Main VDD Plug & Play support code can differentiate between
+display cards that use the same mini-VDD.
+
+The Main VDD calls the function MiniVDD_Dynamic_Init when the mini-VDD is loaded.
+If MiniVDD_Dynamic_Init returns with the carry flag clear (indicating success),
+the Main VDD calls GET_CHIP_ID as a second check to make sure that the user has
+not changed the video card since the last time Windows was run. The Main VDD compares
+the value returned by GET_CHIP_ID with the value stored in the registry and if they
+are different, it reports the error to the Plug & Play subsystem.
+
+If the mini-VDD fails to detect one of the cards it supports, MiniVDD_Dynamic_Init
+returns with the carry flag set (indicating failure) and the Windows 95's Plug & Play
+code loads the standard VGA driver.
+
+If the value returned by GET_CHIP_ID is different than the value stored in the registry,
+or if MiniVDD_Dynamic_Init returns failure, the system displays an error message to
+the user concerning the problem with the display settings and allows the user to run
+hardware detection to re-detect the video card.
+
+**/
+VDDPROC(GET_CHIP_ID, get_chip_id)
+{
+#ifdef SVGA
+ if(svga_init_success)
+ {
+ uint32 chip_id = (((uint32)gSVGA.vendorId) << 16) || ((uint32)gSVGA.deviceId);
+ state->Client_EAX = chip_id;
+ return;
+ }
+ state->Client_EAX = 0;
+#endif
+}
+
+/**
+CHECK_SCREEN_SWITCH_OK (Function 43)
+Call With
+EAX: Contains -1 if running in a known VESA mode.
+EBX: Contains the VM handle (always the Windows VM).
+ECX: Contains the video mode number (if known).
+EBP: Points to the Windows VM's Client Registers.
+Return Values
+CY indicates that the hi-res application may not be switched away from. NC indicates
+that it is safe to switch away from the hi-res application.
+Remarks
+The Main VDD calls this routine whenever a user presses ALT-ENTER or ALT-TAB to
+switch away from a full-screen MS-DOS prompt. The mini-VDD should determine if
+it knows how to restore this mode. If it is a VESA mode or standard VGA mode,
+the Main VDD knows how to restore it and unless the mini-VDD has special
+considerations, it should return NC. Otherwise, it should return CY causing the
+system to beep to alert the user that the hi-res VM cannot be switched away from.
+This notification is not given if a user presses CTRL-ALT-DEL to terminate a full-screen
+application. In this case, no save of the screen is attempted and it will be impossible
+to restore the screen if the user tries to switch back. In this case, if the user tries
+to switch back, the system terminates the application.
+
+**/
+VDDPROC(CHECK_SCREEN_SWITCH_OK, check_screen_switch_ok)
+{
+
+}
+
+/**
+GET_BANK_SIZE (Function 37)
+Call With
+EBX: Contains the VM handle (always the currently executing VM).
+ECX: Contains the VESA BIOS mode number that is currently running.
+EBP: Points to the Windows VM's Client Registers.
+Return Values
+Save everything that you use. CY returned means that mini-VDD handled the call. EDX contains the current bank size. EAX contains the physical address of the memory aperture or zero to indicate a standard memory aperture at physical address A000:0h.
+Remarks
+This routine is called during the save process of a VESA hi-res screen. It tells the Main VDD how large each bank is (so that during the save and restore process, it will know how many bytes to process per pass of the save/restore loop). It also informs the Main VDD where to access the VRAM. Most VESA programs currently set their VRAM at A000:0h. However, VESA version 2 does allow for flat linear apertures. The mini-VDD should determine if the VESA program is using an aperture and return the correct data to the Main VDD.
+
+**/
+VDDPROC(GET_BANK_SIZE, get_bank_size)
+{
+
+}
+
+/**
+GET_CURRENT_BANK_READ (Function 33)
+The parameters and return values for this function are the same as for GET_CURRENT_BANK_WRITE. See GET_CURRENT_BANK_WRITE for details.
+See also GET_CURRENT_BANK_WRITE.
+
+**/
+VDDPROC(GET_CURRENT_BANK_READ, get_current_bank_read)
+{
+
+}
+
+/**
+GET_CURRENT_BANK_WRITE (Function 32)
+Call With
+EBX: Contains the VM handle (always the currently executing VM).
+EBP: Points to the Windows VM's Client Registers.
+Return Values
+Save everything that you use. CY returned means that the mini-VDD handled the call. NC returned means that Main VDD should use a VESA call to retrieve the bank. If successful, EDX contains the current bank (write or read) as set in hardware.
+Remarks
+GET_CURRENT_BANK_WRITE and GET_CURRENT_BANK_READ are made when the user presses ALT-TAB to switch away from a VESA hi-res application. The Main VDD uses GET_CURRENT_BANK_WRITE to retrieve the current state of the banking registers (which are "Windows" in VESA terminology). It then saves these for later restoration when the user presses ALT-TAB back to the VESA hi-res application. The Main VDD uses VESA function 4F05h to get the bank if the mini-VDD fails this call.
+
+**/
+VDDPROC(GET_CURRENT_BANK_WRITE, get_current_bank_write)
+{
+
+}
+
+/**
+GET_TOTAL_VRAM_SIZE (Function 36)
+Call With
+EBX: Contains the VM handle (always the currently executing VM).
+EBP: Contains the Windows VM's Client Registers.
+Return Values
+Save everything that you use. CY returned means that mini-VDD handled the call.
+ECX contains the total size of VRAM on the card.
+Remarks
+Whenever the VDD saves a hi-res mode, it saves all of the card's video memory to
+the swap file. This is because VESA applications have full access to the total memory
+on the card, even if their visible screen size is less than the total VRAM size on the card.
+Therefore, the Main VDD must know the total VRAM size. If the mini-VDD does not
+handle this call, the Main VDD will do a time-consuming call to
+VESA BIOS function 4F00h to obtain this information.
+For performance reasons, you should implement this function.
+
+**/
+VDDPROC(GET_TOTAL_VRAM_SIZE, get_total_vram_size)
+{
+#ifdef SVGA
+ if(svga_init_success)
+ {
+ uint32 vram_size = SVGA_ReadReg(SVGA_REG_VRAM_SIZE);
+ state->Client_ECX = vram_size;
+
+ VDD_CY;
+ return;
+ }
+
+ state->Client_ECX = 0;
+ VDD_NC;
+#endif
+}
+
+/**
+PRE_HIRES_SAVE_RESTORE (Function 39)
+Call With
+EBX: Contains the VM handle (always the currently executing VM).
+EBP: Points to the Windows VM's Client Registers.
+Return Values
+Save everything that you use. No values or flags need to be returned.
+Remarks
+This call is very similar to PRE_HIRES_TO_VGA in that it allows the mini-VDD to modify port trapping, set flags, etc. in preparation for the mode change into the VESA/hi-res mode. In fact, the S3 example mini-VDD dispatches this call to the exact same routine as PRE_HIRES_TO_VGA.
+
+**/
+VDDPROC(PRE_HIRES_SAVE_RESTORE, pre_hires_save_restore)
+{
+
+}
+
+/**
+POST_HIRES_SAVE_RESTORE (Function 40)
+Call With
+EBX: Contains the VM handle (always the currently executing VM).
+EBP: Points to the Windows VM's Client Registers.
+Return Values
+Save everything that you use. No values or flags need to be returned.
+Remarks
+This function is very similar to POST_HIRES_TO_VGA in that it allows the mini-VDD to modify port trapping, set flags, etc. after the mode change into the VESA/hi-res mode. The S3 example mini-VDD dispatches this call to the exact same routine as POST_HIRES_TO_VGA.
+
+**/
+VDDPROC(POST_HIRES_SAVE_RESTORE, post_hires_save_restore)
+{
+
+}
+
+/**
+SET_BANK (Function 34)
+Call With
+EAX: Contains the read bank to set.
+EBX: Contains the VM handle (always the currently executing VM).
+EDX: Contains the write bank to set.
+EBP: Points to the Windows VM's Client Registers.
+Return Values
+Save everything that you use. CY returned means that the mini-VDD handled the call. NC returned means that the Main VDD should use a VESA call to set the bank.
+Remarks
+This call requests the mini-VDD to set the read/write bank passed in EAX/EDX. The mini-VDD simply needs to set the bank into hardware and return CY to the Main VDD.
+
+**/
+VDDPROC(SET_BANK, set_bank)
+{
+
+}
+
+/**
+SET_HIRES_MODE (Function 38)
+Call With
+EAX: Contains hi-res mode number to set (may be a VESA or non-VESA mode).
+EBX: Contains the VM handle (always the currently executing VM).
+EBP: Points to the Windows VM's Client Registers.
+Return Values
+Save everything that you use. CY returned means that the mini-VDD handled the call. NC returned indicates that the mini-VDD did not handle the call.
+Remarks
+This routine is called by the VESA/hi-res restore routine in the Main VDD when the user switches back to a full screen VESA/hi-res mode VM. If you are only interested in being able to restore VESA standard hi-res modes, then you do not need to implement this function since the Main VDD will call Interrupt 10h Function 4F02h in order to set the VESA mode number. You should only implement this function if you are going to save/restore chipset specific modes that are not VESA modes.
+If the mode number passed in EAX is a VESA mode number, you should return NC and let the Main VDD set the mode. If the mode number passed in EAX is a non-VESA hi-res mode that is particular to your card, if possible, this function should not touch VRAM since this could cause page faults and confuse the register state of the mode set. In other words, try not to erase the screen during the mode set if possible.
+
+**/
+VDDPROC(SET_HIRES_MODE, set_hires_mode)
+{
+
+}
+
+/**
+VESA_CALL_POST_PROCESSING (Function 47)
+Call With
+EBX: Contains the VM handle in which the VESA call was made.
+EDX: The low word contains the VESA function code that was just done. The high word contains the VESA mode number if a VESA mode change (function 4F02h) has just occurred.
+EBP: Points to the VM's client registers. The client registers contain the return values from the VESA call.
+Return Values
+Save everything that you use. Nothing is returned to the caller.
+Remarks
+This function allows a mini-VDD to perform any necessary processing after a VESA call. For example, this function could fix up the hardware that might have been put in an unexpected state by the VESA call, or it could readjust register trapping. The S3 sample mini-VDD has an example of how this hook could be used to by a mini-VDD.
+
+**/
+VDDPROC(VESA_CALL_POST_PROCESSING, vesa_call_post_processing)
+{
+
+}
+
+/**
+VESA_SUPPORT (Function 41)
+Call With
+EBX: Contains the VM handle (always the currently executing VM).
+EBP: Points to the Windows VM's Client Registers. Client registers contain the VESA call values.
+Return Values
+Save everything that you use. CY returned means that the mini-VDD completely handled the VESA call and that the VESA.COM or VESA BIOS should not be called. NC returned means that the mini-VDD did not completely handle the call and that the VESA.COM or VESA BIOS should be called. The client registers contain the return values from the VESA call if the mini-VDD handles the call.
+Remarks
+This routine is the "hook" by which a mini-VDD could implement an entire Ring 0 protected mode VESA support. This is recommended, since it eliminates all of the problems of old VESA.COM programs. It also allows much faster VESA performance since the functions are supported at 32 bit Ring 0.
+The mini-VDD's VESA support decides what to do based on values in the Client registers. For example, Client_AX will contain 4Fxx indicating what VESA call the application is doing. Then, the mini-VDD can handle the call, filling in return structures (such as those returned by VESA function 4F00h), etc., and return CY to the Main VDD.
+This routine could also be used to setup a VESA call while still letting the Ring 3 VESA BIOS handle the call. The mini-VDD would do what it wants to do, and then return NC indicating that the Main VDD should call the Ring 3 VESA BIOS or VESA.COM program.
+
+**/
+VDDPROC(VESA_SUPPORT, vesa_support)
+{
+
+}
+
+void Enable_Global_Trapping(DWORD port)
+{
+ static DWORD sPort = 0;
+ sPort = port;
+
+ _asm push edx
+ _asm mov edx, [sPort];
+ VMMCall(Enable_Global_Trapping);
+ _asm pop edx
+}
+
+
+void Disable_Global_Trapping(DWORD port)
+{
+ static DWORD sPort = 0;
+ sPort = port;
+
+ _asm push edx
+ _asm mov edx, [sPort];
+ VMMCall(Disable_Global_Trapping);
+ _asm pop edx
+}
+
+/* for QEMU */
+VDDPROC(PRE_HIRES_TO_VGA, pre_hires_to_vga)
+{
+ Disable_Global_Trapping(0x1CE);
+ Disable_Global_Trapping(0x1CF);
+}
+
+VDDPROC(POST_HIRES_TO_VGA, post_hires_to_vga)
+{
+ Enable_Global_Trapping(0x1CE);
+ Enable_Global_Trapping(0x1CF);
+}
+
+VDDPROC(ENABLE_TRAPS, enable_traps)
+{
+ Enable_Global_Trapping(0x1CE);
+ Enable_Global_Trapping(0x1CF);
+}
+
+VDDPROC(DISPLAY_DRIVER_DISABLING, display_driver_disabling)
+{
+ Disable_Global_Trapping(0x1CE);
+ Disable_Global_Trapping(0x1CF);
+}
diff --git a/minivdd_func.h b/minivdd_func.h
index 53d15c3..cf67e02 100644
--- a/minivdd_func.h
+++ b/minivdd_func.h
@@ -8,8 +8,10 @@ VDDFUNC(REGISTER_DISPLAY_DRIVER, register_display_driver)
//VDDFUNC(GET_VDD_BANK, get_vdd_bank)
//VDDFUNC(SET_VDD_BANK, set_vdd_bank)
//VDDFUNC(RESET_BANK, reset_bank)
-//VDDFUNC(PRE_HIRES_TO_VGA, pre_hires_to_vga)
-//VDDFUNC(POST_HIRES_TO_VGA, post_hires_to_vga)
+#ifdef QEMU
+VDDFUNC(PRE_HIRES_TO_VGA, pre_hires_to_vga)
+VDDFUNC(POST_HIRES_TO_VGA, post_hires_to_vga)
+#endif
//VDDFUNC(PRE_VGA_TO_HIRES, pre_vga_to_hires)
//VDDFUNC(POST_VGA_TO_HIRES, post_vga_to_hires)
//VDDFUNC(SAVE_REGISTERS, save_registers)
@@ -17,7 +19,9 @@ VDDFUNC(REGISTER_DISPLAY_DRIVER, register_display_driver)
//VDDFUNC(MODIFY_REGISTER_STATE, modify_register_state)
//VDDFUNC(ACCESS_VGA_MEMORY_MODE, access_vga_memory_mode)
//VDDFUNC(ACCESS_LINEAR_MEMORY_MODE, access_linear_memory_mode)
-//VDDFUNC(ENABLE_TRAPS, enable_traps)
+#ifdef QEMU
+VDDFUNC(ENABLE_TRAPS, enable_traps)
+#endif
//VDDFUNC(DISABLE_TRAPS, disable_traps)
//VDDFUNC(MAKE_HARDWARE_NOT_BUSY, make_hardware_not_busy)
//VDDFUNC(VIRTUALIZE_CRTC_IN, virtualize_crtc_in)
@@ -30,7 +34,9 @@ VDDFUNC(REGISTER_DISPLAY_DRIVER, register_display_driver)
//VDDFUNC(RESET_LATCH_BANK, reset_latch_bank)
//VDDFUNC(SAVE_LATCHES, save_latches)
//VDDFUNC(RESTORE_LATCHES, restore_latches)
-//VDDFUNC(DISPLAY_DRIVER_DISABLING, display_driver_disabling)
+#ifdef QEMU
+VDDFUNC(DISPLAY_DRIVER_DISABLING, display_driver_disabling)
+#endif
//VDDFUNC(SELECT_PLANE, select_plane)
//VDDFUNC(PRE_CRTC_MODE_CHANGE, pre_crtc_mode_change)
//VDDFUNC(POST_CRTC_MODE_CHANGE, post_crtc_mode_change)
@@ -40,13 +46,17 @@ VDDFUNC(REGISTER_DISPLAY_DRIVER, register_display_driver)
//VDDFUNC(GET_CURRENT_BANK_READ, get_current_bank_read)
///! VDDFUNC(SET_BANK, set_bank)
//VDDFUNC(CHECK_HIRES_MODE, check_hires_mode)
+#ifdef SVGA
VDDFUNC(GET_TOTAL_VRAM_SIZE, get_total_vram_size)
+#endif
///! VDDFUNC(GET_BANK_SIZE, get_bank_size)
///! VDDFUNC(SET_HIRES_MODE, set_hires_mode)
///! VDDFUNC(PRE_HIRES_SAVE_RESTORE, pre_hires_save_restore)
///! VDDFUNC(POST_HIRES_SAVE_RESTORE, post_hires_save_restore)
///! VDDFUNC(VESA_SUPPORT, vesa_support)
+#ifdef SVGA
VDDFUNC(GET_CHIP_ID, get_chip_id)
+#endif
///! VDDFUNC(CHECK_SCREEN_SWITCH_OK, check_screen_switch_ok)
//VDDFUNC(VIRTUALIZE_BLTER_IO, virtualize_blter_io)
//VDDFUNC(SAVE_MESSAGE_MODE_STATE, save_message_mode_state)
diff --git a/minivdd_qemu.c b/minivdd_qemu.c
new file mode 100644
index 0000000..cc51e73
--- /dev/null
+++ b/minivdd_qemu.c
@@ -0,0 +1,2 @@
+#define QEMU
+#include "minivdd.c"
diff --git a/minivdd_svga.c b/minivdd_svga.c
index 8ea2cd1..54b99a4 100644
--- a/minivdd_svga.c
+++ b/minivdd_svga.c
@@ -1,325 +1,2 @@
-/*****************************************************************************
-
-Copyright (c) 2023 Jaroslav Hensl <emulator@emulace.cz>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-*****************************************************************************/
-#include "winhack.h"
-#include "vmm.h"
-#include "vmwsvxd.h"
-
-#include "minivdd32.h"
-
-#include "svga_all.h"
-
-/* code and data is same segment */
-#include "code32.h"
-
-extern Bool svga_init_success;
-
-/*
-You can implement all the VESA support entirely in your mini-VDD. Doing so will
-cause VESA applications to run more efficiently since all of the VESA support is
-done at Ring 0. You can expect a 20% speed increase by implementing VESA
-unctionality in your mini-VDD over using a real mode VESA driver.
-Following are the VESA functions you can implement in your mini-VDD:
- CHECK_HIRES_MODE
- CHECK_SCREEN_SWITCH_OK
- GET_BANK_SIZE
- GET_CURRENT_BANK_READ
- GET_CURRENT_BANK_WRITE
- GET_TOTAL_VRAM_SIZE
- POST_HIRES_SAVE_RESTORE
- PRE_HIRES_SAVE_RESTORE
- SET_BANK
- SET_HIRES_MODE
- VESA_CALL_POST_PROCESSING
- VESA_SUPPORT
-*/
-
-
-/**
-REGISTER_DISPLAY_DRIVER (Function 0)
-Call With
-EBX: Contains the Windows VM handle.
-EBP: Contains the Windows VM's Client Registers.
-All other registers are via agreement between the display driver and the mini-VDD.
-Return Values
-Whatever is agreed upon by the display driver and mini-VDD.
-Remarks
-This function is called in response to a display driver call to the Main VDD function VDD_REGISTER_DISPLAY_DRIVER_INFO.
-See also VDD_REGISTER_DISPLAY_DRIVER_INFO.
-
-**/
-VDDPROC(REGISTER_DISPLAY_DRIVER, register_display_driver)
-{
- VDD_NC;
-}
-
-/**
-GET_CHIP_ID (Function 42)
-Call With
-EBX: Contains the VM handle (always the Windows VM).
-EBP: Points to the Windows VM's Client Registers.
-Return Values
-Save everything that you use. EAX contains the ChipID.
-Remarks
-Several mini-VDD's support multiple chipsets that utilize different display drivers.
-For example, ATI's mini-VDD supports the VGA Wonder which uses SUPERVGA.DRV, the Mach8
-which uses ATIM8.DRV, the Mach32 which uses ATIM32.DRV, and the Mach64 which uses ATIM64.DRV.
-Therefore, the detection for each of these chipsets is included in the ATI mini-VDD.
-GET_CHIP_ID is the only way the Main VDD Plug & Play support code can differentiate between
-display cards that use the same mini-VDD.
-
-The Main VDD calls the function MiniVDD_Dynamic_Init when the mini-VDD is loaded.
-If MiniVDD_Dynamic_Init returns with the carry flag clear (indicating success),
-the Main VDD calls GET_CHIP_ID as a second check to make sure that the user has
-not changed the video card since the last time Windows was run. The Main VDD compares
-the value returned by GET_CHIP_ID with the value stored in the registry and if they
-are different, it reports the error to the Plug & Play subsystem.
-
-If the mini-VDD fails to detect one of the cards it supports, MiniVDD_Dynamic_Init
-returns with the carry flag set (indicating failure) and the Windows 95's Plug & Play
-code loads the standard VGA driver.
-
-If the value returned by GET_CHIP_ID is different than the value stored in the registry,
-or if MiniVDD_Dynamic_Init returns failure, the system displays an error message to
-the user concerning the problem with the display settings and allows the user to run
-hardware detection to re-detect the video card.
-
-**/
-VDDPROC(GET_CHIP_ID, get_chip_id)
-{
- if(svga_init_success)
- {
- uint32 chip_id = (((uint32)gSVGA.vendorId) << 16) || ((uint32)gSVGA.deviceId);
- state->Client_EAX = chip_id;
- return;
- }
- state->Client_EAX = 0;
-}
-
-/**
-CHECK_SCREEN_SWITCH_OK (Function 43)
-Call With
-EAX: Contains -1 if running in a known VESA mode.
-EBX: Contains the VM handle (always the Windows VM).
-ECX: Contains the video mode number (if known).
-EBP: Points to the Windows VM's Client Registers.
-Return Values
-CY indicates that the hi-res application may not be switched away from. NC indicates
-that it is safe to switch away from the hi-res application.
-Remarks
-The Main VDD calls this routine whenever a user presses ALT-ENTER or ALT-TAB to
-switch away from a full-screen MS-DOS prompt. The mini-VDD should determine if
-it knows how to restore this mode. If it is a VESA mode or standard VGA mode,
-the Main VDD knows how to restore it and unless the mini-VDD has special
-considerations, it should return NC. Otherwise, it should return CY causing the
-system to beep to alert the user that the hi-res VM cannot be switched away from.
-This notification is not given if a user presses CTRL-ALT-DEL to terminate a full-screen
-application. In this case, no save of the screen is attempted and it will be impossible
-to restore the screen if the user tries to switch back. In this case, if the user tries
-to switch back, the system terminates the application.
-
-**/
-VDDPROC(CHECK_SCREEN_SWITCH_OK, check_screen_switch_ok)
-{
-
-}
-
-/**
-GET_BANK_SIZE (Function 37)
-Call With
-EBX: Contains the VM handle (always the currently executing VM).
-ECX: Contains the VESA BIOS mode number that is currently running.
-EBP: Points to the Windows VM's Client Registers.
-Return Values
-Save everything that you use. CY returned means that mini-VDD handled the call. EDX contains the current bank size. EAX contains the physical address of the memory aperture or zero to indicate a standard memory aperture at physical address A000:0h.
-Remarks
-This routine is called during the save process of a VESA hi-res screen. It tells the Main VDD how large each bank is (so that during the save and restore process, it will know how many bytes to process per pass of the save/restore loop). It also informs the Main VDD where to access the VRAM. Most VESA programs currently set their VRAM at A000:0h. However, VESA version 2 does allow for flat linear apertures. The mini-VDD should determine if the VESA program is using an aperture and return the correct data to the Main VDD.
-
-**/
-VDDPROC(GET_BANK_SIZE, get_bank_size)
-{
-
-}
-
-/**
-GET_CURRENT_BANK_READ (Function 33)
-The parameters and return values for this function are the same as for GET_CURRENT_BANK_WRITE. See GET_CURRENT_BANK_WRITE for details.
-See also GET_CURRENT_BANK_WRITE.
-
-**/
-VDDPROC(GET_CURRENT_BANK_READ, get_current_bank_read)
-{
-
-}
-
-/**
-GET_CURRENT_BANK_WRITE (Function 32)
-Call With
-EBX: Contains the VM handle (always the currently executing VM).
-EBP: Points to the Windows VM's Client Registers.
-Return Values
-Save everything that you use. CY returned means that the mini-VDD handled the call. NC returned means that Main VDD should use a VESA call to retrieve the bank. If successful, EDX contains the current bank (write or read) as set in hardware.
-Remarks
-GET_CURRENT_BANK_WRITE and GET_CURRENT_BANK_READ are made when the user presses ALT-TAB to switch away from a VESA hi-res application. The Main VDD uses GET_CURRENT_BANK_WRITE to retrieve the current state of the banking registers (which are "Windows" in VESA terminology). It then saves these for later restoration when the user presses ALT-TAB back to the VESA hi-res application. The Main VDD uses VESA function 4F05h to get the bank if the mini-VDD fails this call.
-
-**/
-VDDPROC(GET_CURRENT_BANK_WRITE, get_current_bank_write)
-{
-
-}
-
-/**
-GET_TOTAL_VRAM_SIZE (Function 36)
-Call With
-EBX: Contains the VM handle (always the currently executing VM).
-EBP: Contains the Windows VM's Client Registers.
-Return Values
-Save everything that you use. CY returned means that mini-VDD handled the call.
-ECX contains the total size of VRAM on the card.
-Remarks
-Whenever the VDD saves a hi-res mode, it saves all of the card's video memory to
-the swap file. This is because VESA applications have full access to the total memory
-on the card, even if their visible screen size is less than the total VRAM size on the card.
-Therefore, the Main VDD must know the total VRAM size. If the mini-VDD does not
-handle this call, the Main VDD will do a time-consuming call to
-VESA BIOS function 4F00h to obtain this information.
-For performance reasons, you should implement this function.
-
-**/
-VDDPROC(GET_TOTAL_VRAM_SIZE, get_total_vram_size)
-{
- if(svga_init_success)
- {
- uint32 vram_size = SVGA_ReadReg(SVGA_REG_VRAM_SIZE);
- state->Client_ECX = vram_size;
-
- VDD_CY;
- return;
- }
-
- state->Client_ECX = 0;
- VDD_NC;
-}
-
-/**
-PRE_HIRES_SAVE_RESTORE (Function 39)
-Call With
-EBX: Contains the VM handle (always the currently executing VM).
-EBP: Points to the Windows VM's Client Registers.
-Return Values
-Save everything that you use. No values or flags need to be returned.
-Remarks
-This call is very similar to PRE_HIRES_TO_VGA in that it allows the mini-VDD to modify port trapping, set flags, etc. in preparation for the mode change into the VESA/hi-res mode. In fact, the S3 example mini-VDD dispatches this call to the exact same routine as PRE_HIRES_TO_VGA.
-
-**/
-VDDPROC(PRE_HIRES_SAVE_RESTORE, pre_hires_save_restore)
-{
-
-}
-
-/**
-POST_HIRES_SAVE_RESTORE (Function 40)
-Call With
-EBX: Contains the VM handle (always the currently executing VM).
-EBP: Points to the Windows VM's Client Registers.
-Return Values
-Save everything that you use. No values or flags need to be returned.
-Remarks
-This function is very similar to POST_HIRES_TO_VGA in that it allows the mini-VDD to modify port trapping, set flags, etc. after the mode change into the VESA/hi-res mode. The S3 example mini-VDD dispatches this call to the exact same routine as POST_HIRES_TO_VGA.
-
-**/
-VDDPROC(POST_HIRES_SAVE_RESTORE, post_hires_save_restore)
-{
-
-}
-
-/**
-SET_BANK (Function 34)
-Call With
-EAX: Contains the read bank to set.
-EBX: Contains the VM handle (always the currently executing VM).
-EDX: Contains the write bank to set.
-EBP: Points to the Windows VM's Client Registers.
-Return Values
-Save everything that you use. CY returned means that the mini-VDD handled the call. NC returned means that the Main VDD should use a VESA call to set the bank.
-Remarks
-This call requests the mini-VDD to set the read/write bank passed in EAX/EDX. The mini-VDD simply needs to set the bank into hardware and return CY to the Main VDD.
-
-**/
-VDDPROC(SET_BANK, set_bank)
-{
-
-}
-
-/**
-SET_HIRES_MODE (Function 38)
-Call With
-EAX: Contains hi-res mode number to set (may be a VESA or non-VESA mode).
-EBX: Contains the VM handle (always the currently executing VM).
-EBP: Points to the Windows VM's Client Registers.
-Return Values
-Save everything that you use. CY returned means that the mini-VDD handled the call. NC returned indicates that the mini-VDD did not handle the call.
-Remarks
-This routine is called by the VESA/hi-res restore routine in the Main VDD when the user switches back to a full screen VESA/hi-res mode VM. If you are only interested in being able to restore VESA standard hi-res modes, then you do not need to implement this function since the Main VDD will call Interrupt 10h Function 4F02h in order to set the VESA mode number. You should only implement this function if you are going to save/restore chipset specific modes that are not VESA modes.
-If the mode number passed in EAX is a VESA mode number, you should return NC and let the Main VDD set the mode. If the mode number passed in EAX is a non-VESA hi-res mode that is particular to your card, if possible, this function should not touch VRAM since this could cause page faults and confuse the register state of the mode set. In other words, try not to erase the screen during the mode set if possible.
-
-**/
-VDDPROC(SET_HIRES_MODE, set_hires_mode)
-{
-
-}
-
-/**
-VESA_CALL_POST_PROCESSING (Function 47)
-Call With
-EBX: Contains the VM handle in which the VESA call was made.
-EDX: The low word contains the VESA function code that was just done. The high word contains the VESA mode number if a VESA mode change (function 4F02h) has just occurred.
-EBP: Points to the VM's client registers. The client registers contain the return values from the VESA call.
-Return Values
-Save everything that you use. Nothing is returned to the caller.
-Remarks
-This function allows a mini-VDD to perform any necessary processing after a VESA call. For example, this function could fix up the hardware that might have been put in an unexpected state by the VESA call, or it could readjust register trapping. The S3 sample mini-VDD has an example of how this hook could be used to by a mini-VDD.
-
-**/
-VDDPROC(VESA_CALL_POST_PROCESSING, vesa_call_post_processing)
-{
-
-}
-
-/**
-VESA_SUPPORT (Function 41)
-Call With
-EBX: Contains the VM handle (always the currently executing VM).
-EBP: Points to the Windows VM's Client Registers. Client registers contain the VESA call values.
-Return Values
-Save everything that you use. CY returned means that the mini-VDD completely handled the VESA call and that the VESA.COM or VESA BIOS should not be called. NC returned means that the mini-VDD did not completely handle the call and that the VESA.COM or VESA BIOS should be called. The client registers contain the return values from the VESA call if the mini-VDD handles the call.
-Remarks
-This routine is the "hook" by which a mini-VDD could implement an entire Ring 0 protected mode VESA support. This is recommended, since it eliminates all of the problems of old VESA.COM programs. It also allows much faster VESA performance since the functions are supported at 32 bit Ring 0.
-The mini-VDD's VESA support decides what to do based on values in the Client registers. For example, Client_AX will contain 4Fxx indicating what VESA call the application is doing. Then, the mini-VDD can handle the call, filling in return structures (such as those returned by VESA function 4F00h), etc., and return CY to the Main VDD.
-This routine could also be used to setup a VESA call while still letting the Ring 3 VESA BIOS handle the call. The mini-VDD would do what it wants to do, and then return NC indicating that the Main VDD should call the Ring 3 VESA BIOS or VESA.COM program.
-
-**/
-VDDPROC(VESA_SUPPORT, vesa_support)
-{
-
-}
+#define SVGA
+#include "minivdd.c"
diff --git a/modes.c b/modes.c
index b5403ef..fef8099 100644
--- a/modes.c
+++ b/modes.c
@@ -201,13 +201,15 @@ static int IsModeOK( WORD wXRes, WORD wYRes, WORD wBpp )
if( !FixModeInfo( &mode ) )
return( 0 );
-#ifdef SVGA
+#if defined(SVGA) || defined(QEMU)
/* not working in vmware, in vbox is working without acceleration, so only confusing users */
if(wBpp == 24)
{
return 0;
}
+#endif
+#ifdef SVGA
/* some implementations not support 8 and 16 bpp */
if(gSVGA.only32bit && wBpp != 32)
{
diff --git a/qemuvxd.c b/qemuvxd.c
new file mode 100644
index 0000000..72eb668
--- /dev/null
+++ b/qemuvxd.c
@@ -0,0 +1,403 @@
+/*****************************************************************************
+
+Copyright (c) 2023 Jaroslav Hensl <emulator@emulace.cz>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+*****************************************************************************/
+
+/*
+ * This file is generally C port of boxvmini.asm by Philip Kelley
+ */
+
+#define QEMU
+
+#include "winhack.h"
+#include "vmm.h"
+#include "vmwsvxd.h"
+
+#include "svga_all.h"
+
+#include "minivdd32.h"
+
+#include "version.h"
+
+#include "code32.h"
+
+void QEMU_Control();
+void QEMU_API_Entry();
+
+/*
+ VXD structure
+ this variable must be in first address in code segment.
+ In other cases VXD isn't loadable (WLINK bug?)
+*/
+DDB QEMU_DDB = {
+ NULL, // must be NULL
+ DDK_VERSION, // DDK_Version
+ UNDEFINED_DEVICE_ID, // Device ID
+ VMWSVXD_MAJOR_VER, // Major Version
+ VMWSVXD_MINOR_VER, // Minor Version
+ NULL,
+ "QEMU_VXD",
+ VDD_Init_Order, //Undefined_Init_Order,
+ (DWORD)QEMU_Control,
+ (DWORD)QEMU_API_Entry,
+ (DWORD)QEMU_API_Entry,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL, // DDB_Win32_Service_Table
+ NULL, // prev
+ sizeof(DDB)
+};
+
+/* string tables */
+#ifdef DBGPRINT
+char dbg_hello[] = "Hello world!\n";
+char dbg_version[] = "VMM version: ";
+
+char dbg_Device_Init_proc[] = "Device_Init_proc\n";
+char dbg_Device_Init_proc_succ[] = "Device_Init_proc success\n";
+char dbg_dic_unknown[] = "DeviceIOControl: Unknown: %d\n";
+char dbg_dic_system[] = "DeviceIOControl: System code: %d\n";
+
+char dbg_str[] = "%s\n";
+
+#endif
+
+DWORD *DispatchTable = 0;
+DWORD DispatchTableLength = 0;
+Bool svga_init_success = FALSE;
+
+/**
+ * VMM calls wrapers
+ **/
+DWORD Get_VMM_Version()
+{
+ static WORD ver = 0;
+
+ _asm push ecx
+ _asm push eax
+ _asm xor eax, eax
+ VMMCall(Get_VMM_Version);
+ _asm mov [ver],ax
+ _asm pop ecx
+ _asm pop eax
+
+ return ver;
+}
+
+void Install_IO_Handler(DWORD port, DWORD callback)
+{
+ static DWORD sPort = 0;
+ static DWORD sCallback = 0;
+
+ sPort = port;
+ sCallback = callback;
+
+/*
+ * esi <- IOCallback
+ * edx <- I/O port numbers
+ */
+ _asm
+ {
+ push esi
+ push edx
+ mov esi, [sCallback]
+ mov edx, [sPort]
+ }
+ VMMCall(Install_IO_Handler);
+ _asm
+ {
+ pop edx
+ pop esi
+ }
+}
+
+ULONG __declspec(naked) __cdecl _PhysIntoV86(ULONG PhysPage, ULONG VM, ULONG VMLinPgNum, ULONG nPages, ULONG flags)
+{
+ VMMJmp(_PhysIntoV86);
+}
+
+ULONG __declspec(naked) __cdecl _PageAllocate(ULONG nPages, ULONG pType, ULONG VM, ULONG AlignMask, ULONG minPhys, ULONG maxPhys, ULONG *PhysAddr, ULONG flags)
+{
+ VMMJmp(_PageAllocate);
+}
+
+ULONG __declspec(naked) __cdecl _PageFree(PVOID hMem, DWORD flags)
+{
+ VMMJmp(_PageFree);
+}
+
+/* from minivdd.c */
+void Enable_Global_Trapping(DWORD port);
+void Disable_Global_Trapping(DWORD port);
+
+/**
+ * VDD calls wrapers
+ **/
+void VDD_Get_Mini_Dispatch_Table()
+{
+ VxDCall(VDD, Get_Mini_Dispatch_Table);
+ _asm mov [DispatchTable],edi
+ _asm mov [DispatchTableLength],ecx
+}
+
+/**
+ * Control Handles
+ **/
+void Sys_Critical_Init_proc()
+{
+ // nop
+}
+
+/*
+ * 32-bit DeviceIoControl ends here
+ * (not much to do now)
+ *
+ */
+DWORD __stdcall Device_IO_Control_entry(struct DIOCParams *params)
+{
+ switch(params->dwIoControlCode)
+ {
+ case DIOC_OPEN:
+ case DIOC_CLOSEHANDLE:
+ dbg_printf(dbg_dic_system, params->dwIoControlCode);
+ return 0;
+ }
+ dbg_printf(dbg_dic_unknown, params->dwIoControlCode);
+
+ return 1;
+}
+
+void __declspec(naked) Device_IO_Control_proc()
+{
+ _asm {
+ push esi /* struct DIOCParams */
+ call Device_IO_Control_entry
+ retn
+ }
+}
+
+void Device_Init_proc();
+void __stdcall Device_Dynamic_Init_proc(DWORD WinVMHandle);
+void __stdcall Device_Init_Complete(DWORD VM);
+
+/*
+ * service module calls (init, exit, deviceIoControl, ...)
+ * clear carry if succes (this is always success)
+ */
+void __declspec(naked) QEMU_Control()
+{
+ // eax = 0x00 - Sys Critical Init
+ // eax = 0x01 - sys dynamic init
+ // eax = 0x1B - dynamic init
+ // eax = 0x1C - dynamic exit
+ // eax = 0x23 - device IO control
+
+ _asm {
+ cmp eax,Sys_Critical_Init
+ jnz control_1
+ pushad
+ call Sys_Critical_Init_proc
+ popad
+ clc
+ ret
+ control_1:
+ cmp eax,Device_Init
+ jnz control_2
+ pushad
+ call Device_Init_proc
+ popad
+ clc
+ ret
+ control_2:
+ cmp eax,Init_Complete
+ jnz control_3
+ pushad
+ push ebx ; VM handle
+ call Device_Init_Complete
+ popad
+ clc
+ ret
+ control_3:
+ cmp eax,0x1B ; dynamic init
+ jnz control_4
+ pushad
+ push ebx
+ call Device_Dynamic_Init_proc
+ popad
+ clc
+ ret
+ control_4:
+ cmp eax,W32_DEVICEIOCONTROL
+ jnz control_5
+ jmp Device_IO_Control_proc
+ control_5:
+ clc
+ ret
+ };
+}
+
+WORD __stdcall QEMU_API_Proc(PCRS_32 state)
+{
+ WORD rc = 0xFFFF;
+ WORD service = state->Client_EDX & 0xFFFF;
+ switch(service)
+ {
+ case VMWSVXD_PM16_VERSION:
+ rc = (VMWSVXD_MAJOR_VER << 8) | VMWSVXD_MINOR_VER;
+ break;
+ case VMWSVXD_PM16_VMM_VERSION:
+ rc = Get_VMM_Version();
+ break;
+ /* create region = input: ECX - num_pages; output: EDX - lin. address of descriptor, ECX - PPN of descriptor */
+ case VMWSVXD_PM16_ZEROMEM:
+ {
+ ULONG i = 0;
+ unsigned char *ptr = (unsigned char *)state->Client_ESI;
+ for(i = 0; i < state->Client_ECX; i++)
+ {
+ ptr[i] = 0;
+ }
+ rc = 1;
+ break;
+ }
+ }
+
+ if(rc == 0xFFFF)
+ {
+ state->Client_EFlags |= 0x1; // set carry
+ }
+ else
+ {
+ state->Client_EFlags &= 0xFFFFFFFEUL; // clear carry
+ }
+
+ return rc;
+}
+
+/*
+ * Service calls from protected mode (usually 16 bit) and virtual 86 mode
+ * CPU state before call is already on stack (EBP points it).
+ * Converts the call to __stdcall and call 'VMWS_API_Proc', result of this
+ * function is placed to saved AX register.
+ *
+ */
+void __declspec(naked) QEMU_API_Entry()
+{
+ _asm {
+ push ebp
+ call QEMU_API_Proc
+ mov [ebp+1Ch], ax
+ retn
+ }
+}
+
+static DWORD dwWindowsVMHandle = NULL;
+
+/**
+ * This is fix of broken screen when open DOS window
+ *
+ **/
+void __declspec(naked) virtual_0x1ce()
+{
+/*
+ * AX/AL contains the value to be read or written on the port.
+ * EBX contains the handle of the VM accessing the port.
+ * ECX contains the direction (in/out) and size (byte/word) of the operation.
+ * EDX contains the port number, which for us will either be 1CEh or 1CFh.
+ */
+ VxDCall(VDD, Get_VM_Info); // esi = result
+ _asm{
+ cmp edi, dwWindowsVMHandle ; Is the CRTC controlled by Windows?
+ jne _Virtual1CEPhysical ; If not, we should allow the I/O
+ cmp ebx, edi ; Is the calling VM Windows?
+ je _Virtual1CEPhysical ; If not, we should eat the I/O
+ ret
+ _Virtual1CEPhysical:
+ }
+ VxDJmp(VDD, Do_Physical_IO);
+}
+
+/* generate all entry pro VDD function */
+#define VDDFUNC(_fnname, _procname) void __declspec(naked) _procname ## _entry() { \
+ _asm { push ebp }; \
+ _asm { call _procname ## _proc }; \
+ _asm { retn }; \
+ }
+#include "minivdd_func.h"
+#undef VDDFUNC
+
+#define VDDFUNC(id, procname) DispatchTable[id] = (DWORD)(procname ## _entry);
+
+/* init device and fill dispatch table */
+void Device_Dynamic_Init_proc(DWORD WinVMHandle)
+{
+ dbg_printf(dbg_Device_Init_proc);
+ //VMMCall(_Allocate_Device_CB_Area);
+
+ VDD_Get_Mini_Dispatch_Table();
+ if(DispatchTableLength >= 0x31)
+ {
+ #include "minivdd_func.h"
+ }
+
+ dwWindowsVMHandle = WinVMHandle;
+
+ Install_IO_Handler(0x1ce, (DWORD)virtual_0x1ce);
+ Disable_Global_Trapping(0x1ce);
+ Install_IO_Handler(0x1cf, (DWORD)virtual_0x1ce);
+ Disable_Global_Trapping(0x1cf);
+
+ dbg_printf(dbg_Device_Init_proc_succ);
+}
+#undef VDDFUNC
+
+/*
+ * At Windows shutdown time, the display driver calls VDD_DRIVER_UNREGISTER,
+ * which calls our DisplayDriverDisabling callback, and soon thereafter
+ * does an INT 10h (AH=0) to mode 3 (and then 13) in V86 mode. However, the
+ * memory ranges for display memory are not always mapped!
+ *
+ * If the VGA ROM BIOS, during execution of such a set video mode call, tries to
+ * clear the screen, and the appropriate memory range isn't mapped, then we end
+ * up in a page fault handler, which I guess maps the memory and then resumes
+ * execution in V86 mode. But strangely, in QEMU, this fault & resume mechanism
+ * does not work with KVM or WHPX assist, at least on Intel. The machine hangs
+ * instead (I have not root caused why).
+ *
+ * We can dodge this problem by setting up real mappings up front.
+ *
+ * At entry, EBX contains a Windows VM handle.
+ *
+ */
+void Device_Init_Complete(DWORD VM)
+{
+ _PhysIntoV86(0xA0, VM, 0xA0, 16, 0);
+ _PhysIntoV86(0xB8, VM, 0xB8, 8, 0);
+}
+
+void Device_Init_proc()
+{
+ /* NOP */
+}
diff --git a/version.h b/version.h
index 2311c4b..a520bc0 100644
--- a/version.h
+++ b/version.h
@@ -5,7 +5,7 @@
#define DRV_STR(x) DRV_STR_(x)
/* DRV, VXD and DLL have to have the same */
-#define DRV_API_LEVEL 20230710UL
+#define DRV_API_LEVEL 20230805UL
/* on binaries equals 1 and for INF is 1 = separate driver, 2 = softgpu pack */
#define DRV_VER_MAJOR 1
diff --git a/vmdisp9x.inf b/vmdisp9x.inf
index 41e8906..2a7a754 100644
--- a/vmdisp9x.inf
+++ b/vmdisp9x.inf
@@ -27,6 +27,8 @@ DX.CopyBackup=10,SYSBCKUP
boxvmini.drv=1
vmwsmini.drv=1
vmwsmini.vxd=1
+qemumini.drv=1
+qemumini.vxd=1
;mesa:mesa3d.dll=1
;mesa:vmwsgl32.dll=1
;openglide:glide2x.dll=1
@@ -79,6 +81,7 @@ boxvmini.drv,,,0x00000004
[Qemu.Copy]
qemumini.drv,,,0x00000004
+qemumini.vxd,,,0x00000004
;mesa:mesa3d.dll,,,0x00000004
;bridge:bridge99.dll,,,0x00000004
@@ -112,7 +115,7 @@ vmwsmini.vxd,,,0x00000004
[Qemu.AddReg]
HKR,DEFAULT,drv,,qemumini.drv
-;HKR,DEFAULT,minivdd,,qemumini.vxd
+HKR,DEFAULT,minivdd,,qemumini.vxd
HKR,DEFAULT,Mode,,"8,640,480"
[VBox.AddReg]
diff --git a/vmware/svga3d_dx.h b/vmware/svga3d_dx.h
new file mode 100644
index 0000000..9ebbf0b
--- /dev/null
+++ b/vmware/svga3d_dx.h
@@ -0,0 +1,1562 @@
+/**********************************************************
+ * Copyright 2007-2017 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/*
+ * svga3d_dx.h --
+ *
+ * SVGA 3d hardware definitions for DX10 support.
+ */
+
+#ifndef _SVGA3D_DX_H_
+#define _SVGA3D_DX_H_
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_VMCORE
+
+#define SVGA3D_MAX_QUERY 64
+
+typedef uint32 SVGA3dSurfaceId;
+typedef uint8 SVGA3dQueryTypeUint8;
+
+
+#include "svga3d_limits.h"
+
+/* Matches D3D10_DDI_INPUT_CLASSIFICATION and D3D10_INPUT_CLASSIFICATION */
+#define SVGA3D_INPUT_MIN 0
+#define SVGA3D_INPUT_PER_VERTEX_DATA 0
+#define SVGA3D_INPUT_PER_INSTANCE_DATA 1
+#define SVGA3D_INPUT_MAX 2
+typedef uint32 SVGA3dInputClassification;
+
+/* Matches D3D10DDIRESOURCE_TYPE */
+#define SVGA3D_RESOURCE_TYPE_MIN 1
+#define SVGA3D_RESOURCE_BUFFER 1
+#define SVGA3D_RESOURCE_TEXTURE1D 2
+#define SVGA3D_RESOURCE_TEXTURE2D 3
+#define SVGA3D_RESOURCE_TEXTURE3D 4
+#define SVGA3D_RESOURCE_TEXTURECUBE 5
+#define SVGA3D_RESOURCE_TYPE_DX10_MAX 6
+#define SVGA3D_RESOURCE_BUFFEREX 6
+#define SVGA3D_RESOURCE_TYPE_MAX 7
+typedef uint32 SVGA3dResourceType;
+
+/* Matches D3D10_DDI_COLOR_WRITE_ENABLE and D3D10_COLOR_WRITE_ENABLE */
+#define SVGA3D_COLOR_WRITE_ENABLE_RED (1 << 0)
+#define SVGA3D_COLOR_WRITE_ENABLE_GREEN (1 << 1)
+#define SVGA3D_COLOR_WRITE_ENABLE_BLUE (1 << 2)
+#define SVGA3D_COLOR_WRITE_ENABLE_ALPHA (1 << 3)
+#define SVGA3D_COLOR_WRITE_ENABLE_ALL (SVGA3D_COLOR_WRITE_ENABLE_RED | \
+ SVGA3D_COLOR_WRITE_ENABLE_GREEN | \
+ SVGA3D_COLOR_WRITE_ENABLE_BLUE | \
+ SVGA3D_COLOR_WRITE_ENABLE_ALPHA)
+typedef uint8 SVGA3dColorWriteEnable;
+
+/* Matches D3D10_DDI_DEPTH_WRITE_MASK and D3D10_DEPTH_WRITE_MASK */
+#define SVGA3D_DEPTH_WRITE_MASK_ZERO 0
+#define SVGA3D_DEPTH_WRITE_MASK_ALL 1
+typedef uint8 SVGA3dDepthWriteMask;
+
+/* Matches D3D10_DDI_FILTER and D3D10_FILTER */
+#define SVGA3D_FILTER_MIP_LINEAR (1 << 0)
+#define SVGA3D_FILTER_MAG_LINEAR (1 << 2)
+#define SVGA3D_FILTER_MIN_LINEAR (1 << 4)
+#define SVGA3D_FILTER_ANISOTROPIC (1 << 6)
+#define SVGA3D_FILTER_COMPARE (1 << 7)
+typedef uint32 SVGA3dFilter;
+
+/* Matches D3D10_DDI_CULL_MODE */
+#define SVGA3D_CULL_INVALID 0
+#define SVGA3D_CULL_MIN 1
+#define SVGA3D_CULL_NONE 1
+#define SVGA3D_CULL_FRONT 2
+#define SVGA3D_CULL_BACK 3
+#define SVGA3D_CULL_MAX 4
+typedef uint8 SVGA3dCullMode;
+
+/* Matches D3D10_DDI_COMPARISON_FUNC */
+#define SVGA3D_COMPARISON_INVALID 0
+#define SVGA3D_COMPARISON_MIN 1
+#define SVGA3D_COMPARISON_NEVER 1
+#define SVGA3D_COMPARISON_LESS 2
+#define SVGA3D_COMPARISON_EQUAL 3
+#define SVGA3D_COMPARISON_LESS_EQUAL 4
+#define SVGA3D_COMPARISON_GREATER 5
+#define SVGA3D_COMPARISON_NOT_EQUAL 6
+#define SVGA3D_COMPARISON_GREATER_EQUAL 7
+#define SVGA3D_COMPARISON_ALWAYS 8
+#define SVGA3D_COMPARISON_MAX 9
+typedef uint8 SVGA3dComparisonFunc;
+
+/*
+ * SVGA3D_MULTISAMPLE_DISABLE disables MSAA for all primitives.
+ * SVGA3D_MULTISAMPLE_DISABLE_LINE, which is supported in DX10.1,
+ * disables MSAA for lines only.
+ */
+#define SVGA3D_MULTISAMPLE_DISABLE 0
+#define SVGA3D_MULTISAMPLE_ENABLE 1
+#define SVGA3D_MULTISAMPLE_DX_MAX 1
+#define SVGA3D_MULTISAMPLE_DISABLE_LINE 2
+#define SVGA3D_MULTISAMPLE_MAX 2
+typedef uint8 SVGA3dMultisampleEnable;
+
+#define SVGA3D_DX_MAX_VERTEXBUFFERS 32
+#define SVGA3D_DX_MAX_VERTEXINPUTREGISTERS 16
+#define SVGA3D_DX_SM41_MAX_VERTEXINPUTREGISTERS 32
+#define SVGA3D_DX_MAX_SOTARGETS 4
+#define SVGA3D_DX_MAX_SRVIEWS 128
+#define SVGA3D_DX_MAX_CONSTBUFFERS 16
+#define SVGA3D_DX_MAX_SAMPLERS 16
+
+#define SVGA3D_DX_MAX_CONSTBUF_BINDING_SIZE (4096 * 4 * (uint32)sizeof(uint32))
+
+typedef uint32 SVGA3dShaderResourceViewId;
+typedef uint32 SVGA3dRenderTargetViewId;
+typedef uint32 SVGA3dDepthStencilViewId;
+
+typedef uint32 SVGA3dShaderId;
+typedef uint32 SVGA3dElementLayoutId;
+typedef uint32 SVGA3dSamplerId;
+typedef uint32 SVGA3dBlendStateId;
+typedef uint32 SVGA3dDepthStencilStateId;
+typedef uint32 SVGA3dRasterizerStateId;
+typedef uint32 SVGA3dQueryId;
+typedef uint32 SVGA3dStreamOutputId;
+
+typedef union {
+ struct {
+ float r;
+ float g;
+ float b;
+ float a;
+ };
+
+ float value[4];
+} SVGA3dRGBAFloat;
+
+typedef
+struct {
+ uint32 cid;
+ SVGAMobId mobid;
+}
+SVGAOTableDXContextEntry;
+
+typedef
+struct SVGA3dCmdDXDefineContext {
+ uint32 cid;
+}
+SVGA3dCmdDXDefineContext; /* SVGA_3D_CMD_DX_DEFINE_CONTEXT */
+
+typedef
+struct SVGA3dCmdDXDestroyContext {
+ uint32 cid;
+}
+SVGA3dCmdDXDestroyContext; /* SVGA_3D_CMD_DX_DESTROY_CONTEXT */
+
+/*
+ * Bind a DX context.
+ *
+ * validContents should be set to 0 for new contexts,
+ * and 1 if this is an old context which is getting paged
+ * back on to the device.
+ *
+ * For new contexts, it is recommended that the driver
+ * issue commands to initialize all interesting state
+ * prior to rendering.
+ */
+typedef
+struct SVGA3dCmdDXBindContext {
+ uint32 cid;
+ SVGAMobId mobid;
+ uint32 validContents;
+}
+SVGA3dCmdDXBindContext; /* SVGA_3D_CMD_DX_BIND_CONTEXT */
+
+/*
+ * Readback a DX context.
+ * (Request that the device flush the contents back into guest memory.)
+ */
+typedef
+struct SVGA3dCmdDXReadbackContext {
+ uint32 cid;
+}
+SVGA3dCmdDXReadbackContext; /* SVGA_3D_CMD_DX_READBACK_CONTEXT */
+
+/*
+ * Invalidate a guest-backed context.
+ */
+typedef
+struct SVGA3dCmdDXInvalidateContext {
+ uint32 cid;
+}
+SVGA3dCmdDXInvalidateContext; /* SVGA_3D_CMD_DX_INVALIDATE_CONTEXT */
+
+typedef
+struct SVGA3dCmdDXSetSingleConstantBuffer {
+ uint32 slot;
+ SVGA3dShaderType type;
+ SVGA3dSurfaceId sid;
+ uint32 offsetInBytes;
+ uint32 sizeInBytes;
+}
+SVGA3dCmdDXSetSingleConstantBuffer;
+/* SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER */
+
+typedef
+struct SVGA3dCmdDXSetShaderResources {
+ uint32 startView;
+ SVGA3dShaderType type;
+
+ /*
+ * Followed by a variable number of SVGA3dShaderResourceViewId's.
+ */
+}
+SVGA3dCmdDXSetShaderResources; /* SVGA_3D_CMD_DX_SET_SHADER_RESOURCES */
+
+typedef
+struct SVGA3dCmdDXSetShader {
+ SVGA3dShaderId shaderId;
+ SVGA3dShaderType type;
+}
+SVGA3dCmdDXSetShader; /* SVGA_3D_CMD_DX_SET_SHADER */
+
+typedef
+struct SVGA3dCmdDXSetSamplers {
+ uint32 startSampler;
+ SVGA3dShaderType type;
+
+ /*
+ * Followed by a variable number of SVGA3dSamplerId's.
+ */
+}
+SVGA3dCmdDXSetSamplers; /* SVGA_3D_CMD_DX_SET_SAMPLERS */
+
+typedef
+struct SVGA3dCmdDXDraw {
+ uint32 vertexCount;
+ uint32 startVertexLocation;
+}
+SVGA3dCmdDXDraw; /* SVGA_3D_CMD_DX_DRAW */
+
+typedef
+struct SVGA3dCmdDXDrawIndexed {
+ uint32 indexCount;
+ uint32 startIndexLocation;
+ int32 baseVertexLocation;
+}
+SVGA3dCmdDXDrawIndexed; /* SVGA_3D_CMD_DX_DRAW_INDEXED */
+
+typedef
+struct SVGA3dCmdDXDrawInstanced {
+ uint32 vertexCountPerInstance;
+ uint32 instanceCount;
+ uint32 startVertexLocation;
+ uint32 startInstanceLocation;
+}
+SVGA3dCmdDXDrawInstanced; /* SVGA_3D_CMD_DX_DRAW_INSTANCED */
+
+typedef
+struct SVGA3dCmdDXDrawIndexedInstanced {
+ uint32 indexCountPerInstance;
+ uint32 instanceCount;
+ uint32 startIndexLocation;
+ int32 baseVertexLocation;
+ uint32 startInstanceLocation;
+}
+SVGA3dCmdDXDrawIndexedInstanced; /* SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED */
+
+typedef
+struct SVGA3dCmdDXDrawIndexedInstancedIndirect {
+ SVGA3dSurfaceId argsBufferSid;
+ uint32 byteOffsetForArgs;
+}
+SVGA3dCmdDXDrawIndexedInstancedIndirect;
+/* SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT */
+
+typedef
+struct SVGA3dCmdDXDrawInstancedIndirect {
+ SVGA3dSurfaceId argsBufferSid;
+ uint32 byteOffsetForArgs;
+}
+SVGA3dCmdDXDrawInstancedIndirect;
+/* SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT */
+
+typedef
+struct SVGA3dCmdDXDrawAuto {
+ uint32 pad0;
+}
+SVGA3dCmdDXDrawAuto; /* SVGA_3D_CMD_DX_DRAW_AUTO */
+
+typedef
+struct SVGA3dCmdDXDispatch {
+ uint32 threadGroupCountX;
+ uint32 threadGroupCountY;
+ uint32 threadGroupCountZ;
+}
+SVGA3dCmdDXDispatch;
+/* SVGA_3D_CMD_DX_DISPATCH */
+
+typedef
+struct SVGA3dCmdDXDispatchIndirect {
+ SVGA3dSurfaceId argsBufferSid;
+ uint32 byteOffsetForArgs;
+}
+SVGA3dCmdDXDispatchIndirect;
+/* SVGA_3D_CMD_DX_DISPATCH_INDIRECT */
+
+typedef
+struct SVGA3dCmdDXSetInputLayout {
+ SVGA3dElementLayoutId elementLayoutId;
+}
+SVGA3dCmdDXSetInputLayout; /* SVGA_3D_CMD_DX_SET_INPUT_LAYOUT */
+
+typedef
+struct SVGA3dVertexBuffer {
+ SVGA3dSurfaceId sid;
+ uint32 stride;
+ uint32 offset;
+}
+SVGA3dVertexBuffer;
+
+typedef
+struct SVGA3dCmdDXSetVertexBuffers {
+ uint32 startBuffer;
+ /* Followed by a variable number of SVGA3dVertexBuffer's. */
+}
+SVGA3dCmdDXSetVertexBuffers; /* SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS */
+
+typedef
+struct SVGA3dCmdDXSetIndexBuffer {
+ SVGA3dSurfaceId sid;
+ SVGA3dSurfaceFormat format;
+ uint32 offset;
+}
+SVGA3dCmdDXSetIndexBuffer; /* SVGA_3D_CMD_DX_SET_INDEX_BUFFER */
+
+typedef
+struct SVGA3dCmdDXSetTopology {
+ SVGA3dPrimitiveType topology;
+}
+SVGA3dCmdDXSetTopology; /* SVGA_3D_CMD_DX_SET_TOPOLOGY */
+
+typedef
+struct SVGA3dCmdDXSetRenderTargets {
+ SVGA3dDepthStencilViewId depthStencilViewId;
+ /* Followed by a variable number of SVGA3dRenderTargetViewId's. */
+}
+SVGA3dCmdDXSetRenderTargets; /* SVGA_3D_CMD_DX_SET_RENDERTARGETS */
+
+typedef
+struct SVGA3dCmdDXSetBlendState {
+ SVGA3dBlendStateId blendId;
+ float blendFactor[4];
+ uint32 sampleMask;
+}
+SVGA3dCmdDXSetBlendState; /* SVGA_3D_CMD_DX_SET_BLEND_STATE */
+
+typedef
+struct SVGA3dCmdDXSetDepthStencilState {
+ SVGA3dDepthStencilStateId depthStencilId;
+ uint32 stencilRef;
+}
+SVGA3dCmdDXSetDepthStencilState; /* SVGA_3D_CMD_DX_SET_DEPTHSTENCIL_STATE */
+
+typedef
+struct SVGA3dCmdDXSetRasterizerState {
+ SVGA3dRasterizerStateId rasterizerId;
+}
+SVGA3dCmdDXSetRasterizerState; /* SVGA_3D_CMD_DX_SET_RASTERIZER_STATE */
+
+/* Matches D3D10DDI_QUERY_MISCFLAG and D3D10_QUERY_MISC_FLAG */
+#define SVGA3D_DXQUERY_FLAG_PREDICATEHINT (1 << 0)
+typedef uint32 SVGA3dDXQueryFlags;
+
+/*
+ * The SVGADXQueryDeviceState and SVGADXQueryDeviceBits are used by the device
+ * to track query state transitions, but are not intended to be used by the
+ * driver.
+ */
+#define SVGADX_QDSTATE_INVALID ((uint8)-1) /* Query has no state */
+#define SVGADX_QDSTATE_MIN 0
+#define SVGADX_QDSTATE_IDLE 0 /* Query hasn't started yet */
+#define SVGADX_QDSTATE_ACTIVE 1 /* Query is actively gathering data */
+#define SVGADX_QDSTATE_PENDING 2 /* Query is waiting for results */
+#define SVGADX_QDSTATE_FINISHED 3 /* Query has completed */
+#define SVGADX_QDSTATE_MAX 4
+typedef uint8 SVGADXQueryDeviceState;
+
+typedef
+struct {
+ SVGA3dQueryTypeUint8 type;
+ uint16 pad0;
+ SVGADXQueryDeviceState state;
+ SVGA3dDXQueryFlags flags;
+ SVGAMobId mobid;
+ uint32 offset;
+}
+SVGACOTableDXQueryEntry;
+
+typedef
+struct SVGA3dCmdDXDefineQuery {
+ SVGA3dQueryId queryId;
+ SVGA3dQueryType type;
+ SVGA3dDXQueryFlags flags;
+}
+SVGA3dCmdDXDefineQuery; /* SVGA_3D_CMD_DX_DEFINE_QUERY */
+
+typedef
+struct SVGA3dCmdDXDestroyQuery {
+ SVGA3dQueryId queryId;
+}
+SVGA3dCmdDXDestroyQuery; /* SVGA_3D_CMD_DX_DESTROY_QUERY */
+
+typedef
+struct SVGA3dCmdDXBindQuery {
+ SVGA3dQueryId queryId;
+ SVGAMobId mobid;
+}
+SVGA3dCmdDXBindQuery; /* SVGA_3D_CMD_DX_BIND_QUERY */
+
+typedef
+struct SVGA3dCmdDXSetQueryOffset {
+ SVGA3dQueryId queryId;
+ uint32 mobOffset;
+}
+SVGA3dCmdDXSetQueryOffset; /* SVGA_3D_CMD_DX_SET_QUERY_OFFSET */
+
+typedef
+struct SVGA3dCmdDXBeginQuery {
+ SVGA3dQueryId queryId;
+}
+SVGA3dCmdDXBeginQuery; /* SVGA_3D_CMD_DX_QUERY_BEGIN */
+
+typedef
+struct SVGA3dCmdDXEndQuery {
+ SVGA3dQueryId queryId;
+}
+SVGA3dCmdDXEndQuery; /* SVGA_3D_CMD_DX_QUERY_END */
+
+typedef
+struct SVGA3dCmdDXReadbackQuery {
+ SVGA3dQueryId queryId;
+}
+SVGA3dCmdDXReadbackQuery; /* SVGA_3D_CMD_DX_READBACK_QUERY */
+
+typedef
+struct SVGA3dCmdDXMoveQuery {
+ SVGA3dQueryId queryId;
+ SVGAMobId mobid;
+ uint32 mobOffset;
+}
+SVGA3dCmdDXMoveQuery; /* SVGA_3D_CMD_DX_MOVE_QUERY */
+
+typedef
+struct SVGA3dCmdDXBindAllQuery {
+ uint32 cid;
+ SVGAMobId mobid;
+}
+SVGA3dCmdDXBindAllQuery; /* SVGA_3D_CMD_DX_BIND_ALL_QUERY */
+
+typedef
+struct SVGA3dCmdDXReadbackAllQuery {
+ uint32 cid;
+}
+SVGA3dCmdDXReadbackAllQuery; /* SVGA_3D_CMD_DX_READBACK_ALL_QUERY */
+
+typedef
+struct SVGA3dCmdDXSetPredication {
+ SVGA3dQueryId queryId;
+ uint32 predicateValue;
+}
+SVGA3dCmdDXSetPredication; /* SVGA_3D_CMD_DX_SET_PREDICATION */
+
+typedef
+struct MKS3dDXSOState {
+ uint32 offset; /* Starting offset */
+ uint32 intOffset; /* Internal offset */
+ uint32 vertexCount; /* vertices written */
+ uint32 sizeInBytes; /* max bytes to write */
+}
+SVGA3dDXSOState;
+
+/* Set the offset field to this value to append SO values to the buffer */
+#define SVGA3D_DX_SO_OFFSET_APPEND ((uint32) ~0u)
+
+typedef
+struct SVGA3dSoTarget {
+ SVGA3dSurfaceId sid;
+ uint32 offset;
+ uint32 sizeInBytes;
+}
+SVGA3dSoTarget;
+
+typedef
+struct SVGA3dCmdDXSetSOTargets {
+ uint32 pad0;
+ /* Followed by a variable number of SVGA3dSOTarget's. */
+}
+SVGA3dCmdDXSetSOTargets; /* SVGA_3D_CMD_DX_SET_SOTARGETS */
+
+typedef
+struct SVGA3dViewport
+{
+ float x;
+ float y;
+ float width;
+ float height;
+ float minDepth;
+ float maxDepth;
+}
+SVGA3dViewport;
+
+typedef
+struct SVGA3dCmdDXSetViewports {
+ uint32 pad0;
+ /* Followed by a variable number of SVGA3dViewport's. */
+}
+SVGA3dCmdDXSetViewports; /* SVGA_3D_CMD_DX_SET_VIEWPORTS */
+
+#define SVGA3D_DX_MAX_VIEWPORTS 16
+
+typedef
+struct SVGA3dCmdDXSetScissorRects {
+ uint32 pad0;
+ /* Followed by a variable number of SVGASignedRect's. */
+}
+SVGA3dCmdDXSetScissorRects; /* SVGA_3D_CMD_DX_SET_SCISSORRECTS */
+
+#define SVGA3D_DX_MAX_SCISSORRECTS 16
+
+typedef
+struct SVGA3dCmdDXClearRenderTargetView {
+ SVGA3dRenderTargetViewId renderTargetViewId;
+ SVGA3dRGBAFloat rgba;
+}
+SVGA3dCmdDXClearRenderTargetView; /* SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW */
+
+typedef
+struct SVGA3dCmdDXClearDepthStencilView {
+ uint16 flags;
+ uint16 stencil;
+ SVGA3dDepthStencilViewId depthStencilViewId;
+ float depth;
+}
+SVGA3dCmdDXClearDepthStencilView; /* SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW */
+
+typedef
+struct SVGA3dCmdDXPredCopyRegion {
+ SVGA3dSurfaceId dstSid;
+ uint32 dstSubResource;
+ SVGA3dSurfaceId srcSid;
+ uint32 srcSubResource;
+ SVGA3dCopyBox box;
+}
+SVGA3dCmdDXPredCopyRegion;
+/* SVGA_3D_CMD_DX_PRED_COPY_REGION */
+
+typedef
+struct SVGA3dCmdDXPredCopy {
+ SVGA3dSurfaceId dstSid;
+ SVGA3dSurfaceId srcSid;
+}
+SVGA3dCmdDXPredCopy; /* SVGA_3D_CMD_DX_PRED_COPY */
+
+typedef
+struct SVGA3dCmdDXPredConvertRegion {
+ SVGA3dSurfaceId dstSid;
+ uint32 dstSubResource;
+ SVGA3dSurfaceId srcSid;
+ uint32 srcSubResource;
+ SVGA3dCopyBox box;
+}
+SVGA3dCmdDXPredConvertRegion; /* SVGA_3D_CMD_DX_PRED_CONVERT_REGION */
+
+typedef
+struct SVGA3dCmdDXPredConvert {
+ SVGA3dSurfaceId dstSid;
+ SVGA3dSurfaceId srcSid;
+}
+SVGA3dCmdDXPredConvert; /* SVGA_3D_CMD_DX_PRED_CONVERT */
+
+typedef
+struct SVGA3dCmdDXBufferCopy {
+ SVGA3dSurfaceId dest;
+ SVGA3dSurfaceId src;
+ uint32 destX;
+ uint32 srcX;
+ uint32 width;
+}
+SVGA3dCmdDXBufferCopy;
+/* SVGA_3D_CMD_DX_BUFFER_COPY */
+
+/*
+ * Perform a surface copy between a multisample, and a non-multisampled
+ * surface.
+ */
+typedef
+struct {
+ SVGA3dSurfaceId dstSid;
+ uint32 dstSubResource;
+ SVGA3dSurfaceId srcSid;
+ uint32 srcSubResource;
+ SVGA3dSurfaceFormat copyFormat;
+}
+SVGA3dCmdDXResolveCopy; /* SVGA_3D_CMD_DX_RESOLVE_COPY */
+
+/*
+ * Perform a predicated surface copy between a multisample, and a
+ * non-multisampled surface.
+ */
+typedef
+struct {
+ SVGA3dSurfaceId dstSid;
+ uint32 dstSubResource;
+ SVGA3dSurfaceId srcSid;
+ uint32 srcSubResource;
+ SVGA3dSurfaceFormat copyFormat;
+}
+SVGA3dCmdDXPredResolveCopy; /* SVGA_3D_CMD_DX_PRED_RESOLVE_COPY */
+
+typedef uint32 SVGA3dDXStretchBltMode;
+#define SVGADX_STRETCHBLT_LINEAR (1 << 0)
+#define SVGADX_STRETCHBLT_FORCE_SRC_SRGB (1 << 1)
+#define SVGADX_STRETCHBLT_MODE_MAX (1 << 2)
+
+typedef
+struct SVGA3dCmdDXStretchBlt {
+ SVGA3dSurfaceId srcSid;
+ uint32 srcSubResource;
+ SVGA3dSurfaceId dstSid;
+ uint32 destSubResource;
+ SVGA3dBox boxSrc;
+ SVGA3dBox boxDest;
+ SVGA3dDXStretchBltMode mode;
+}
+SVGA3dCmdDXStretchBlt; /* SVGA_3D_CMD_DX_STRETCHBLT */
+
+typedef
+struct SVGA3dCmdDXGenMips {
+ SVGA3dShaderResourceViewId shaderResourceViewId;
+}
+SVGA3dCmdDXGenMips; /* SVGA_3D_CMD_DX_GENMIPS */
+
+/*
+ * Update a sub-resource in a guest-backed resource.
+ * (Inform the device that the guest-contents have been updated.)
+ */
+typedef
+struct SVGA3dCmdDXUpdateSubResource {
+ SVGA3dSurfaceId sid;
+ uint32 subResource;
+ SVGA3dBox box;
+}
+SVGA3dCmdDXUpdateSubResource; /* SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE */
+
+/*
+ * Readback a subresource in a guest-backed resource.
+ * (Request the device to flush the dirty contents into the guest.)
+ */
+typedef
+struct SVGA3dCmdDXReadbackSubResource {
+ SVGA3dSurfaceId sid;
+ uint32 subResource;
+}
+SVGA3dCmdDXReadbackSubResource; /* SVGA_3D_CMD_DX_READBACK_SUBRESOURCE */
+
+/*
+ * Invalidate an image in a guest-backed surface.
+ * (Notify the device that the contents can be lost.)
+ */
+typedef
+struct SVGA3dCmdDXInvalidateSubResource {
+ SVGA3dSurfaceId sid;
+ uint32 subResource;
+}
+SVGA3dCmdDXInvalidateSubResource; /* SVGA_3D_CMD_DX_INVALIDATE_SUBRESOURCE */
+
+
+/*
+ * Raw byte wise transfer from a buffer surface into another surface
+ * of the requested box. Supported if 3d is enabled and SVGA_CAP_DX
+ * is set. This command does not take a context.
+ */
+typedef
+struct SVGA3dCmdDXTransferFromBuffer {
+ SVGA3dSurfaceId srcSid;
+ uint32 srcOffset;
+ uint32 srcPitch;
+ uint32 srcSlicePitch;
+ SVGA3dSurfaceId destSid;
+ uint32 destSubResource;
+ SVGA3dBox destBox;
+}
+SVGA3dCmdDXTransferFromBuffer; /* SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER */
+
+
+/*
+ * Raw byte wise transfer from a buffer surface into another surface
+ * of the requested box. Supported if SVGA3D_DEVCAP_DXCONTEXT is set.
+ * The context is implied from the command buffer header.
+ */
+typedef
+struct SVGA3dCmdDXPredTransferFromBuffer {
+ SVGA3dSurfaceId srcSid;
+ uint32 srcOffset;
+ uint32 srcPitch;
+ uint32 srcSlicePitch;
+ SVGA3dSurfaceId destSid;
+ uint32 destSubResource;
+ SVGA3dBox destBox;
+}
+SVGA3dCmdDXPredTransferFromBuffer;
+/* SVGA_3D_CMD_DX_PRED_TRANSFER_FROM_BUFFER */
+
+
+typedef
+struct SVGA3dCmdDXSurfaceCopyAndReadback {
+ SVGA3dSurfaceId srcSid;
+ SVGA3dSurfaceId destSid;
+ SVGA3dCopyBox box;
+}
+SVGA3dCmdDXSurfaceCopyAndReadback;
+/* SVGA_3D_CMD_DX_SURFACE_COPY_AND_READBACK */
+
+/*
+ * SVGA_DX_HINT_NONE: Does nothing.
+ *
+ * SVGA_DX_HINT_PREFETCH_OBJECT:
+ * SVGA_DX_HINT_PREEVICT_OBJECT:
+ * Consumes a SVGAObjectRef, and hints that the host should consider
+ * fetching/evicting the specified object.
+ *
+ * An id of SVGA3D_INVALID_ID can be used if the guest isn't sure
+ * what object was affected. (For instance, if the guest knows that
+ * it is about to evict a DXShader, but doesn't know precisely which one,
+ * the device can still use this to help limit it's search, or track
+ * how many page-outs have happened.)
+ *
+ * SVGA_DX_HINT_PREFETCH_COBJECT:
+ * SVGA_DX_HINT_PREEVICT_COBJECT:
+ * Same as the above, except they consume an SVGACObjectRef.
+ */
+typedef uint32 SVGADXHintId;
+#define SVGA_DX_HINT_NONE 0
+#define SVGA_DX_HINT_PREFETCH_OBJECT 1
+#define SVGA_DX_HINT_PREEVICT_OBJECT 2
+#define SVGA_DX_HINT_PREFETCH_COBJECT 3
+#define SVGA_DX_HINT_PREEVICT_COBJECT 4
+#define SVGA_DX_HINT_MAX 5
+
+typedef
+struct SVGAObjectRef {
+ SVGAOTableType type;
+ uint32 id;
+}
+SVGAObjectRef;
+
+typedef
+struct SVGACObjectRef {
+ SVGACOTableType type;
+ uint32 cid;
+ uint32 id;
+}
+SVGACObjectRef;
+
+typedef
+struct SVGA3dCmdDXHint {
+ SVGADXHintId hintId;
+
+ /*
+ * Followed by variable sized data depending on the hintId.
+ */
+}
+SVGA3dCmdDXHint;
+/* SVGA_3D_CMD_DX_HINT */
+
+typedef
+struct SVGA3dCmdDXBufferUpdate {
+ SVGA3dSurfaceId sid;
+ uint32 x;
+ uint32 width;
+}
+SVGA3dCmdDXBufferUpdate;
+/* SVGA_3D_CMD_DX_BUFFER_UPDATE */
+
+typedef
+struct SVGA3dCmdDXSetConstantBufferOffset {
+ uint32 slot;
+ uint32 offsetInBytes;
+}
+SVGA3dCmdDXSetConstantBufferOffset;
+
+typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetVSConstantBufferOffset;
+/* SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET */
+
+typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetPSConstantBufferOffset;
+/* SVGA_3D_CMD_DX_SET_PS_CONSTANT_BUFFER_OFFSET */
+
+typedef SVGA3dCmdDXSetConstantBufferOffset SVGA3dCmdDXSetGSConstantBufferOffset;
+/* SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET */
+
+
+typedef
+struct {
+ union {
+ struct {
+ uint32 firstElement;
+ uint32 numElements;
+ uint32 pad0;
+ uint32 pad1;
+ } buffer;
+ struct {
+ uint32 mostDetailedMip;
+ uint32 firstArraySlice;
+ uint32 mipLevels;
+ uint32 arraySize;
+ } tex;
+ struct {
+ uint32 firstElement; // D3D11DDIARG_BUFFEREX_SHADERRESOURCEVIEW
+ uint32 numElements;
+ uint32 flags;
+ uint32 pad0;
+ } bufferex;
+ };
+}
+SVGA3dShaderResourceViewDesc;
+
+typedef
+struct {
+ SVGA3dSurfaceId sid;
+ SVGA3dSurfaceFormat format;
+ SVGA3dResourceType resourceDimension;
+ SVGA3dShaderResourceViewDesc desc;
+ uint32 pad;
+}
+SVGACOTableDXSRViewEntry;
+
+typedef
+struct SVGA3dCmdDXDefineShaderResourceView {
+ SVGA3dShaderResourceViewId shaderResourceViewId;
+
+ SVGA3dSurfaceId sid;
+ SVGA3dSurfaceFormat format;
+ SVGA3dResourceType resourceDimension;
+
+ SVGA3dShaderResourceViewDesc desc;
+}
+SVGA3dCmdDXDefineShaderResourceView;
+/* SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW */
+
+typedef
+struct SVGA3dCmdDXDestroyShaderResourceView {
+ SVGA3dShaderResourceViewId shaderResourceViewId;
+}
+SVGA3dCmdDXDestroyShaderResourceView;
+/* SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW */
+
+typedef
+struct SVGA3dRenderTargetViewDesc {
+ union {
+ struct {
+ uint32 firstElement;
+ uint32 numElements;
+ } buffer;
+ struct {
+ uint32 mipSlice;
+ uint32 firstArraySlice;
+ uint32 arraySize;
+ } tex; /* 1d, 2d, cube */
+ struct {
+ uint32 mipSlice;
+ uint32 firstW;
+ uint32 wSize;
+ } tex3D;
+ };
+}
+SVGA3dRenderTargetViewDesc;
+
+typedef
+struct {
+ SVGA3dSurfaceId sid;
+ SVGA3dSurfaceFormat format;
+ SVGA3dResourceType resourceDimension;
+ SVGA3dRenderTargetViewDesc desc;
+ uint32 pad[2];
+}
+SVGACOTableDXRTViewEntry;
+
+typedef
+struct SVGA3dCmdDXDefineRenderTargetView {
+ SVGA3dRenderTargetViewId renderTargetViewId;
+
+ SVGA3dSurfaceId sid;
+ SVGA3dSurfaceFormat format;
+ SVGA3dResourceType resourceDimension;
+
+ SVGA3dRenderTargetViewDesc desc;
+}
+SVGA3dCmdDXDefineRenderTargetView;
+/* SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW */
+
+typedef
+struct SVGA3dCmdDXDestroyRenderTargetView {
+ SVGA3dRenderTargetViewId renderTargetViewId;
+}
+SVGA3dCmdDXDestroyRenderTargetView;
+/* SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW */
+
+/*
+ * Create Depth-stencil view flags
+ * http://msdn.microsoft.com/en-us/library/windows/hardware/ff542167(v=vs.85).aspx
+ */
+#define SVGA3D_DXDSVIEW_CREATE_READ_ONLY_DEPTH 0x01
+#define SVGA3D_DXDSVIEW_CREATE_READ_ONLY_STENCIL 0x02
+#define SVGA3D_DXDSVIEW_CREATE_FLAG_MASK 0x03
+typedef uint8 SVGA3DCreateDSViewFlags;
+
+typedef
+struct {
+ SVGA3dSurfaceId sid;
+ SVGA3dSurfaceFormat format;
+ SVGA3dResourceType resourceDimension;
+ uint32 mipSlice;
+ uint32 firstArraySlice;
+ uint32 arraySize;
+ SVGA3DCreateDSViewFlags flags;
+ uint8 pad0;
+ uint16 pad1;
+ uint32 pad2;
+}
+SVGACOTableDXDSViewEntry;
+
+typedef
+struct SVGA3dCmdDXDefineDepthStencilView {
+ SVGA3dDepthStencilViewId depthStencilViewId;
+
+ SVGA3dSurfaceId sid;
+ SVGA3dSurfaceFormat format;
+ SVGA3dResourceType resourceDimension;
+ uint32 mipSlice;
+ uint32 firstArraySlice;
+ uint32 arraySize;
+ SVGA3DCreateDSViewFlags flags; /* D3D11DDIARG_CREATEDEPTHSTENCILVIEW */
+ uint8 pad0;
+ uint16 pad1;
+}
+SVGA3dCmdDXDefineDepthStencilView;
+/* SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW */
+
+typedef
+struct SVGA3dCmdDXDestroyDepthStencilView {
+ SVGA3dDepthStencilViewId depthStencilViewId;
+}
+SVGA3dCmdDXDestroyDepthStencilView;
+/* SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW */
+
+typedef
+struct SVGA3dInputElementDesc {
+ uint32 inputSlot;
+ uint32 alignedByteOffset;
+ SVGA3dSurfaceFormat format;
+ SVGA3dInputClassification inputSlotClass;
+ uint32 instanceDataStepRate;
+ uint32 inputRegister;
+}
+SVGA3dInputElementDesc;
+
+typedef
+struct {
+ uint32 elid;
+ uint32 numDescs;
+ SVGA3dInputElementDesc descs[32];
+ uint32 pad[62];
+}
+SVGACOTableDXElementLayoutEntry;
+
+typedef
+struct SVGA3dCmdDXDefineElementLayout {
+ SVGA3dElementLayoutId elementLayoutId;
+ /* Followed by a variable number of SVGA3dInputElementDesc's. */
+}
+SVGA3dCmdDXDefineElementLayout;
+/* SVGA_3D_CMD_DX_DEFINE_ELEMENTLAYOUT */
+
+typedef
+struct SVGA3dCmdDXDestroyElementLayout {
+ SVGA3dElementLayoutId elementLayoutId;
+}
+SVGA3dCmdDXDestroyElementLayout;
+/* SVGA_3D_CMD_DX_DESTROY_ELEMENTLAYOUT */
+
+
+#define SVGA3D_DX_MAX_RENDER_TARGETS 8
+
+typedef
+struct SVGA3dDXBlendStatePerRT {
+ uint8 blendEnable;
+ uint8 srcBlend;
+ uint8 destBlend;
+ uint8 blendOp;
+ uint8 srcBlendAlpha;
+ uint8 destBlendAlpha;
+ uint8 blendOpAlpha;
+ SVGA3dColorWriteEnable renderTargetWriteMask;
+ uint8 logicOpEnable;
+ uint8 logicOp;
+ uint16 pad0;
+}
+SVGA3dDXBlendStatePerRT;
+
+typedef
+struct {
+ uint8 alphaToCoverageEnable;
+ uint8 independentBlendEnable;
+ uint16 pad0;
+ SVGA3dDXBlendStatePerRT perRT[SVGA3D_MAX_RENDER_TARGETS];
+ uint32 pad1[7];
+}
+SVGACOTableDXBlendStateEntry;
+
+/*
+ * XXX - DX10 style (not 10.1 at this point)
+ * XXX - For more information see
+ * http://msdn.microsoft.com/en-us/library/ff541919%28v=VS.85%29.aspx
+ */
+typedef
+struct SVGA3dCmdDXDefineBlendState {
+ SVGA3dBlendStateId blendId;
+ uint8 alphaToCoverageEnable;
+ uint8 independentBlendEnable;
+ uint16 pad0;
+ SVGA3dDXBlendStatePerRT perRT[SVGA3D_MAX_RENDER_TARGETS];
+}
+SVGA3dCmdDXDefineBlendState; /* SVGA_3D_CMD_DX_DEFINE_BLEND_STATE */
+
+typedef
+struct SVGA3dCmdDXDestroyBlendState {
+ SVGA3dBlendStateId blendId;
+}
+SVGA3dCmdDXDestroyBlendState; /* SVGA_3D_CMD_DX_DESTROY_BLEND_STATE */
+
+typedef
+struct {
+ uint8 depthEnable;
+ SVGA3dDepthWriteMask depthWriteMask;
+ SVGA3dComparisonFunc depthFunc;
+ uint8 stencilEnable;
+ uint8 frontEnable;
+ uint8 backEnable;
+ uint8 stencilReadMask;
+ uint8 stencilWriteMask;
+
+ uint8 frontStencilFailOp;
+ uint8 frontStencilDepthFailOp;
+ uint8 frontStencilPassOp;
+ SVGA3dComparisonFunc frontStencilFunc;
+
+ uint8 backStencilFailOp;
+ uint8 backStencilDepthFailOp;
+ uint8 backStencilPassOp;
+ SVGA3dComparisonFunc backStencilFunc;
+}
+SVGACOTableDXDepthStencilEntry;
+
+/*
+ * XXX - For more information see
+ * http://msdn.microsoft.com/en-us/library/ff541944%28v=VS.85%29.aspx
+ */
+typedef
+struct SVGA3dCmdDXDefineDepthStencilState {
+ SVGA3dDepthStencilStateId depthStencilId;
+
+ uint8 depthEnable;
+ SVGA3dDepthWriteMask depthWriteMask;
+ SVGA3dComparisonFunc depthFunc;
+ uint8 stencilEnable;
+ uint8 frontEnable;
+ uint8 backEnable;
+ uint8 stencilReadMask;
+ uint8 stencilWriteMask;
+
+ uint8 frontStencilFailOp;
+ uint8 frontStencilDepthFailOp;
+ uint8 frontStencilPassOp;
+ SVGA3dComparisonFunc frontStencilFunc;
+
+ uint8 backStencilFailOp;
+ uint8 backStencilDepthFailOp;
+ uint8 backStencilPassOp;
+ SVGA3dComparisonFunc backStencilFunc;
+}
+SVGA3dCmdDXDefineDepthStencilState;
+/* SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_STATE */
+
+typedef
+struct SVGA3dCmdDXDestroyDepthStencilState {
+ SVGA3dDepthStencilStateId depthStencilId;
+}
+SVGA3dCmdDXDestroyDepthStencilState;
+/* SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_STATE */
+
+typedef
+struct {
+ uint8 fillMode;
+ SVGA3dCullMode cullMode;
+ uint8 frontCounterClockwise;
+ uint8 provokingVertexLast;
+ int32 depthBias;
+ float depthBiasClamp;
+ float slopeScaledDepthBias;
+ uint8 depthClipEnable;
+ uint8 scissorEnable;
+ SVGA3dMultisampleEnable multisampleEnable;
+ uint8 antialiasedLineEnable;
+ float lineWidth;
+ uint8 lineStippleEnable;
+ uint8 lineStippleFactor;
+ uint16 lineStipplePattern;
+ uint32 forcedSampleCount;
+}
+SVGACOTableDXRasterizerStateEntry;
+
+/*
+ * XXX - For more information see
+ * http://msdn.microsoft.com/en-us/library/ff541988%28v=VS.85%29.aspx
+ */
+typedef
+struct SVGA3dCmdDXDefineRasterizerState {
+ SVGA3dRasterizerStateId rasterizerId;
+
+ uint8 fillMode;
+ SVGA3dCullMode cullMode;
+ uint8 frontCounterClockwise;
+ uint8 provokingVertexLast;
+ int32 depthBias;
+ float depthBiasClamp;
+ float slopeScaledDepthBias;
+ uint8 depthClipEnable;
+ uint8 scissorEnable;
+ SVGA3dMultisampleEnable multisampleEnable;
+ uint8 antialiasedLineEnable;
+ float lineWidth;
+ uint8 lineStippleEnable;
+ uint8 lineStippleFactor;
+ uint16 lineStipplePattern;
+}
+SVGA3dCmdDXDefineRasterizerState;
+/* SVGA_3D_CMD_DX_DEFINE_RASTERIZER_STATE */
+
+typedef
+struct SVGA3dCmdDXDestroyRasterizerState {
+ SVGA3dRasterizerStateId rasterizerId;
+}
+SVGA3dCmdDXDestroyRasterizerState;
+/* SVGA_3D_CMD_DX_DESTROY_RASTERIZER_STATE */
+
+typedef
+struct {
+ SVGA3dFilter filter;
+ uint8 addressU;
+ uint8 addressV;
+ uint8 addressW;
+ uint8 pad0;
+ float mipLODBias;
+ uint8 maxAnisotropy;
+ SVGA3dComparisonFunc comparisonFunc;
+ uint16 pad1;
+ SVGA3dRGBAFloat borderColor;
+ float minLOD;
+ float maxLOD;
+ uint32 pad2[6];
+}
+SVGACOTableDXSamplerEntry;
+
+/*
+ * XXX - For more information see
+ * http://msdn.microsoft.com/en-us/library/ff542011%28v=VS.85%29.aspx
+ */
+typedef
+struct SVGA3dCmdDXDefineSamplerState {
+ SVGA3dSamplerId samplerId;
+ SVGA3dFilter filter;
+ uint8 addressU;
+ uint8 addressV;
+ uint8 addressW;
+ uint8 pad0;
+ float mipLODBias;
+ uint8 maxAnisotropy;
+ SVGA3dComparisonFunc comparisonFunc;
+ uint16 pad1;
+ SVGA3dRGBAFloat borderColor;
+ float minLOD;
+ float maxLOD;
+}
+SVGA3dCmdDXDefineSamplerState; /* SVGA_3D_CMD_DX_DEFINE_SAMPLER_STATE */
+
+typedef
+struct SVGA3dCmdDXDestroySamplerState {
+ SVGA3dSamplerId samplerId;
+}
+SVGA3dCmdDXDestroySamplerState; /* SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE */
+
+
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_UNDEFINED 0
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_POSITION 1
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_CLIP_DISTANCE 2
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_CULL_DISTANCE 3
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_RENDER_TARGET_ARRAY_INDEX 4
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_VIEWPORT_ARRAY_INDEX 5
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_VERTEX_ID 6
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_PRIMITIVE_ID 7
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_INSTANCE_ID 8
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_IS_FRONT_FACE 9
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_SAMPLE_INDEX 10
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_0_EDGE_TESSFACTOR 11
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_0_EDGE_TESSFACTOR 12
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_EQ_1_EDGE_TESSFACTOR 13
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_EQ_1_EDGE_TESSFACTOR 14
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_U_INSIDE_TESSFACTOR 15
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_QUAD_V_INSIDE_TESSFACTOR 16
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_U_EQ_0_EDGE_TESSFACTOR 17
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_V_EQ_0_EDGE_TESSFACTOR 18
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_W_EQ_0_EDGE_TESSFACTOR 19
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_TRI_INSIDE_TESSFACTOR 20
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DETAIL_TESSFACTOR 21
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_FINAL_LINE_DENSITY_TESSFACTOR 22
+#define SVGADX_SIGNATURE_SEMANTIC_NAME_MAX 23
+typedef uint32 SVGA3dDXSignatureSemanticName;
+
+#define SVGADX_SIGNATURE_REGISTER_COMPONENT_UNKNOWN 0
+typedef uint32 SVGA3dDXSignatureRegisterComponentType;
+
+#define SVGADX_SIGNATURE_MIN_PRECISION_DEFAULT 0
+typedef uint32 SVGA3dDXSignatureMinPrecision;
+
+typedef
+struct SVGA3dDXSignatureEntry {
+ uint32 registerIndex;
+ SVGA3dDXSignatureSemanticName semanticName;
+ uint32 mask; /* Lower 4 bits represent X, Y, Z, W channels */
+ SVGA3dDXSignatureRegisterComponentType componentType;
+ SVGA3dDXSignatureMinPrecision minPrecision;
+}
+SVGA3dDXShaderSignatureEntry;
+
+#define SVGADX_SIGNATURE_HEADER_VERSION_0 0x08a92d12
+
+/*
+ * The SVGA3dDXSignatureHeader structure is added after the shader
+ * body in the mob that is bound to the shader. It is followed by the
+ * specified number of SVGA3dDXSignatureEntry structures for each of
+ * the three types of signatures in the order (input, output, patch
+ * constants).
+ */
+typedef
+struct SVGA3dDXSignatureHeader {
+ uint32 headerVersion;
+ uint32 numInputSignatures;
+ uint32 numOutputSignatures;
+ uint32 numPatchConstantSignatures;
+}
+SVGA3dDXShaderSignatureHeader;
+
+
+typedef
+struct SVGA3dCmdDXDefineShader {
+ SVGA3dShaderId shaderId;
+ SVGA3dShaderType type;
+ uint32 sizeInBytes; /* Number of bytes of shader text. */
+}
+SVGA3dCmdDXDefineShader; /* SVGA_3D_CMD_DX_DEFINE_SHADER */
+
+typedef
+struct SVGACOTableDXShaderEntry {
+ SVGA3dShaderType type;
+ uint32 sizeInBytes;
+ uint32 offsetInBytes;
+ SVGAMobId mobid;
+ uint32 pad[4];
+}
+SVGACOTableDXShaderEntry;
+
+typedef
+struct SVGA3dCmdDXDestroyShader {
+ SVGA3dShaderId shaderId;
+}
+SVGA3dCmdDXDestroyShader; /* SVGA_3D_CMD_DX_DESTROY_SHADER */
+
+typedef
+struct SVGA3dCmdDXBindShader {
+ uint32 cid;
+ uint32 shid;
+ SVGAMobId mobid;
+ uint32 offsetInBytes;
+}
+SVGA3dCmdDXBindShader; /* SVGA_3D_CMD_DX_BIND_SHADER */
+
+typedef
+struct SVGA3dCmdDXBindAllShader {
+ uint32 cid;
+ SVGAMobId mobid;
+}
+SVGA3dCmdDXBindAllShader; /* SVGA_3D_CMD_DX_BIND_ALL_SHADER */
+
+typedef
+struct SVGA3dCmdDXCondBindAllShader {
+ uint32 cid;
+ SVGAMobId testMobid;
+ SVGAMobId mobid;
+}
+SVGA3dCmdDXCondBindAllShader; /* SVGA_3D_CMD_DX_COND_BIND_ALL_SHADER */
+
+/*
+ * The maximum number of streamout decl's in each streamout entry.
+ */
+#define SVGA3D_MAX_DX10_STREAMOUT_DECLS 64
+#define SVGA3D_MAX_STREAMOUT_DECLS 512
+
+typedef
+struct SVGA3dStreamOutputDeclarationEntry {
+ uint32 outputSlot;
+ uint32 registerIndex;
+ uint8 registerMask;
+ uint8 pad0;
+ uint16 pad1;
+ uint32 stream;
+}
+SVGA3dStreamOutputDeclarationEntry;
+
+typedef
+struct SVGAOTableStreamOutputEntry {
+ uint32 numOutputStreamEntries;
+ SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_DX10_STREAMOUT_DECLS];
+ uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS];
+ uint32 rasterizedStream;
+ uint32 numOutputStreamStrides;
+ uint32 mobid;
+ uint32 offsetInBytes;
+ uint8 usesMob;
+ uint8 pad0;
+ uint16 pad1;
+ uint32 pad2[246];
+}
+SVGACOTableDXStreamOutputEntry;
+
+typedef
+struct SVGA3dCmdDXDefineStreamOutput {
+ SVGA3dStreamOutputId soid;
+ uint32 numOutputStreamEntries;
+ SVGA3dStreamOutputDeclarationEntry decl[SVGA3D_MAX_DX10_STREAMOUT_DECLS];
+ uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS];
+ uint32 rasterizedStream;
+}
+SVGA3dCmdDXDefineStreamOutput; /* SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT */
+
+/*
+ * Version 2 needed in order to start validating and using the
+ * rasterizedStream field. Unfortunately the device wasn't validating
+ * or using this field and the driver wasn't initializing it in shipped
+ * code, so a new version of the command is needed to allow that code
+ * to continue to work. Also added new numOutputStreamStrides field.
+ */
+
+#define SVGA3D_DX_SO_NO_RASTERIZED_STREAM 0xFFFFFFFF
+
+typedef
+struct SVGA3dCmdDXDefineStreamOutputWithMob {
+ SVGA3dStreamOutputId soid;
+ uint32 numOutputStreamEntries;
+ uint32 numOutputStreamStrides;
+ uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS];
+ uint32 rasterizedStream;
+}
+SVGA3dCmdDXDefineStreamOutputWithMob;
+/* SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB */
+
+typedef
+struct SVGA3dCmdDXBindStreamOutput {
+ SVGA3dStreamOutputId soid;
+ uint32 mobid;
+ uint32 offsetInBytes;
+ uint32 sizeInBytes;
+}
+SVGA3dCmdDXBindStreamOutput; /* SVGA_3D_CMD_DX_BIND_STREAMOUTPUT */
+
+typedef
+struct SVGA3dCmdDXDestroyStreamOutput {
+ SVGA3dStreamOutputId soid;
+}
+SVGA3dCmdDXDestroyStreamOutput; /* SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT */
+
+typedef
+struct SVGA3dCmdDXSetStreamOutput {
+ SVGA3dStreamOutputId soid;
+}
+SVGA3dCmdDXSetStreamOutput; /* SVGA_3D_CMD_DX_SET_STREAMOUTPUT */
+
+typedef
+struct SVGA3dCmdDXSetMinLOD {
+ SVGA3dSurfaceId sid;
+ float minLOD;
+}
+SVGA3dCmdDXSetMinLOD; /* SVGA_3D_CMD_DX_SET_MIN_LOD */
+
+typedef
+struct {
+ uint64 value;
+ uint32 mobId;
+ uint32 mobOffset;
+}
+SVGA3dCmdDXMobFence64; /* SVGA_3D_CMD_DX_MOB_FENCE_64 */
+
+/*
+ * SVGA3dCmdSetCOTable --
+ *
+ * This command allows the guest to bind a mob to a context-object table.
+ */
+typedef
+struct SVGA3dCmdDXSetCOTable {
+ uint32 cid;
+ uint32 mobid;
+ SVGACOTableType type;
+ uint32 validSizeInBytes;
+}
+SVGA3dCmdDXSetCOTable; /* SVGA_3D_CMD_DX_SET_COTABLE */
+
+/*
+ * Guests using SVGA_3D_CMD_DX_GROW_COTABLE are promising that
+ * the new COTable contains the same contents as the old one, except possibly
+ * for some new invalid entries at the end.
+ *
+ * If there is an old cotable mob bound, it also has to still be valid.
+ *
+ * (Otherwise, guests should use the DXSetCOTableBase command.)
+ */
+typedef
+struct SVGA3dCmdDXGrowCOTable {
+ uint32 cid;
+ uint32 mobid;
+ SVGACOTableType type;
+ uint32 validSizeInBytes;
+}
+SVGA3dCmdDXGrowCOTable; /* SVGA_3D_CMD_DX_GROW_COTABLE */
+
+typedef
+struct SVGA3dCmdDXReadbackCOTable {
+ uint32 cid;
+ SVGACOTableType type;
+}
+SVGA3dCmdDXReadbackCOTable; /* SVGA_3D_CMD_DX_READBACK_COTABLE */
+
+typedef
+struct SVGA3dCOTableData {
+ uint32 mobid;
+}
+SVGA3dCOTableData;
+
+typedef
+struct SVGA3dBufferBinding {
+ uint32 bufferId;
+ uint32 stride;
+ uint32 offset;
+}
+SVGA3dBufferBinding;
+
+typedef
+struct SVGA3dConstantBufferBinding {
+ uint32 sid;
+ uint32 offsetInBytes;
+ uint32 sizeInBytes;
+}
+SVGA3dConstantBufferBinding;
+
+typedef
+struct SVGADXInputAssemblyMobFormat {
+ uint32 layoutId;
+ SVGA3dBufferBinding vertexBuffers[SVGA3D_DX_MAX_VERTEXBUFFERS];
+ uint32 indexBufferSid;
+ uint32 pad;
+ uint32 indexBufferOffset;
+ uint32 indexBufferFormat;
+ uint32 topology;
+}
+SVGADXInputAssemblyMobFormat;
+
+typedef
+struct SVGADXContextMobFormat {
+ SVGADXInputAssemblyMobFormat inputAssembly;
+
+ struct {
+ uint32 blendStateId;
+ uint32 blendFactor[4];
+ uint32 sampleMask;
+ uint32 depthStencilStateId;
+ uint32 stencilRef;
+ uint32 rasterizerStateId;
+ uint32 depthStencilViewId;
+ uint32 renderTargetViewIds[SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS];
+ uint32 unorderedAccessViewIds[SVGA3D_MAX_UAVIEWS];
+ } renderState;
+
+ struct {
+ uint32 targets[SVGA3D_DX_MAX_SOTARGETS];
+ uint32 soid;
+ } streamOut;
+ uint32 pad0[11];
+
+ uint8 numViewports;
+ uint8 numScissorRects;
+ uint16 pad1[1];
+
+ uint32 pad2[3];
+
+ SVGA3dViewport viewports[SVGA3D_DX_MAX_VIEWPORTS];
+ uint32 pad3[32];
+
+ SVGASignedRect scissorRects[SVGA3D_DX_MAX_SCISSORRECTS];
+ uint32 pad4[64];
+
+ struct {
+ uint32 queryID;
+ uint32 value;
+ } predication;
+ uint32 pad5[2];
+
+ struct {
+ uint32 shaderId;
+ SVGA3dConstantBufferBinding constantBuffers[SVGA3D_DX_MAX_CONSTBUFFERS];
+ uint32 shaderResources[SVGA3D_DX_MAX_SRVIEWS];
+ uint32 samplers[SVGA3D_DX_MAX_SAMPLERS];
+ } shaderState[SVGA3D_NUM_SHADERTYPE];
+ uint32 pad6[26];
+
+ SVGA3dQueryId queryID[SVGA3D_MAX_QUERY];
+
+ SVGA3dCOTableData cotables[SVGA_COTABLE_MAX];
+ uint32 pad7[380];
+}
+SVGADXContextMobFormat;
+
+#endif // _SVGA3D_DX_H_
diff --git a/vmware/svga3d_limits.h b/vmware/svga3d_limits.h
new file mode 100644
index 0000000..c1340c7
--- /dev/null
+++ b/vmware/svga3d_limits.h
@@ -0,0 +1,106 @@
+/**********************************************************
+ * Copyright 2007-2015 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/*
+ * svga3d_limits.h --
+ *
+ * SVGA 3d hardware limits
+ */
+
+#ifndef _SVGA3D_LIMITS_H_
+#define _SVGA3D_LIMITS_H_
+
+#define INCLUDE_ALLOW_MODULE
+#define INCLUDE_ALLOW_USERLEVEL
+#define INCLUDE_ALLOW_VMCORE
+
+#define SVGA3D_NUM_CLIPPLANES 6
+#define SVGA3D_MAX_RENDER_TARGETS 8
+//#define SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS (SVGA3D_MAX_RENDER_TARGETS)
+#define SVGA3D_MAX_UAVIEWS 8
+#define SVGA3D_MAX_CONTEXT_IDS 256
+#define SVGA3D_MAX_SURFACE_IDS (32 * 1024)
+
+/*
+ * Maximum ID a shader can be assigned on a given context.
+ */
+#define SVGA3D_MAX_SHADERIDS 5000
+/*
+ * Maximum number of shaders of a given type that can be defined
+ * (including all contexts).
+ */
+#define SVGA3D_MAX_SIMULTANEOUS_SHADERS 20000
+
+#define SVGA3D_NUM_TEXTURE_UNITS 32
+#define SVGA3D_NUM_LIGHTS 8
+
+/*
+ * Maximum size in dwords of shader text the SVGA device will allow.
+ * Currently 8 MB.
+ */
+#define SVGA3D_MAX_SHADER_MEMORY_BYTES (8 * 1024 * 1024)
+#define SVGA3D_MAX_SHADER_MEMORY (SVGA3D_MAX_SHADER_MEMORY_BYTES / \
+ sizeof(uint32))
+
+#define SVGA3D_MAX_CLIP_PLANES 6
+
+/*
+ * This is the limit to the number of fixed-function texture
+ * transforms and texture coordinates we can support. It does *not*
+ * correspond to the number of texture image units (samplers) we
+ * support!
+ */
+#define SVGA3D_MAX_TEXTURE_COORDS 8
+
+/*
+ * Number of faces in a cubemap.
+ */
+#define SVGA3D_MAX_SURFACE_FACES 6
+
+/*
+ * Maximum number of array indexes in a GB surface (with DX enabled).
+ */
+#define SVGA3D_SM4_MAX_SURFACE_ARRAYSIZE 512
+#define SVGA3D_SM5_MAX_SURFACE_ARRAYSIZE 2048
+#define SVGA3D_MAX_SURFACE_ARRAYSIZE SVGA3D_SM5_MAX_SURFACE_ARRAYSIZE
+
+/*
+ * The maximum number of vertex arrays we're guaranteed to support in
+ * SVGA_3D_CMD_DRAWPRIMITIVES.
+ */
+#define SVGA3D_MAX_VERTEX_ARRAYS 32
+
+/*
+ * The maximum number of primitive ranges we're guaranteed to support
+ * in SVGA_3D_CMD_DRAWPRIMITIVES.
+ */
+#define SVGA3D_MAX_DRAW_PRIMITIVE_RANGES 32
+
+/*
+ * The maximum number of samples that can be contained in a surface.
+ */
+#define SVGA3D_MAX_SAMPLES 8
+
+#endif // _SVGA3D_LIMITS_H_
diff --git a/vmware/svga3d_reg.h b/vmware/svga3d_reg.h
index 9b009d5..e9f7703 100644
--- a/vmware/svga3d_reg.h
+++ b/vmware/svga3d_reg.h
@@ -38,11 +38,6 @@
* Extra types
*/
-typedef struct uint64 {
- uint32 low;
- uint32 hi;
-} uint64;
-
typedef uint16 SVGA3dLogicOp;
typedef uint32 SVGA3dSurface1Flags;
typedef uint32 SVGA3dSurface2Flags;
diff --git a/vmware/svga_all.h b/vmware/svga_all.h
index de26664..fbc3f73 100644
--- a/vmware/svga_all.h
+++ b/vmware/svga_all.h
@@ -8,6 +8,7 @@
#include "svga3d.h"
#include "svga3d_reg.h"
#include "svga3d_caps.h"
+#include "svga3d_dx.h"
#pragma pack(pop)
#endif /* __SVGA_ALL_H__INCLUDED__ */
diff --git a/vmware/svga_reg.h b/vmware/svga_reg.h
index 04707c3..030e77f 100644
--- a/vmware/svga_reg.h
+++ b/vmware/svga_reg.h
@@ -32,6 +32,14 @@
#ifndef _SVGA_REG_H_
#define _SVGA_REG_H_
+/* uint64 */
+typedef struct uint64 {
+ uint32 low;
+ uint32 hi;
+} uint64;
+
+#define MAX_UINT32 0xFFFFFFFFUL
+
/*
* PCI device IDs.
*/
@@ -339,6 +347,166 @@ struct SVGAGuestPtr {
/*
+ * Register based command buffers --
+ *
+ * Provide an SVGA device interface that allows the guest to submit
+ * command buffers to the SVGA device through an SVGA device register.
+ * The metadata for each command buffer is contained in the
+ * SVGACBHeader structure along with the return status codes.
+ *
+ * The SVGA device supports command buffers if
+ * SVGA_CAP_COMMAND_BUFFERS is set in the device caps register. The
+ * fifo must be enabled for command buffers to be submitted.
+ *
+ * Command buffers are submitted when the guest writing the 64 byte
+ * aligned physical address into the SVGA_REG_COMMAND_LOW and
+ * SVGA_REG_COMMAND_HIGH. SVGA_REG_COMMAND_HIGH contains the upper 32
+ * bits of the physical address. SVGA_REG_COMMAND_LOW contains the
+ * lower 32 bits of the physical address, since the command buffer
+ * headers are required to be 64 byte aligned the lower 6 bits are
+ * used for the SVGACBContext value. Writing to SVGA_REG_COMMAND_LOW
+ * submits the command buffer to the device and queues it for
+ * execution. The SVGA device supports at least
+ * SVGA_CB_MAX_QUEUED_PER_CONTEXT command buffers that can be queued
+ * per context and if that limit is reached the device will write the
+ * status SVGA_CB_STATUS_QUEUE_FULL to the status value of the command
+ * buffer header synchronously and not raise any IRQs.
+ *
+ * It is invalid to submit a command buffer without a valid physical
+ * address and results are undefined.
+ *
+ * The device guarantees that command buffers of size SVGA_CB_MAX_SIZE
+ * will be supported. If a larger command buffer is submitted results
+ * are unspecified and the device will either complete the command
+ * buffer or return an error.
+ *
+ * The device guarantees that any individual command in a command
+ * buffer can be up to SVGA_CB_MAX_COMMAND_SIZE in size which is
+ * enough to fit a 64x64 color-cursor definition. If the command is
+ * too large the device is allowed to process the command or return an
+ * error.
+ *
+ * The device context is a special SVGACBContext that allows for
+ * synchronous register like accesses with the flexibility of
+ * commands. There is a different command set defined by
+ * SVGADeviceContextCmdId. The commands in each command buffer is not
+ * allowed to straddle physical pages.
+ */
+
+#define SVGA_CB_MAX_SIZE (512 * 1024) // 512 KB
+#define SVGA_CB_MAX_QUEUED_PER_CONTEXT 32
+#define SVGA_CB_MAX_COMMAND_SIZE (32 * 1024) // 32 KB
+
+#define SVGA_CB_CONTEXT_MASK 0x3f
+typedef enum {
+ SVGA_CB_CONTEXT_DEVICE = 0x3f,
+ SVGA_CB_CONTEXT_0 = 0x0,
+ SVGA_CB_CONTEXT_MAX = 0x1,
+} SVGACBContext;
+
+
+typedef enum {
+ /*
+ * The guest is supposed to write SVGA_CB_STATUS_NONE to the status
+ * field before submitting the command buffer header, the host will
+ * change the value when it is done with the command buffer.
+ */
+ SVGA_CB_STATUS_NONE = 0,
+
+ /*
+ * Written by the host when a command buffer completes successfully.
+ * The device raises an IRQ with SVGA_IRQFLAG_COMMAND_BUFFER unless
+ * the SVGA_CB_FLAG_NO_IRQ flag is set.
+ */
+ SVGA_CB_STATUS_COMPLETED = 1,
+
+ /*
+ * Written by the host synchronously with the command buffer
+ * submission to indicate the command buffer was not submitted. No
+ * IRQ is raised.
+ */
+ SVGA_CB_STATUS_QUEUE_FULL = 2,
+
+ /*
+ * Written by the host when an error was detected parsing a command
+ * in the command buffer, errorOffset is written to contain the
+ * offset to the first byte of the failing command. The device
+ * raises the IRQ with both SVGA_IRQFLAG_ERROR and
+ * SVGA_IRQFLAG_COMMAND_BUFFER. Some of the commands may have been
+ * processed.
+ */
+ SVGA_CB_STATUS_COMMAND_ERROR = 3,
+
+ /*
+ * Written by the host if there is an error parsing the command
+ * buffer header. The device raises the IRQ with both
+ * SVGA_IRQFLAG_ERROR and SVGA_IRQFLAG_COMMAND_BUFFER. The device
+ * did not processes any of the command buffer.
+ */
+ SVGA_CB_STATUS_CB_HEADER_ERROR = 4,
+
+ /*
+ * Written by the host if the guest requested the host to preempt
+ * the command buffer. The device will not raise any IRQs and the
+ * command buffer was not processed.
+ */
+ SVGA_CB_STATUS_PREEMPTED = 5,
+
+ SVGA_CB_STATUS_FORCE_UINT = MAX_UINT32,
+} SVGACBStatus;
+
+typedef enum {
+ SVGA_CB_FLAG_NONE = 0,
+ SVGA_CB_FLAG_NO_IRQ = 1 << 0,
+ SVGA_CB_FLAG_FORCE_UINT = MAX_UINT32,
+} SVGACBFlags;
+
+typedef
+struct {
+ volatile SVGACBStatus status;
+ volatile uint32 errorOffset;
+ uint64 id;
+ SVGACBFlags flags;
+ uint32 length;
+ union {
+ uint64 pa; // PA
+ } ptr;
+ uint32 mustBeZero[8];
+} SVGACBHeader;
+
+typedef enum {
+ SVGA_DC_CMD_NOP = 0,
+ SVGA_DC_CMD_START_STOP_CONTEXT = 1,
+ SVGA_DC_CMD_PREEMPT = 2,
+ SVGA_DC_CMD_MAX = 3,
+ SVGA_DC_CMD_FORCE_UINT = MAX_UINT32,
+} SVGADeviceContextCmdId;
+
+typedef struct {
+ uint32 enable;
+ SVGACBContext context;
+} SVGADCCmdStartStop;
+
+/*
+ * SVGADCCmdPreempt --
+ *
+ * This command allows the guest to request that all command buffers
+ * on the specified context be preempted that can be. After execution
+ * of this command all command buffers that were preempted will
+ * already have SVGA_CB_STATUS_PREEMPTED written into the status
+ * field. The device might still be processing a command buffer,
+ * assuming execution of it started before the preemption request was
+ * received. Specifying the ignoreIDZero flag to TRUE will cause the
+ * device to not preempt command buffers with the id field in the
+ * command buffer header set to zero.
+ */
+
+typedef struct {
+ SVGACBContext context;
+ uint32 ignoreIDZero;
+} SVGADCCmdPreempt;
+
+/*
* SVGAGMRImageFormat --
*
* This is a packed representation of the source 2D image format
diff --git a/vmwsvxd.c b/vmwsvxd.c
index b50ac01..b600b12 100644
--- a/vmwsvxd.c
+++ b/vmwsvxd.c
@@ -22,6 +22,8 @@ THE SOFTWARE.
*****************************************************************************/
+#define SVGA
+
#include "winhack.h"
#include "vmm.h"
#include "vmwsvxd.h"
@@ -32,6 +34,10 @@ THE SOFTWARE.
#include "version.h"
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+
#if 0
/* dynamic VXDs don't using this init function in discardable segment */
@@ -97,11 +103,58 @@ char dbg_dic_unknown[] = "DeviceIOControl: Unknown: %d\n";
char dbg_dic_system[] = "DeviceIOControl: System code: %d\n";
char dbg_get_ppa[] = "%lx -> %lx\n";
char dbg_get_ppa_beg[] = "Virtual: %lx\n";
+char dbg_mob_allocate[] = "Allocted: %d\n";
char dbg_str[] = "%s\n";
+char dbg_submitcb_fail[] = "CB submit FAILED\n";
+char dbg_submitcb[] = "CB submit %d\n";
+
+char dbg_lockcb[] = "Reused CB (%d) with status: %d\n";
+
#endif
+typedef struct _otinfo_entry_t
+{
+ DWORD phy;
+ void *lin;
+ DWORD size;
+ DWORD flags;
+} otinfo_entry_t;
+
+typedef struct _cmd_buf_t
+{
+ DWORD phy;
+ void *lin;
+ DWORD status;
+} cmd_buf_t;
+
+#define CB_STATUS_EMPTY 0 /* buffer was not used yet */
+#define CB_STATUS_LOCKED 1 /* buffer is using by Ring-3 proccess */
+#define CB_STATUS_PROCESS 2 /* buffer is register by VGPU */
+
+#define CB_COUNT 2
+
+uint64 cmd_buf_next_id = {0, 0};
+
+cmd_buf_t cmd_bufs[CB_COUNT] = {{0}};
+
+#define ROUND_TO_PAGES(_cb)((((_cb) + PAGE_SIZE - 1)/PAGE_SIZE)*PAGE_SIZE)
+
+#define SVGA3D_MAX_MOBS (SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_CONTEXT_IDS + SVGA3D_MAX_SURFACE_IDS)
+
+#define FLAG_ALLOCATED 1
+#define FLAG_ACTIVE 2
+
+otinfo_entry_t otable[SVGA_OTABLE_DX_MAX] = {
+ {0, NULL, ROUND_TO_PAGES(SVGA3D_MAX_MOBS*sizeof(SVGAOTableMobEntry)), 0}, /* SVGA_OTABLE_MOB */
+ {0, NULL, ROUND_TO_PAGES(SVGA3D_MAX_SURFACE_IDS*sizeof(SVGAOTableSurfaceEntry)), 0}, /* SVGA_OTABLE_SURFACE */
+ {0, NULL, ROUND_TO_PAGES(SVGA3D_MAX_CONTEXT_IDS*sizeof(SVGAOTableContextEntry)), 0}, /* SVGA_OTABLE_CONTEXT */
+ {0, NULL, 0, 0}, /* SVGA_OTABLE_SHADER - not used */
+ {0, NULL, ROUND_TO_PAGES(64*sizeof(SVGAOTableScreenTargetEntry)), 0}, /* SVGA_OTABLE_SCREENTARGET (VBOX_VIDEO_MAX_SCREENS) */
+ {0, NULL, ROUND_TO_PAGES(SVGA3D_MAX_CONTEXT_IDS*sizeof(SVGAOTableDXContextEntry)), 0}, /* SVGA_OTABLE_DXCONTEXT */
+};
+
DWORD *DispatchTable = 0;
DWORD DispatchTableLength = 0;
@@ -175,34 +228,16 @@ void Sys_Critical_Init_proc()
#define SVGA_DBG 0x110B
#define SVGA_SYNC 0x1116
#define SVGA_RING 0x1117
+#define SVGA_ALLOCPHY 0x1200
+#define SVGA_FREEPHY 0x1201
+#define SVGA_OTABLE_QUERY 0x1202
+#define SVGA_OTABLE_FLAGS 0x1203
-DWORD __stdcall Device_IO_Control_entry(struct DIOCParams *params)
-{
- switch(params->dwIoControlCode)
- {
- case DIOC_OPEN:
- case DIOC_CLOSEHANDLE:
- dbg_printf(dbg_dic_system, params->dwIoControlCode);
- return 0;
- case SVGA_SYNC:
- //dbg_printf(dbg_dic_sync);
- SVGA_Flush();
- return 0;
- case SVGA_RING:
- //dbg_printf(dbg_dic_ring);
- SVGA_WriteReg(SVGA_REG_SYNC, 1);
- return 0;
- case SVGA_DBG:
-#ifdef DBGPRINT
- dbg_printf(dbg_str, params->lpInBuffer);
-#endif
- return 0;
- }
-
- dbg_printf(dbg_dic_unknown, params->dwIoControlCode);
-
- return 1;
-}
+#define SVGA_CB_LOCK 0x1204
+#define SVGA_CB_SUBMIT 0x1205
+#define SVGA_CB_SYNC 0x1206
+
+DWORD __stdcall Device_IO_Control_entry(struct DIOCParams *params);
void __declspec(naked) Device_IO_Control_proc()
{
@@ -438,55 +473,190 @@ static BOOL GMRFree(ULONG DataAddr, ULONG GMRAddr)
}
/**
- * PM16 driver RING0 calls
+ *
+ *
**/
-BOOL CreateRegion(unsigned int nPages, ULONG *lpLAddr, ULONG *lpPPN, ULONG *lpPGBLK)
-{
- return GMRAlloc(nPages, lpLAddr, lpPGBLK, lpPPN);
+static void AllocateOTable()
+{
+ int i;
+ for(i = 0; i < SVGA_OTABLE_DX_MAX; i++)
+ {
+ otinfo_entry_t *entry = &otable[i];
+ if(entry->size != 0 && (entry->flags & FLAG_ALLOCATED) == 0)
+ {
+ entry->lin = (void*)_PageAllocate(entry->size/PAGE_SIZE, PG_SYS, 0, 0, 0x0, 0x100000, &entry->phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
+ if(entry->lin)
+ {
+ dbg_printf(dbg_mob_allocate, i);
+ entry->flags |= FLAG_ALLOCATED;
+ }
+ }
+ }
}
-BOOL FreeRegion(ULONG LAddr, ULONG PGBLK)
+static void AllocateCB()
{
- return GMRFree(LAddr, PGBLK);
+ int i;
+ for(i = 0; i < CB_COUNT; i++)
+ {
+ if(cmd_bufs[i].phy == 0)
+ {
+ cmd_bufs[i].lin = (void *)_PageAllocate((SVGA_CB_MAX_SIZE+PAGE_SIZE-1)/PAGE_SIZE, PG_SYS, 0, 0, 0x0, 0x100000, &(cmd_bufs[i].phy), PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
+ cmd_bufs[i].status = CB_STATUS_EMPTY;
+ }
+ }
}
-#define MOB_PER_PAGE_CNT (P_SIZE/sizeof(ULONG))
-
-BOOL CreateMOB(unsigned int nPages, ULONG *lpLAddr, ULONG *lpPPN)
+static BOOL isCBfree(int index)
{
- unsigned int mobBasePages = (nPages + MOB_PER_PAGE_CNT - 1)/MOB_PER_PAGE_CNT;
- ULONG phy;
- ULONG laddr;
+ switch(cmd_bufs[index].status)
+ {
+ case CB_STATUS_EMPTY:
+ return TRUE;
+ case CB_STATUS_PROCESS:
+ {
+ SVGACBHeader *cb = (SVGACBHeader *)cmd_bufs[index].lin;
+ if(cb->status > SVGA_CB_STATUS_NONE)
+ {
+ return TRUE;
+ }
+ break;
+ }
+ }
- laddr = _PageAllocate(nPages + mobBasePages, PG_SYS, 0, 0x0, 0, 0x0fffff, &phy, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
- if(laddr)
+ return FALSE;
+}
+
+/* inc 64-bit id */
+static void nextID_CB()
+{
+ _asm
{
- unsigned int i;
- ULONG ppu = (phy/P_SIZE) + mobBasePages;
- ULONG *ptr = (ULONG*)laddr;
-
- for(i = 0; i < nPages; i++)
+ inc dword ptr [cmd_buf_next_id]
+ adc dword ptr [cmd_buf_next_id+4], 0
+ }
+}
+
+static void *LockCB()
+{
+ int index;
+ for(index = 0; index < CB_COUNT; index++)
+ {
+ if(isCBfree(index))
{
- ptr[i] = ppu;
- ppu++;
+ {
+ SVGACBHeader *cb = (SVGACBHeader *)cmd_bufs[index].lin;
+ dbg_printf(dbg_lockcb, index, cb->status);
+ }
+ cmd_bufs[index].status = CB_STATUS_LOCKED;
+ return cmd_bufs[index].lin;
}
+ }
+
+ return NULL;
+}
- *lpLAddr = laddr;
- *lpPPN = (phy/P_SIZE);
- return TRUE;
+/*
+ cbctx_id = SVGA_CB_CONTEXT_0,...
+*/
+
+static BOOL submitCB(void *ptr, DWORD cbctx_id)
+{
+ int index;
+
+ for(index = 0; index < CB_COUNT; index++)
+ {
+ if(cmd_bufs[index].lin == ptr)
+ {
+ SVGACBHeader *cb = (SVGACBHeader *)cmd_bufs[index].lin;
+ if(cb->length > 0)
+ {
+ cb->status = SVGA_CB_STATUS_NONE;
+ cb->ptr.pa.hi = 0;
+ cb->ptr.pa.low = cmd_bufs[index].phy + sizeof(SVGACBHeader);
+ cb->flags |= SVGA_CB_FLAG_NO_IRQ;
+ cb->id.low = cmd_buf_next_id.low;
+ cb->id.hi = cmd_buf_next_id.hi;
+
+ SVGA_WriteReg(SVGA_REG_COMMAND_HIGH, 0); // high part of 64-bit memory address...
+ SVGA_WriteReg(SVGA_REG_COMMAND_LOW, cmd_bufs[index].phy | cbctx_id);
+ cmd_bufs[index].status = CB_STATUS_PROCESS;
+
+ dbg_printf(dbg_submitcb, index);
+
+ nextID_CB();
+ }
+ else
+ {
+ cmd_bufs[index].status = CB_STATUS_EMPTY;
+ }
+
+ return TRUE;
+ }
}
+ dbg_printf(dbg_submitcb_fail);
+
return FALSE;
}
-BOOL FreeMOB(ULONG LAddr)
+/* wait until all CB are completed */
+static void syncCB()
{
- if(_PageFree((PVOID)LAddr, 0) != 0)
+ int index;
+ BOOL synced;
+ do
+ {
+ synced = TRUE;
+ for(index = 0; index < CB_COUNT; index++)
+ {
+ switch(cmd_bufs[index].status)
+ {
+ case CB_STATUS_EMPTY:
+ case CB_STATUS_LOCKED:
+ break;
+ case CB_STATUS_PROCESS:
+ {
+ SVGACBHeader *cb = (SVGACBHeader *)cmd_bufs[index].lin;
+ if(cb->status == SVGA_CB_STATUS_NONE)
+ {
+ synced = FALSE;
+ }
+ break;
+ }
+ }
+ }
+ } while(!synced);
+}
+
+/**
+ * PM16 driver RING0 calls
+ **/
+BOOL CreateRegion(unsigned int nPages, ULONG *lpLAddr, ULONG *lpPPN, ULONG *lpPGBLK)
+{
+ return GMRAlloc(nPages, lpLAddr, lpPGBLK, lpPPN);
+}
+
+BOOL FreeRegion(ULONG LAddr, ULONG PGBLK)
+{
+ return GMRFree(LAddr, PGBLK);
+}
+
+BOOL AllocPhysical(DWORD nPages, DWORD *outLinear, DWORD *outPhysical)
+{
+ *outLinear = _PageAllocate(nPages, PG_SYS, 0, 0, 0x0, 0x100000, outPhysical, PAGECONTIG | PAGEUSEALIGN | PAGEFIXED);
+
+ if(*outLinear != NULL)
{
return TRUE;
}
- return FALSE;
+ return FALSE;
+}
+
+void FreePhysical(DWORD linear)
+{
+ _PageFree((void*)linear, 0);
}
WORD __stdcall VMWS_API_Proc(PCRS_32 state)
@@ -540,42 +710,6 @@ WORD __stdcall VMWS_API_Proc(PCRS_32 state)
}
break;
}
- /* Create MOB = input: ECX - num_pages; output: EDX - lin. address of descriptor, ECX - PPN of descriptor */
- case VMWSVXD_PM16_CREATE_MOB:
- {
- ULONG lAddr;
- ULONG PPN;
-
- if(CreateMOB(state->Client_ECX, &lAddr, &PPN))
- {
- state->Client_ECX = PPN;
- state->Client_EDX = lAddr;
- rc = 1;
- }
- else
- {
- state->Client_ECX = 0;
- state->Client_EDX = 0;
-
- dbg_printf(dbg_region_err);
-
- rc = 0;
- }
- break;
- }
- /* Free MOB = input: ECX: lin. address */
- case VMWSVXD_PM16_DESTROY_MOB:
- {
- if(FreeMOB(state->Client_ECX))
- {
- rc = 1;
- }
- else
- {
- rc = 0;
- }
- break;
- }
/* clear memory on linear address (ESI) by defined size (ECX) */
case VMWSVXD_PM16_ZEROMEM:
{
@@ -639,6 +773,8 @@ void __declspec(naked) VMWS_API_Entry()
void Device_Init_proc()
{
dbg_printf(dbg_Device_Init_proc);
+ AllocateOTable();
+ AllocateCB();
// VMMCall _Allocate_Device_CB_Area
if(SVGA_Init(FALSE) == 0)
@@ -654,3 +790,122 @@ void Device_Init_proc()
}
}
#undef VDDFUNC
+
+
+DWORD __stdcall Device_IO_Control_entry(struct DIOCParams *params)
+{
+ switch(params->dwIoControlCode)
+ {
+ case DIOC_OPEN:
+ case DIOC_CLOSEHANDLE:
+ dbg_printf(dbg_dic_system, params->dwIoControlCode);
+ return 0;
+ case SVGA_SYNC:
+ //dbg_printf(dbg_dic_sync);
+ SVGA_Flush();
+ return 0;
+ case SVGA_RING:
+ //dbg_printf(dbg_dic_ring);
+ SVGA_WriteReg(SVGA_REG_SYNC, 1);
+ return 0;
+ case SVGA_ALLOCPHY:
+ {
+ DWORD nPages = ((DWORD*)params->lpInBuffer)[0];
+ DWORD *linear = &((DWORD*)params->lpOutBuffer)[0];
+ DWORD *phy = &((DWORD*)params->lpOutBuffer)[1];
+ if(AllocPhysical(nPages, linear, phy))
+ {
+ return 0;
+ }
+ return 1;
+ }
+ case SVGA_FREEPHY:
+ {
+ DWORD linear = ((DWORD*)params->lpInBuffer)[0];
+ FreePhysical(linear);
+ return 0;
+ }
+ /* input:
+ - id
+ output:
+ - linear
+ - physical
+ - size
+ - flags
+ */
+ case SVGA_OTABLE_QUERY:
+ {
+ DWORD id = ((DWORD*)params->lpInBuffer)[0];
+ DWORD *out = (DWORD*)params->lpOutBuffer;
+ if(id < SVGA_OTABLE_DX_MAX)
+ {
+ out[0] = (DWORD)otable[id].lin;
+ out[1] = otable[id].phy;
+ out[2] = otable[id].size;
+ out[3] = otable[id].flags;
+ return 0;
+ }
+ return 1;
+ }
+ /* input:
+ - id
+ - new flags
+ */
+ case SVGA_OTABLE_FLAGS:
+ {
+ DWORD id = ((DWORD*)params->lpInBuffer)[0];
+ DWORD flags = ((DWORD*)params->lpInBuffer)[1];
+ if(id < SVGA_OTABLE_DX_MAX)
+ {
+ otable[id].flags = flags;
+ return 0;
+ }
+ return 1;
+ }
+ /*
+ input:
+ output:
+ - linear address of buffer
+ */
+ case SVGA_CB_LOCK:
+ {
+ void *ptr = LockCB();
+ if(ptr)
+ {
+ DWORD* out = (DWORD*)params->lpOutBuffer;
+ *out = (DWORD)ptr;
+ return 0;
+ }
+ return 1;
+ }
+ /*
+ input:
+ - linear address of buffer
+ - CB context ID
+ output:
+ */
+ case SVGA_CB_SUBMIT:
+ {
+ DWORD *in = (DWORD*)params->lpInBuffer;
+
+ if(submitCB((void*)in[0], in[1]))
+ {
+ return 0;
+ }
+ return 1;
+ }
+ /* none arguments */
+ case SVGA_CB_SYNC:
+ syncCB();
+ return 0;
+ case SVGA_DBG:
+#ifdef DBGPRINT
+ dbg_printf(dbg_str, params->lpInBuffer);
+#endif
+ return 0;
+ }
+
+ dbg_printf(dbg_dic_unknown, params->dwIoControlCode);
+
+ return 1;
+}
diff --git a/vmwsvxd.h b/vmwsvxd.h
index 3eb2442..9e2f371 100644
--- a/vmwsvxd.h
+++ b/vmwsvxd.h
@@ -7,15 +7,13 @@
*/
#define VMWSVXD_DEVICE_ID 0x7fe7
-#define VMWSVXD_MAJOR_VER 2
+#define VMWSVXD_MAJOR_VER 4 /* should be 4 for windows 95 and newer */
#define VMWSVXD_MINOR_VER 0
#define VMWSVXD_PM16_VERSION 0
#define VMWSVXD_PM16_VMM_VERSION 1
#define VMWSVXD_PM16_CREATE_REGION 2
#define VMWSVXD_PM16_DESTROY_REGION 3
-#define VMWSVXD_PM16_CREATE_MOB 4
-#define VMWSVXD_PM16_DESTROY_MOB 5
#define VMWSVXD_PM16_ZEROMEM 6
#define VMWSVXD_PM16_APIVER 7