├── wrappers ├── mesa │ └── src │ │ ├── szdata.c │ │ ├── Makefile.in │ │ └── wglinfo.c ├── 3dfx │ ├── drv │ │ ├── shasum.txt │ │ ├── Makefile │ │ └── instdrv.c │ ├── ovl │ │ ├── glideovl.lnk │ │ ├── Makefile │ │ └── clib.h │ ├── dso │ │ ├── Makefile │ │ └── clib.h │ ├── dxe │ │ ├── Makefile │ │ └── clib.h │ └── src │ │ ├── version.rc │ │ └── Makefile.in └── fxlib │ ├── hpat.h │ ├── fxlibnt.c │ ├── fxlib9x.c │ ├── fxlib.h │ ├── md5.c │ ├── fxhpat.c │ ├── fxtime.c │ └── fxhook.c ├── .github └── FUNDING.yml ├── virgil3d ├── README.md ├── MINGW-packages │ ├── PKGBUILD │ └── 0001-Virglrenderer-on-Windows-and-macOS.patch ├── 0002-Virgil3D-macOS-GLSL-version.patch └── 0001-Virgil3D-with-SDL2-OpenGL.patch ├── qemu-0 └── hw │ └── 3dfx │ ├── meson.build │ ├── szgrdata.h │ ├── gllstbuf.h │ ├── vertex3x.h │ ├── glidewnd.h │ ├── gllstbuf.c │ ├── glide2x_impl.h │ ├── g2xfuncs.h │ └── glidewnd.c ├── qemu-1 └── hw │ └── mesa │ ├── meson.build │ ├── mglvarry.h │ ├── mglmapbo.h │ ├── mglfuncs.h │ ├── mglcntx.h │ ├── extensions_table.c │ ├── mesagl_pfn.h │ ├── mesagl_impl.h │ ├── mglvarry.c │ ├── mglmapbo.c │ ├── szgldata.c │ ├── extensions_defs.h │ └── mesagl_blit.c ├── scripts ├── sign_commit ├── vidmodes └── conf_wrapper └── README.md /wrappers/mesa/src/szdata.c: -------------------------------------------------------------------------------- 1 | #include "szgldata.c" 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ['https://paypal.me/kjliew'] 2 | -------------------------------------------------------------------------------- /virgil3d/README.md: -------------------------------------------------------------------------------- 1 | ## Virgil 3D with SDL2 OpenGL for native Windows & macOS 2 | -------------------------------------------------------------------------------- /wrappers/3dfx/drv/shasum.txt: -------------------------------------------------------------------------------- 1 | 8d8c8b00825bedc048951b295dc8ae8269d8b82d fxmemmap.vxd 2 | 2f1836284b6d1d352585992b7d60e300c9031808 fxptl.sys 3 | -------------------------------------------------------------------------------- /qemu-0/hw/3dfx/meson.build: -------------------------------------------------------------------------------- 1 | i386_system_ss.add(files( 2 | 'glide2x_impl.c', 3 | 'glidept_mm.c', 4 | 'glidewnd.c', 5 | 'gllstbuf.c', 6 | )) 7 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/meson.build: -------------------------------------------------------------------------------- 1 | i386_system_ss.add(files( 2 | 'extensions_table.c', 3 | 'mesagl_blit.c', 4 | 'mesagl_impl.c', 5 | 'mesapt_mm.c', 6 | 'mglcntx_linux.c', 7 | 'mglcntx_mingw.c', 8 | 'mglmapbo.c', 9 | 'mglvarry.c', 10 | 'szgldata.c', 11 | 'tokglstr.c', 12 | )) 13 | -------------------------------------------------------------------------------- /wrappers/3dfx/ovl/glideovl.lnk: -------------------------------------------------------------------------------- 1 | format os2 le dll initglobal 2 | #debug all 3 | name glide2x.ovl 4 | file glideovl.obj 5 | #library clib3s.lib 6 | option description 'GLIDE2X.OVL' 7 | option map 8 | option nocaseexact 9 | option nod 10 | option quiet 11 | #option undefsok 12 | EXPORT __DLLstart_ 13 | -------------------------------------------------------------------------------- /qemu-0/hw/3dfx/szgrdata.h: -------------------------------------------------------------------------------- 1 | #define SIZE_GRHWCONFIG 148 2 | #define SIZE_GRVERTEX 60 3 | #define SIZE_GRSTATE 312 4 | #define SIZE_GRTEXINFO 20 5 | #define SIZE_GRSSTPERFSTATS 20 6 | #define SIZE_GRLFBINFO 20 7 | #define SIZE_GU3DFHEADER 24 8 | #define SIZE_GU3DFINFO 1056 9 | #define SIZE_GUTEXTABLE 1024 10 | #define SIZE_GUNCCTABLE 112 11 | #define SIZE_GUTEXPALETTE 1024 12 | #define SIZE_GRMIPMAPINFO 196 13 | #define SIZE_GRRESOLUTION 16 14 | #ifndef GLIDE2X_IMPL_H 15 | static const char buildstr[] = __REV__ __TIME__" "__DATE__" build "; 16 | #endif 17 | -------------------------------------------------------------------------------- /wrappers/3dfx/dso/Makefile: -------------------------------------------------------------------------------- 1 | QEMU_SRC_DIR=../../../qemu-0 2 | GIT=$(shell git rev-parse --short HEAD | sed "s/\(.*\)/\1\-/") 3 | CROSS= 4 | CC=$(CROSS)gcc 5 | CFLAGS=-I$(QEMU_SRC_DIR)/hw/3dfx -D__REV__=\"$(GIT)\" -Wall -Werror -O3 -fomit-frame-pointer 6 | LDFLAGS= 7 | 8 | TARGET2=libglide.so.2 9 | 10 | all: $(TARGET2) 11 | 12 | $(TARGET2): glidedso.o 13 | @echo " CFLAGS $(CFLAGS)" 14 | @echo " LD $@" 15 | @$(CC) $(LDFLAGS) $(CFLAGS) -shared -Wl,-soname,$@ -o $@ $+ 16 | 17 | %.o: %.c clib.h 18 | @echo " CC $@" 19 | @$(CC) -I ../src $(CFLAGS) -c -o $@ $< 20 | 21 | clean: 22 | @rm -f *.o *.a *.map 23 | 24 | distclean: clean 25 | @rm -f $(TARGET2) 26 | 27 | -------------------------------------------------------------------------------- /wrappers/3dfx/drv/Makefile: -------------------------------------------------------------------------------- 1 | FXLIB=../../fxlib 2 | CROSS?= 3 | CC=$(CROSS)gcc 4 | CFLAGS=-march=x86-64-v2 -mtune=generic -mfpmath=sse 5 | CFLAGS+=-pipe -I$(FXLIB) -Wall -Wextra -Werror 6 | OUTDIR?=build 7 | 8 | all: instdrv.exe fxmemmap.vxd fxptl.sys shasum 9 | 10 | instdrv.exe: instdrv.c 11 | @if [ ! -d ../$(OUTDIR) ]; then exit 1; fi 12 | @echo " LD $@" 13 | @$(CC) $(CFLAGS) -s -o ../$(OUTDIR)/$@ $< ../$(OUTDIR)/fxlibnt.o 14 | 15 | fxmemmap.vxd: fxmemmap.xxd 16 | @echo " DRV $@" 17 | @xxd -r $< ../$(OUTDIR)/$@ 18 | 19 | fxptl.sys: fxptl.xxd 20 | @echo " DRV $@" 21 | @xxd -r $< ../$(OUTDIR)/$@ 22 | 23 | shasum: shasum.txt 24 | @shasum ../$(OUTDIR)/fxmemmap.vxd ../$(OUTDIR)/fxptl.sys | sed "s/.\.\.\/$(OUTDIR)\///" | diff - $< 25 | -------------------------------------------------------------------------------- /wrappers/fxlib/hpat.h: -------------------------------------------------------------------------------- 1 | #ifndef __HPAT_H 2 | #define __HPAT_H 3 | 4 | enum { 5 | HP_NONE, 6 | HP_98ME, 7 | HP_2KXP, 8 | HP_ANYO, 9 | HP_DONE, 10 | }; 11 | struct E_PATCH { 12 | int offs, len; 13 | char *cb; 14 | }; 15 | #define PATCH_D(a,b) { a, sizeof(b)/sizeof(char) - 1, b } 16 | #define E_PATCH_END() { 0, 0 } 17 | 18 | typedef struct fxCompatTbl { 19 | char *modName, *md5; 20 | int op_mask; 21 | struct E_PATCH *ptr; 22 | } COMPATFX, * PCOMPATFX; 23 | 24 | const int fxCompatPlatformId(const int); 25 | const PCOMPATFX fxCompatTblPtr(void); 26 | /* fxtime.c */ 27 | typedef struct timeEvent { 28 | void *Kill, *Set; 29 | } EVENTFX, * PEVENTFX; 30 | void fxEventHookPtr(const PEVENTFX); 31 | #endif //__HPAT_H 32 | -------------------------------------------------------------------------------- /wrappers/3dfx/ovl/Makefile: -------------------------------------------------------------------------------- 1 | WATCOM_PATH=$(shell dirname `which wcc386`) 2 | WCC=$(WATCOM_PATH)/wcc386 3 | WLD=$(WATCOM_PATH)/wlink 4 | QEMU_SRC_DIR=../../../qemu-0 5 | INCLUDES=-I$(QEMU_SRC_DIR)/hw/3dfx -I../src 6 | CFLAGS=-zq -we -6s -ohtx -bd -fpi87 7 | OUTDIR?=build 8 | 9 | all: glide2x.ovl 10 | 11 | glide2x.ovl: glideovl.obj 12 | @echo " CFLAGS $(CFLAGS)" 13 | @echo " WLD $@" 14 | @$(WLD) @$(<:obj=lnk) 15 | @if [ -d ../$(OUTDIR) ]; then cp -v $@ ../$(OUTDIR); fi 16 | 17 | glideovl.obj: glideovl.c 18 | @git rev-parse --short HEAD | sed "s/\(.*\)/\#define\ __REV__\ \"\1\-\"/" > stamp.h 19 | @echo " WCC $@" 20 | @if [ x`uname | sed "s/_.*//"` == xMINGW32 ]; then \ 21 | INCLUDES=`echo $(INCLUDES) | sed "s/\//\\\\\/g"`; \ 22 | $(WCC) `echo $$INCLUDES` $(CFLAGS) $<; else \ 23 | $(WCC) $(INCLUDES) $(CFLAGS) -fo=$@ $<; fi 24 | @rm stamp.h 25 | 26 | clean: 27 | @rm -f *.map *.obj *.err *.ovl 28 | 29 | distclean: clean 30 | @rm -f ../$(OUTDIR)/*.ovl 31 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/mglvarry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU MESA GL Pass-Through 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #ifndef _MGL_VERTARRY_H 22 | #define _MGL_VERTARRY_H 23 | 24 | void *LookupVertex(uint32_t, uint32_t); 25 | int FreeVertex(void); 26 | 27 | #endif //_MGL_VERTARRY_H 28 | 29 | -------------------------------------------------------------------------------- /qemu-0/hw/3dfx/gllstbuf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU 3Dfx Glide Pass-Through 3 | * 4 | * Copyright (c) 2018-2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #ifndef _SV_TRCKR_H 22 | #define _SV_TRCKR_H 23 | 24 | void *LookupGrState(uint32_t handle, int size); 25 | void *LookupVtxLayout(uint32_t handle, int size); 26 | int FreeGrState(void); 27 | int FreeVtxLayout(void); 28 | 29 | #endif //_SV_TRCKR_H 30 | 31 | -------------------------------------------------------------------------------- /wrappers/3dfx/dxe/Makefile: -------------------------------------------------------------------------------- 1 | QEMU_SRC_DIR=../../../qemu-0 2 | GIT=$(shell git rev-parse --short HEAD | sed "s/\(.*\)/\1\-/") 3 | X86?=i686 4 | CROSS=$(X86)-pc-msdosdjgpp- 5 | CC=$(CROSS)gcc 6 | CFLAGS=-I$(QEMU_SRC_DIR)/hw/3dfx -D__REV__=\"$(GIT)\" -Wall -Werror -O3 -fomit-frame-pointer 7 | DXEGEN=dxe3gen 8 | OUTDIR?=build 9 | 10 | TARGET2=glide2x.dxe 11 | TARGET3=glide3x.dxe 12 | 13 | all: $(TARGET2) $(TARGET3) 14 | 15 | $(TARGET3): gl301dxe.o 16 | @echo " CFLAGS $(CFLAGS)" 17 | @echo " DXE $@" 18 | @DXE_LD_LIBRARY_PATH=$(shell which $(CC) | sed "s/bin\///;s/\-gcc$$/\/lib/") \ 19 | $(DXEGEN) -o $@ -Y libfxgl3.a -E _gr -E _gu $+ -lc -Map glide3x.map 20 | @if [ -d ../$(OUTDIR) ]; then cp -v libfxgl3.a $(TARGET3) ../$(OUTDIR); fi 21 | 22 | $(TARGET2): glidedxe.o 23 | @echo " CFLAGS $(CFLAGS)" 24 | @echo " DXE $@" 25 | @DXE_LD_LIBRARY_PATH=$(shell which $(CC) | sed "s/bin\///;s/\-gcc$$/\/lib/") \ 26 | $(DXEGEN) -o $@ -Y libfxgl2.a -E _Convert -E _gr -E _gu $+ -lc -Map glide2x.map 27 | @if [ -d ../$(OUTDIR) ]; then cp -v libfxgl2.a $(TARGET2) ../$(OUTDIR); fi 28 | 29 | %.o: %.c clib.h 30 | @echo " CC $@" 31 | @$(CC) -I../src $(CFLAGS) -c -o $@ $< 32 | 33 | clean: 34 | @rm -f *.o *.a *.map $(TARGET2) $(TARGET3) 35 | 36 | distclean: clean 37 | @rm -f ../$(OUTDIR)/*.dxe 38 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/mglmapbo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU MESA GL Pass-Through 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #ifndef _MGL_MAPBO_H 22 | #define _MGL_MAPBO_H 23 | 24 | typedef struct { 25 | int idx, lvl, tgt, ocpy; 26 | uintptr_t hva, gpa; 27 | uint32_t mused, mapsz, offst, range, acc; 28 | } mapbufo_t; 29 | 30 | void InitBufObj(void); 31 | mapbufo_t *LookupBufObj(const int); 32 | int FreeBufObj(const int); 33 | int MapBufObjGpa(mapbufo_t *); 34 | 35 | void InitSyncObj(void); 36 | uint32_t AddSyncObj(const uintptr_t); 37 | uintptr_t LookupSyncObj(const uint32_t); 38 | uintptr_t DeleteSyncObj(const uintptr_t); 39 | 40 | #endif //_MGL_MAPBO_H 41 | 42 | -------------------------------------------------------------------------------- /scripts/sign_commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TOP=. 4 | GIT=`echo $@ | sed "s/\-git=\(.*\)/\1/;s/\ .*//"` 5 | if [ -z $GIT ]; then GIT=.; else shift; fi; 6 | ARG=$@; if [ -z $ARG ]; then ARG=HEAD; fi 7 | REV=`cd $GIT; git rev-parse --short $ARG | sed "s/\(.*\)/\1\-/"` 8 | EMUS=$(basename $(dirname `find $TOP/include -name whpx.h`)) 9 | CRYP=$(grep HASH_ALG $TOP/qapi/crypto.json | sed "s/.*\:\ //;s/.*\(HASH_[A-Z]*\).*/\1/") 10 | MODS=$(cat $TOP/target/i386/meson.build | tail -n 2 | head -n 1 | \ 11 | sed "s/.*:\ //;s/\}//") 12 | if [ -z $REV ] || [ -z $EMUS ] || [ -z $MODS ]; then exit 1; fi 13 | [ ! -z $CRYP ] && sed -i -e "s/HASH_ALGO/$CRYP/" \ 14 | $TOP/hw/mesa/mesagl_pfn.h 15 | expr "$(grep base_init\) $TOP/include/qom/object.h)" : "\(.*\*klass,\ void\ \)" >/dev/null && \ 16 | sed -i -e "s/\*klass,\ const\ void/\*klass,\ void/;s/\"system\(\/address\-\)/\"exec\1/" \ 17 | $(grep -rl \*klass,\ const\ void $TOP/hw/{3dfx,mesa}) 18 | sed -i -e "s/\"sys.*\//\"$EMUS\//" \ 19 | $(grep -rl \"sys.*\/ $TOP/hw/{3dfx,mesa}) 20 | sed -i -e "s/i386.*_ss/$MODS/" \ 21 | $TOP/hw/{3dfx,mesa}/meson.build 22 | 23 | VLC=$(find $TOP -maxdepth 2 -name vl.c) 24 | SRC=" \ 25 | $TOP/hw/3dfx/g2xfuncs.h \ 26 | $TOP/hw/mesa/mglfuncs.h \ 27 | $VLC \ 28 | " \ 29 | 30 | echo $REV 31 | sed -i -e "s/\(rev_\[\).*\].*/\1\]\ =\ \"$REV\"/" $SRC 32 | grep "rev_\[" $SRC | sed "s/\(rev_\[\).*\].*/\1\]\ =\ \"$REV\"/" 33 | -------------------------------------------------------------------------------- /qemu-0/hw/3dfx/vertex3x.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU 3Dfx Glide Pass-Through 3 | * 4 | * Copyright (c) 2018-2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #ifndef _VERTEX3X_H 22 | #define _VERTEX3X_H 23 | 24 | static const int slen[] = 25 | { 8, 4, 4, 4, 4, 4, 12, 4, 8, 4, 8, 4 }; 26 | static int vlut[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 27 | static void vlut_vvars(int param, int offs, int mode) 28 | { 29 | vlut[GR_PARAM_IDX(param)] = (mode)? offs:0; 30 | if (GR_PARAM_PARGB == param) { 31 | vlut[GR_PARAM_IDX(GR_PARAM_A)] = 0; 32 | vlut[GR_PARAM_IDX(GR_PARAM_RGB)] = 0; 33 | } 34 | if (GR_PARAM_RGB == param) 35 | vlut[GR_PARAM_IDX(GR_PARAM_PARGB)] = 0; 36 | } 37 | static int size_vertex3x(void) 38 | { 39 | int n = sizeof(slen) / sizeof(int), ret = slen[0]; 40 | for (int i = 0; i < n; i++) 41 | ret = (vlut[i] && ((vlut[i] + slen[i]) > ret))? (vlut[i] + slen[i]):ret; 42 | 43 | return ret; 44 | } 45 | 46 | #endif //_VERTEX3X_H 47 | 48 | -------------------------------------------------------------------------------- /wrappers/3dfx/src/version.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef GLIDE2 4 | #define DLLNAME "glide2x.dll\0" 5 | #define VERSIONDEF 2,43,0,0363 6 | #define VERSIONSTR "2.43\0" 7 | #endif 8 | #ifdef GLIDE1 9 | #define DLLNAME "glide.dll\0" 10 | #define VERSIONDEF 2,11,0,0323 11 | #define VERSIONSTR "2.11\0" 12 | #endif 13 | #ifdef GLIDE3 14 | #define DLLNAME "glide3x.dll\0" 15 | #define VERSIONDEF 3,01,0,0455 16 | #define VERSIONSTR "3.01\0" 17 | #endif 18 | 19 | #ifndef DLLNAME 20 | #error undefined DLLNAME 21 | #endif 22 | 23 | #define HWSTR " Voodoo Banshee\256, Voodoo3\256, & Velocity(tm) 100/200\256\0" 24 | #define PRODNAME "Glide\256 for Voodoo Banshee\256, Voodoo3\256, & Velocity(tm) 100/200\256\0" 25 | 26 | VS_VERSION_INFO VERSIONINFO 27 | FILEVERSION VERSIONDEF 28 | PRODUCTVERSION VERSIONDEF 29 | FILEFLAGSMASK 0x0030003FL 30 | BEGIN 31 | BLOCK "StringFileInfo" 32 | BEGIN 33 | BLOCK "040904E4" 34 | BEGIN 35 | VALUE "CompanyName", "3Dfx Interactive, Inc.\0" 36 | VALUE "FileDescription", "3Dfx Interactive, Inc. Glide DLL\0" 37 | VALUE "FileVersion", VERSIONSTR 38 | VALUE "InternalName", DLLNAME 39 | VALUE "LegalCopyright", "Copyright \251 3Dfx Interactive, Inc. 1997\0" 40 | VALUE "OriginalFilename", DLLNAME 41 | VALUE "ProductName", PRODNAME 42 | VALUE "ProductVersion", VERSIONSTR 43 | VALUE "Graphics Subsystem", HWSTR 44 | END 45 | END 46 | BLOCK "VarFileInfo" 47 | BEGIN 48 | /* the following line should be extended for localized versions */ 49 | VALUE "Translation", 0x409, 1252 50 | END 51 | END 52 | -------------------------------------------------------------------------------- /qemu-0/hw/3dfx/glidewnd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU 3Dfx Glide Pass-Through 3 | * 4 | * Copyright (c) 2018-2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #ifndef GLIDEWND_H 22 | #define GLIDEWND_H 23 | 24 | int GRFifoTrace(void); 25 | int GRFuncTrace(void); 26 | int glide_fpslimit(void); 27 | int glide_vsyncoff(void); 28 | int glide_lfbmerge(void); 29 | int glide_lfbdirty(void); 30 | int glide_lfbnoaux(void); 31 | int glide_lfbmode(void); 32 | void glide_winres(const int, int *, int *); 33 | int stat_window(const int, void *); 34 | void init_window(const int, const char *, void *); 35 | void fini_window(void *); 36 | 37 | typedef struct { 38 | int activate; 39 | uint32_t *arg; 40 | uint32_t FEnum; 41 | uintptr_t GrContext; 42 | } window_cb; 43 | 44 | typedef struct { 45 | uintptr_t hva; 46 | uint32_t mapsz; 47 | uint32_t acc; 48 | } mapbufo_t; 49 | 50 | int glide_mapbufo(mapbufo_t *, int); 51 | 52 | typedef struct _perfstat { 53 | void (*stat)(void); 54 | void (*last)(void); 55 | } PERFSTAT, *PPERFSTAT; 56 | 57 | void glidestat(PPERFSTAT); 58 | 59 | #endif // GLIDEWND_H 60 | -------------------------------------------------------------------------------- /wrappers/3dfx/dso/clib.h: -------------------------------------------------------------------------------- 1 | #ifndef CLIB_H 2 | #define CLIB_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #ifndef O_BINARY 11 | #define O_BINARY 0 12 | #endif 13 | 14 | typedef unsigned long FxU32; 15 | typedef int FxBool; 16 | 17 | static INLINE uint32_t f2u32(const float f) 18 | { 19 | uint32_t u32; 20 | char *s = (char *)&f; 21 | char *d = (char *)&u32; 22 | 23 | *d++ = *s++; 24 | *d++ = *s++; 25 | *d++ = *s++; 26 | *d++ = *s++; 27 | 28 | return u32; 29 | } 30 | 31 | static int fd = -1; 32 | static int init_fd(void) 33 | { 34 | if (fd == -1) 35 | fd = open("/dev/mem", O_RDWR|O_SYNC); 36 | if (fd == -1) { 37 | fprintf(stderr, "Error: /dev/mem open failed\n"); 38 | return 1; 39 | } 40 | return 0; 41 | } 42 | 43 | static void *MapPhysToLin(void *physaddr, unsigned int size) 44 | { 45 | off_t offset = (off_t)physaddr; 46 | size_t len = size; 47 | 48 | // Truncate offset to a multiple of the page size, or mmap will fail. 49 | size_t pagesize = sysconf(_SC_PAGE_SIZE); 50 | off_t page_base = (offset / pagesize) * pagesize; 51 | off_t page_offset = offset - page_base; 52 | 53 | unsigned char *mem = mmap(NULL, page_offset + len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, page_base); 54 | if (mem == MAP_FAILED) { 55 | DPRINTF("Error: mmap() failed\n"); 56 | return 0; 57 | } 58 | 59 | return mem; 60 | } 61 | 62 | static FxBool fxMapLinear(FxU32 busNumber, FxU32 physical_addr, FxU32 *linear_addr, FxU32 *length) 63 | { 64 | *linear_addr = (FxU32)MapPhysToLin((void *)physical_addr, *length); 65 | if (*linear_addr == 0) 66 | return 0; 67 | return 1; 68 | } 69 | 70 | #endif //CLIB_H 71 | 72 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/mglfuncs.h: -------------------------------------------------------------------------------- 1 | #include "mgldefs.h" 2 | #include "mglfunci.h" 3 | 4 | int szgldata(int, int); 5 | int szglname(int); 6 | const char *tokglstr(const int); 7 | 8 | typedef struct { 9 | int enable; 10 | int size; 11 | int type; 12 | int stride; 13 | void *ptr; 14 | } vtxarry_t; 15 | 16 | #define PAGE_SIZE 0x1000 17 | 18 | #define MESAGL_MAGIC 0x5b5eb5e5 19 | #define MESAGL_HWNDC 0x574e4443 20 | #define MESAGL_HPBDC 0x50424443 21 | #define MESA_FIFO_BASE 0xec000000 22 | #define MESA_FBTM_BASE 0xea000000 23 | 24 | #define MBUFO_BASE (0xE0U << 24) 25 | #define MBUFO_SIZE (0x08U << 24) 26 | 27 | #define ALIGNED(x) ((x%8)?(((x>>3)+1)<<3):x) 28 | #define ALIGNBO(x) ((x%16)?(((x>>4)+1)<<4):x) 29 | #define MGLFBT_SIZE 0x2000000 30 | #define MGLSHM_SIZE 0x3ffc000 31 | #define FIRST_FIFO 24 32 | #define MAX_FIFO 0xc0000 33 | #define MAX_DATA ((MGLSHM_SIZE - (4*MAX_FIFO) - (4*4096)) >> 2) 34 | #define MAX_LVLCNTX ((MESAGL_MAGIC & 0x0FU) + 1) 35 | #define MAX_TEXUNIT 8 36 | #define MAX_PBUFFER 16 37 | #define DISPTMR_DEFAULT 2000 38 | #define MESAGL_CRASH_RC 3000 39 | 40 | #ifdef QEMU_OSDEP_H 41 | #if (((QEMU_VERSION_MAJOR << 8) | \ 42 | (QEMU_VERSION_MINOR << 4) | \ 43 | QEMU_VERSION_MICRO) < 0x710) 44 | #define qemu_real_host_page_size() qemu_real_host_page_size 45 | #define qemu_real_host_page_mask() qemu_real_host_page_mask 46 | #endif 47 | #endif /* QEMU_OSDEP_H */ 48 | 49 | #define COMMIT_SIGN \ 50 | const char rev_[ALIGNED(1)] 51 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/mglcntx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU MESA GL Pass-Through 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #ifndef MGLCNTX_H 22 | #define MGLCNTX_H 23 | 24 | #include "qemu/atomic.h" 25 | 26 | void SetMesaFuncPtr(void *); 27 | void *MesaGLGetProc(const char *); 28 | int MGLExtIsAvail(const char *, const char *); 29 | int MGLUpdateGuestBufo(mapbufo_t *, const int); 30 | void MGLTmpContext(void); 31 | void MGLWndRelease(void); 32 | int MGLMakeCurrent(uint32_t, int); 33 | int MGLSwapBuffers(void); 34 | int MGLChoosePixelFormat(void); 35 | int MGLDescribePixelFormat(int, unsigned int, void *); 36 | int MGLSetPixelFormat(int, const void *); 37 | int CompareAttribArray(const int *); 38 | void MGLActivateHandler(const int, const int); 39 | void MGLCursorDefine(int, int, int, int, const void *); 40 | void MGLMouseWarp(const uint32_t); 41 | int NumPbuffer(void); 42 | int DrawableContext(void); 43 | void MGLFuncHandler(const char *); 44 | void MGLDeleteContext(int); 45 | int MGLCreateContext(uint32_t); 46 | 47 | int glwnd_ready(void); 48 | void deactivateCancel(void); 49 | void deactivateSched(const int); 50 | void deactivateGuiRefSched(void); 51 | int find_xstr(const char *, const char *); 52 | 53 | typedef struct _perfstat { 54 | void (*stat)(void); 55 | void (*last)(void); 56 | } PERFSTAT, *PPERFSTAT; 57 | 58 | void mesastat(PPERFSTAT); 59 | 60 | #endif // MGLCNTX_H 61 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/extensions_table.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Mesa 3-D graphics library 3 | * 4 | * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 | * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a 8 | * copy of this software and associated documentation files (the "Software"), 9 | * to deal in the Software without restriction, including without limitation 10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | * and/or sell copies of the Software, and to permit persons to whom the 12 | * Software is furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included 15 | * in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | * OTHER DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "extensions_defs.h" 27 | 28 | /** 29 | * Given a member \c x of struct gl_extensions, return offset of 30 | * \c x in bytes. 31 | */ 32 | #define o(x) offsetof(struct gl_extensions, x) 33 | 34 | /** 35 | * \brief Table of supported OpenGL extensions for all API's. 36 | */ 37 | const struct mesa_extension _mesa_extension_table[] = { 38 | #define EXT(name_str, driver_cap, gll_ver, glc_ver, gles_ver, gles2_ver, yyyy) \ 39 | { .name = "GL_" #name_str, .offset = o(driver_cap), \ 40 | .version = { \ 41 | [API_OPENGL_COMPAT] = gll_ver, \ 42 | [API_OPENGL_CORE] = glc_ver, \ 43 | [API_OPENGLES] = gles_ver, \ 44 | [API_OPENGLES2] = gles2_ver, \ 45 | }, \ 46 | .year = yyyy \ 47 | }, 48 | #include "extensions_table.h" 49 | #undef EXT 50 | }; 51 | -------------------------------------------------------------------------------- /virgil3d/MINGW-packages/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Courtesy of qemu-3dfx 2 | 3 | _realname=virglrenderer 4 | pkgbase=mingw-w64-${_realname} 5 | pkgname=${MINGW_PACKAGE_PREFIX}-${_realname} 6 | pkgver=1.2.0 7 | pkgrel=1 8 | pkgdesc='A virtual 3D GPU library, that allows the guest operating system to use the host GPU to accelerate 3D rendering' 9 | arch=('any') 10 | mingw_arch=('mingw64') 11 | url='https://virgil3d.github.io/' 12 | license=(MIT) 13 | depends=("${MINGW_PACKAGE_PREFIX}-libepoxy") 14 | makedepends=("${MINGW_PACKAGE_PREFIX}-python" 15 | "${MINGW_PACKAGE_PREFIX}-cc" 16 | "${MINGW_PACKAGE_PREFIX}-meson" 17 | "${MINGW_PACKAGE_PREFIX}-ninja") 18 | _venv=(pyyaml) 19 | _tag=$pkgver 20 | source=("virglrenderer-$pkgver.tar.bz2::https://gitlab.freedesktop.org/virgl/virglrenderer/-/archive/$_tag/virglrenderer-$_tag.tar.bz2" 21 | "0001-Virglrenderer-on-Windows-and-macOS.patch") 22 | sha256sums=('f4f52db11297b52b35c8c2d5bf5e21b7997b52f8bfad99ea2b1c155997cff4ad' 23 | '930078db6a8bf66e43445707e40c5bb7e6356d63f964ea637275f9cfd02d0d13') 24 | 25 | prepare() { 26 | cd virglrenderer-$_tag 27 | mkdir -p src/gallium/include/sys && \ 28 | touch src/gallium/include/sys/ioccom.h 29 | sed "s/\(error=switch\)/\1\',\'\-Wno\-unknown\-attributes\',\'\-Wno\-unused\-parameter/" -i meson.build 30 | sed "s/\(fvisibility=hidden\)/\1\',\'\-mno\-ms\-bitfields/" -i meson.build 31 | sed "s/\(strstr.*Quadro.*\ NULL\)/1\ ||\ \1/" -i src/vrend/vrend_renderer.c 32 | patch -p2 -i ${srcdir}/0001-Virglrenderer-on-Windows-and-macOS.patch 33 | } 34 | 35 | build() { 36 | cd virglrenderer-$_tag 37 | python -m venv pyvenv && \ 38 | source pyvenv/bin/activate 39 | python -m pip install --upgrade pip 40 | pip install $_venv 41 | MSYS2_ARG_CONV_EXCL="--prefix" \ 42 | CFLAGS="-march=x86-64-v2 -mtune=generic -flto=auto -O3" \ 43 | meson setup --prefix="${MINGW_PREFIX}" build # -Dtests=true 44 | ninja -C build 45 | } 46 | 47 | package() { 48 | cd virglrenderer-$_tag 49 | DESTDIR="$pkgdir" ninja -C build install 50 | install -D -m644 "${srcdir}/${_realname}-${pkgver}/COPYING" "${pkgdir}/${MINGW_PREFIX}/share/licenses/${_realname}/COPYING" 51 | } 52 | -------------------------------------------------------------------------------- /wrappers/mesa/src/Makefile.in: -------------------------------------------------------------------------------- 1 | QEMU_SRC_DIR=../../../qemu-1 2 | FXLIB=../../fxlib 3 | CROSS= 4 | CC=$(CROSS)gcc 5 | RC=windres 6 | DLLTOOL=dlltool 7 | STRIP=strip 8 | CFLAGS=-march=x86-64-v2 -mtune=generic -mfpmath=sse -O3 9 | CFLAGS+=-pipe -I$(QEMU_SRC_DIR)/hw/mesa -I$(FXLIB) -Wall -Werror -flto=auto -fomit-frame-pointer 10 | LDFLAGS=-static-libgcc 11 | LDFLAGS+=-Wl,--disable-auto-image-base,--no-seh,--dynamicbase,--nxcompat 12 | SRCDIR=../src 13 | TARGET=opengl32.dll 14 | TOOLS=wglinfo.exe 15 | GENDEF=gendef 16 | 17 | C_OBJS:=\ 18 | fxhook.o \ 19 | fxhpat.o \ 20 | fxlib9x.o \ 21 | fxlibnt.o \ 22 | fxtime.o \ 23 | md5.o \ 24 | 25 | 26 | all: fxlib $(TARGET) exports-check $(TOOLS) 27 | 28 | exports-check: $(TARGET) 29 | @if [ $$(objdump -x $(TARGET) | grep "\[[\ 0-9]*\]" | grep -v "^\[" | \ 30 | grep -v -e reloc -e Export\ RVA | wc -l) -ne 2976 ]; \ 31 | then exit 1; fi 32 | 33 | $(TARGET): $(C_OBJS) szdata.o wrapgl32.o stamp.o 34 | @echo " CFLAGS $(CFLAGS)" 35 | @echo " LDFLAGS $(LDFLAGS)" 36 | @$(CC) -shared $(CFLAGS) -o $@ $+ $(LDFLAGS) 37 | @$(GENDEF) - $@ | sed "s/\(@[0-9]*\)@.*/\1/;s/\(^.*\)\(@[0-9]*\)/\1\ =\ \1\2/;s/^mgl/wgl/;s/wgd//" | \ 38 | sed "s/\ ;\ Check!!!.*//;/lto_priv/d;/CallWndProc/d" | \ 39 | grep -e ^LIB -e ^EXP -e " = " > $(@:.dll=.def) 40 | @echo " LD $@" 41 | @$(CC) -shared $(CFLAGS) -o $@ $(@:dll=def) $+ $(LDFLAGS) 42 | 43 | $(TOOLS): 44 | @echo " LD $@" 45 | @$(CC) $(CFLAGS) -s -o $@ $(SRCDIR)/wglinfo.c $(LDFLAGS) -lgdi32 -lopengl32 46 | 47 | stamp.o: 48 | @git rev-parse --short HEAD | sed "s/\(.*\)/const\ char\ rev_\[\]\ =\ \"\1\-\";/" > /tmp/$(@:o=c) 49 | @echo -n " REV $@"; cat /tmp/$(@:o=c) | sed "s/.*rev_\[\]\ =//;s/;//" 50 | @$(CC) -c -o $@ /tmp/$(@:o=c) 51 | 52 | fxlib: 53 | @if [ "$$MSYSTEM" != "MINGW32" ]; then echo "Error: MSYSTEM == $$MSYSTEM"; exit 1; fi 54 | @echo " CC $(C_OBJS)" 55 | @for i in $(C_OBJS); do \ 56 | $(CC) $(CFLAGS) -c -o $$i $(FXLIB)/`echo $$i | sed "s/\.o/\.c/"`; \ 57 | done 58 | 59 | %.o: $(SRCDIR)/%.c 60 | @echo " CC $@" 61 | @$(CC) $(CFLAGS) -c -o $@ $< 62 | 63 | clean: 64 | @rm -f *.o *.def 65 | @if [ -f $(TARGET) ]; then \ 66 | $(STRIP) --strip-unneeded $(TARGET); \ 67 | sh -c 'ls -l $(TARGET)'; \ 68 | strings $(TARGET) | grep " build "; fi 69 | 70 | distclean: clean 71 | @rm -f $(TARGET) $(TOOLS) 72 | 73 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/mesagl_pfn.h: -------------------------------------------------------------------------------- 1 | #include 2 | #define MESA_PFN(p,f) \ 3 | p p_##f = (p)GLFEnumFuncPtr(FEnum_##f) 4 | #define PFN_CALL(f) \ 5 | p_##f 6 | #include "crypto/hash.h" 7 | #define ASSERT_ATTEST(x) \ 8 | do { Error *errp = NULL; char *div; \ 9 | struct iovec iv = { .iov_base = x, .iov_len = strnlen(x, 48) }; \ 10 | qcrypto_hash_digestv(QCRYPTO_HASH_ALGO_SHA1, &iv, 1, &div, &errp); \ 11 | MesaContextAttest(div, &s->mglCntxAtt); g_free(div); \ 12 | } while(0) 13 | #define ATTEST_IV \ 14 | "fc35584449182ef9965c04f436f9d076046513f5", \ 15 | "39ece786a71bbacb296403bd8a8e614e4577b6f3", \ 16 | "73038aa5f5097e56144520afe60e479cc63ad986", \ 17 | "92c71e59f94fd963f9de76cce14e6b659b2613d3", \ 18 | "2b7bc2db7b4bb878ba3addf54392346f7568fb87", \ 19 | "9c2d2de9e4c69860d0050c0bb4cdd203c8c72975", \ 20 | NULL 21 | typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC) (GLenum cap); 22 | typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void); 23 | typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGPROC) (GLenum name); 24 | typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture); 25 | typedef void (APIENTRYP PFNGLBITMAPPROC) (GLsizei width,GLsizei height,GLfloat xorig,GLfloat yorig,GLfloat xmove,GLfloat ymove,const GLubyte *bitmap); 26 | typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); 27 | typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures); 28 | typedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap); 29 | typedef void (APIENTRYP PFNGLDRAWARRAYSPROC) (GLenum mode, GLint first, GLsizei count); 30 | typedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap); 31 | typedef void (APIENTRYP PFNGLENDLISTPROC) (void); 32 | typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures); 33 | typedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data); 34 | typedef void (APIENTRYP PFNGLGETMAPIVPROC) (GLenum target,GLenum query,GLint *v); 35 | typedef void (APIENTRYP PFNGLGETTEXLEVELPARAMETERIVPROC) (GLenum target, GLint level, GLenum pname, GLint *params); 36 | typedef void (APIENTRYP PFNGLNEWLISTPROC) (GLuint list,GLenum mode); 37 | typedef void (APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param); 38 | typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param); 39 | typedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height); 40 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/mesagl_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU MESA GL Pass-Through 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #ifndef MESAGL_IMPL_H 22 | #define MESAGL_IMPL_H 23 | 24 | #include 25 | #include "extensions_defs.h" 26 | #include "mglfuncs.h" 27 | #include "mglvarry.h" 28 | #include "mglmapbo.h" 29 | #include "mglcntx.h" 30 | 31 | int GLFEnumArgsCnt(const int); 32 | void *GLFEnumFuncPtr(const int); 33 | int ExtFuncIsValid(const char *); 34 | int GLIsD3D12(void); 35 | int wrMapOrderPoints(uint32_t); 36 | int wrSizeTexture(const int, const int, const int); 37 | int wrSizeMapBuffer(const int); 38 | void wrCompileShaderStatus(const int); 39 | void wrFillBufObj(uint32_t, void *, mapbufo_t *); 40 | void wrFlushBufObj(uint32_t, mapbufo_t *); 41 | void wrContextSRGB(int); 42 | void fgFontGenList(int, int, uint32_t); 43 | const char *getGLFuncStr(int); 44 | void doMesaFunc(int, uint32_t *, uintptr_t *, uintptr_t *); 45 | void GLBufOAccelCfg(int); 46 | void GLRenderScaler(int); 47 | void GLContextMSAA(int); 48 | void GLContextZERO(int); 49 | void GLBlitFlip(int); 50 | void GLDispTimerCfg(int); 51 | void GLExtUncapped(int); 52 | int GetGLExtYear(void); 53 | int GetGLExtLength(void); 54 | int GetVertCacheMB(void); 55 | int GetDispTimerMS(void); 56 | int GetBufOAccelEN(void); 57 | int GetContextMSAA(void); 58 | int GetContextZERO(void); 59 | int ContextUseSRGB(void); 60 | int ContextVsyncOff(void); 61 | int RenderScalerOff(void); 62 | int ScalerBlitFlip(void); 63 | int ScalerSRGBCorr(void); 64 | int SwapFpsLimit(int); 65 | int GetFpsLimit(void); 66 | int GLShaderDump(void); 67 | int GLCheckError(void); 68 | int GLFifoTrace(void); 69 | int GLFuncTrace(void); 70 | void FiniMesaGL(void); 71 | void ImplMesaGLReset(void); 72 | int InitMesaGL(void); 73 | void InitMesaGLExt(void); 74 | 75 | #include "mesagl_pfn.h" 76 | void MesaContextAttest(const char *, int *); 77 | void MesaBlitFree(void); 78 | void MesaBlitScale(void); 79 | void MesaRenderScaler(const uint32_t, void *); 80 | 81 | #endif //MESAGL_IMPL_H 82 | -------------------------------------------------------------------------------- /virgil3d/0002-Virgil3D-macOS-GLSL-version.patch: -------------------------------------------------------------------------------- 1 | diff -Nru ../orig/qemu-7.2.0/ui/sdl2.c ./ui/sdl2.c 2 | --- ../orig/qemu-7.2.0/ui/sdl2.c 3 | +++ ./ui/sdl2.c 4 | @@ -96,6 +96,10 @@ 5 | } 6 | #ifdef CONFIG_OPENGL 7 | if (scon->opengl) { 8 | +#ifdef CONFIG_DARWIN 9 | + /* Apple OpenGL quirk */ 10 | + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); 11 | +#endif 12 | flags |= SDL_WINDOW_OPENGL; 13 | } 14 | #endif 15 | diff -Nru ../orig/qemu-6.1.0/ui/shader/texture-blit-flip.vert ./ui/shader/texture-blit-flip.vert 16 | --- ../orig/qemu-6.1.0/ui/shader/texture-blit-flip.vert 17 | +++ ./ui/shader/texture-blit-flip.vert 18 | @@ -1,5 +1,3 @@ 19 | -#version 300 es 20 | - 21 | in vec2 in_position; 22 | out vec2 ex_tex_coord; 23 | 24 | diff -Nru ../orig/qemu-6.1.0/ui/shader/texture-blit.frag ./ui/shader/texture-blit.frag 25 | --- ../orig/qemu-6.1.0/ui/shader/texture-blit.frag 26 | +++ ./ui/shader/texture-blit.frag 27 | @@ -1,5 +1,3 @@ 28 | -#version 300 es 29 | - 30 | uniform sampler2D image; 31 | in mediump vec2 ex_tex_coord; 32 | out mediump vec4 out_frag_color; 33 | diff -Nru ../orig/qemu-6.1.0/ui/shader/texture-blit.vert ./ui/shader/texture-blit.vert 34 | --- ../orig/qemu-6.1.0/ui/shader/texture-blit.vert 35 | +++ ./ui/shader/texture-blit.vert 36 | @@ -1,5 +1,3 @@ 37 | -#version 300 es 38 | - 39 | in vec2 in_position; 40 | out vec2 ex_tex_coord; 41 | 42 | diff -Nru ../orig/qemu-6.1.0/ui/shader.c ./ui/shader.c 43 | --- ../orig/qemu-6.1.0/ui/shader.c 44 | +++ ./ui/shader.c 45 | @@ -152,11 +152,22 @@ 46 | QemuGLShader *qemu_gl_init_shader(void) 47 | { 48 | QemuGLShader *gls = g_new0(QemuGLShader, 1); 49 | + const GLchar *header = epoxy_is_desktop_gl() ? "#version 140\n" : "#version 300 es\n"; 50 | + char *frag_src = g_new0(GLchar, 1 + strlen(header) + sizeof(texture_blit_frag_src)); 51 | + char *vert_src = g_new0(GLchar, 1 + strlen(header) + 52 | + MAX(sizeof(texture_blit_vert_src), sizeof(texture_blit_flip_vert_src))); 53 | + char *vert_src_body = g_stpcpy(vert_src, header); 54 | + char *frag_src_body = g_stpcpy(frag_src, header); 55 | 56 | + strcpy(vert_src_body, texture_blit_vert_src); 57 | + strcpy(frag_src_body, texture_blit_frag_src); 58 | gls->texture_blit_prog = qemu_gl_create_compile_link_program 59 | - (texture_blit_vert_src, texture_blit_frag_src); 60 | + (vert_src, frag_src); 61 | + strcpy(vert_src_body, texture_blit_flip_vert_src); 62 | gls->texture_blit_flip_prog = qemu_gl_create_compile_link_program 63 | - (texture_blit_flip_vert_src, texture_blit_frag_src); 64 | + (vert_src, frag_src); 65 | + g_free(vert_src); 66 | + g_free(frag_src); 67 | if (!gls->texture_blit_prog || !gls->texture_blit_flip_prog) { 68 | exit(1); 69 | } 70 | -------------------------------------------------------------------------------- /qemu-0/hw/3dfx/gllstbuf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU 3Dfx Glide Pass-Through 3 | * 4 | * Copyright (c) 2018-2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #include "qemu/osdep.h" 22 | 23 | #include "gllstbuf.h" 24 | 25 | typedef struct _llstbuf { 26 | uint32_t id; 27 | int sz; 28 | uint8_t *st; 29 | struct _llstbuf *next; 30 | } LLSTBUF, * PLLSTBUF; 31 | 32 | static PLLSTBUF llGrState = NULL; 33 | static PLLSTBUF llVtxLayout = NULL; 34 | 35 | static void *LookupStBuf(PLLSTBUF *pbuf, int st_size, uint32_t handle) 36 | { 37 | PLLSTBUF p = *pbuf; 38 | 39 | while (p) { 40 | if ((p->id == handle) && (p->sz == st_size)) 41 | break; 42 | if (p->next == NULL) 43 | break; 44 | p = p->next; 45 | } 46 | 47 | if (p == NULL) { 48 | p = g_new(LLSTBUF, 1); 49 | p->id = handle; 50 | p->sz = st_size; 51 | p->st = g_malloc(p->sz); 52 | p->next = NULL; 53 | *pbuf = p; 54 | } 55 | else { 56 | if (!((p->id == handle) && (p->sz == st_size))) { 57 | p->next = g_new(LLSTBUF, 1); 58 | p = p->next; 59 | p->id = handle; 60 | p->sz = st_size; 61 | p->st = g_malloc(p->sz); 62 | p->next = NULL; 63 | } 64 | } 65 | 66 | return p->st; 67 | } 68 | 69 | static int FreeStBuf(PLLSTBUF *pbuf) 70 | { 71 | PLLSTBUF p = *pbuf; 72 | int cnt = 0; 73 | while (p) { 74 | PLLSTBUF next = p->next; 75 | g_free(p->st); 76 | g_free(p); 77 | p = next; 78 | cnt++; 79 | } 80 | *pbuf = p; 81 | return cnt; 82 | } 83 | 84 | void *LookupGrState(uint32_t handle, int size) 85 | { 86 | return LookupStBuf(&llGrState, size, handle); 87 | } 88 | void *LookupVtxLayout(uint32_t handle, int size) 89 | { 90 | return LookupStBuf(&llVtxLayout, size, handle); 91 | } 92 | int FreeGrState(void) 93 | { 94 | return FreeStBuf(&llGrState); 95 | } 96 | int FreeVtxLayout(void) 97 | { 98 | return FreeStBuf(&llVtxLayout); 99 | } 100 | 101 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/mglvarry.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU MESA GL Pass-Through 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #include "qemu/osdep.h" 22 | 23 | #include "mglfuncs.h" 24 | #include "mglvarry.h" 25 | 26 | typedef struct _vertArry { 27 | uint32_t tagLo; 28 | uint32_t tagHi; 29 | uint8_t *ptr; 30 | struct _vertArry *next; 31 | } VERTARRY, * PVERTARRY; 32 | 33 | static PVERTARRY vertexArry = NULL; 34 | 35 | static void *LookupVertArry(PVERTARRY *pArry, uint32_t handle, uint32_t size) 36 | { 37 | PVERTARRY p = *pArry; 38 | 39 | if (handle == 0) 40 | return NULL; 41 | 42 | while (p) { 43 | if (((handle >= p->tagLo) && (handle < p->tagHi)) && 44 | ((p->tagHi - handle) >= (size >> 1))) 45 | break; 46 | if (p->next == NULL) 47 | break; 48 | p = p->next; 49 | } 50 | 51 | if (p == NULL) { 52 | p = g_new(VERTARRY, 1); 53 | p->tagLo = (handle > size)? (handle - size):PAGE_SIZE; 54 | p->tagHi = p->tagLo + (size << 1); 55 | p->ptr = g_malloc(size << 1); 56 | p->next = NULL; 57 | fprintf(stderr, " alloc vaddr %08x-%08x from hndl %08x\n", p->tagLo, p->tagHi, handle); 58 | *pArry = p; 59 | } 60 | else { 61 | if (((handle >= p->tagLo) && (handle < p->tagHi)) && 62 | ((p->tagHi - handle) >= (size >> 1))) { } 63 | else { 64 | p->next = g_new(VERTARRY, 1); 65 | p = p->next; 66 | p->tagLo = (handle > size)? (handle - size):PAGE_SIZE; 67 | p->tagHi = p->tagLo + (size << 1); 68 | p->ptr = g_malloc(size << 1); 69 | fprintf(stderr, " alloc vaddr %08x-%08x from hndl %08x\n", p->tagLo, p->tagHi, handle); 70 | p->next = NULL; 71 | } 72 | } 73 | 74 | return p->ptr + (handle - p->tagLo); 75 | } 76 | 77 | static int FreeVertArry(PVERTARRY *pArry) 78 | { 79 | PVERTARRY p = *pArry; 80 | int cnt = 0; 81 | while (p) { 82 | PVERTARRY next = p->next; 83 | g_free(p->ptr); 84 | g_free(p); 85 | p = next; 86 | cnt++; 87 | } 88 | *pArry = p; 89 | return cnt; 90 | } 91 | 92 | void *LookupVertex(uint32_t handle, uint32_t size) { return LookupVertArry(&vertexArry, handle, size); } 93 | int FreeVertex(void) { return FreeVertArry(&vertexArry); } 94 | 95 | -------------------------------------------------------------------------------- /scripts/vidmodes: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | DEPS=" \ 4 | sdl2-config \ 5 | " \ 6 | 7 | for i in $DEPS; do 8 | printf %s "checking for $i... " 9 | if [ -z $(which $i 2>/dev/null) ]; then 10 | echo not found 11 | exit 1 12 | fi 13 | echo $(which $i) 14 | done 15 | echo "SDL2 version" `sdl2-config --version` 16 | cat >/tmp/res.c < 18 | #include "SDL.h" 19 | 20 | static void sdl2_display_reslist(void) 21 | { 22 | SDL_DisplayMode dtMode, *dt = &dtMode; 23 | int displayIndex = 0, numModes; 24 | SDL_GetDesktopDisplayMode(displayIndex, dt); 25 | fprintf(stderr, "%4d %-4d (%s)\n", dt->w, dt->h,"desktop"); 26 | numModes = SDL_GetNumDisplayModes(displayIndex); 27 | if (numModes > 1) { 28 | SDL_DisplayMode mode; 29 | int width = 0, height = 0; 30 | for (int i = 0; !SDL_GetDisplayMode(displayIndex, i, &mode); i++) { 31 | if (width == mode.w && height == mode.h) 32 | continue; 33 | if (i && (mode.w > dt->w || mode.h > dt->h)) 34 | continue; 35 | if (mode.w < 640 || mode.h < 480) 36 | continue; 37 | if ((mode.w < 1280) && ((4.0f/3) != ((1.0f*mode.w)/mode.h))) 38 | continue; 39 | if (mode.w % sizeof(uint64_t)) 40 | continue; 41 | if (170 == (mode.w / sizeof(uint64_t))) 42 | mode.w += 8; 43 | #define RES(w,h) ((w<<16) | h) 44 | #define RESLIST_ADD(a,b) if (a) { fprintf(stderr, "\e[35m%4d %-4d aspect %.6f\n\e[0m", (b>>16), (b&0xFFFFU), 1.f*(b>>16)/(b&0xFFFFU)); } 45 | RESLIST_ADD((mode.w == 1920 && mode.h == 1080 && width >= 2560), RES(1920,1440)); 46 | RESLIST_ADD((mode.w == 1600 && mode.h == 900 && width >= 1680), RES(1600,1200)); 47 | RESLIST_ADD((mode.w == 1440 && mode.h == 900 && height < 1080), RES(1440,1080)); 48 | RESLIST_ADD((mode.w == 1352 && width == 1512 && dt->h >= 960), RES(1440,900)); 49 | RESLIST_ADD((mode.w == 1280 && mode.h == 800 && width > 1440), RES(1440,900)); 50 | RESLIST_ADD((mode.w == 1280 && mode.h == 720 && width > 1280), RES(1280,800)); 51 | RESLIST_ADD((mode.w == 1152 && mode.h == 864 && dt->h >= 960), RES(1200,900)); 52 | RESLIST_ADD((mode.w == 1024 && width == 1280 && dt->h >= 960), RES(1200,900)); 53 | RESLIST_ADD((mode.w == 1024 && width == 1280 && dt->h >= 960), RES(1152,864)); 54 | width = mode.w; height = mode.h; 55 | fprintf(stderr, "%4d %-4d aspect %.6f\n", width, height, 1.f*width/height); 56 | } 57 | RESLIST_ADD((width > 1200 && dt->h >= 960), RES(1200,900)); 58 | RESLIST_ADD((width > 1152 && dt->h >= 960), RES(1152,864)); 59 | RESLIST_ADD((width > 1024), RES(1024,768)); 60 | RESLIST_ADD((width > 800), RES(800,600)); 61 | RESLIST_ADD((width > 640), RES(640,480)); 62 | } 63 | } 64 | 65 | int main(int argc, char *argv[]) 66 | { 67 | if (SDL_Init(SDL_INIT_VIDEO)) 68 | exit(1); 69 | sdl2_display_reslist(); 70 | return 0; 71 | } 72 | EOF 73 | cc `sdl2-config --cflags` -o /tmp/vidres /tmp/res.c `sdl2-config --libs` && \ 74 | /tmp/vidres && \ 75 | rm -f /tmp/vidres /tmp/res.c 76 | -------------------------------------------------------------------------------- /wrappers/fxlib/fxlibnt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fxlib.h" 3 | 4 | 5 | static FxU32 pciErrorCode; 6 | static HANDLE hMemmapFile; 7 | 8 | static FxBool fxlibFini(void) 9 | { 10 | if (hMemmapFile != INVALID_HANDLE_VALUE) CloseHandle(hMemmapFile); 11 | 12 | return FXTRUE; 13 | } 14 | 15 | static FxBool fxlibInit(void) 16 | { 17 | hMemmapFile = INVALID_HANDLE_VALUE; 18 | 19 | hMemmapFile = CreateFile("\\\\.\\MAPMEM", 20 | GENERIC_READ | GENERIC_WRITE, 21 | 0, 22 | NULL, 23 | OPEN_EXISTING, 24 | FILE_ATTRIBUTE_NORMAL, 25 | NULL); 26 | if (hMemmapFile == INVALID_HANDLE_VALUE) { 27 | pciErrorCode = PCI_ERR_MAPMEMDRV; 28 | return FXFALSE; 29 | } 30 | 31 | return FXTRUE; 32 | } 33 | 34 | static FxBool 35 | fxMapLinear(FxU32 busNumber, FxU32 physical_addr, 36 | FxU32 *linear_addr, FxU32 *length) 37 | { 38 | FxU32 cbReturned; 39 | PHYSICAL_MEMORY_INFO pmi; 40 | 41 | pmi.InterfaceType = PCIBus; 42 | pmi.BusNumber = busNumber; 43 | pmi.BusAddress.HighPart = 0x00000000; 44 | pmi.BusAddress.LowPart = physical_addr; 45 | pmi.AddressSpace = 0; 46 | pmi.Length = *length; 47 | 48 | if(!DeviceIoControl(hMemmapFile, 49 | (FxU32)IOCTL_MAPMEM_MAP_USER_PHYSICAL_MEMORY, 50 | &pmi, sizeof(PHYSICAL_MEMORY_INFO), 51 | linear_addr, sizeof(PVOID), 52 | &cbReturned, NULL)) { 53 | pciErrorCode = PCI_ERR_MAPMEM; 54 | return FXFALSE; 55 | } 56 | 57 | return FXTRUE; 58 | } 59 | 60 | static FxBool 61 | fxUnmapLinear(FxU32 linear_addr, FxU32 length) 62 | { 63 | FxU32 cbReturned; 64 | 65 | return DeviceIoControl(hMemmapFile, 66 | (FxU32)IOCTL_MAPMEM_UNMAP_USER_PHYSICAL_MEMORY, 67 | &linear_addr, sizeof(PVOID), 68 | NULL, 0, 69 | &cbReturned, NULL); 70 | } 71 | 72 | static FxBool 73 | fxGetMSR(MSRInfo* in, MSRInfo* out) 74 | { 75 | ULONG retLen; 76 | 77 | return DeviceIoControl(hMemmapFile, (FxU32)IOCTL_MAPMEM_GET_MSR, 78 | in, sizeof(*in), 79 | out, sizeof(*out), 80 | &retLen, NULL); 81 | } 82 | 83 | static FxBool 84 | fxSetMSR(MSRInfo* in, MSRInfo* out) 85 | { 86 | ULONG retLen; 87 | 88 | return DeviceIoControl(hMemmapFile, (FxU32)IOCTL_MAPMEM_SET_MSR, 89 | in, sizeof(*in), 90 | out, sizeof(*out), 91 | &retLen, NULL); 92 | } 93 | 94 | static FxBool 95 | fxSetPermission(const FxU32 addrBase, const FxU32 addrLen, 96 | const FxBool writePermP) 97 | { 98 | return FXFALSE; 99 | } 100 | 101 | void kmdDrvInit(PDRVFUNC drv) 102 | { 103 | drv->Init = &fxlibInit; 104 | drv->Fini = &fxlibFini; 105 | drv->MapLinear = &fxMapLinear; 106 | drv->UnmapLinear = &fxUnmapLinear; 107 | drv->GetMSR = &fxGetMSR; 108 | drv->SetMSR = &fxSetMSR; 109 | drv->SetPermission = &fxSetPermission; 110 | } 111 | -------------------------------------------------------------------------------- /scripts/conf_wrapper: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | MKFILE=Makefile 4 | CROSS= 5 | CC=gcc 6 | CHECK_DEPS=" \ 7 | dirname \ 8 | gendef \ 9 | git \ 10 | grep \ 11 | head \ 12 | make \ 13 | sed \ 14 | shasum \ 15 | uname \ 16 | wc \ 17 | xxd \ 18 | " \ 19 | 20 | CC_CHECK=0 21 | CHECK_CC=" \ 22 | mingw32-$CC \ 23 | i686-w64-mingw32-$CC \ 24 | " \ 25 | 26 | echo -n "checking for which... " 27 | if [ ! -x /usr/bin/which ]; then 28 | echo not found 29 | exit 1 30 | fi 31 | echo $(which which) 32 | for i in $CHECK_DEPS; do 33 | echo -n "checking for $i... " 34 | if [ -z $(which $i 2>/dev/null) ]; then 35 | echo not found 36 | exit 1 37 | fi 38 | echo $(which $i) 39 | done 40 | if [ ! -z $1 ]; then 41 | MKFILE=$1 42 | fi 43 | if [ x`uname | sed "s/_.*//"` == xMINGW32 ]; then 44 | echo " MSYSTEM=$MSYSTEM" 45 | TARGET_CC=`gcc -v 2>&1 | grep ^Target` 46 | echo " $TARGET_CC" 47 | if expr "$TARGET_CC" : ".*\(\ i686.*mingw32\)" > /dev/null ||\ 48 | expr "$TARGET_CC" : ".*\(\ mingw32\)" > /dev/null; then 49 | CC_CHECK=1 50 | else 51 | echo "Error: Invalid CC target for WIN32" 52 | exit 1 53 | fi 54 | fi 55 | if [ x`uname` == xDarwin ] || [ x`uname` == xLinux ]; then 56 | echo " `uname` cross build" 57 | CC_CHECK=2 58 | fi 59 | if [ $CC_CHECK -eq 0 ]; then 60 | echo "Error: Unsupported cross build" 61 | if [ ! -z $MSYSTEM ]; then 62 | echo " Invalid MSYSTEM=$MSYSTEM" 63 | fi 64 | exit 1 65 | fi 66 | if [ $CC_CHECK -eq 2 ]; then 67 | for i in $CHECK_CC; do 68 | if [ ! -z $(which $i 2>/dev/null) ]; then 69 | CROSS=`which $i | sed "s/.*\///;s/$CC.*//"` 70 | echo " CROSS=$CROSS" 71 | echo " CC=$CC" 72 | fi 73 | done 74 | if [ -z $CROSS ]; then 75 | echo "Error: Supported cross build options not found" 76 | for j in $CHECK_CC; do 77 | echo " $j" | sed "s/\-$CC//" 78 | done 79 | exit 1 80 | fi 81 | fi 82 | if [ ! -f ../src/Makefile.in ]; then 83 | echo "Error: Missing ../src/Makefile.in" 84 | exit 1 85 | fi 86 | cat ../src/Makefile.in | sed "s/^\(CROSS=\).*/\1$CROSS/" > $MKFILE 87 | if [ $CC_CHECK -eq 2 ]; then 88 | sed -i -e "s/^\(RC=\)/\1\$(CROSS)/" $MKFILE 89 | sed -i -e "s/^\(STRIP=\)/\1\$(CROSS)/" $MKFILE 90 | sed -i -e "s/^\(DLLTOOL=\)/\1\$(CROSS)/" $MKFILE 91 | sed -i -e "s/^\(TOOLS=\)wglinfo.exe.*/\1/" $MKFILE 92 | sed -i -e "/.*MSYSTEM\"\ !=\ \"MINGW32\".*/d" $MKFILE 93 | fi 94 | DJGPP_DXE=`which {i586,i686}-pc-msdosdjgpp-gcc 2>/dev/null` 95 | DXE_X86=`echo $DJGPP_DXE | sed "s/.*bin\///;s/.pc\-msdosdjgpp.*//"` 96 | if [ -z $DJGPP_DXE ]; then 97 | echo -- DJGPP DXE not supported -- 98 | sed -i -e "/.*make\ \-C\ .*dxe/d" $MKFILE 99 | else 100 | echo " DXE "`$DJGPP_DXE -v 2>&1 | grep ^Target` 101 | sed -i -e "s/\(dxe\ OUTDIR.*\)/\1\ X86=$DXE_X86/" $MKFILE 102 | fi 103 | DOS32_OVL=`which wcc386 2>/dev/null` 104 | if [ -z $DOS32_OVL ]; then 105 | echo -- DOS32 OVL not supported -- 106 | sed -i -e "/.*make\ \-C\ .*ovl/d" $MKFILE 107 | else 108 | echo " OVL "`$DOS32_OVL | head -n 1` 109 | fi 110 | echo "conf_wrapper: creating $MKFILE" 111 | 112 | -------------------------------------------------------------------------------- /wrappers/fxlib/fxlib9x.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "fxlib.h" 3 | 4 | 5 | static FxU32 pciErrorCode; 6 | static HANDLE hMemmapFile; 7 | 8 | static FxBool fxlibFini(void) 9 | { 10 | FxBool 11 | retVal = (hMemmapFile != INVALID_HANDLE_VALUE); 12 | 13 | if (retVal) CloseHandle( hMemmapFile ); 14 | return retVal; 15 | } 16 | 17 | static FxBool fxlibInit(void) 18 | { 19 | hMemmapFile = CreateFile("\\\\.\\FXMEMMAP.VXD", 0, 0, NULL, 0, 20 | FILE_FLAG_DELETE_ON_CLOSE, NULL); 21 | if ( hMemmapFile == INVALID_HANDLE_VALUE ) { 22 | pciErrorCode = PCI_ERR_MEMMAPVXD; 23 | return FXFALSE; 24 | } 25 | 26 | return FXTRUE; 27 | } 28 | 29 | static FxBool 30 | fxMapLinear(FxU32 busNumber, FxU32 physical_addr, 31 | FxU32 *linear_addr, FxU32 *length) 32 | { 33 | FxU32 nret; 34 | FxU32 Physical [2]; /* Physical address[0] & size[1] */ 35 | FxU32 Linear [2]; /* Linear address[0] & size[1] */ 36 | LPDWORD pPhysical = Physical; 37 | LPDWORD pLinear = Linear; 38 | 39 | Physical[0] = physical_addr; 40 | Physical[1] = *length; 41 | 42 | DeviceIoControl(hMemmapFile, GETLINEARADDR, 43 | &pPhysical, sizeof(pPhysical), 44 | &pLinear, sizeof(pLinear), 45 | &nret, NULL); 46 | 47 | *linear_addr = Linear[0]; 48 | 49 | if ( nret == 0 ) { 50 | pciErrorCode = PCI_ERR_MEMMAP; 51 | return FXFALSE; 52 | } 53 | 54 | return FXTRUE; 55 | } 56 | 57 | static FxBool 58 | fxUnmapLinear(FxU32 linear_addr, FxU32 length) 59 | { 60 | FxU32 nret; 61 | 62 | return DeviceIoControl(hMemmapFile, DECREMENTMUTEX, 63 | NULL, 0, 64 | NULL, 0, 65 | &nret, NULL); 66 | } 67 | 68 | static FxBool 69 | fxGetMSR(MSRInfo* in, MSRInfo* out) 70 | { 71 | FxU32 nret; 72 | 73 | return DeviceIoControl( hMemmapFile, GETMSR, 74 | in, sizeof(*in), 75 | out, sizeof(*out), 76 | &nret, NULL); 77 | } 78 | 79 | static FxBool 80 | fxSetMSR(MSRInfo* in, MSRInfo* out) 81 | { 82 | FxU32 nret; 83 | 84 | return DeviceIoControl( hMemmapFile, SETMSR, 85 | in, sizeof(*in), 86 | out, sizeof(*out), 87 | &nret, NULL); 88 | } 89 | 90 | /* Ganked from vmm.h */ 91 | #define PC_USER 0x00040000 /* make the pages ring 3 accessible */ 92 | 93 | static FxBool 94 | fxSetPermission(const FxU32 addrBase, const FxU32 addrLen, 95 | const FxBool writePermP) 96 | { 97 | FxU32 vxdParamArray[] = { 98 | addrBase, 99 | addrLen, 100 | 0 101 | }; 102 | FxU32 nRet = 0; 103 | 104 | /* Set the user accessable bit. We don't dork w/ the 105 | * rest of the bits. 106 | */ 107 | vxdParamArray[2] = (writePermP ? PC_USER : 0); 108 | 109 | return DeviceIoControl(hMemmapFile, SETADDRPERM, 110 | vxdParamArray, sizeof(vxdParamArray), 111 | NULL, 0, 112 | &nRet, NULL); 113 | } 114 | 115 | void vxdDrvInit(PDRVFUNC drv) 116 | { 117 | drv->Init = &fxlibInit; 118 | drv->Fini = &fxlibFini; 119 | drv->MapLinear = &fxMapLinear; 120 | drv->UnmapLinear = &fxUnmapLinear; 121 | drv->GetMSR = &fxGetMSR; 122 | drv->SetMSR = &fxSetMSR; 123 | drv->SetPermission = &fxSetPermission; 124 | } 125 | -------------------------------------------------------------------------------- /wrappers/3dfx/drv/instdrv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fxlib.h" 4 | 5 | BOOL StopDriver(void) 6 | { 7 | SC_HANDLE hSCManager = NULL; 8 | SC_HANDLE hService = NULL; 9 | SERVICE_STATUS ServiceStatus; 10 | BOOL bRet = FALSE; 11 | 12 | hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 13 | 14 | if (hSCManager) { 15 | hService = OpenService(hSCManager, "MAPMEM", SERVICE_ALL_ACCESS); 16 | CloseServiceHandle(hSCManager); 17 | 18 | if (hService) { 19 | bRet = ControlService(hService, SERVICE_CONTROL_STOP, &ServiceStatus); 20 | CloseServiceHandle(hService); 21 | } 22 | } 23 | 24 | return bRet; 25 | } 26 | 27 | BOOL RemoveDriver(void) 28 | { 29 | SC_HANDLE hSCManager; 30 | SC_HANDLE hService; 31 | BOOL bRet = FALSE; 32 | 33 | StopDriver(); 34 | 35 | hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 36 | 37 | if (hSCManager) { 38 | hService = OpenService(hSCManager, "MAPMEM", SERVICE_ALL_ACCESS); 39 | CloseServiceHandle(hSCManager); 40 | 41 | if (hService) { 42 | bRet = DeleteService(hService); 43 | CloseServiceHandle(hService); 44 | } 45 | } 46 | 47 | return bRet; 48 | } 49 | 50 | BOOL InstallDriver(void) 51 | { 52 | SC_HANDLE hSCManager = NULL; 53 | SC_HANDLE hService = NULL; 54 | 55 | hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 56 | 57 | if (hSCManager) { 58 | hService = CreateService(hSCManager, 59 | "MAPMEM", "MAPMEM", 60 | SERVICE_ALL_ACCESS, 61 | SERVICE_KERNEL_DRIVER, 62 | SERVICE_AUTO_START, 63 | SERVICE_ERROR_NORMAL, 64 | "\%SystemRoot\%\\system32\\drivers\\fxptl.sys", 65 | NULL, NULL, NULL, NULL, NULL); 66 | 67 | CloseServiceHandle(hSCManager); 68 | } 69 | 70 | if (hService == NULL) 71 | return FALSE; 72 | CloseServiceHandle(hService); 73 | return TRUE; 74 | } 75 | 76 | BOOL StartDriver(void) 77 | { 78 | SC_HANDLE hSCManager; 79 | SC_HANDLE hService; 80 | BOOL bRet = FALSE; 81 | 82 | hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 83 | 84 | if (hSCManager) { 85 | hService = OpenService(hSCManager, "MAPMEM", SERVICE_ALL_ACCESS); 86 | CloseServiceHandle(hSCManager); 87 | 88 | if (hService) { 89 | bRet = StartService(hService, 0, NULL) || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING; 90 | CloseServiceHandle(hService); 91 | } 92 | } 93 | 94 | return bRet; 95 | } 96 | 97 | static volatile unsigned long *ptm; 98 | int main(int argc, char *argv[]) 99 | { 100 | (void)argc; (void)argv; 101 | DRVFUNC drv; 102 | OSVERSIONINFO osInfo = { .dwOSVersionInfoSize = sizeof(OSVERSIONINFO) }; 103 | unsigned long linear, length = 0x1000; 104 | 105 | GetVersionEx(&osInfo); 106 | if (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) 107 | kmdDrvInit(&drv); 108 | else { 109 | printf("Platform Id != WIN32_NT\n"); 110 | return 1; 111 | } 112 | 113 | RemoveDriver(); 114 | 115 | if (!InstallDriver()) 116 | return 1; 117 | printf("Driver installed\n"); 118 | if (!StartDriver()) 119 | return 1; 120 | printf("Driver started\n"); 121 | 122 | if (!drv.Init()) 123 | return 1; 124 | printf("fxLibInit OK\n"); 125 | 126 | if(!drv.MapLinear(0, 0xfbdff000, &linear, &length)) 127 | return 1; 128 | printf("fxMapLinear OK, %08lx\n", linear); 129 | 130 | ptm = (unsigned long *)linear; 131 | ptm[0xfbcU >> 2] = (0xa0UL << 12) | 0x243; 132 | 133 | 134 | drv.UnmapLinear(linear, length); 135 | drv.Fini(); 136 | 137 | return 0; 138 | } 139 | 140 | -------------------------------------------------------------------------------- /wrappers/fxlib/fxlib.h: -------------------------------------------------------------------------------- 1 | #ifndef FXLIB_H 2 | #define FXLIB_H 3 | 4 | #define FXTRUE 1 5 | #define FXFALSE 0 6 | 7 | #define GETLINEARADDR 2 8 | #define GETMSR 6 /* Get the contents of an MSR */ 9 | #define SETMSR 7 10 | #define DECREMENTMUTEX 8 11 | #define SETADDRPERM 10 12 | 13 | #define PCI_ERR_MEMMAPVXD 2 14 | #define PCI_ERR_MAPMEMDRV 3 15 | #define PCI_ERR_MEMMAP 16 16 | #define PCI_ERR_MAPMEM 17 17 | 18 | typedef int FxBool; 19 | typedef unsigned long FxU32; 20 | typedef struct { 21 | FxU32 22 | msrNum, /* Which MSR? */ 23 | msrLo, msrHi; /* MSR Values */ 24 | } MSRInfo; 25 | 26 | #ifdef small 27 | /* MSYS/MinGW.org headers #define small char */ 28 | #undef small 29 | #include 30 | #endif 31 | 32 | #ifndef _DDK_NTDDK_H 33 | typedef enum _INTERFACE_TYPE { 34 | InterfaceTypeUndefined = -1, 35 | Internal, 36 | Isa, 37 | Eisa, 38 | MicroChannel, 39 | TurboChannel, 40 | PCIBus, 41 | VMEBus, 42 | NuBus, 43 | PCMCIABus, 44 | CBus, 45 | MPIBus, 46 | MPSABus, 47 | ProcessorInternal, 48 | InternalPowerBus, 49 | PNPISABus, 50 | PNPBus, 51 | Vmcs, 52 | MaximumInterfaceType 53 | } INTERFACE_TYPE, *PINTERFACE_TYPE; 54 | #endif //_DDK_NTDDK_H 55 | 56 | #define FILE_DEVICE_MAPMEM 0x00008000 57 | // 58 | // Macro definition for defining IOCTL and FSCTL function control codes. Note 59 | // that function codes 0-2047 are reserved for Microsoft Corporation, and 60 | // 2048-4095 are reserved for customers. 61 | // 62 | #define MAPMEM_IOCTL_INDEX 0x800 63 | 64 | // 65 | // Define our own private IOCTL 66 | // 67 | #define IOCTL_MAPMEM_MAP_USER_PHYSICAL_MEMORY CTL_CODE(FILE_DEVICE_MAPMEM , \ 68 | MAPMEM_IOCTL_INDEX, \ 69 | METHOD_BUFFERED, \ 70 | FILE_ANY_ACCESS) 71 | 72 | #define IOCTL_MAPMEM_UNMAP_USER_PHYSICAL_MEMORY CTL_CODE(FILE_DEVICE_MAPMEM, \ 73 | MAPMEM_IOCTL_INDEX+1,\ 74 | METHOD_BUFFERED, \ 75 | FILE_ANY_ACCESS) 76 | 77 | #define IOCTL_MAPMEM_GET_MSR CTL_CODE(FILE_DEVICE_MAPMEM , \ 78 | MAPMEM_IOCTL_INDEX+2, \ 79 | METHOD_BUFFERED, \ 80 | FILE_ANY_ACCESS) 81 | 82 | #define IOCTL_MAPMEM_SET_MSR CTL_CODE(FILE_DEVICE_MAPMEM, \ 83 | MAPMEM_IOCTL_INDEX+3,\ 84 | METHOD_BUFFERED, \ 85 | FILE_ANY_ACCESS) 86 | 87 | typedef struct 88 | { 89 | INTERFACE_TYPE InterfaceType; // Isa, Eisa, etc.... 90 | ULONG BusNumber; // Bus number 91 | LARGE_INTEGER BusAddress; // Bus-relative address 92 | ULONG AddressSpace; // 0 is memory, 1 is I/O 93 | ULONG Length; // Length of section to map 94 | 95 | } 96 | PHYSICAL_MEMORY_INFO, *PPHYSICAL_MEMORY_INFO; 97 | 98 | typedef struct DrvFuncTbl { 99 | FxBool (*Init)(void); 100 | FxBool (*Fini)(void); 101 | FxBool (*MapLinear)(FxU32, FxU32, FxU32 *, FxU32 *); 102 | FxBool (*UnmapLinear)(FxU32, FxU32); 103 | FxBool (*SetMSR)(MSRInfo *, MSRInfo *); 104 | FxBool (*GetMSR)(MSRInfo *, MSRInfo *); 105 | FxBool (*SetPermission)(const FxU32, const FxU32, const FxBool); 106 | } DRVFUNC, * PDRVFUNC; 107 | 108 | void vxdDrvInit(PDRVFUNC); 109 | void kmdDrvInit(PDRVFUNC); 110 | /* fxhook.c */ 111 | void HookEntryHook(unsigned int *, const unsigned int); 112 | void HookParseRange(unsigned int *, unsigned int **, unsigned int *); 113 | void HookTimeGetTime(const unsigned int); 114 | void HookGetTimeModAddr(const SYSTEM_INFO *, const DWORD, const unsigned int); 115 | /* fxhpat.c */ 116 | void HookPatchfxCompat(const DWORD); 117 | 118 | #endif // FXLIB_H 119 | 120 | -------------------------------------------------------------------------------- /virgil3d/0001-Virgil3D-with-SDL2-OpenGL.patch: -------------------------------------------------------------------------------- 1 | diff -Nru ../orig/qemu-8.2.1/include/ui/egl-helpers.h ./include/ui/egl-helpers.h 2 | --- ../orig/qemu-8.2.1/include/ui/egl-helpers.h 3 | +++ ./include/ui/egl-helpers.h 4 | @@ -2,7 +2,15 @@ 5 | #define EGL_HELPERS_H 6 | 7 | #include 8 | +#ifdef CONFIG_EGL 9 | #include 10 | +#else 11 | +typedef int EGLConfig; 12 | +typedef int EGLContext; 13 | +typedef int EGLDisplay; 14 | +typedef int EGLNativeWindowType; 15 | +typedef int EGLSurface; 16 | +#endif 17 | #ifdef CONFIG_GBM 18 | #include 19 | #endif 20 | diff -Nru ../orig/qemu-8.2.1/meson.build ./meson.build 21 | --- ../orig/qemu-8.2.1/meson.build 22 | +++ ./meson.build 23 | @@ -1431,12 +1431,14 @@ 24 | required: get_option('coreaudio')) 25 | endif 26 | 27 | +egl = not_found 28 | opengl = not_found 29 | if not get_option('opengl').auto() or have_system or have_vhost_user_gpu 30 | epoxy = dependency('epoxy', method: 'pkg-config', 31 | required: get_option('opengl')) 32 | + opengl = epoxy 33 | if cc.has_header('epoxy/egl.h', dependencies: epoxy) 34 | - opengl = epoxy 35 | + egl = epoxy 36 | elif get_option('opengl').enabled() 37 | error('epoxy/egl.h not found') 38 | endif 39 | @@ -2122,6 +2124,7 @@ 40 | endif 41 | config_host_data.set('CONFIG_CURL', curl.found()) 42 | config_host_data.set('CONFIG_CURSES', curses.found()) 43 | +config_host_data.set('CONFIG_EGL', egl.found()) 44 | config_host_data.set('CONFIG_GBM', gbm.found()) 45 | config_host_data.set('CONFIG_GIO', gio.found()) 46 | config_host_data.set('CONFIG_GLUSTERFS', glusterfs.found()) 47 | @@ -4369,6 +4372,7 @@ 48 | summary_info += {'libusb': libusb} 49 | summary_info += {'usb net redir': usbredir} 50 | summary_info += {'OpenGL support (epoxy)': opengl} 51 | +summary_info += {'EGL': egl} 52 | summary_info += {'GBM': gbm} 53 | summary_info += {'libiscsi support': libiscsi} 54 | summary_info += {'libnfs support': libnfs} 55 | diff -Nru ../orig/qemu-8.2.1/ui/egl-helpers.c ./ui/egl-helpers.c 56 | --- ../orig/qemu-8.2.1/ui/egl-helpers.c 57 | +++ ./ui/egl-helpers.c 58 | @@ -33,6 +33,7 @@ 59 | 60 | const char *qemu_egl_get_error_string(void) 61 | { 62 | +#ifdef CONFIG_EGL 63 | EGLint error = eglGetError(); 64 | 65 | switch (error) { 66 | @@ -69,6 +70,9 @@ 67 | default: 68 | return "Unknown EGL error"; 69 | } 70 | +#else 71 | + return "Unknown error"; 72 | +#endif //CONFIG_EGL 73 | } 74 | 75 | static void egl_fb_delete_texture(egl_fb *fb) 76 | @@ -394,6 +398,8 @@ 77 | 78 | /* ---------------------------------------------------------------------- */ 79 | 80 | +#ifdef CONFIG_EGL 81 | + 82 | EGLSurface qemu_egl_init_surface_x11(EGLContext ectx, EGLNativeWindowType win) 83 | { 84 | EGLSurface esurface; 85 | @@ -661,3 +667,5 @@ 86 | display_opengl = 1; 87 | return true; 88 | } 89 | + 90 | +#endif //#ifdef CONFIG_EGL 91 | diff -Nru ../orig/qemu-8.2.1/ui/meson.build ./ui/meson.build 92 | --- ../orig/qemu-8.2.1/ui/meson.build 93 | +++ ./ui/meson.build 94 | @@ -62,13 +62,15 @@ 95 | opengl_ss = ss.source_set() 96 | opengl_ss.add(gbm, pixman) 97 | opengl_ss.add(when: [opengl], 98 | - if_true: files('shader.c', 'console-gl.c', 'egl-helpers.c', 'egl-context.c')) 99 | + if_true: files('shader.c', 'console-gl.c', 'egl-helpers.c')) 100 | + opengl_ss.add(when: [opengl, egl], 101 | + if_true: files('egl-context.c')) 102 | ui_modules += {'opengl' : opengl_ss} 103 | endif 104 | 105 | if opengl.found() 106 | egl_headless_ss = ss.source_set() 107 | - egl_headless_ss.add(when: [opengl, pixman], 108 | + egl_headless_ss.add(when: [opengl, egl, pixman], 109 | if_true: [files('egl-headless.c'), gbm]) 110 | ui_modules += {'egl-headless' : egl_headless_ss} 111 | endif 112 | @@ -114,8 +116,8 @@ 113 | gtk_ss.add(files('gtk-clipboard.c')) 114 | endif 115 | gtk_ss.add(when: x11, if_true: files('x_keymap.c')) 116 | - gtk_ss.add(when: opengl, if_true: files('gtk-gl-area.c')) 117 | - gtk_ss.add(when: [x11, opengl], if_true: files('gtk-egl.c')) 118 | + gtk_ss.add(when: [opengl, egl], if_true: files('gtk-gl-area.c')) 119 | + gtk_ss.add(when: [x11, opengl, egl], if_true: files('gtk-egl.c')) 120 | ui_modules += {'gtk' : gtk_ss} 121 | endif 122 | 123 | -------------------------------------------------------------------------------- /qemu-0/hw/3dfx/glide2x_impl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU 3Dfx Glide Pass-Through 3 | * 4 | * Copyright (c) 2018-2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #ifndef GLIDE2X_IMPL_H 22 | #define GLIDE2X_IMPL_H 23 | 24 | #include 25 | 26 | #include "glidewnd.h" 27 | #include "g2xfuncs.h" 28 | #include "szgrdata.h" 29 | 30 | #define GLIDEPT_MM_BASE 0xfbdff000 31 | 32 | #define GR_RESOLUTION_320x200 0x0 33 | #define GR_RESOLUTION_320x240 0x1 34 | #define GR_RESOLUTION_400x256 0x2 35 | #define GR_RESOLUTION_512x384 0x3 36 | #define GR_RESOLUTION_640x200 0x4 37 | #define GR_RESOLUTION_640x350 0x5 38 | #define GR_RESOLUTION_640x400 0x6 39 | #define GR_RESOLUTION_640x480 0x7 40 | #define GR_RESOLUTION_800x600 0x8 41 | #define GR_RESOLUTION_960x720 0x9 42 | #define GR_RESOLUTION_856x480 0xa 43 | #define GR_RESOLUTION_512x256 0xb 44 | #define GR_RESOLUTION_1024x768 0xC 45 | #define GR_RESOLUTION_1280x1024 0xD 46 | #define GR_RESOLUTION_1600x1200 0xE 47 | #define GR_RESOLUTION_400x300 0xF 48 | 49 | #define GR_TEXTABLE_PALETTE 0x2 50 | 51 | #define GR_TEXFMT_YIQ_422 0x1 52 | #define GR_TEXFMT_P_8 0x5 /* 8-bit palette */ 53 | #define GR_TEXFMT_AYIQ_8422 0x9 54 | #define GR_TEXFMT_AP_88 0xe /* 8-bit alpha 8-bit palette */ 55 | 56 | #define GR_CONTROL_ACTIVATE 0x1 57 | #define GR_CONTROL_DEACTIVATE 0x2 58 | #define GR_PASSTHRU_SHOW_SST1 0x1 59 | #define GR_PASSTHRU_SHOW_VGA 0x0 60 | #define GR_PASSTHRU 0x3 61 | 62 | typedef struct { 63 | uint32_t small; 64 | uint32_t large; 65 | uint32_t aspect; 66 | uint32_t format; 67 | void *data; 68 | } wrTexInfo; 69 | 70 | typedef struct { 71 | uint32_t small; 72 | uint32_t large; 73 | uint32_t aspect; 74 | uint32_t format; 75 | uint32_t data; 76 | } wrgTexInfo; 77 | 78 | typedef struct { 79 | uint32_t width, height; 80 | uint32_t small, large; 81 | uint32_t aspect; 82 | uint32_t format; 83 | } wr3dfHeader; 84 | 85 | typedef struct { 86 | uint8_t header[SIZE_GU3DFHEADER]; 87 | uint8_t table[SIZE_GUTEXTABLE]; 88 | void *data; 89 | uint32_t mem_required; 90 | } wr3dfInfo; 91 | 92 | typedef struct { 93 | uint8_t header[SIZE_GU3DFHEADER]; 94 | uint8_t table[SIZE_GUTEXTABLE]; 95 | uint32_t data; 96 | uint32_t mem_required; 97 | } wrg3dfInfo; 98 | 99 | typedef struct { 100 | wr3dfInfo *info3df; 101 | wrTexInfo *texInfo; 102 | void *fbuf; 103 | uint32_t flen; 104 | } wrTexStruct; 105 | 106 | typedef struct { 107 | int size; 108 | void *lfbPtr; 109 | uint32_t stride; 110 | uint32_t writeMode; 111 | uint32_t origin; 112 | } wrLfbInfo; 113 | 114 | typedef struct { 115 | int size; 116 | uint32_t lfbPtr; 117 | uint32_t stride; 118 | uint32_t writeMode; 119 | uint32_t origin; 120 | } wrgLfbInfo; 121 | 122 | int GRFEnumArgsCnt(int); 123 | uint32_t texTableValid(uint32_t); 124 | uint32_t wrReadRegion(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t arg5, uintptr_t arg6); 125 | uint32_t wrWriteRegion(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t arg5, uint32_t arg6, uintptr_t arg7); 126 | uintptr_t wrGetProcAddress(uintptr_t); 127 | const char *wrGetString(uint32_t); 128 | const char *getGRFuncStr(int); 129 | 130 | #ifndef CONSOLE_H 131 | void glide_renderer_stat(const int); 132 | #endif //CONSOLE_H 133 | void doGlideFunc(int, uint32_t *, uintptr_t *, uintptr_t *, int); 134 | void conf_glide2x(const uint32_t, const int); 135 | void cwnd_glide2x(void *, void *, void *); 136 | int init_glide2x(const char *); 137 | void fini_glide2x(void); 138 | int init_g3ext(void); 139 | 140 | #endif // GLIDE2X_IMPL_H 141 | 142 | -------------------------------------------------------------------------------- /wrappers/3dfx/ovl/clib.h: -------------------------------------------------------------------------------- 1 | #ifndef CLIB_H 2 | #define CLIB_H 3 | 4 | #ifndef UINT32_MAX 5 | #define UINT32_MAX 0xffffffffU 6 | #endif 7 | typedef unsigned char uint8_t; 8 | typedef unsigned short uint16_t; 9 | typedef unsigned uint32_t; 10 | typedef unsigned long FxU32; 11 | typedef int FxBool; 12 | 13 | void _dxe_putc(int c) 14 | { 15 | __asm 16 | { 17 | mov dx, 0x3F8; 18 | mov eax, c; 19 | out dx, al; 20 | } 21 | } 22 | 23 | static unsigned getTickAcpi(void) 24 | { 25 | static unsigned tick; 26 | unsigned tickAcpi; 27 | 28 | __asm 29 | { 30 | mov dx, 0x608; 31 | in eax, dx; 32 | mov tickAcpi, eax; 33 | } 34 | 35 | if ((tick & 0x00FFFFFFU) > tickAcpi) 36 | tick = (((tick >> 24) + 1) << 24) | tickAcpi; 37 | else 38 | tick = (tick & 0xFF000000U) | tickAcpi; 39 | #define TICK_ACPI 0x369E99U /* 3.579545 MHz */ 40 | return tick; 41 | } 42 | 43 | static unsigned getDosPSPSeg(void) 44 | { 45 | unsigned segPSP; 46 | 47 | __asm 48 | { 49 | mov ah, 0x62; /* Get PSP selector */ 50 | int 0x21; 51 | mov ax, 0x06; /* Get selector base */ 52 | int 0x31; 53 | movzx eax, cx; 54 | shl eax, 0x10; 55 | mov ax, dx; 56 | mov segPSP, eax; 57 | } 58 | 59 | return segPSP; 60 | } 61 | 62 | static void memcpy(const void *s1, const void *s2, unsigned n) 63 | { 64 | int i = 0; 65 | char *dst = (char *)s1, *src = (char *)s2; 66 | for (; i < n; i++) 67 | dst[i] = src[i]; 68 | } 69 | 70 | static void memset(const void *s1, const char c, unsigned n) 71 | { 72 | int i = 0; 73 | char *dst = (char *)s1; 74 | for (; i < n; i++) 75 | dst[i] = c; 76 | } 77 | 78 | static int strncmp(const char *s1, const char *s2, unsigned n) 79 | { 80 | if (n == 0) 81 | return (0); 82 | do { 83 | if (*s1 != *s2++) 84 | return (*(unsigned char *)s1 - *(unsigned char *)--s2); 85 | if (*s1++ == 0) 86 | break; 87 | } while (--n != 0); 88 | return (0); 89 | } 90 | 91 | static int strnlen(const char *s, unsigned n) 92 | { 93 | int i; 94 | if (n == 0) 95 | return (0); 96 | for (i = 0; i < n; i++) { 97 | if (s[i] == 0) 98 | break; 99 | } 100 | return i; 101 | } 102 | 103 | static char *basename(const char *name) 104 | { 105 | int i = 0; 106 | char *p = (char *)name; 107 | while (name[i++]); 108 | for (--i; i > 0; i--) { 109 | if ((name[i] == '/') || (name[i] == '\\')) 110 | break; 111 | } 112 | return (i)? (p + i + 1):p; 113 | } 114 | 115 | static int open(const char *path) 116 | { 117 | int retval, err; 118 | 119 | __asm 120 | { 121 | mov eax, 0x3d00; 122 | mov edx, path; 123 | int 0x21; 124 | mov retval, eax; 125 | setc al; 126 | movzx eax, al; 127 | mov err, eax 128 | } 129 | 130 | if (err) 131 | retval = -1; 132 | 133 | return retval; 134 | } 135 | 136 | static int close(int handle) 137 | { 138 | int err; 139 | 140 | __asm 141 | { 142 | mov eax, 0x3e00; 143 | mov ebx, handle; 144 | int 0x21; 145 | setc al; 146 | movzx eax, al; 147 | mov err, eax; 148 | } 149 | 150 | if (err) 151 | return -1; 152 | return 0; 153 | } 154 | 155 | static int fsize(int handle) 156 | { 157 | int retval; 158 | 159 | __asm 160 | { 161 | mov eax, 0x4202; 162 | mov ebx, handle; 163 | xor ecx, ecx; 164 | xor edx, edx; 165 | int 0x21; 166 | shl edx, 0x10; 167 | add eax, edx 168 | mov retval, eax; 169 | mov eax, 0x4200; 170 | xor ecx, ecx 171 | xor edx, edx; 172 | int 0x21; 173 | } 174 | 175 | return retval; 176 | } 177 | 178 | static int read(int handle, void *buf, unsigned size) 179 | { 180 | int retval; 181 | 182 | __asm 183 | { 184 | mov eax, 0x3f00; 185 | mov ebx, handle; 186 | mov ecx, size; 187 | mov edx, buf; 188 | int 0x21; 189 | mov retval, eax; 190 | } 191 | 192 | return retval; 193 | } 194 | 195 | static INLINE uint32_t f2u32(const float f) 196 | { 197 | uint32_t u32; 198 | char *s = (char *)&f; 199 | char *d = (char *)&u32; 200 | 201 | *d++ = *s++; 202 | *d++ = *s++; 203 | *d++ = *s++; 204 | *d++ = *s++; 205 | 206 | return u32; 207 | } 208 | 209 | static void *MapPhysToLin(void *physaddr, unsigned int size) 210 | { 211 | void *linaddr; 212 | unsigned int l = size; 213 | 214 | __asm 215 | { 216 | push ebx; 217 | push esi; 218 | push edi; 219 | mov bx, WORD PTR [physaddr + 2] 220 | mov cx, WORD PTR [physaddr] 221 | mov si, WORD PTR [l + 2] 222 | mov di, WORD PTR [l] 223 | 224 | // Call DPMI function MapPhysicalToLinear (0x800) 225 | mov ax, 800h 226 | int 31h 227 | 228 | jnc success 229 | xor bx, bx 230 | xor cx, cx 231 | success: 232 | mov WORD PTR [linaddr + 2], bx 233 | mov WORD PTR [linaddr], cx 234 | pop edi; 235 | pop esi; 236 | pop ebx; 237 | } 238 | 239 | return linaddr; 240 | } 241 | 242 | static FxBool fxMapLinear(FxU32 busNumber, FxU32 physical_addr, FxU32 *linear_addr, FxU32 *length) 243 | { 244 | *linear_addr = (FxU32)MapPhysToLin((void *)physical_addr, *length); 245 | if (*linear_addr == 0) 246 | return 0; 247 | return 1; 248 | } 249 | 250 | #endif //CLIB_H 251 | 252 | -------------------------------------------------------------------------------- /wrappers/3dfx/src/Makefile.in: -------------------------------------------------------------------------------- 1 | QEMU_SRC_DIR=../../../qemu-0 2 | FXLIB=../../fxlib 3 | GIT=$(shell git rev-parse --short HEAD | sed "s/\(.*\)/\1\-/") 4 | CROSS= 5 | CC=$(CROSS)gcc 6 | RC=windres 7 | DLLTOOL=dlltool 8 | STRIP=strip 9 | CFLAGS=-march=x86-64-v2 -mtune=generic -mfpmath=sse -O3 10 | CFLAGS+=-pipe -I$(QEMU_SRC_DIR)/hw/3dfx -I$(FXLIB) -D__REV__=\"$(GIT)\" -Wall -Werror -flto=auto -fomit-frame-pointer 11 | LDFLAGS=-static-libgcc 12 | LDFLAGS+=-Wl,--disable-auto-image-base,--no-seh,--dynamicbase,--nxcompat 13 | SRCDIR=../src 14 | TARGET1=glide.dll 15 | TARGET2=glide2x.dll 16 | TARGET3=glide3x.dll 17 | GENDEF=gendef 18 | OUTDIR=$(shell basename `pwd`) 19 | 20 | PCINOOP=\ 21 | Close@0 \ 22 | DeviceExists@4 \ 23 | FindCard@12 \ 24 | FindCardMulti@16 \ 25 | FindFreeMTRR@4 \ 26 | FindMTRRMatch@16 \ 27 | GetConfigData@20 \ 28 | MapCard@20 \ 29 | MapCardMulti@24 \ 30 | MapPhysicalToLinear@12 \ 31 | Open@0 \ 32 | SetConfigData@20 \ 33 | SetMTRR@16 \ 34 | UnmapPhysical@8 \ 35 | 36 | C_OBJS:=\ 37 | fxhook.o \ 38 | fxhpat.o \ 39 | fxlib9x.o \ 40 | fxlibnt.o \ 41 | fxtime.o \ 42 | md5.o \ 43 | 44 | 45 | all: fxlib $(TARGET1) $(TARGET2) $(TARGET3) exports-check fxdrv 46 | 47 | fxdrv: 48 | @make -C ../dxe OUTDIR=$(OUTDIR) 49 | @make -C ../ovl OUTDIR=$(OUTDIR) 50 | @make -C ../drv OUTDIR=$(OUTDIR) CROSS=$(CROSS) 51 | 52 | exports-check: $(TARGET1) $(TARGET2) $(TARGET3) 53 | @if [ $$(objdump -x $(TARGET2) | grep "\[[\ 0-9]*\]" | grep -v "^\[" | \ 54 | grep -v -e reloc -e Export\ RVA | wc -l) -ne 144 ] || \ 55 | [ $$(objdump -x $(TARGET1) | grep "\[[\ 0-9]*\]" | grep -v "^\[" | \ 56 | grep -v -e reloc -e Export\ RVA | wc -l) -ne 131 ] || \ 57 | [ $$(objdump -x $(TARGET3) | grep "\[[\ 0-9]*\]" | grep -v "^\[" | \ 58 | grep -v -e reloc -e Export\ RVA | wc -l) -ne 94 ]; \ 59 | then exit 1; fi 60 | 61 | $(TARGET2): $(C_OBJS) pciNoop.o glidedll.o 62 | @echo " CFLAGS $(CFLAGS)" 63 | @echo " LDFLAGS $(LDFLAGS)" 64 | @echo " RC $(@:.dll=_res.o)" 65 | @$(RC) -Jrc -Ocoff -DGLIDE2 -o $(@:.dll=_res.o) ../src/version.rc 66 | @$(CC) -shared $(CFLAGS) -o $@ $+ $(LDFLAGS) 67 | @$(GENDEF) - $@ | sed "s/\(@[0-9]*\)@.*/\1/;s/\(^.*@[0-9]*\)/_\1\ =\ \1/" | \ 68 | sed "s/\ ;\ Check!!!.*//" | \ 69 | grep -e ^LIB -e ^EXP -e " = " > $(@:.dll=.def) 70 | @echo " LD $@" 71 | @$(CC) -shared $(CFLAGS) -o $@ $(@:dll=def) $(@:.dll=_res.o) $+ $(LDFLAGS) 72 | @$(GENDEF) - $@ | sed "s/\(@[0-9]*\)@.*/\1/;s/^_//" > lib$(@:dll=def) 73 | @$(DLLTOOL) -U -d lib$(@:dll=def) -l lib$@.a 74 | 75 | $(TARGET1): $(C_OBJS) gl211dll.o 76 | @echo " CFLAGS $(CFLAGS)" 77 | @echo " LDFLAGS $(LDFLAGS)" 78 | @echo " RC $(@:.dll=_res.o)" 79 | @$(RC) -Jrc -Ocoff -DGLIDE1 -o $(@:.dll=_res.o) ../src/version.rc 80 | @$(CC) -shared $(CFLAGS) -o $@ $+ $(LDFLAGS) 81 | @$(GENDEF) - $@ | sed "s/\(@[0-9]*\)@.*/\1/;s/\(^.*@[0-9]*\)/_\1\ =\ \1/" | \ 82 | sed "s/\ ;\ Check!!!.*//" | \ 83 | grep -e ^LIB -e ^EXP -e " = " > $(@:.dll=.def) 84 | @echo " LD $@" 85 | @$(CC) -shared $(CFLAGS) -o $@ $(@:dll=def) $(@:.dll=_res.o) $+ $(LDFLAGS) 86 | 87 | $(TARGET3): $(C_OBJS) gl301dll.o 88 | @echo " CFLAGS $(CFLAGS)" 89 | @echo " LDFLAGS $(LDFLAGS)" 90 | @echo " RC $(@:.dll=_res.o)" 91 | @$(RC) -Jrc -Ocoff -DGLIDE3 -o $(@:.dll=_res.o) ../src/version.rc 92 | @$(CC) -shared $(CFLAGS) -o $@ $+ $(LDFLAGS) 93 | @$(GENDEF) - $@ | sed "s/\(@[0-9]*\)@.*/\1/;s/\(^.*@[0-9]*\)/_\1\ =\ \1/" | \ 94 | sed "s/\ ;\ Check!!!.*//" | \ 95 | grep -e ^LIB -e ^EXP -e " = " > $(@:.dll=.def) 96 | @echo " LD $@" 97 | @$(CC) -shared $(CFLAGS) -o $@ $(@:dll=def) $(@:.dll=_res.o) $+ $(LDFLAGS) 98 | @$(GENDEF) - $@ | sed "s/\(@[0-9]*\)@.*/\1/;s/^_//" > lib$(@:dll=def) 99 | @$(DLLTOOL) -U -d lib$(@:dll=def) -l lib$@.a 100 | 101 | fxlib: 102 | @if [ "$$MSYSTEM" != "MINGW32" ]; then echo "Error: MSYSTEM == $$MSYSTEM"; exit 1; fi 103 | @echo " CC $(C_OBJS)" 104 | @for i in $(C_OBJS); do \ 105 | $(CC) $(CFLAGS) -c -o $$i $(FXLIB)/`echo $$i | sed "s/\.o/\.c/"`; \ 106 | done 107 | 108 | pciNoop.o: 109 | @echo "#include " > $(@:.o=.c) 110 | @echo "#define PT_CALL __stdcall" >> $(@:.o=.c) 111 | @for i in $(PCINOOP); do \ 112 | ARGS=`echo $$i | sed "s/.*@//"`; \ 113 | FUNC=`echo $$i | sed "s/@[0-9]*//"`; \ 114 | printf "%s" "void PT_CALL pci$$FUNC(" >>$(@:.o=.c); \ 115 | if [ $$ARGS -eq 0 ]; then printf "%s" "void" >>$(@:.o=.c); \ 116 | else printf "%s" "uint32_t arg0" >>$(@:.o=.c); \ 117 | if [ $$(((ARGS>>2)-1)) -ne 0 ]; then \ 118 | for j in $$(seq 1 $$(((ARGS>>2)-1))); do \ 119 | printf "%s" ", uint32_t arg$$j" >>$(@:.o=.c); \ 120 | done; fi; \ 121 | fi; printf "%s\n" ") { }" >>$(@:.o=.c); \ 122 | done 123 | @echo " CC $@" 124 | @$(CC) -c -o $@ $(@:.o=.c) 125 | 126 | %.o: $(SRCDIR)/%.c 127 | @echo " CC $@" 128 | @$(CC) $(CFLAGS) -c -o $@ $< 129 | 130 | clean: 131 | @make -C ../dxe $@ 132 | @make -C ../ovl $@ 133 | @rm -f *.[co] *.def 134 | @if [ ! -z "$$(find . | grep "\.dll\.a$$")" ]; then \ 135 | $(STRIP) --strip-unneeded *.dll *.a; \ 136 | sh -c 'ls -l glide*'; fi 137 | 138 | distclean: clean 139 | @make -C ../dxe $@ OUTDIR=$(OUTDIR) 140 | @make -C ../ovl $@ OUTDIR=$(OUTDIR) 141 | @rm -f $(TARGET1) $(TARGET2) $(TARGET3) *.a *.vxd *.sys *.exe *.zip 142 | 143 | -------------------------------------------------------------------------------- /wrappers/3dfx/dxe/clib.h: -------------------------------------------------------------------------------- 1 | #ifndef CLIB_H 2 | #define CLIB_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | typedef unsigned char uint8_t; 14 | typedef unsigned uint32_t; 15 | typedef unsigned long FxU32; 16 | typedef int FxBool; 17 | 18 | void _dxe_putc(int c) { outportb(0x3f8, (c & 0xFF)); } 19 | 20 | static int open(const char *path) 21 | { 22 | int retval; 23 | 24 | int dos_segment, dos_selector; 25 | 26 | if ((dos_segment=__dpmi_allocate_dos_memory((0x40 >> 4), &dos_selector)) == -1) 27 | return -1; 28 | movedata(_my_ds(), (unsigned int)path, dos_selector, 0, 0x40); 29 | 30 | __dpmi_regs r; 31 | 32 | r.x.ax = 0x3D00; 33 | r.x.dx = 0; 34 | r.x.ds = dos_segment; 35 | __dpmi_int(0x21, &r); 36 | if ( r.x.flags & 1 ) 37 | retval = -1; 38 | retval = r.x.ax; 39 | 40 | __dpmi_free_dos_memory(dos_selector); 41 | DPRINTF("%s opened handle %d\r\n", path, retval); 42 | 43 | return retval; 44 | } 45 | 46 | static int close(int handle) 47 | { 48 | __dpmi_regs r; 49 | 50 | r.h.ah = 0x3E; 51 | r.x.bx = handle; 52 | __dpmi_int(0x21, &r); 53 | if ( r.x.flags & 1 ) 54 | return -1; 55 | return 0; 56 | } 57 | 58 | static int fsize(int handle) 59 | { 60 | int retval; 61 | __dpmi_regs r; 62 | 63 | r.x.ax = 0x4202; 64 | r.x.bx = handle; 65 | r.x.cx = 0; 66 | r.x.dx = 0; 67 | __dpmi_int(0x21, &r); 68 | 69 | retval = ((int)r.x.dx << 0x10) + r.x.ax; 70 | 71 | r.x.ax = 0x4200; 72 | r.x.bx = handle; 73 | r.x.cx = 0; 74 | r.x.dx = 0; 75 | __dpmi_int(0x21, &r); 76 | 77 | DPRINTF("handle %d fsize %x\r\n", handle, retval); 78 | 79 | return retval; 80 | } 81 | 82 | static unsigned int _dxe_read(int handle, void *buffer, unsigned int count, unsigned int *result) 83 | { 84 | __dpmi_regs r; 85 | int dos_segment; 86 | int dos_selector; 87 | unsigned int dos_buffer_size, read_size; 88 | unsigned char *p_buffer; 89 | 90 | /* Allocate ~64K or less transfer buffer from DOS */ 91 | dos_buffer_size = ( count < 0xFFE0 ) ? count : 0xFFE0; 92 | if ( (dos_segment=__dpmi_allocate_dos_memory((dos_buffer_size + 15) >> 4, &dos_selector)) == -1 ) 93 | { 94 | return 8; 95 | } 96 | 97 | /* Reads blocks of file and transfers these into user buffer. */ 98 | p_buffer = buffer; 99 | *result = 0; 100 | while( count ) 101 | { 102 | read_size = ( count < dos_buffer_size ) ? count : dos_buffer_size; 103 | r.h.ah = 0x3F; 104 | r.x.bx = handle; 105 | r.x.cx = read_size; 106 | r.x.ds = dos_segment; 107 | r.x.dx = 0; 108 | __dpmi_int(0x21, &r); 109 | if ( r.x.flags & 1 ) 110 | { 111 | __dpmi_free_dos_memory(dos_selector); 112 | return r.x.ax; 113 | } 114 | if ( r.x.ax ) 115 | movedata(dos_selector, 0, _my_ds(), (unsigned int)p_buffer, r.x.ax); 116 | count -= read_size; 117 | p_buffer += r.x.ax; 118 | *result += r.x.ax; 119 | DPRINTF("read chunk %x\r\n", read_size); 120 | } 121 | 122 | /* Frees allocated DOS transfer buffer. */ 123 | __dpmi_free_dos_memory(dos_selector); 124 | return 0; 125 | } 126 | 127 | 128 | static int read(int handle, void *buf, unsigned size) 129 | { 130 | int retval, err; 131 | (void)err; 132 | 133 | err = _dxe_read(handle, buf, size, (unsigned int *)&retval); 134 | DPRINTF("_dxe_read %d\r\n", err); 135 | 136 | return retval; 137 | } 138 | 139 | static INLINE uint32_t f2u32(const float f) 140 | { 141 | uint32_t u32; 142 | char *s = (char *)&f; 143 | char *d = (char *)&u32; 144 | 145 | *d++ = *s++; 146 | *d++ = *s++; 147 | *d++ = *s++; 148 | *d++ = *s++; 149 | 150 | return u32; 151 | } 152 | 153 | static int *_ptr_djgpp_base_address; 154 | static int *_ptr_djgpp_selector_limit; 155 | static unsigned short *_ptr_djgpp_ds_alias; 156 | static int *_ptr_crt0_startup_flags; 157 | 158 | static void _dxe_sync(void) 159 | { 160 | *_ptr_crt0_startup_flags = _crt0_startup_flags; 161 | } 162 | 163 | static int _dxe_crt0(void) 164 | { 165 | unsigned long p; 166 | 167 | for (p = 0x1000; p < 0x4000; p+=4) { 168 | if ((0xd189cb8c == _farpeekl(_my_cs(), p)) && 169 | (0xcd10e9c1 == _farpeekl(_my_cs(), (p + 0x04)))) 170 | break; 171 | } 172 | 173 | if (0x4000 == p) 174 | return 1; 175 | 176 | _ptr_djgpp_base_address = (int *)_farpeekl(_my_cs(), (p + 0x33)); 177 | _ptr_djgpp_selector_limit = (int *)_farpeekl(_my_cs(), (p + 0x42)); 178 | _ptr_djgpp_ds_alias = (unsigned short *)_farpeekl(_my_cs(), (p + 0x21)); 179 | _ptr_crt0_startup_flags = (int *)_farpeekl(_my_cs(), (p + 0x0b)); 180 | 181 | __djgpp_base_address = *_ptr_djgpp_base_address; 182 | __djgpp_selector_limit = *_ptr_djgpp_selector_limit; 183 | __djgpp_ds_alias = *_ptr_djgpp_ds_alias; 184 | _crt0_startup_flags = *_ptr_crt0_startup_flags; 185 | 186 | return 0; 187 | } 188 | 189 | static void *MapPhysToLin(void *physaddr, unsigned int size) 190 | { 191 | void *linaddr; 192 | 193 | __dpmi_meminfo mi; 194 | mi.address = (unsigned long)physaddr; 195 | mi.size = size; 196 | 197 | if (_dxe_crt0()) 198 | return NULL; 199 | if ((_crt0_startup_flags & _CRT0_FLAG_NEARPTR) == 0) { 200 | if (__djgpp_nearptr_enable() == 0) 201 | return NULL; 202 | } 203 | _dxe_sync(); 204 | 205 | if (__dpmi_physical_address_mapping(&mi)) 206 | DPRINTF("Map PA 0x%x failed\r\n", mi.address); 207 | 208 | if (__dpmi_lock_linear_region(&mi)) 209 | DPRINTF("Lock region failed VA 0x%x\r\n", mi.address); 210 | 211 | linaddr = (void *)(mi.address + __djgpp_conventional_base); 212 | 213 | return linaddr; 214 | } 215 | 216 | static FxBool fxMapLinear(FxU32 busNumber, FxU32 physical_addr, FxU32 *linear_addr, FxU32 *length) 217 | { 218 | *linear_addr = (FxU32)MapPhysToLin((void *)physical_addr, *length); 219 | if (*linear_addr == 0) 220 | return 0; 221 | return 1; 222 | } 223 | 224 | #endif //CLIB_H 225 | 226 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/mglmapbo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU MESA GL Pass-Through 3 | * 4 | * Copyright (c) 2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #include "qemu/osdep.h" 22 | 23 | #include "mglfuncs.h" 24 | #include "mglmapbo.h" 25 | 26 | #if defined(__x86_64__) 27 | #if defined(__clang__) 28 | #pragma clang attribute push (__attribute((target("crc32"))), apply_to=function) 29 | #elif defined(__GNUC__) 30 | #pragma GCC push_options 31 | #pragma GCC target("crc32") 32 | #else 33 | #error Require either GCC or Clang to compile 34 | #endif 35 | #include 36 | #elif defined(__aarch64__) 37 | #define _mm_crc32_u64 __builtin_arm_crc32cd 38 | #else 39 | #error Undefined target CRC32 intrinsics 40 | #endif 41 | 42 | typedef struct _bufobj { 43 | mapbufo_t bo; 44 | struct _bufobj *next; 45 | } MAPBO, * PMAPBO; 46 | 47 | typedef struct _syncobj { 48 | uintptr_t sync; 49 | uint32_t g_sync; 50 | struct _syncobj *next; 51 | } SYNCO, * PSYNCO; 52 | 53 | static PMAPBO pbufo = NULL; 54 | static PSYNCO psynco = NULL; 55 | 56 | void InitSyncObj(void) 57 | { 58 | PSYNCO p = psynco; 59 | while (p) { 60 | PSYNCO next = p->next; 61 | g_free(p); 62 | p = next; 63 | } 64 | psynco = p; 65 | } 66 | 67 | uint32_t AddSyncObj(const uintptr_t sync) 68 | { 69 | PSYNCO p = psynco; 70 | 71 | if (!sync) 72 | return 0; 73 | 74 | if (!p) { 75 | p = g_new0(SYNCO, 1); 76 | p->sync = sync; 77 | p->g_sync = _mm_crc32_u64(p->g_sync, p->sync); 78 | psynco = p; 79 | } 80 | else { 81 | while (p->sync != sync && p->next) 82 | p = p->next; 83 | if (p->sync != sync) { 84 | p->next = g_new0(SYNCO, 1); 85 | p = p->next; 86 | p->sync = sync; 87 | p->g_sync = _mm_crc32_u64(p->g_sync, p->sync); 88 | 89 | } 90 | } 91 | return p->g_sync; 92 | } 93 | 94 | uintptr_t LookupSyncObj(const uint32_t g_sync) 95 | { 96 | PSYNCO p = psynco; 97 | 98 | if (!p) 99 | return INT32_MAX; 100 | 101 | while (p->g_sync != g_sync && p->next) 102 | p = p->next; 103 | 104 | if (p->g_sync != g_sync) 105 | return INT32_MAX; 106 | 107 | return p->sync; 108 | } 109 | 110 | uintptr_t DeleteSyncObj(const uintptr_t sync) 111 | { 112 | PSYNCO p = psynco, q = NULL; 113 | 114 | if (p) { 115 | while (p->sync != sync && p->next) { 116 | q = p; 117 | p = p->next; 118 | } 119 | if (p->sync == sync) { 120 | if (!q) { 121 | q = p->next; 122 | psynco = q; 123 | } 124 | else 125 | q->next = p->next; 126 | g_free(p); 127 | } 128 | } 129 | return sync; 130 | } 131 | 132 | #if defined(__x86_64__) 133 | #if defined(__clang__) 134 | #pragma clang attribute pop 135 | #elif defined(__GNUC__) 136 | #pragma GCC pop_options 137 | #endif 138 | #endif 139 | 140 | void InitBufObj(void) 141 | { 142 | PMAPBO p = pbufo; 143 | while (p) { 144 | PMAPBO next = p->next; 145 | g_free(p); 146 | p = next; 147 | } 148 | pbufo = p; 149 | } 150 | 151 | mapbufo_t *LookupBufObj(const int idx) 152 | { 153 | PMAPBO p = pbufo; 154 | 155 | if (p == NULL) { 156 | p = g_new0(MAPBO, 1); 157 | p->bo.idx = idx; 158 | pbufo = p; 159 | } 160 | else { 161 | while ((idx != p->bo.idx) && p->next) 162 | p = p->next; 163 | if (idx != p->bo.idx) { 164 | p->next = g_new0(MAPBO, 1); 165 | p = p->next; 166 | p->bo.idx = idx; 167 | } 168 | } 169 | return &p->bo; 170 | } 171 | 172 | int FreeBufObj(const int idx) 173 | { 174 | PMAPBO curr = pbufo, prev = NULL; 175 | 176 | int cnt; 177 | 178 | if (curr) { 179 | while ((idx != curr->bo.idx) && curr->next) { 180 | prev = curr; 181 | curr = curr->next; 182 | } 183 | if (idx == curr->bo.idx) { 184 | if (!prev) { 185 | prev = curr->next; 186 | pbufo = prev; 187 | } 188 | else 189 | prev->next = curr->next; 190 | g_free(curr); 191 | } 192 | } 193 | 194 | cnt = 0; 195 | curr = pbufo; 196 | 197 | while (curr) { 198 | cnt++; 199 | curr = curr->next; 200 | } 201 | return cnt; 202 | } 203 | 204 | int MapBufObjGpa(mapbufo_t *bufo) 205 | { 206 | PMAPBO curr = pbufo; 207 | int ret = 0; 208 | 209 | bufo->gpa = bufo->hva & (MBUFO_SIZE - 1); 210 | if (bufo != &curr->bo) { 211 | uintptr_t addr_lo = MBUFO_SIZE - 1, addr_hi = 0; 212 | uint32_t bufo_sz = ALIGNBO(bufo->mapsz) + (uint32_t)(bufo->hva & (qemu_real_host_page_size() - 1)); 213 | while (bufo != &curr->bo) { 214 | uint32_t curr_sz = curr->bo.mapsz + (uint32_t)(curr->bo.hva & (qemu_real_host_page_size() - 1)); 215 | addr_lo = ((curr->bo.gpa & qemu_real_host_page_mask()) < addr_lo)? 216 | (curr->bo.gpa & qemu_real_host_page_mask()):addr_lo; 217 | addr_hi = (((curr->bo.gpa + curr_sz) & qemu_real_host_page_mask()) > addr_hi)? 218 | ((curr->bo.gpa + curr_sz) & qemu_real_host_page_mask()):addr_hi; 219 | curr = curr->next; 220 | ret++; 221 | } 222 | if (((bufo->gpa + bufo_sz) < addr_lo) || (bufo->gpa >= addr_hi)) 223 | return ret; 224 | bufo->gpa = 0; 225 | if (!bufo->gpa && (addr_lo > bufo_sz)) 226 | bufo->gpa = addr_lo - bufo_sz; 227 | if (!bufo->gpa && ((addr_hi + bufo_sz) < MBUFO_SIZE)) 228 | bufo->gpa = addr_hi; 229 | } 230 | return ret; 231 | } 232 | 233 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QEMU MESA GL/3Dfx Glide Pass-Through 2 | Copyright (C) 2018-2025
3 | KJ Liew \ 4 | ## Content 5 | qemu-0/hw/3dfx - Overlay for QEMU source tree to add 3Dfx Glide pass-through device model 6 | qemu-1/hw/mesa - Overlay for QEMU source tree to add MESA GL pass-through device model 7 | scripts/sign_commit - Script for stamping commit id 8 | wrappers/3dfx - Glide wrappers for supported guest OS/environment (DOS/Windows/DJGPP/Linux) 9 | wrappers/mesa - MESA GL wrapper for supported guest OS/environment (Windows) 10 | ## Patch 11 | 00-qemu92x-mesa-glide.patch - Patch for QEMU version 9.2.x (MESA & Glide) 12 | 01-qemu82x-mesa-glide.patch - Patch for QEMU version 8.2.x (MESA & Glide) 13 | 02-qemu72x-mesa-glide.patch - Patch for QEMU version 7.2.x (MESA & Glide) 14 | ## QEMU Windows Guests Glide/OpenGL/Direct3D Acceleration 15 | Witness, experience and share your thoughts on modern CPU/GPU prowess for retro Windows games on Apple Silicon macOS, modern Windows and Linux. Most games can be installed and played in pristine condition without the hassle of hunting down unofficial, fan-made patches to play them on modern Windows or Linux/Wine. 16 | - YouTube channel (https://www.youtube.com/@qemu-3dfx/videos) 17 | - VOGONS forums (https://www.vogons.org) 18 | - Wiki (https://github.com/kjliew/qemu-3dfx/wiki) 19 | ## Building QEMU 20 | Following instructions are based on `MSYS2/mingw-w64` BASH shell environment on modern Windows. It is meant to be simple and minor variations are inevitable due to different flavors of Linux distributions. 21 | 22 | Simple guide to apply the patch:
23 | (using `00-qemu92x-mesa-glide.patch`) 24 | 25 | $ mkdir ~/myqemu && cd ~/myqemu 26 | $ git clone https://github.com/kjliew/qemu-3dfx.git 27 | $ cd qemu-3dfx 28 | $ wget https://download.qemu.org/qemu-9.2.2.tar.xz 29 | $ tar xf qemu-9.2.2.tar.xz 30 | $ cd qemu-9.2.2 31 | $ rsync -r ../qemu-0/hw/3dfx ../qemu-1/hw/mesa ./hw/ 32 | $ patch -p0 -i ../00-qemu92x-mesa-glide.patch 33 | $ bash ../scripts/sign_commit 34 | $ mkdir ../build && cd ../build 35 | $ ../qemu-9.2.2/configure && make 36 | 37 | ## Building Guest Wrappers 38 | **Requirements:** 39 | - `base-devel` (make, sed, xxd etc.) 40 | - `gendef, shasum` 41 | - `mingw32` cross toolchain (`binutils, gcc, windres, dlltool`) for WIN32 DLL wrappers 42 | - `Open-Watcom-1.9/v2.0` or `Watcom C/C++ 11.0` for DOS32 OVL wrapper 43 | - `{i586,i686}-pc-msdosdjgpp` cross toolchain (`binutils, gcc, dxe3gen`) for DJGPP DXE wrappers 44 |
45 | 46 | $ cd ~/myqemu/qemu-3dfx/wrappers/3dfx 47 | $ mkdir build && cd build 48 | $ bash ../../../scripts/conf_wrapper 49 | $ make && make clean 50 | 51 | $ cd ~/myqemu/qemu-3dfx/wrappers/mesa 52 | $ mkdir build && cd build 53 | $ bash ../../../scripts/conf_wrapper 54 | $ make && make clean 55 | 56 | ## Installing Guest Wrappers 57 | **For Win9x/ME:** 58 | - Copy `FXMEMMAP.VXD` to `C:\WINDOWS\SYSTEM` 59 | - Copy `GLIDE.DLL`, `GLIDE2X.DLL` and `GLIDE3X.DLL` to `C:\WINDOWS\SYSTEM` 60 | - Copy `GLIDE2X.OVL` to `C:\WINDOWS` 61 | - Copy `OPENGL32.DLL` to `Game Installation` folders 62 | 63 | **For Win2k/XP:** 64 | - Copy `FXPTL.SYS` to `%SystemRoot%\system32\drivers` 65 | - Copy `GLIDE.DLL`, `GLIDE2X.DLL` and `GLIDE3X.DLL` to `%SystemRoot%\system32` 66 | - Run `INSTDRV.EXE`, require Administrator Priviledge 67 | - Copy `OPENGL32.DLL` to `Game Installation` folders 68 | 69 | ## Donation 70 | If this project helps you relive the nostalgic memory of Good Old Windows Games, you can now donate in the course of supporting **Games Preservation** with QEMU. Your donation also motivates and encourages further research in making QEMU the ultimate platform for Retro Windows Games. 71 | 72 | For $89.99 donation, you will deserve the following donor's privileges: 73 | - QEMU binary package built for platform of your choice (choose **ONE**: Windows 10/11, Ubuntu, etc.) 74 | - QEMU-enhanced OpenGLide **Host-side wrappers** built for platform of your choice (choose **ONE**: Windows 10/11, Ubuntu, etc.) 75 | - QEMU-enhanced [**WineD3D libraries for Win98/2K/ME/XP VMs**](https://www.winehq.org) for DirectDraw/Direct3D games up to DirectX 9.0c 76 | - Game controllers support with [**QEMU USB Gamepad**](https://github.com/kjliew/qemu-3dfx/wiki/QEMU-USB-Gamepad) 77 | - SDL2 clipboard sharing through built-in [**QEMU vdagent**](https://www.kraxel.org/blog/2021/05/qemu-cut-paste/) 78 | - OpenGLide **Guest-side wrappers** for Windows 79 | - Elect up to 5 games for priority support and your name as the honorary sponsor in the supported & tested list of games. 80 | 81 | [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=XE47KTASERX4A) 82 | ### A Note to Donation 83 | The purpose of the donation is for preserving retailed CD/DVD games in their originality. It may be used to purchase the game online or from local thrift shops. The donation is **NOT** the ticket for one to learn how to use QEMU Virtual Machine in general. Sometimes, it may be difficult to get virtualization acceleration working and that would result in serious degradation of game experience with QEMU. It is a **willing donation pledge and non-refundable**. Many classic Windows games also have re-releases from GOG/Steam that work on modern Windows and Linux. It can be an option to consider before making a donation. 84 | 85 | Donations without leaving notes on **Platform of Choice** are regarded as upper-class donors who have no desire in exercising donor's privileges. A measure to avoid unneccessary spamming on emails. Donors are expected to proactively follow up the communication to exercise donor's privileges as wished. All donations are tracked in PayPal transaction history. Only **"ONE"** platform of choice per donation. Upgrades eligibility are limited to the **SAME** platform of choice. 86 | ### About Game Election 87 | The game election serves the purpose of allocating additional focus and resources to make them work. Sometimes, it means considerable efforts in researching, debugging and tracing the games to root cause the failures and come up with solutions. It is **OPTIONAL** to make game election upon donation. My YouTube channel has video demos of games which already worked and more may be showing up periodically. It is typically a safe assumption that games using the same engine (IdTech1/2/3, LithTech, Unreal etc.) would work, too. The _N_ counts of eligibility would only be accounted once the game were made to work. If upgrades were neccessary, it would be a **FREE upgrade** for QEMU binary packages. 88 | -------------------------------------------------------------------------------- /wrappers/fxlib/md5.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple MD5 implementation 3 | * 4 | * Compile with: gcc -o md5 -O3 -lm md5.c 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | // leftrotate function definition 12 | #define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) 13 | 14 | // These vars will contain the hash 15 | static uint32_t h0, h1, h2, h3; 16 | static char digest[32 + 1]; 17 | 18 | static void md5(uint8_t *initial_msg, size_t initial_len) { 19 | 20 | // Message (to prepare) 21 | uint8_t *msg = NULL; 22 | 23 | // Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating 24 | 25 | // r specifies the per-round shift amounts 26 | 27 | uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 28 | 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 29 | 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 30 | 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}; 31 | 32 | // Use binary integer part of the sines of integers (in radians) as constants// Initialize variables: 33 | uint32_t k[] = { 34 | 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 35 | 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 36 | 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 37 | 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 38 | 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 39 | 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 40 | 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 41 | 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 42 | 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 43 | 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 44 | 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 45 | 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 46 | 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 47 | 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 48 | 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 49 | 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391}; 50 | 51 | h0 = 0x67452301; 52 | h1 = 0xefcdab89; 53 | h2 = 0x98badcfe; 54 | h3 = 0x10325476; 55 | 56 | // Pre-processing: adding a single 1 bit 57 | //append "1" bit to message 58 | /* Notice: the input bytes are considered as bits strings, 59 | where the first bit is the most significant bit of the byte.[37] */ 60 | 61 | // Pre-processing: padding with zeros 62 | //append "0" bit until message length in bit ≡ 448 (mod 512) 63 | //append length mod (2 pow 64) to message 64 | 65 | int new_len = ((((initial_len + 8) / 64) + 1) * 64) - 8; 66 | 67 | msg = calloc(new_len + 64, 1); // also appends "0" bits 68 | // (we alloc also 64 extra bytes...) 69 | memcpy(msg, initial_msg, initial_len); 70 | msg[initial_len] = 128; // write the "1" bit 71 | 72 | uint32_t bits_len = 8*initial_len; // note, we append the len 73 | memcpy(msg + new_len, &bits_len, 4); // in bits at the end of the buffer 74 | 75 | // Process the message in successive 512-bit chunks: 76 | //for each 512-bit chunk of message: 77 | int offset; 78 | for(offset=0; offset 2 | #include 3 | #include "hpat.h" 4 | 5 | static struct E_PATCH tie95_vga[] = { 6 | PATCH_D(0x16092, "\xE9\x7F\x01"), 7 | E_PATCH_END() 8 | }; 9 | static struct E_PATCH tie95_exe[] = { 10 | PATCH_D(0x30377, "\x38\xE0"), 11 | E_PATCH_END() 12 | }; 13 | static struct E_PATCH xwg95_exe[] = { 14 | PATCH_D(0x856d7, "\x38\xE0"), 15 | E_PATCH_END() 16 | }; 17 | static struct E_PATCH fforce_exe[] = { 18 | PATCH_D(0x366f1, "\x38\xE0"), 19 | PATCH_D(0x3673f, "\x38\xE0"), 20 | PATCH_D(0x3678d, "\x38\xE0"), 21 | PATCH_D(0x367d4, "\x38\xE0"), 22 | E_PATCH_END() 23 | }; 24 | static struct E_PATCH engrel_blit[] = { 25 | PATCH_D(0xbf0a8, "\x00"), 26 | E_PATCH_END() 27 | }; 28 | static struct E_PATCH engrel_cursor[] = { 29 | PATCH_D(0x1805a, "\x38\xC4"), 30 | E_PATCH_END() 31 | }; 32 | static struct E_PATCH req_demo[] = { 33 | PATCH_D(0x64a0c, "\xEB"), 34 | E_PATCH_END() 35 | }; 36 | static struct E_PATCH d3d_exe[] = { 37 | PATCH_D(0x65b2d, "\xEB"), 38 | E_PATCH_END() 39 | }; 40 | static struct E_PATCH hg_exe[] = { 41 | PATCH_D(0x0133e, "\x90\x90"), 42 | E_PATCH_END() 43 | }; 44 | static struct E_PATCH tomb3_exe_1[] = { 45 | PATCH_D(0x8ec41, "\xB4\x01\x90"), 46 | PATCH_D(0x8ec52, "\xB0\x00\x90"), 47 | E_PATCH_END() 48 | }; 49 | static struct E_PATCH tomb3_exe_2[] = { 50 | PATCH_D(0x97321, "\xB4\x01\x90"), 51 | PATCH_D(0x97332, "\xB0\x00\x90"), 52 | E_PATCH_END() 53 | }; 54 | static struct E_PATCH tomb4_exe[] = { 55 | PATCH_D(0x8da53, "\x90\xB4\x00"), 56 | PATCH_D(0x8da64, "\x90\xB0\x00"), 57 | E_PATCH_END() 58 | }; 59 | static struct E_PATCH go_retail[] = { 60 | PATCH_D(0x40a52, "\xEB\x0D"), 61 | E_PATCH_END() 62 | }; 63 | static struct E_PATCH go_g400_1[] = { 64 | PATCH_D(0x40d0f, "\xEB\x0D"), 65 | E_PATCH_END() 66 | }; 67 | static struct E_PATCH go_g400_2[] = { 68 | PATCH_D(0x0c2f4, "\xEB\x08"), 69 | PATCH_D(0x0c30e, "\xEB"), 70 | E_PATCH_END() 71 | }; 72 | static struct E_PATCH go_g400_3[] = { 73 | PATCH_D(0x097a9, "\xEB"), 74 | E_PATCH_END() 75 | }; 76 | static struct E_PATCH turok_dem[] = { 77 | PATCH_D(0x0c6e2, "\xEB\x06"), 78 | E_PATCH_END() 79 | }; 80 | static struct E_PATCH turok_exe[] = { 81 | PATCH_D(0x0c122, "\xEB\x06"), 82 | E_PATCH_END() 83 | }; 84 | static struct E_PATCH pod_d3d[] = { 85 | PATCH_D(0xc7a5a, "\x04"), 86 | E_PATCH_END() 87 | }; 88 | static struct E_PATCH pod_3dfx[] = { 89 | PATCH_D(0x86347, "\x04"), 90 | E_PATCH_END() 91 | }; 92 | static struct E_PATCH matrox_reef_1[] = { 93 | PATCH_D(0x03f57, "\xEB"), 94 | E_PATCH_END() 95 | }; 96 | static struct E_PATCH matrox_reef_2[] = { 97 | PATCH_D(0x79935, "\x4B"), 98 | E_PATCH_END() 99 | }; 100 | static struct E_PATCH rush1024[] = { 101 | PATCH_D(0x5fe1e, "\xEB"), 102 | E_PATCH_END() 103 | }; 104 | static struct E_PATCH rush800[] = { 105 | PATCH_D(0x4ee0e, "\xEB"), 106 | E_PATCH_END() 107 | }; 108 | static struct E_PATCH rush640[] = { 109 | PATCH_D(0x5fdfe, "\xEB"), 110 | E_PATCH_END() 111 | }; 112 | static struct E_PATCH mhead_exe[] = { 113 | PATCH_D(0x70dec, "\xEB"), 114 | E_PATCH_END() 115 | }; 116 | static struct E_PATCH sonicr_exe[] = { 117 | PATCH_D(0x801c9, "\x0F\xB6\xD7\xB3\xAA"), 118 | PATCH_D(0x801d7, "\xF7\xF9\xF7\xEB"), 119 | E_PATCH_END() 120 | }; 121 | static COMPATFX fxCompatTbl[] = { 122 | /* Rage Expendable Retailed & G400 EMBM */ 123 | { "go.exe", "330113cfeb00ae4de299f041fb5714ba", HP_ANYO, go_g400_3 }, 124 | { "go.exe", "c86b59bdfa1360eb43879e59fb3ac89f", HP_ANYO, go_g400_2 }, 125 | { "go.exe", "6cf594d3a8704ba5281f4a11fc3adf7e", HP_ANYO, go_g400_1 }, 126 | { "go.exe", "b64b448d7448103417edbb413e13283c", HP_ANYO, go_retail }, 127 | /* Tie95 3D */ 128 | { "tie95.exe", "384d3ae028aadae67c617a09ed5ea085", HP_2KXP, tie95_exe }, 129 | { "tie95.exe", "a736f8ec53825b4a824060b3af7a332b", HP_2KXP, tie95_vga }, 130 | /* X-Wing95 3D */ 131 | { "xwing95.exe", "7e490350a5f3d35d674c7e6d923660e2", HP_2KXP, xwg95_exe }, 132 | /* Fighting Force */ 133 | { "fforce.exe", "81ee5e035d23e130430f31723cecaf64", HP_2KXP, fforce_exe }, 134 | /* Warhammer: Dark Omen */ 135 | { "engrel.exe", "8dc25757be926088167cb1663b7c7b76", HP_ANYO, engrel_blit }, 136 | { "engrel.exe", "1a0b17352c8fee8c62732ef4f7aae95f", HP_2KXP, engrel_cursor }, 137 | /* Requiem Demo D3D */ 138 | { "reqdemo_d3d.exe", "2ee1cf9120c4f13eef06da62600b0c23", HP_ANYO, req_demo }, 139 | /* Requiem D3D 1.2 */ 140 | { "d3d.exe", "b783b9fbca594286b606eb07912740b6", HP_ANYO, d3d_exe }, 141 | /* Heavy Gear 1.2 */ 142 | { "hg.exe", "4685aa795e3916c1bb0de5616a86bfa0", HP_2KXP, hg_exe }, 143 | /* Tomb Raider III */ 144 | { "tomb3.exe", "47c2bb0445fce035d2d264b71bf1faae", HP_2KXP, tomb3_exe_1 }, 145 | { "tomb3.exe", "160e4d0cc6740731ff4598c47c75719c", HP_2KXP, tomb3_exe_2 }, 146 | /* Tomb Raider IV */ 147 | { "tomb4.exe", "e720ab3d4682cbd563a9c3943812fcac", HP_2KXP, tomb4_exe }, 148 | /* Turok Demo v1.01 */ 149 | { "TurokDemo.exe", "58d26953c755bcc64f330f1a3c0441bd", HP_ANYO, turok_dem }, 150 | /* Turok Dinosaur Hunter USA v1.0 */ 151 | { "Turok.exe", "cba05017b943451e8a7b55f22a3d0de9", HP_ANYO, turok_exe }, 152 | /* P.O.D 2.0 Gold/MMX - D3D */ 153 | { "podd3dx.exe", "63313d5b17e048b2fff0dd65e81c22da", HP_ANYO, pod_d3d }, 154 | /* P.O.D 2.0 Gold/MMX - 3Dfx */ 155 | { "podx3dfx.exe", "81176f654fca4af5f50b5636b993a953", HP_ANYO, pod_3dfx }, 156 | /* Matrox Reef Demo 1.1 */ 157 | { "FishDemoClient.exe", "f02a846eeb79b6bf68f48f8746931580", HP_ANYO, matrox_reef_1 }, 158 | { "FishDemoClient.exe", "016a923e609f837871396888e5a63fb9", HP_ANYO, matrox_reef_2 }, 159 | /* San Francisco Rush: The Rock Alcatraz edition */ 160 | { "rush1280.exe", "88f69a4ad549909c2995808834854108", HP_ANYO, rush1024 }, 161 | { "rush1024.exe", "88f69a4ad549909c2995808834854108", HP_ANYO, rush1024 }, 162 | { "rush800.exe", "fe8485db1ef3af6680b003cf9ebe4aa0", HP_ANYO, rush800 }, 163 | { "rush640.exe", "9f118eaba1374c5504bfc22aa4a9187a", HP_ANYO, rush640 }, 164 | /* Motorhead Matrox G200 p3.0 */ 165 | { "motor.exe", "580e38ba69420a0d44469b92d509b093", HP_ANYO, mhead_exe }, 166 | /* Sonic R SEGA 1998 */ 167 | { "sonicr.exe", "ac3ccb986cb31d277afa0f2a43109e32", HP_ANYO, sonicr_exe }, 168 | E_PATCH_END() 169 | }; 170 | 171 | const char *basename(const char *name); 172 | const char *md5page(const char *msg); 173 | const int fxCompatPlatformId(const int id) 174 | { 175 | static int PlatformId; 176 | PlatformId = (id)? id:PlatformId; 177 | return PlatformId; 178 | } 179 | const PCOMPATFX fxCompatTblPtr(void) 180 | { 181 | static int once; 182 | if (!once) { 183 | once = !once; 184 | return fxCompatTbl; 185 | } 186 | return 0; 187 | } 188 | void HookPatchfxCompat(const DWORD hpMask) 189 | { 190 | TCHAR modName[MAX_PATH]; 191 | fxCompatPlatformId(hpMask); 192 | if (GetModuleFileName(NULL, modName, MAX_PATH) < MAX_PATH) { 193 | int i = 0, j; 194 | while (fxCompatTbl[i].modName) { 195 | DWORD modBase = (DWORD)GetModuleHandle(0), oldProt; 196 | void *modPage; 197 | j = 0; 198 | modPage = (unsigned char *)(modBase + (fxCompatTbl[i].ptr[j].offs & ~0xFFFU)); 199 | if ((fxCompatTbl[i].op_mask & hpMask) && 200 | !stricmp(fxCompatTbl[i].modName, basename(modName)) && 201 | !strcmp(fxCompatTbl[i].md5, md5page((const char *)modPage)) && 202 | VirtualProtect(modPage, sizeof(void *), PAGE_EXECUTE_READWRITE, &oldProt)) { 203 | fxCompatTbl[i].op_mask |= HP_DONE; 204 | while(fxCompatTbl[i].ptr[j].offs) { 205 | memcpy((unsigned char *)(modBase + fxCompatTbl[i].ptr[j].offs), 206 | fxCompatTbl[i].ptr[j].cb, fxCompatTbl[i].ptr[j].len); 207 | j++; 208 | } 209 | VirtualProtect(modPage, sizeof(void *), oldProt, &oldProt); 210 | } 211 | i++; 212 | } 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /wrappers/fxlib/fxtime.c: -------------------------------------------------------------------------------- 1 | /* 2 | * MMSYSTEM time functions 3 | * 4 | * Copyright 1993 Martin Ayotte 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 | */ 20 | 21 | #include 22 | #include "hpat.h" 23 | 24 | typedef struct tagWINE_TIMERENTRY { 25 | UINT wDelay; 26 | UINT wResol; 27 | LPTIMECALLBACK lpFunc; /* can be lots of things */ 28 | DWORD_PTR dwUser; 29 | UINT16 wFlags; 30 | UINT16 wTimerID; 31 | DWORD dwTriggerTime; 32 | } WINE_TIMERENTRY, *LPWINE_TIMERENTRY; 33 | 34 | static WINE_TIMERENTRY timers[16]; 35 | static UINT timers_created; 36 | static CRITICAL_SECTION WINMM_cs, TIME_cbcrst; 37 | 38 | static HANDLE TIME_hMMTimer; 39 | 40 | #define MMSYSTIME_MININTERVAL (1) 41 | #define MMSYSTIME_MAXINTERVAL (65535) 42 | #ifndef ARRAY_SIZE 43 | #define ARRAY_SIZE ARRAYSIZE 44 | #endif 45 | 46 | extern DWORD (WINAPI *fxTick)(void); 47 | 48 | static int TIME_MMSysTimeCallback(void) 49 | { 50 | WINE_TIMERENTRY *timer; 51 | int i, delta_time; 52 | 53 | /* since timeSetEvent() and timeKillEvent() can be called 54 | * from 16 bit code, there are cases where win16 lock is 55 | * locked upon entering timeSetEvent(), and then the mm timer 56 | * critical section is locked. This function cannot call the 57 | * timer callback with the crit sect locked (because callback 58 | * may need to acquire Win16 lock, thus providing a deadlock 59 | * situation). 60 | * To cope with that, we just copy the WINE_TIMERENTRY struct 61 | * that need to trigger the callback, and call it without the 62 | * mm timer crit sect locked. 63 | */ 64 | 65 | for (;;) 66 | { 67 | for (i = 0; i < ARRAY_SIZE(timers); i++) 68 | if (timers[i].wTimerID) break; 69 | if (i == ARRAY_SIZE(timers)) return -1; 70 | timer = timers + i; 71 | for (i++; i < ARRAY_SIZE(timers); i++) 72 | { 73 | if (!timers[i].wTimerID) continue; 74 | if (timers[i].dwTriggerTime < timer->dwTriggerTime) 75 | timer = timers + i; 76 | } 77 | 78 | delta_time = timer->dwTriggerTime - fxTick(); 79 | if (delta_time > 0) break; 80 | 81 | if (timer->wFlags & TIME_PERIODIC) 82 | timer->dwTriggerTime += timer->wDelay; 83 | 84 | switch(timer->wFlags & (TIME_CALLBACK_EVENT_SET|TIME_CALLBACK_EVENT_PULSE)) 85 | { 86 | case TIME_CALLBACK_EVENT_SET: 87 | SetEvent(timer->lpFunc); 88 | break; 89 | case TIME_CALLBACK_EVENT_PULSE: 90 | PulseEvent(timer->lpFunc); 91 | break; 92 | case TIME_CALLBACK_FUNCTION: 93 | { 94 | DWORD_PTR user = timer->dwUser; 95 | UINT16 id = timer->wTimerID; 96 | UINT16 flags = timer->wFlags; 97 | LPTIMECALLBACK func = timer->lpFunc; 98 | 99 | if (flags & TIME_KILL_SYNCHRONOUS) EnterCriticalSection(&TIME_cbcrst); 100 | LeaveCriticalSection(&WINMM_cs); 101 | 102 | func(id, 0, user, 0, 0); 103 | 104 | EnterCriticalSection(&WINMM_cs); 105 | if (flags & TIME_KILL_SYNCHRONOUS) LeaveCriticalSection(&TIME_cbcrst); 106 | if (id != timer->wTimerID) timer = NULL; 107 | } 108 | break; 109 | } 110 | if (timer && !(timer->wFlags & TIME_PERIODIC)) 111 | timer->wTimerID = 0; 112 | } 113 | return delta_time; 114 | } 115 | 116 | static DWORD CALLBACK TIME_MMSysTimeThread(LPVOID arg) 117 | { 118 | int sleep_time; 119 | 120 | EnterCriticalSection(&WINMM_cs); 121 | while (1) 122 | { 123 | sleep_time = TIME_MMSysTimeCallback(); 124 | 125 | if (sleep_time < 0) 126 | break; 127 | if (sleep_time == 0) 128 | continue; 129 | 130 | LeaveCriticalSection(&WINMM_cs); 131 | Sleep(1); 132 | EnterCriticalSection(&WINMM_cs); 133 | } 134 | CloseHandle(TIME_hMMTimer); 135 | TIME_hMMTimer = NULL; 136 | LeaveCriticalSection(&WINMM_cs); 137 | //FreeLibraryAndExitThread(arg, 0); 138 | return 0; 139 | } 140 | 141 | static void TIME_MMTimeStart(void) 142 | { 143 | HMODULE mod; 144 | if (TIME_hMMTimer) return; 145 | 146 | DWORD thread_id; 147 | BOOL (WINAPI *p_getModuleHandleExA)(DWORD, LPCSTR, HMODULE *) = (BOOL (WINAPI *)(DWORD, LPCSTR, HMODULE *)) 148 | GetProcAddress(GetModuleHandle("kernel32.dll"), "GetModuleHandleExA"); 149 | mod = NULL; 150 | if (p_getModuleHandleExA) 151 | p_getModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)TIME_MMSysTimeThread, &mod); 152 | TIME_hMMTimer = CreateThread(NULL, 0, TIME_MMSysTimeThread, mod, 0, &thread_id); 153 | SetThreadPriority(TIME_hMMTimer, THREAD_PRIORITY_TIME_CRITICAL); 154 | } 155 | 156 | static MMRESULT WINAPI HookSetEvent(UINT wDelay, UINT wResol, LPTIMECALLBACK lpFunc, 157 | DWORD_PTR dwUser, UINT wFlags) 158 | { 159 | WORD new_id = 0; 160 | int i; 161 | 162 | if (wDelay < MMSYSTIME_MININTERVAL || wDelay > MMSYSTIME_MAXINTERVAL) 163 | return 0; 164 | 165 | if (!TIME_hMMTimer) { 166 | InitializeCriticalSection(&WINMM_cs); 167 | InitializeCriticalSection(&TIME_cbcrst); 168 | } 169 | EnterCriticalSection(&WINMM_cs); 170 | 171 | for (i = 0; i < ARRAY_SIZE(timers); i++) 172 | if (!timers[i].wTimerID) break; 173 | if (i == ARRAY_SIZE(timers)) 174 | { 175 | LeaveCriticalSection(&WINMM_cs); 176 | return 0; 177 | } 178 | 179 | new_id = ARRAY_SIZE(timers)*(++timers_created) + i; 180 | if (!new_id) new_id = ARRAY_SIZE(timers)*(++timers_created) + i; 181 | 182 | timers[i].wDelay = wDelay; 183 | timers[i].dwTriggerTime = fxTick() + wDelay; 184 | 185 | /* FIXME - wResol is not respected, although it is not clear 186 | that we could change our precision meaningfully */ 187 | timers[i].wResol = wResol; 188 | timers[i].lpFunc = lpFunc; 189 | timers[i].dwUser = dwUser; 190 | timers[i].wFlags = wFlags; 191 | timers[i].wTimerID = new_id; 192 | 193 | TIME_MMTimeStart(); 194 | 195 | LeaveCriticalSection(&WINMM_cs); 196 | 197 | return new_id; 198 | } 199 | 200 | static MMRESULT WINAPI HookKillEvent(UINT wID) 201 | { 202 | WINE_TIMERENTRY *timer; 203 | WORD flags; 204 | 205 | EnterCriticalSection(&WINMM_cs); 206 | 207 | timer = &timers[wID % ARRAY_SIZE(timers)]; 208 | if (timer->wTimerID != wID) 209 | { 210 | LeaveCriticalSection(&WINMM_cs); 211 | return TIMERR_NOCANDO; 212 | } 213 | 214 | timer->wTimerID = 0; 215 | flags = timer->wFlags; 216 | int i = 0; 217 | for (; i < ARRAY_SIZE(timers); i++) 218 | if (timers[i].wTimerID) break; 219 | LeaveCriticalSection(&WINMM_cs); 220 | 221 | if (flags & TIME_KILL_SYNCHRONOUS) 222 | { 223 | EnterCriticalSection(&TIME_cbcrst); 224 | LeaveCriticalSection(&TIME_cbcrst); 225 | } 226 | 227 | if (i == ARRAY_SIZE(timers)) { 228 | while(TIME_hMMTimer) Sleep(1); 229 | DeleteCriticalSection(&TIME_cbcrst); 230 | DeleteCriticalSection(&WINMM_cs); 231 | } 232 | 233 | return TIMERR_NOERROR; 234 | } 235 | 236 | void fxEventHookPtr(const PEVENTFX e) 237 | { 238 | e->Kill = &HookKillEvent; 239 | e->Set = &HookSetEvent; 240 | } 241 | -------------------------------------------------------------------------------- /virgil3d/MINGW-packages/0001-Virglrenderer-on-Windows-and-macOS.patch: -------------------------------------------------------------------------------- 1 | diff -Nru orig/virglrenderer-1.2.0/src/gallium/auxiliary/tgsi/tgsi_text.h src/virglrenderer-1.2.0/src/gallium/auxiliary/tgsi/tgsi_text.h 2 | --- orig/virglrenderer-1.2.0/src/gallium/auxiliary/tgsi/tgsi_text.h 3 | +++ src/virglrenderer-1.2.0/src/gallium/auxiliary/tgsi/tgsi_text.h 4 | @@ -34,6 +34,9 @@ 5 | 6 | #include "pipe/p_compiler.h" 7 | 8 | +#ifdef __WIN32__ 9 | +#define uint unsigned 10 | +#endif 11 | struct tgsi_token; 12 | 13 | bool 14 | diff -Nru orig/virglrenderer-1.2.0/src/mesa/compat/c11/threads_win32.h src/virglrenderer-1.2.0/src/mesa/compat/c11/threads_win32.h 15 | --- orig/virglrenderer-1.2.0/src/mesa/compat/c11/threads_win32.h 16 | +++ src/virglrenderer-1.2.0/src/mesa/compat/c11/threads_win32.h 17 | @@ -175,7 +175,7 @@ 18 | return 0; 19 | } 20 | 21 | -static void impl_tss_dtor_invoke() 22 | +static void impl_tss_dtor_invoke(void) 23 | { 24 | int i; 25 | for (i = 0; i < EMULATED_THREADS_TSS_DTOR_SLOTNUM; i++) { 26 | diff -Nru orig/virglrenderer-1.2.0/src/virgl_util.h src/virglrenderer-1.2.0/src/virgl_util.h 27 | --- orig/virglrenderer-1.2.0/src/virgl_util.h 28 | +++ src/virglrenderer-1.2.0/src/virgl_util.h 29 | @@ -29,6 +29,9 @@ 30 | #include 31 | #include 32 | 33 | +#ifdef WIN32 34 | +#include 35 | +#endif 36 | #ifdef HAVE_CONFIG_H 37 | #include "config.h" 38 | #endif 39 | diff -Nru orig/virglrenderer-1.2.0/src/vrend/vrend_blitter.h src/virglrenderer-1.2.0/src/vrend/vrend_blitter.h 40 | --- orig/virglrenderer-1.2.0/src/vrend/vrend_blitter.h 41 | +++ src/virglrenderer-1.2.0/src/vrend/vrend_blitter.h 42 | @@ -30,7 +30,7 @@ 43 | /* shaders for blitting */ 44 | 45 | #define FS_HEADER_GL \ 46 | - "#version 130\n" \ 47 | + "#version 140\n" \ 48 | "// Blitter\n" \ 49 | "%s" \ 50 | 51 | @@ -48,7 +48,7 @@ 52 | "precision mediump float;\n" \ 53 | 54 | #define HEADER_GL \ 55 | - "#version 130\n" \ 56 | + "#version 140\n" \ 57 | "// Blitter\n" \ 58 | 59 | #define HEADER_GLES \ 60 | diff -Nru orig/virglrenderer-1.2.0/src/vrend/vrend_formats.c src/virglrenderer-1.2.0/src/vrend/vrend_formats.c 61 | --- orig/virglrenderer-1.2.0/src/vrend/vrend_formats.c 62 | +++ src/virglrenderer-1.2.0/src/vrend/vrend_formats.c 63 | @@ -655,11 +655,11 @@ 64 | 65 | if (table[i].internalformat != 0 && 66 | !(table[i].flags & VIRGL_TEXTURE_CAN_MULTISAMPLE) && 67 | - function_available) { 68 | + (function_available || is_desktop_gl)) { 69 | GLuint tex_id; 70 | glGenTextures(1, &tex_id); 71 | glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_id); 72 | - if (table[i].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE) { 73 | + if (table[i].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE && enable_storage) { 74 | glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, 75 | table[i].internalformat, 32, 32, GL_TRUE); 76 | } else { 77 | diff -Nru orig/virglrenderer-1.2.0/src/vrend/vrend_renderer.c src/virglrenderer-1.2.0/src/vrend/vrend_renderer.c 78 | --- orig/virglrenderer-1.2.0/src/vrend/vrend_renderer.c 79 | +++ src/virglrenderer-1.2.0/src/vrend/vrend_renderer.c 80 | @@ -387,6 +387,7 @@ 81 | uint64_t features[feat_last / 64 + 1]; 82 | 83 | bool finishing : 1; 84 | + bool gl_apple : 1; 85 | bool use_gles : 1; 86 | bool use_core_profile : 1; 87 | bool use_external_blob : 1; 88 | @@ -4887,6 +4888,7 @@ 89 | box->width, box->height, box->depth, 90 | format, type, data); 91 | } else { 92 | + if (has_feature(feat_clear_texture)) 93 | glClearTexSubImage(res->gl_id, level, 94 | box->x, box->y, box->z, 95 | box->width, box->height, box->depth, 96 | @@ -7518,6 +7520,8 @@ 97 | GLenum err; 98 | 99 | err = glGetError(); 100 | + if (err == GL_INVALID_ENUM && vrend_state.gl_apple) 101 | + err = glGetError(); 102 | if (err == GL_NO_ERROR) 103 | return true; 104 | 105 | @@ -7629,6 +7633,7 @@ 106 | virgl_info("gl_version %d - compat profile\n", gl_ver); 107 | } 108 | 109 | + vrend_state.gl_apple = (strcmp((const char *)glGetString(GL_VENDOR), "Apple") == 0); 110 | vrend_state.use_integer = use_integer(); 111 | 112 | init_features(gles ? 0 : gl_ver, 113 | @@ -7991,6 +7996,7 @@ 114 | grctx->shader_cfg.has_gpu_shader5 = has_feature(feat_gpu_shader5); 115 | grctx->shader_cfg.has_es31_compat = has_feature(feat_gles31_compatibility); 116 | grctx->shader_cfg.has_conservative_depth = has_feature(feat_conservative_depth); 117 | + grctx->shader_cfg.gl_apple = vrend_state.gl_apple; 118 | grctx->shader_cfg.use_integer = vrend_state.use_integer; 119 | grctx->shader_cfg.has_dual_src_blend = has_feature(feat_dual_src_blend); 120 | grctx->shader_cfg.has_fbfetch_coherent = has_feature(feat_framebuffer_fetch); 121 | @@ -8617,6 +8623,7 @@ 122 | 123 | const bool format_can_texture_storage = has_feature(feat_texture_storage) && 124 | (tex_conv_table[format].flags & VIRGL_TEXTURE_CAN_TEXTURE_STORAGE); 125 | + const bool format_has_storage_multisample = has_feature(feat_storage_multisample); 126 | 127 | if (format_can_texture_storage) 128 | gr->storage_bits |= VREND_STORAGE_GL_IMMUTABLE; 129 | @@ -8690,7 +8697,7 @@ 130 | } 131 | 132 | if (pr->nr_samples > 1) { 133 | - if (format_can_texture_storage) { 134 | + if (format_can_texture_storage && format_has_storage_multisample) { 135 | if (gr->target == GL_TEXTURE_2D_MULTISAMPLE) { 136 | glTexStorage2DMultisample(gr->target, pr->nr_samples, 137 | internalformat, pr->width0, pr->height0, 138 | @@ -9674,7 +9681,7 @@ 139 | glReadnPixelsARB(x, y, width, height, format, type, bufSize, data); 140 | else if (epoxy_gl_version() >= 45) 141 | glReadnPixels(x, y, width, height, format, type, bufSize, data); 142 | - else if (has_feature(feat_gles_khr_robustness)) 143 | + else if (vrend_state.use_gles && has_feature(feat_gles_khr_robustness)) 144 | glReadnPixelsKHR(x, y, width, height, format, type, bufSize, data); 145 | else 146 | glReadPixels(x, y, width, height, format, type, data); 147 | @@ -10503,7 +10510,7 @@ 148 | slice_offset = src_box->z * slice_size; 149 | cube_slice = (src_res->target == GL_TEXTURE_CUBE_MAP) ? src_box->z + src_box->depth : cube_slice; 150 | i = (src_res->target == GL_TEXTURE_CUBE_MAP) ? src_box->z : 0; 151 | - if (slice_offset + src_box->width * src_box->height + cube_slice * slice_size > total_size) { 152 | + if (src_box->z && (slice_offset + src_box->width * src_box->height + cube_slice * slice_size > total_size)) { 153 | virgl_error("Offset out of bound: %d\n", src_box->z); 154 | goto cleanup; 155 | } 156 | diff -Nru orig/virglrenderer-1.2.0/src/vrend/vrend_shader.c src/virglrenderer-1.2.0/src/vrend/vrend_shader.c 157 | --- orig/virglrenderer-1.2.0/src/vrend/vrend_shader.c 158 | +++ src/virglrenderer-1.2.0/src/vrend/vrend_shader.c 159 | @@ -3356,6 +3356,7 @@ 160 | bool has_offset = strbuf_get_len (&offset_buf) != 0; 161 | // EXT_texture_shadow_lod defines a few more functions handling bias 162 | if (has_bias && 163 | + ctx->cfg->has_texture_shadow_lod && 164 | (inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY || 165 | inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE || 166 | inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY)) 167 | @@ -3363,6 +3364,7 @@ 168 | 169 | // EXT_texture_shadow_lod also adds the missing textureOffset for 2DArrayShadow in GLES 170 | if ((has_bias || has_offset) && ctx->cfg->use_gles && 171 | + ctx->cfg->has_texture_shadow_lod && 172 | (inst->Texture.Texture == TGSI_TEXTURE_SHADOW1D_ARRAY || 173 | inst->Texture.Texture == TGSI_TEXTURE_SHADOW2D_ARRAY)) 174 | ctx->shader_req_bits |= SHADER_REQ_TEXTURE_SHADOW_LOD; 175 | @@ -6301,10 +6303,10 @@ 176 | 177 | if (ctx->prog_type == TGSI_PROCESSOR_VERTEX && ctx->cfg->use_explicit_locations) 178 | emit_ext(glsl_strbufs, "ARB_explicit_attrib_location", "require"); 179 | - if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && fs_emit_layout(ctx)) 180 | + if (ctx->prog_type == TGSI_PROCESSOR_FRAGMENT && fs_emit_layout(ctx) && !ctx->cfg->gl_apple) 181 | emit_ext(glsl_strbufs, "ARB_fragment_coord_conventions", "require"); 182 | 183 | - if (ctx->ubo_used_mask) 184 | + if (ctx->ubo_used_mask && !ctx->cfg->gl_apple) 185 | emit_ext(glsl_strbufs, "ARB_uniform_buffer_object", "require"); 186 | 187 | if (ctx->num_cull_dist_prop || ctx->key->num_in_cull || ctx->key->num_out_cull) 188 | @@ -6322,6 +6322,16 @@ 189 | for (uint32_t i = 0; i < ARRAY_SIZE(shader_req_table); i++) { 190 | if (shader_req_table[i].key == SHADER_REQ_SAMPLER_RECT && ctx->glsl_ver_required >= 140) 191 | continue; 192 | + if (ctx->cfg->gl_apple) { 193 | + switch (shader_req_table[i].key) { 194 | + case SHADER_REQ_SAMPLER_MS: 195 | + case SHADER_REQ_INSTANCE_ID: 196 | + case SHADER_REQ_TXQ_LEVELS: 197 | + continue; 198 | + default: 199 | + break; 200 | + } 201 | + } 202 | 203 | if (ctx->shader_req_bits & shader_req_table[i].key) { 204 | emit_ext(glsl_strbufs, shader_req_table[i].string, "require"); 205 | diff -Nru orig/virglrenderer-1.2.0/src/vrend/vrend_shader.h src/virglrenderer-1.2.0/src/vrend/vrend_shader.h 206 | --- orig/virglrenderer-1.2.0/src/vrend/vrend_shader.h 207 | +++ src/virglrenderer-1.2.0/src/vrend/vrend_shader.h 208 | @@ -244,6 +244,7 @@ 209 | uint32_t glsl_version : 12; 210 | uint32_t max_draw_buffers : 4; 211 | uint32_t max_shader_patch_varyings : 6; 212 | + uint32_t gl_apple : 1; 213 | uint32_t use_gles : 1; 214 | uint32_t use_core_profile : 1; 215 | uint32_t use_explicit_locations : 1; 216 | -------------------------------------------------------------------------------- /wrappers/mesa/src/wglinfo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #ifdef HAVE_XTRA 7 | #define __MSC__ 8 | #include 9 | /* 10 | ** grGetString types 11 | */ 12 | #define GR_EXTENSION 0xa0 13 | #define GR_HARDWARE 0xa1 14 | #define GR_RENDERER 0xa2 15 | #define GR_VENDOR 0xa3 16 | #define GR_VERSION 0xa4 17 | #endif 18 | 19 | static void MGLTmpContext(char **str, char **wstr) 20 | { 21 | #define FATAL(s) \ 22 | do { fprintf(stderr, "%s failed\n", s); \ 23 | *str = NULL; *wstr = NULL; return; } while(0) 24 | HWND tmpWin = CreateWindow("STATIC", "dummy", 25 | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 26 | 0, 0, 640, 480, NULL, NULL, NULL, NULL); 27 | HDC tmpDC = GetDC(tmpWin); 28 | PIXELFORMATDESCRIPTOR pfd; 29 | memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); 30 | pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); 31 | pfd.nVersion = 1; 32 | pfd.iPixelType = PFD_TYPE_RGBA; 33 | pfd.iLayerType = PFD_MAIN_PLANE, 34 | pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; 35 | pfd.cColorBits = 32; 36 | pfd.cDepthBits = 24; 37 | pfd.cAlphaBits = 8; 38 | pfd.cStencilBits = 8; 39 | HGLRC tmpGL; 40 | if (SetPixelFormat(tmpDC, ChoosePixelFormat(tmpDC, &pfd), &pfd)) { 41 | tmpGL = wglCreateContext(tmpDC); 42 | wglMakeCurrent(tmpDC, tmpGL); 43 | } 44 | else 45 | FATAL("SetPixelFormat()"); 46 | 47 | const char * (WINAPI *wglGetString)(HDC hdc) = (const char * (WINAPI *)(HDC)) 48 | wglGetProcAddress("wglGetExtensionsStringARB"); 49 | int (WINAPI *wglGetSwapIntervalEXT)(void) = (int (WINAPI *)(void)) 50 | wglGetProcAddress("wglGetSwapIntervalEXT"); 51 | /* 52 | BOOL (WINAPI *wglChoosePixelFormatARB)(HDC, const int *, const FLOAT *, UINT, int *, UINT *) = 53 | (BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *)) 54 | wglGetProcAddress("wglChoosePixelFormatARB"); 55 | */ 56 | BOOL (WINAPI *wglGetPixelFormatAttribivARB)(HDC, int, int, UINT, const int *, int *) = 57 | (BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *)) 58 | wglGetProcAddress("wglGetPixelFormatAttribivARB"); 59 | 60 | const int na[] = { WGL_NUMBER_PIXEL_FORMATS_ARB }, 61 | piAttr[] = { 62 | WGL_DRAW_TO_WINDOW_ARB, 63 | WGL_DRAW_TO_BITMAP_ARB, 64 | WGL_ACCELERATION_ARB, 65 | WGL_NEED_PALETTE_ARB, 66 | WGL_NEED_SYSTEM_PALETTE_ARB, 67 | WGL_SWAP_LAYER_BUFFERS_ARB, 68 | WGL_SWAP_METHOD_ARB, 69 | WGL_NUMBER_OVERLAYS_ARB, 70 | WGL_NUMBER_UNDERLAYS_ARB, 71 | WGL_SUPPORT_GDI_ARB, 72 | WGL_SUPPORT_OPENGL_ARB, 73 | WGL_DOUBLE_BUFFER_ARB, 74 | WGL_STEREO_ARB, 75 | WGL_PIXEL_TYPE_ARB, 76 | WGL_COLOR_BITS_ARB, 77 | WGL_RED_BITS_ARB, 78 | WGL_GREEN_BITS_ARB, 79 | WGL_BLUE_BITS_ARB, 80 | WGL_ALPHA_BITS_ARB, 81 | WGL_ALPHA_SHIFT_ARB, 82 | WGL_RED_SHIFT_ARB, 83 | WGL_GREEN_SHIFT_ARB, 84 | WGL_BLUE_SHIFT_ARB, 85 | WGL_ACCUM_BITS_ARB, 86 | WGL_ACCUM_RED_BITS_ARB, 87 | WGL_ACCUM_GREEN_BITS_ARB, 88 | WGL_ACCUM_BLUE_BITS_ARB, 89 | WGL_ACCUM_ALPHA_BITS_ARB, 90 | WGL_DEPTH_BITS_ARB, 91 | WGL_STENCIL_BITS_ARB, 92 | WGL_AUX_BUFFERS_ARB, 93 | WGL_SAMPLE_BUFFERS_ARB, 94 | WGL_SAMPLES_ARB, 95 | }; 96 | const UINT nAttr = sizeof(piAttr) / sizeof(int); 97 | int nPix, n[nAttr]; 98 | 99 | const char accel[] = "0NGF", 100 | swap[] = "XCU", 101 | type[] = "f0rc"; 102 | const struct { 103 | char *fmt; 104 | int enm; 105 | } strname[] = { 106 | { .fmt = "Renderer : %s [ %d ]\n", .enm = GL_RENDERER, }, 107 | { .fmt = "Vendor : %s [ %d ]\n", .enm = GL_VENDOR, }, 108 | { .fmt = "Version : %s [ %d ]\n\n", .enm = GL_VERSION, }, 109 | { .fmt = "Shading Language Version : %s [ %d ]\n\n", .enm = GL_SHADING_LANGUAGE_VERSION, }, 110 | { .fmt = 0, .enm = 0, }, 111 | }; 112 | for (int i = 0; strname[i].enm; i++) { 113 | const char *namestr; 114 | char *namebuf; 115 | namestr = (const char *)glGetString(strname[i].enm); 116 | namebuf = (namestr)? HeapAlloc(GetProcessHeap(), 0, 1 + strlen(namestr)):0; 117 | if (namestr && namebuf) { 118 | lstrcpy(namebuf, namestr); 119 | printf(strname[i].fmt, namebuf, 1 + strlen(namestr)); 120 | HeapFree(GetProcessHeap(), 0, namebuf); 121 | } 122 | } 123 | 124 | if (!wglGetPixelFormatAttribivARB) 125 | FATAL("wglGetPixelFormatAttribivARB()"); 126 | wglGetPixelFormatAttribivARB(tmpDC, 1, 0, 1, na, &nPix); 127 | printf("Total pixel formats %d swap interval %d\n", nPix, wglGetSwapIntervalEXT()); 128 | printf("\n" 129 | " w b a p n s s o u g o d s t a \n" 130 | " i m c a s l w v n d g b t y ac u n\n" 131 | " fmt n p c l p y p l l i l f e p cb r g b a a r g b cm r g b a d s x b s\n" 132 | "--------------------------------------------------------------------------------------------\n"); 133 | /* 134 | 0x001 1 0 F 0 0 0 U 0 0 0 1 0 0 r 32 8 8 8 0 0 16 8 0 64 16 16 16 16 24 0 4 0 0 135 | 0x002 1 0 F 0 0 0 U 0 0 0 1 0 0 r 32 8 8 8 8 24 16 8 0 64 16 16 16 16 24 0 4 0 0 136 | 0x003 1 0 F 0 0 0 U 0 0 0 1 0 0 r 32 8 8 8 0 0 16 8 0 64 16 16 16 16 24 8 4 0 0 137 | */ 138 | int curr = GetPixelFormat(tmpDC); 139 | wglGetPixelFormatAttribivARB(tmpDC, curr, 0, nAttr, piAttr, n); 140 | printf( 141 | "0x%03x %-2x%-2x%-2c%-2x%-2x%-2x%-2c%-2x%-2x%-2x%-2x%-2x%-2x%-2c%3d %3d%3d%3d%3d %3d%3d%3d%3d %2d %2d %2d %2d %2d %2d %d %d %d %2d\n", 142 | curr, n[0],n[1],accel[n[2]&0x3],n[3],n[4],n[5],swap[n[6]&0x3],n[7],n[8],n[9],n[10],n[11],n[12],type[(n[13]&0xC)>>2],n[14],n[15], 143 | n[16],n[17],n[18],n[19],n[20],n[21],n[22],n[23],n[24],n[25],n[26],n[27],n[28],n[29],n[30],n[31],n[32]); 144 | for (int i = 1; i <= nPix; i++) { 145 | if (curr == i ) 146 | continue; 147 | wglGetPixelFormatAttribivARB(tmpDC, i, 0, nAttr, piAttr, n); 148 | printf( 149 | "0x%03x %-2x%-2x%-2c%-2x%-2x%-2x%-2c%-2x%-2x%-2x%-2x%-2x%-2x%-2c%3d %3d%3d%3d%3d %3d%3d%3d%3d %2d %2d %2d %2d %2d %2d %d %d %d %2d\n", 150 | i, n[0],n[1],accel[n[2]&0x3],n[3],n[4],n[5],swap[n[6]&0x3],n[7],n[8],n[9],n[10],n[11],n[12],type[(n[13]&0xC)>>2],n[14],n[15], 151 | n[16],n[17],n[18],n[19],n[20],n[21],n[22],n[23],n[24],n[25],n[26],n[27],n[28],n[29],n[30],n[31],n[32]); 152 | } 153 | printf("\n"); 154 | 155 | const char *glstr = (const char *)glGetString(GL_EXTENSIONS), 156 | *wglstr = (const char *)wglGetString(tmpDC); 157 | 158 | *str = HeapAlloc(GetProcessHeap(), 0, (glstr)? (1 + strlen(glstr)):sizeof(void *)); 159 | *wstr = HeapAlloc(GetProcessHeap(), 0, (wglstr)? (1 + strlen(wglstr)):sizeof(void *)); 160 | if (*str) 161 | lstrcpy(*str, glstr); 162 | if (*wstr) 163 | lstrcpy(*wstr, wglstr); 164 | 165 | wglMakeCurrent(NULL, NULL); 166 | wglDeleteContext(tmpGL); 167 | ReleaseDC(tmpWin, tmpDC); 168 | DestroyWindow(tmpWin); 169 | } 170 | 171 | void fxprobe(void) 172 | { 173 | #ifdef HAVE_XTRA 174 | struct _pfn { 175 | int (FX_CALL *sstQueryBoards)(void *); 176 | int (FX_CALL *sstQueryHardware)(void *); 177 | void (FX_CALL *glideGetVersion)(void *); 178 | void (FX_CALL *glideInit)(void); 179 | void (FX_CALL *glideShutdown)(void); 180 | int (FX_CALL *texMinAddress)(int); 181 | int (FX_CALL *texMaxAddress)(int); 182 | const char *(FX_CALL *getString)(int); 183 | } _fx; 184 | 185 | HMODULE fx = LoadLibrary("glide2x.dll"); 186 | if (fx) { 187 | _fx.sstQueryBoards = (int (FX_CALL *)(void *)) GetProcAddress(fx, "_grSstQueryBoards@4"); 188 | _fx.sstQueryHardware = (int (FX_CALL *)(void *)) GetProcAddress(fx, "_grSstQueryHardware@4"); 189 | _fx.glideInit = (void (FX_CALL *)(void)) GetProcAddress(fx, "_grGlideInit@0"); 190 | _fx.glideShutdown = (void (FX_CALL *)(void)) GetProcAddress(fx, "_grGlideShutdown@0"); 191 | _fx.glideGetVersion = (void (FX_CALL *)(void *)) GetProcAddress(fx, "_grGlideGetVersion@4"); 192 | _fx.texMinAddress = (int (FX_CALL *)(int)) GetProcAddress(fx, "_grTexMinAddress@4"); 193 | _fx.texMaxAddress = (int (FX_CALL *)(int)) GetProcAddress(fx, "_grTexMaxAddress@4"); 194 | 195 | GrHwConfiguration hwc; 196 | char version[80]; 197 | const char *sstType[] = { 198 | "VOODOO", "SST96", "AT3D", "Voodoo2", "Banshee", "Voodoo3", "Voodoo4", "Other", 199 | }; 200 | if (_fx.sstQueryBoards(&hwc) && hwc.num_sst) { 201 | _fx.glideInit(); 202 | _fx.glideGetVersion(version); 203 | printf("\nnum_sst %d - %s\n", hwc.num_sst, version); 204 | if (_fx.sstQueryHardware(&hwc)) { 205 | for (int i = 0; i < hwc.num_sst; i++) { 206 | printf(" Board type: %s\n", sstType[hwc.SSTs[i].type & 0x7U]); 207 | printf(" FBI rev %d: %2d MB\n", hwc.SSTs[i].sstBoard.VoodooConfig.fbiRev & 0xFU, 208 | hwc.SSTs[i].sstBoard.VoodooConfig.fbRam); 209 | for (int j = 0; j < hwc.SSTs[i].sstBoard.VoodooConfig.nTexelfx; j++) 210 | printf(" TMU%d rev %d: %2d MB addr %08x-%08x\n", j, 211 | hwc.SSTs[i].sstBoard.VoodooConfig.tmuConfig[j].tmuRev & 0xFU, 212 | hwc.SSTs[i].sstBoard.VoodooConfig.tmuConfig[j].tmuRam, 213 | _fx.texMinAddress(j), _fx.texMaxAddress(j)); 214 | printf(" SLI detect: %s\n", (hwc.SSTs[i].sstBoard.VoodooConfig.sliDetect)? "Yes":"No"); 215 | } 216 | } 217 | _fx.glideShutdown(); 218 | } 219 | FreeLibrary(fx); 220 | } 221 | fx = LoadLibrary("glide3x.dll"); 222 | if (fx) { 223 | _fx.glideInit = (void (FX_CALL *)(void)) GetProcAddress(fx, "_grGlideInit@0"); 224 | _fx.glideShutdown = (void (FX_CALL *)(void)) GetProcAddress(fx, "_grGlideShutdown@0"); 225 | _fx.getString = (const char *(FX_CALL *)(int)) GetProcAddress(fx, "_grGetString@4"); 226 | 227 | _fx.glideInit(); 228 | printf("\n Vendor : %s %s\n", _fx.getString(GR_VENDOR), _fx.getString(GR_RENDERER)); 229 | printf(" Extension : %s\n", _fx.getString(GR_EXTENSION)); 230 | printf(" Hardware : %s\n", _fx.getString(GR_HARDWARE)); 231 | printf(" Version : %s\n", _fx.getString(GR_VERSION)); 232 | _fx.glideShutdown(); 233 | FreeLibrary(fx); 234 | } 235 | #endif //HAVE_XTRA 236 | } 237 | 238 | int main() 239 | { 240 | char *str; 241 | char *wstr; 242 | MGLTmpContext(&str, &wstr); 243 | if (str && wstr) { 244 | printf("%s [ %d ]\n%s [ %d ]\n", str, 1 + strlen(str), wstr, 1 + strlen(wstr)); 245 | HeapFree(GetProcessHeap(), 0, str); 246 | HeapFree(GetProcessHeap(), 0, wstr); 247 | fxprobe(); 248 | } 249 | return 0; 250 | } 251 | 252 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/extensions_defs.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** 5 | * Enable flag for each OpenGL extension. Different device drivers will 6 | * enable different extensions at runtime. 7 | */ 8 | struct gl_extensions 9 | { 10 | uint32_t dummy; /* don't remove this! */ 11 | uint32_t dummy_true; /* Set true by _mesa_init_extensions(). */ 12 | uint32_t ANGLE_texture_compression_dxt; 13 | uint32_t ARB_ES2_compatibility; 14 | uint32_t ARB_ES3_compatibility; 15 | uint32_t ARB_ES3_1_compatibility; 16 | uint32_t ARB_ES3_2_compatibility; 17 | uint32_t ARB_arrays_of_arrays; 18 | uint32_t ARB_base_instance; 19 | uint32_t ARB_bindless_texture; 20 | uint32_t ARB_blend_func_extended; 21 | uint32_t ARB_buffer_storage; 22 | uint32_t ARB_clip_control; 23 | uint32_t ARB_color_buffer_float; 24 | uint32_t ARB_compatibility; 25 | uint32_t ARB_compute_shader; 26 | uint32_t ARB_compute_variable_group_size; 27 | uint32_t ARB_conditional_render_inverted; 28 | uint32_t ARB_conservative_depth; 29 | uint32_t ARB_copy_image; 30 | uint32_t ARB_cull_distance; 31 | uint32_t ARB_depth_buffer_float; 32 | uint32_t ARB_depth_clamp; 33 | uint32_t ARB_derivative_control; 34 | uint32_t ARB_draw_buffers_blend; 35 | uint32_t ARB_draw_elements_base_vertex; 36 | uint32_t ARB_draw_indirect; 37 | uint32_t ARB_draw_instanced; 38 | uint32_t ARB_fragment_coord_conventions; 39 | uint32_t ARB_fragment_layer_viewport; 40 | uint32_t ARB_fragment_program; 41 | uint32_t ARB_fragment_program_shadow; 42 | uint32_t ARB_fragment_shader; 43 | uint32_t ARB_framebuffer_no_attachments; 44 | uint32_t ARB_framebuffer_object; 45 | uint32_t ARB_fragment_shader_interlock; 46 | uint32_t ARB_enhanced_layouts; 47 | uint32_t ARB_explicit_attrib_location; 48 | uint32_t ARB_explicit_uniform_location; 49 | uint32_t ARB_gl_spirv; 50 | uint32_t ARB_gpu_shader5; 51 | uint32_t ARB_gpu_shader_fp64; 52 | uint32_t ARB_gpu_shader_int64; 53 | uint32_t ARB_half_float_vertex; 54 | uint32_t ARB_indirect_parameters; 55 | uint32_t ARB_instanced_arrays; 56 | uint32_t ARB_internalformat_query; 57 | uint32_t ARB_internalformat_query2; 58 | uint32_t ARB_map_buffer_range; 59 | uint32_t ARB_occlusion_query; 60 | uint32_t ARB_occlusion_query2; 61 | uint32_t ARB_pipeline_statistics_query; 62 | uint32_t ARB_polygon_offset_clamp; 63 | uint32_t ARB_post_depth_coverage; 64 | uint32_t ARB_query_buffer_object; 65 | uint32_t ARB_robust_buffer_access_behavior; 66 | uint32_t ARB_sample_locations; 67 | uint32_t ARB_sample_shading; 68 | uint32_t ARB_seamless_cube_map; 69 | uint32_t ARB_shader_atomic_counter_ops; 70 | uint32_t ARB_shader_atomic_counters; 71 | uint32_t ARB_shader_ballot; 72 | uint32_t ARB_shader_bit_encoding; 73 | uint32_t ARB_shader_clock; 74 | uint32_t ARB_shader_draw_parameters; 75 | uint32_t ARB_shader_group_vote; 76 | uint32_t ARB_shader_image_load_store; 77 | uint32_t ARB_shader_image_size; 78 | uint32_t ARB_shader_precision; 79 | uint32_t ARB_shader_stencil_export; 80 | uint32_t ARB_shader_storage_buffer_object; 81 | uint32_t ARB_shader_texture_image_samples; 82 | uint32_t ARB_shader_texture_lod; 83 | uint32_t ARB_shader_viewport_layer_array; 84 | uint32_t ARB_shading_language_packing; 85 | uint32_t ARB_shading_language_420pack; 86 | uint32_t ARB_shadow; 87 | uint32_t ARB_sparse_buffer; 88 | uint32_t ARB_sparse_texture; 89 | uint32_t ARB_sparse_texture2; 90 | uint32_t ARB_sparse_texture_clamp; 91 | uint32_t ARB_stencil_texturing; 92 | uint32_t ARB_spirv_extensions; 93 | uint32_t ARB_sync; 94 | uint32_t ARB_tessellation_shader; 95 | uint32_t ARB_texture_buffer_object; 96 | uint32_t ARB_texture_buffer_object_rgb32; 97 | uint32_t ARB_texture_buffer_range; 98 | uint32_t ARB_texture_compression_bptc; 99 | uint32_t ARB_texture_compression_rgtc; 100 | uint32_t ARB_texture_cube_map_array; 101 | uint32_t ARB_texture_filter_anisotropic; 102 | uint32_t ARB_texture_filter_minmax; 103 | uint32_t ARB_texture_float; 104 | uint32_t ARB_texture_gather; 105 | uint32_t ARB_texture_mirror_clamp_to_edge; 106 | uint32_t ARB_texture_multisample; 107 | uint32_t ARB_texture_non_power_of_two; 108 | uint32_t ARB_texture_stencil8; 109 | uint32_t ARB_texture_query_levels; 110 | uint32_t ARB_texture_query_lod; 111 | uint32_t ARB_texture_rg; 112 | uint32_t ARB_texture_rgb10_a2ui; 113 | uint32_t ARB_texture_view; 114 | uint32_t ARB_timer_query; 115 | uint32_t ARB_transform_feedback2; 116 | uint32_t ARB_transform_feedback3; 117 | uint32_t ARB_transform_feedback_instanced; 118 | uint32_t ARB_transform_feedback_overflow_query; 119 | uint32_t ARB_uniform_buffer_object; 120 | uint32_t ARB_vertex_attrib_64bit; 121 | uint32_t ARB_vertex_program; 122 | uint32_t ARB_vertex_shader; 123 | uint32_t ARB_vertex_type_10f_11f_11f_rev; 124 | uint32_t ARB_vertex_type_2_10_10_10_rev; 125 | uint32_t ARB_viewport_array; 126 | uint32_t EXT_blend_equation_separate; 127 | uint32_t EXT_color_buffer_float; 128 | uint32_t EXT_color_buffer_half_float; 129 | uint32_t EXT_demote_to_helper_invocation; 130 | uint32_t EXT_depth_bounds_test; 131 | uint32_t EXT_disjoint_timer_query; 132 | uint32_t EXT_draw_buffers2; 133 | uint32_t EXT_EGL_image_storage; 134 | uint32_t EXT_float_blend; 135 | uint32_t EXT_framebuffer_multisample; 136 | uint32_t EXT_framebuffer_multisample_blit_scaled; 137 | uint32_t EXT_framebuffer_sRGB; 138 | uint32_t EXT_gpu_program_parameters; 139 | uint32_t EXT_gpu_shader4; 140 | uint32_t EXT_memory_object; 141 | uint32_t EXT_memory_object_fd; 142 | uint32_t EXT_memory_object_win32; 143 | uint32_t EXT_multisampled_render_to_texture; 144 | uint32_t EXT_packed_float; 145 | uint32_t EXT_protected_textures; 146 | uint32_t EXT_provoking_vertex; 147 | uint32_t EXT_render_snorm; 148 | uint32_t EXT_semaphore; 149 | uint32_t EXT_semaphore_fd; 150 | uint32_t EXT_semaphore_win32; 151 | uint32_t EXT_shader_image_load_formatted; 152 | uint32_t EXT_shader_image_load_store; 153 | uint32_t EXT_shader_integer_mix; 154 | uint32_t EXT_shader_samples_identical; 155 | uint32_t EXT_sRGB; 156 | uint32_t EXT_stencil_two_side; 157 | uint32_t EXT_shadow_samplers; 158 | uint32_t EXT_texture_array; 159 | uint32_t EXT_texture_buffer_object; 160 | uint32_t EXT_texture_compression_astc_decode_mode; 161 | uint32_t EXT_texture_compression_latc; 162 | uint32_t EXT_texture_compression_s3tc; 163 | uint32_t EXT_texture_compression_s3tc_srgb; 164 | uint32_t EXT_texture_env_dot3; 165 | uint32_t EXT_texture_filter_anisotropic; 166 | uint32_t EXT_texture_filter_minmax; 167 | uint32_t EXT_texture_integer; 168 | uint32_t EXT_texture_mirror_clamp; 169 | uint32_t EXT_texture_norm16; 170 | uint32_t EXT_texture_shadow_lod; 171 | uint32_t EXT_texture_shared_exponent; 172 | uint32_t EXT_texture_snorm; 173 | uint32_t EXT_texture_sRGB; 174 | uint32_t EXT_texture_sRGB_R8; 175 | uint32_t EXT_texture_sRGB_RG8; 176 | uint32_t EXT_texture_sRGB_decode; 177 | uint32_t EXT_texture_swizzle; 178 | uint32_t EXT_texture_type_2_10_10_10_REV; 179 | uint32_t EXT_transform_feedback; 180 | uint32_t EXT_timer_query; 181 | uint32_t EXT_vertex_array_bgra; 182 | uint32_t EXT_window_rectangles; 183 | uint32_t OES_copy_image; 184 | uint32_t OES_primitive_bounding_box; 185 | uint32_t OES_sample_variables; 186 | uint32_t OES_standard_derivatives; 187 | uint32_t OES_texture_buffer; 188 | uint32_t OES_texture_cube_map_array; 189 | uint32_t OES_texture_view; 190 | uint32_t OES_viewport_array; 191 | uint32_t OVR_multiview; 192 | uint32_t OVR_multiview2; 193 | uint32_t OVR_multiview_multisampled_render_to_texture; 194 | /* vendor extensions */ 195 | uint32_t AMD_compressed_ATC_texture; 196 | uint32_t AMD_framebuffer_multisample_advanced; 197 | uint32_t AMD_depth_clamp_separate; 198 | uint32_t AMD_gpu_shader_half_float; 199 | uint32_t AMD_performance_monitor; 200 | uint32_t AMD_pinned_memory; 201 | uint32_t AMD_seamless_cubemap_per_texture; 202 | uint32_t AMD_vertex_shader_layer; 203 | uint32_t AMD_vertex_shader_viewport_index; 204 | uint32_t ANDROID_extension_pack_es31a; 205 | uint32_t ARM_shader_framebuffer_fetch_depth_stencil; 206 | uint32_t ATI_meminfo; 207 | uint32_t ATI_texture_compression_3dc; 208 | uint32_t ATI_texture_mirror_once; 209 | uint32_t ATI_texture_env_combine3; 210 | uint32_t ATI_fragment_shader; 211 | uint32_t GREMEDY_string_marker; 212 | uint32_t INTEL_blackhole_render; 213 | uint32_t INTEL_conservative_rasterization; 214 | uint32_t INTEL_performance_query; 215 | uint32_t INTEL_shader_atomic_float_minmax; 216 | uint32_t INTEL_shader_integer_functions2; 217 | uint32_t KHR_blend_equation_advanced; 218 | uint32_t KHR_blend_equation_advanced_coherent; 219 | uint32_t KHR_robustness; 220 | uint32_t KHR_shader_subgroup; 221 | uint32_t KHR_texture_compression_astc_hdr; 222 | uint32_t KHR_texture_compression_astc_ldr; 223 | uint32_t KHR_texture_compression_astc_sliced_3d; 224 | uint32_t MESA_framebuffer_flip_y; 225 | uint32_t MESA_texture_const_bandwidth; 226 | uint32_t MESA_pack_invert; 227 | uint32_t MESA_tile_raster_order; 228 | uint32_t EXT_shader_framebuffer_fetch; 229 | uint32_t EXT_shader_framebuffer_fetch_non_coherent; 230 | uint32_t MESA_shader_integer_functions; 231 | uint32_t MESA_window_pos; 232 | uint32_t MESA_ycbcr_texture; 233 | uint32_t NV_alpha_to_coverage_dither_control; 234 | uint32_t NV_compute_shader_derivatives; 235 | uint32_t NV_conditional_render; 236 | uint32_t NV_copy_depth_to_color; 237 | uint32_t NV_copy_image; 238 | uint32_t NV_fill_rectangle; 239 | uint32_t NV_fog_distance; 240 | uint32_t NV_primitive_restart; 241 | uint32_t NV_shader_atomic_float; 242 | uint32_t NV_shader_atomic_int64; 243 | uint32_t NV_texture_barrier; 244 | uint32_t NV_texture_env_combine4; 245 | uint32_t NV_texture_rectangle; 246 | uint32_t NV_vdpau_interop; 247 | uint32_t NV_conservative_raster; 248 | uint32_t NV_conservative_raster_dilate; 249 | uint32_t NV_conservative_raster_pre_snap_triangles; 250 | uint32_t NV_conservative_raster_pre_snap; 251 | uint32_t NV_viewport_array2; 252 | uint32_t NV_viewport_swizzle; 253 | uint32_t NVX_gpu_memory_info; 254 | uint32_t TDFX_texture_compression_FXT1; 255 | uint32_t OES_EGL_image; 256 | uint32_t OES_draw_texture; 257 | uint32_t OES_depth_texture_cube_map; 258 | uint32_t OES_EGL_image_external; 259 | uint32_t OES_texture_3D; 260 | uint32_t OES_texture_float; 261 | uint32_t OES_texture_float_linear; 262 | uint32_t OES_texture_half_float; 263 | uint32_t OES_texture_half_float_linear; 264 | uint32_t OES_compressed_ETC1_RGB8_texture; 265 | uint32_t OES_geometry_shader; 266 | uint32_t OES_texture_compression_astc; 267 | uint32_t extension_sentinel; 268 | /** The extension string */ 269 | const uint8_t *String; 270 | /** Number of supported extensions */ 271 | uint32_t Count; 272 | /** 273 | * The context version which extension helper functions compare against. 274 | * By default, the value is equal to ctx->Version. This changes to ~0 275 | * while meta is in progress. 276 | */ 277 | uint8_t Version; 278 | }; 279 | 280 | /** 281 | * Enum for the OpenGL APIs we know about and may support. 282 | * 283 | * NOTE: This must match the api_enum table in 284 | * src/mesa/main/get_hash_generator.py 285 | */ 286 | typedef enum 287 | { 288 | API_OPENGL_COMPAT, /* legacy / compatibility contexts */ 289 | API_OPENGLES, 290 | API_OPENGLES2, 291 | API_OPENGL_CORE, 292 | API_OPENGL_LAST = API_OPENGL_CORE 293 | } gl_api; 294 | 295 | /** 296 | * \brief An element of the \c extension_table. 297 | */ 298 | struct mesa_extension { 299 | /** Name of extension, such as "GL_ARB_depth_clamp". */ 300 | const char *name; 301 | 302 | /** Offset (in bytes) of the corresponding member in struct gl_extensions. */ 303 | size_t offset; 304 | 305 | /** Minimum version the extension requires for the given API 306 | * (see gl_api defined in mtypes.h). The value is equal to: 307 | * 10 * major_version + minor_version 308 | */ 309 | uint8_t version[API_OPENGL_LAST + 1]; 310 | 311 | /** Year the extension was proposed or approved. Used to sort the 312 | * extension string chronologically. */ 313 | uint16_t year; 314 | }; 315 | 316 | extern const struct mesa_extension _mesa_extension_table[]; 317 | 318 | 319 | /* Generate enums for the functions below */ 320 | enum { 321 | #define EXT(name_str, ...) MESA_EXTENSION_##name_str, 322 | #include "extensions_table.h" 323 | #undef EXT 324 | MESA_EXTENSION_COUNT 325 | }; 326 | 327 | 328 | -------------------------------------------------------------------------------- /wrappers/fxlib/fxhook.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "hpat.h" 5 | 6 | void HookEntryHook(uint32_t *patch, const uint32_t orig) 7 | { 8 | #define MAX_HOOK_ENTRY 8 9 | static int nhook; 10 | static struct hookrec { 11 | uint32_t *patch; 12 | uint32_t data; 13 | } HookTbl[MAX_HOOK_ENTRY]; 14 | 15 | if (patch && orig && (nhook < MAX_HOOK_ENTRY)) { 16 | HookTbl[nhook].patch = patch; 17 | HookTbl[nhook].data = orig; 18 | nhook++; 19 | } 20 | 21 | if (!patch && !orig) { 22 | DWORD oldProt; 23 | if (nhook) { 24 | for (int i = 0; i < nhook; i++) { 25 | VirtualProtect(HookTbl[i].patch, sizeof(intptr_t), PAGE_EXECUTE_READWRITE, &oldProt); 26 | if (!IsBadWritePtr(HookTbl[i].patch, sizeof(intptr_t))) 27 | (HookTbl[i].patch)[0] = HookTbl[i].data; 28 | VirtualProtect(HookTbl[i].patch, sizeof(intptr_t), oldProt, &oldProt); 29 | } 30 | } 31 | memset(HookTbl, 0, sizeof(struct hookrec[MAX_HOOK_ENTRY])); 32 | nhook = 0; 33 | } 34 | #undef MAX_HOOK_ENTRY 35 | } 36 | 37 | static inline int acpi_tick_asm(void) 38 | { 39 | int ret; 40 | int pmio = 0x608; 41 | asm volatile( 42 | "movl %1, %%edx\n" 43 | "in %%dx, %%eax\n" 44 | "movl %%eax, %0\n" 45 | :"=m"(ret) 46 | :"r"(pmio) 47 | :"edx" 48 | ); 49 | return ret; 50 | } 51 | 52 | struct tckRef { 53 | LARGE_INTEGER freq, run; 54 | }; 55 | static void HookTimeTckRef(struct tckRef **tick) 56 | { 57 | #define TICK_8254 0x1234F0U /* 1.193200 MHz */ 58 | #define TICK_ACPI 0x369E99U /* 3.579545 MHz */ 59 | static struct tckRef ref; 60 | 61 | if (!tick) { 62 | if (!ref.freq.u.LowPart) { 63 | QueryPerformanceFrequency(&ref.freq); 64 | if ((VER_PLATFORM_WIN32_WINDOWS == fxCompatPlatformId(0)) && (ref.freq.QuadPart < TICK_8254)) { 65 | LONGLONG mmTick = GetTickCount(); 66 | __atomic_store_n(&ref.run.QuadPart, ((mmTick * TICK_ACPI) / 1000), __ATOMIC_RELAXED); 67 | while (acpi_tick_asm() < (ref.run.u.LowPart & 0x00FFFFFFU)) 68 | asm volatile("pause\n"); 69 | } 70 | } 71 | } 72 | else 73 | *tick = &ref; 74 | } 75 | 76 | static BOOL WINAPI elapsedTickProc(LARGE_INTEGER *count) 77 | { 78 | struct tckRef *tick; 79 | uintptr_t aligned = (uintptr_t)count; 80 | HookTimeTckRef(&tick); 81 | 82 | if ((VER_PLATFORM_WIN32_WINDOWS == fxCompatPlatformId(0)) && (tick->freq.QuadPart < TICK_8254)) { 83 | DWORD t = acpi_tick_asm(); 84 | if ((tick->run.u.LowPart & 0x00FFFFFFU) > t) 85 | __atomic_store_n(&tick->run.QuadPart, ((((tick->run.QuadPart >> 24) + 1) << 24) | t), __ATOMIC_RELAXED); 86 | else 87 | __atomic_store_n(&tick->run.u.LowPart, ((tick->run.u.LowPart & 0xFF000000U) | t), __ATOMIC_RELAXED); 88 | 89 | if (count && !(aligned & (sizeof(uintptr_t)-1)) && !IsBadWritePtr(count, sizeof(LARGE_INTEGER))) { 90 | __atomic_store_n(&count->QuadPart, ((tick->run.QuadPart * tick->freq.QuadPart) / TICK_ACPI), __ATOMIC_RELAXED); 91 | SetLastError(0); 92 | return TRUE; 93 | } 94 | } 95 | else if (count && !(aligned & (sizeof(uintptr_t)-1)) && !IsBadWritePtr(count, sizeof(LARGE_INTEGER))) 96 | return QueryPerformanceCounter(count); 97 | SetLastError(ERROR_NOACCESS); 98 | return FALSE; 99 | } 100 | 101 | static DWORD WINAPI TimeHookProc(void) 102 | { 103 | struct tckRef *tick; 104 | LARGE_INTEGER li; 105 | HookTimeTckRef(&tick); 106 | if (tick->freq.QuadPart < TICK_8254) 107 | elapsedTickProc(&li); 108 | else 109 | QueryPerformanceCounter(&li); 110 | return (li.QuadPart * 1000) / tick->freq.QuadPart; 111 | } 112 | #undef TICK_8254 113 | #undef TICK_ACPI 114 | 115 | DWORD (WINAPI *fxTick)(void) = (DWORD (WINAPI *)(void))&TimeHookProc; 116 | 117 | void HookParseRange(uint32_t *start, uint32_t **iat, uint32_t *eoffs) 118 | { 119 | const char idata[] = ".idata", rdata[] = ".rdata", dtext[] = ".text"; 120 | uint32_t addr = *start, range = *eoffs; 121 | 122 | if (addr && (0x4550U == *(uint32_t *)addr)) { 123 | for (int i = 0; i < range; i += 0x04) { 124 | if (!memcmp((void *)(addr + i), idata, sizeof(idata))) { 125 | *eoffs = (((uint32_t *)(addr + i))[2])? 126 | ((uint32_t *)(addr + i))[2]:((uint32_t *)(addr + i))[4]; 127 | addr = (addr & ~(range - 1)) + ((uint32_t *)(addr + i))[3]; 128 | *iat = (uint32_t *)addr; 129 | *start = addr; 130 | break; 131 | } 132 | } 133 | for (int i = 0; (addr != (uint32_t)(*iat)) && (i < range); i += 0x04) { 134 | if (!memcmp((void *)(addr + i), rdata, sizeof(rdata))) { 135 | addr = (addr & ~(range - 1)) + ((uint32_t *)(addr + i))[3]; 136 | *iat = (uint32_t *)addr; 137 | *start = addr; 138 | break; 139 | } 140 | } 141 | for (int i = 0; (addr != (uint32_t)(*iat)) && (i < range); i += 0x04) { 142 | if(!memcmp((void *)(addr + i), dtext, sizeof(dtext))) { 143 | addr = (addr & ~(range - 1)) + ((uint32_t *)(addr + i))[3]; 144 | *iat = (uint32_t *)addr; 145 | *start = addr; 146 | break; 147 | } 148 | } 149 | } 150 | } 151 | 152 | #ifdef __REV__ 153 | #define OHST_DMESG(fmt, ...) 154 | #else 155 | #define PT_CALL __stdcall 156 | #define ALIGNED(x) ((x%8)?(((x>>3)+1)<<3):x) 157 | #define GL_DEBUG_SOURCE_OTHER_ARB 0x824B 158 | #define GL_DEBUG_TYPE_OTHER_ARB 0x8251 159 | #define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 160 | #define OHST_DMESG(fmt, ...) \ 161 | do { void PT_CALL glDebugMessageInsertARB(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, uint32_t arg5); \ 162 | FILE *f = fopen("NUL", "w"); int c = fprintf(f, fmt, ##__VA_ARGS__); fclose(f); \ 163 | char *str = HeapAlloc(GetProcessHeap(), 0, ALIGNED((c+1))); \ 164 | sprintf(str, fmt, ##__VA_ARGS__); \ 165 | glDebugMessageInsertARB(GL_DEBUG_SOURCE_OTHER_ARB, GL_DEBUG_TYPE_OTHER_ARB, GL_DEBUG_SEVERITY_LOW_ARB, -1, (c+1), (uint32_t)str); \ 166 | HeapFree(GetProcessHeap(), 0, str); \ 167 | } while(0) 168 | #endif 169 | #define FFOP_KERNELTICK 0x0001 170 | #define FFOP_TIMEEVENT 0x0002 171 | static void HookPatchTimer(const uint32_t start, const uint32_t *iat, 172 | const DWORD range, const DWORD dwFFop) 173 | { 174 | DWORD oldProt; 175 | uint32_t addr = start, *patch = (uint32_t *)iat; 176 | const char funcTime[] = "timeGetTime", 177 | funcEventKill[] = "timeKillEvent", 178 | funcEventSet[] = "timeSetEvent", 179 | funcTick[] = "GetTickCount", 180 | funcPerf[] = "QueryPerformanceCounter"; 181 | 182 | if (addr && (addr == (uint32_t)patch) && 183 | VirtualProtect(patch, sizeof(intptr_t), PAGE_EXECUTE_READWRITE, &oldProt)) { 184 | DWORD hkTime = (DWORD)GetProcAddress(GetModuleHandle("winmm.dll"), funcTime), 185 | hkEventKill = (dwFFop & FFOP_TIMEEVENT)? 186 | (DWORD)GetProcAddress(GetModuleHandle("winmm.dll"), funcEventKill):0, 187 | hkEventSet = (dwFFop & FFOP_TIMEEVENT)? 188 | (DWORD)GetProcAddress(GetModuleHandle("winmm.dll"), funcEventSet):0, 189 | hkTick = (dwFFop & FFOP_KERNELTICK)? 190 | (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"), funcTick):0, 191 | hkPerf = (VER_PLATFORM_WIN32_WINDOWS == fxCompatPlatformId(0) && 192 | !(dwFFop & FFOP_KERNELTICK))? 193 | (DWORD)GetProcAddress(GetModuleHandle("kernel32.dll"), funcPerf):0; 194 | EVENTFX timeEvent; 195 | fxEventHookPtr(&timeEvent); 196 | for (int i = 0; i < (range >> 2); i++) { 197 | #define HOOKPROC(haddr, proc, name) \ 198 | if (haddr && (haddr == patch[i])) { \ 199 | HookEntryHook(&patch[i], patch[i]); \ 200 | patch[i] = (uint32_t)proc; \ 201 | haddr = 0; \ 202 | OHST_DMESG("..hooked %s", name); } 203 | HOOKPROC(hkTime, &TimeHookProc, funcTime); 204 | HOOKPROC(hkEventKill, timeEvent.Kill, funcEventKill); 205 | HOOKPROC(hkEventSet, timeEvent.Set, funcEventSet); 206 | HOOKPROC(hkTick, &TimeHookProc, funcTick); 207 | HOOKPROC(hkPerf, &elapsedTickProc, funcPerf); 208 | } 209 | VirtualProtect(patch, sizeof(intptr_t), oldProt, &oldProt); 210 | } 211 | } 212 | 213 | static void dolog_compat_patched(void) 214 | { 215 | PCOMPATFX nptr = fxCompatTblPtr(); 216 | for (int i = 0; nptr && nptr[i].modName; i++) { 217 | if (nptr[i].op_mask & HP_DONE) 218 | OHST_DMESG("..%s patched", nptr[i].modName); 219 | } 220 | } 221 | 222 | void HookGetTimeModAddr(const SYSTEM_INFO *si, const DWORD dwFFop, const uint32_t maddr) 223 | { 224 | uint32_t addr = maddr, *patch, range; 225 | HookTimeTckRef(0); 226 | for (int i = 0; addr && (i < si->dwPageSize); i+=0x04) { 227 | if (0x4550U == *(uint32_t *)addr) break; 228 | addr += 0x04; 229 | } 230 | addr = (addr && (0x4550U == *(uint32_t *)addr))? addr:0; 231 | patch = (uint32_t *)(addr & ~(si->dwPageSize - 1)); 232 | range = si->dwPageSize; 233 | HookParseRange(&addr, &patch, &range); 234 | HookPatchTimer(addr, patch, range - (((uint32_t)patch) & (si->dwPageSize - 1)), dwFFop); 235 | } 236 | 237 | void HookTimeGetTime(const uint32_t caddr) 238 | { 239 | uint32_t addr, *patch; 240 | SYSTEM_INFO si; 241 | char buffer[MAX_PATH + 1], dotstr[] = ".hook"; 242 | unsigned int len = GetModuleFileName(0, buffer, sizeof(buffer)); 243 | struct { 244 | int modNum; 245 | char *modName[9]; 246 | } modList = { 247 | .modNum = 0, 248 | .modName = { 249 | &buffer[(0 * (MAX_PATH / 8))], 250 | &buffer[(1 * (MAX_PATH / 8))], 251 | &buffer[(2 * (MAX_PATH / 8))], 252 | &buffer[(3 * (MAX_PATH / 8))], 253 | &buffer[(4 * (MAX_PATH / 8))], 254 | &buffer[(5 * (MAX_PATH / 8))], 255 | &buffer[(6 * (MAX_PATH / 8))], 256 | &buffer[(7 * (MAX_PATH / 8))], 257 | NULL, 258 | } 259 | }; 260 | 261 | GetSystemInfo(&si); 262 | HookTimeTckRef(0); 263 | DWORD dwFFop = 0; 264 | 265 | if (len && len < (MAX_PATH - sizeof(dotstr))) { 266 | strncat(buffer, dotstr, MAX_PATH); 267 | FILE *fp = fopen(buffer, "r"); 268 | if (fp) { 269 | char line[32]; 270 | while(fgets(line, sizeof(line), fp)) { 271 | addr = strtoul(line, 0, 16); 272 | if (addr > 0x1000) { 273 | addr &= ~(si.dwPageSize - 1); 274 | patch = (uint32_t *)addr; 275 | HookPatchTimer(addr, patch, si.dwPageSize, dwFFop); 276 | dwFFop = 0; 277 | } 278 | else { 279 | if (!memcmp(line, "0xFF,KernelTick", strlen("0xFF,KernelTick"))) 280 | dwFFop |= FFOP_KERNELTICK; 281 | if (!memcmp(line, "0xFF,TimeEvent", strlen("0xFF,TimeEvent"))) 282 | dwFFop |= FFOP_TIMEEVENT; 283 | if (!memcmp(line, "0x0,", strlen("0x0,")) && modList.modName[modList.modNum]) { 284 | line[strcspn(line, "\r\n")] = 0; 285 | strncpy(modList.modName[modList.modNum], line + strlen("0x0,"), (MAX_PATH / 8)); 286 | modList.modNum++; 287 | } 288 | } 289 | } 290 | fclose(fp); 291 | if (!modList.modNum && !dwFFop) { 292 | dolog_compat_patched(); 293 | return; 294 | } 295 | } 296 | modList.modName[modList.modNum] = NULL; 297 | } 298 | 299 | if (caddr && !IsBadReadPtr((void *)(caddr - 0x06), 0x06)) { 300 | uint16_t *callOp = (uint16_t *)(caddr - 0x06); 301 | uint8_t *callOp2 = (uint8_t *)(caddr - 0x05); 302 | addr = (0x15ff == (*callOp))? *(uint32_t *)(caddr - 0x04):0; 303 | if (0xe8 == (*callOp2)) { 304 | uint32_t rel = *(uint32_t *)(caddr - 0x04); 305 | uint16_t *jmpOp = (uint16_t *)(caddr + rel); 306 | if (0x25ff == (*jmpOp)) 307 | addr = *(uint32_t *)(caddr + rel + 0x02); 308 | } 309 | if (addr > 0x1000) { 310 | addr &= ~(si.dwPageSize - 1); 311 | patch = (uint32_t *)addr; 312 | HookPatchTimer(addr, patch, si.dwPageSize, dwFFop); 313 | } 314 | } 315 | for (int i = 0; i <= modList.modNum; i++) { 316 | addr = (uint32_t)GetModuleHandle(modList.modName[i]); 317 | addr = (addr)? addr:((uint32_t)LoadLibrary(modList.modName[i])); 318 | HookGetTimeModAddr(&si, dwFFop, addr); 319 | } 320 | dolog_compat_patched(); 321 | } 322 | -------------------------------------------------------------------------------- /qemu-0/hw/3dfx/g2xfuncs.h: -------------------------------------------------------------------------------- 1 | 2 | /* Start - generated by mkgfuncs */ 3 | 4 | typedef enum { 5 | FEnum_ConvertAndDownloadRle, /* 0x00 */ 6 | FEnum_grAADrawLine, /* 0x01 */ 7 | FEnum_grAADrawPoint, /* 0x02 */ 8 | FEnum_grAADrawPolygon, /* 0x03 */ 9 | FEnum_grAADrawPolygonVertexList, /* 0x04 */ 10 | FEnum_grAADrawTriangle, /* 0x05 */ 11 | FEnum_grAlphaBlendFunction, /* 0x06 */ 12 | FEnum_grAlphaCombine, /* 0x07 */ 13 | FEnum_grAlphaControlsITRGBLighting, /* 0x08 */ 14 | FEnum_grAlphaTestFunction, /* 0x09 */ 15 | FEnum_grAlphaTestReferenceValue, /* 0x0a */ 16 | FEnum_grBufferClear, /* 0x0b */ 17 | FEnum_grBufferNumPending, /* 0x0c */ 18 | FEnum_grBufferSwap, /* 0x0d */ 19 | FEnum_grCheckForRoom, /* 0x0e */ 20 | FEnum_grChromakeyMode, /* 0x0f */ 21 | FEnum_grChromakeyValue, /* 0x10 */ 22 | FEnum_grClipWindow, /* 0x11 */ 23 | FEnum_grColorCombine, /* 0x12 */ 24 | FEnum_grColorMask, /* 0x13 */ 25 | FEnum_grConstantColorValue4, /* 0x14 */ 26 | FEnum_grConstantColorValue, /* 0x15 */ 27 | FEnum_grCullMode, /* 0x16 */ 28 | FEnum_grDepthBiasLevel, /* 0x17 */ 29 | FEnum_grDepthBufferFunction, /* 0x18 */ 30 | FEnum_grDepthBufferMode, /* 0x19 */ 31 | FEnum_grDepthMask, /* 0x1a */ 32 | FEnum_grDisableAllEffects, /* 0x1b */ 33 | FEnum_grDitherMode, /* 0x1c */ 34 | FEnum_grDrawLine, /* 0x1d */ 35 | FEnum_grDrawPlanarPolygon, /* 0x1e */ 36 | FEnum_grDrawPlanarPolygonVertexList, /* 0x1f */ 37 | FEnum_grDrawPoint, /* 0x20 */ 38 | FEnum_grDrawPolygon, /* 0x21 */ 39 | FEnum_grDrawPolygonVertexList, /* 0x22 */ 40 | FEnum_grDrawTriangle, /* 0x23 */ 41 | FEnum_grErrorSetCallback, /* 0x24 */ 42 | FEnum_grFogColorValue, /* 0x25 */ 43 | FEnum_grFogMode, /* 0x26 */ 44 | FEnum_grFogTable, /* 0x27 */ 45 | FEnum_grGammaCorrectionValue, /* 0x28 */ 46 | FEnum_grGlideGetState, /* 0x29 */ 47 | FEnum_grGlideGetVersion, /* 0x2a */ 48 | FEnum_grGlideInit, /* 0x2b */ 49 | FEnum_grGlideSetState, /* 0x2c */ 50 | FEnum_grGlideShamelessPlug, /* 0x2d */ 51 | FEnum_grGlideShutdown, /* 0x2e */ 52 | FEnum_grHints, /* 0x2f */ 53 | FEnum_grLfbConstantAlpha, /* 0x30 */ 54 | FEnum_grLfbConstantDepth, /* 0x31 */ 55 | FEnum_grLfbLock, /* 0x32 */ 56 | FEnum_grLfbReadRegion, /* 0x33 */ 57 | FEnum_grLfbUnlock, /* 0x34 */ 58 | FEnum_grLfbWriteColorFormat, /* 0x35 */ 59 | FEnum_grLfbWriteColorSwizzle, /* 0x36 */ 60 | FEnum_grLfbWriteRegion, /* 0x37 */ 61 | FEnum_grRenderBuffer, /* 0x38 */ 62 | FEnum_grResetTriStats, /* 0x39 */ 63 | FEnum_grSplash, /* 0x3a */ 64 | FEnum_grSstConfigPipeline, /* 0x3b */ 65 | FEnum_grSstControl, /* 0x3c */ 66 | FEnum_grSstIdle, /* 0x3d */ 67 | FEnum_grSstIsBusy, /* 0x3e */ 68 | FEnum_grSstOrigin, /* 0x3f */ 69 | FEnum_grSstPerfStats, /* 0x40 */ 70 | FEnum_grSstQueryBoards, /* 0x41 */ 71 | FEnum_grSstQueryHardware, /* 0x42 */ 72 | FEnum_grSstResetPerfStats, /* 0x43 */ 73 | FEnum_grSstScreenHeight, /* 0x44 */ 74 | FEnum_grSstScreenWidth, /* 0x45 */ 75 | FEnum_grSstSelect, /* 0x46 */ 76 | FEnum_grSstStatus, /* 0x47 */ 77 | FEnum_grSstVRetraceOn, /* 0x48 */ 78 | FEnum_grSstVidMode, /* 0x49 */ 79 | FEnum_grSstVideoLine, /* 0x4a */ 80 | FEnum_grSstWinClose, /* 0x4b */ 81 | FEnum_grSstWinOpen, /* 0x4c */ 82 | FEnum_grTexCalcMemRequired, /* 0x4d */ 83 | FEnum_grTexClampMode, /* 0x4e */ 84 | FEnum_grTexCombine, /* 0x4f */ 85 | FEnum_grTexCombineFunction, /* 0x50 */ 86 | FEnum_grTexDetailControl, /* 0x51 */ 87 | FEnum_grTexDownloadMipMap, /* 0x52 */ 88 | FEnum_grTexDownloadMipMapLevel, /* 0x53 */ 89 | FEnum_grTexDownloadMipMapLevelPartial, /* 0x54 */ 90 | FEnum_grTexDownloadTable, /* 0x55 */ 91 | FEnum_grTexDownloadTablePartial, /* 0x56 */ 92 | FEnum_grTexFilterMode, /* 0x57 */ 93 | FEnum_grTexLodBiasValue, /* 0x58 */ 94 | FEnum_grTexMaxAddress, /* 0x59 */ 95 | FEnum_grTexMinAddress, /* 0x5a */ 96 | FEnum_grTexMipMapMode, /* 0x5b */ 97 | FEnum_grTexMultibase, /* 0x5c */ 98 | FEnum_grTexMultibaseAddress, /* 0x5d */ 99 | FEnum_grTexNCCTable, /* 0x5e */ 100 | FEnum_grTexSource, /* 0x5f */ 101 | FEnum_grTexTextureMemRequired, /* 0x60 */ 102 | FEnum_grTriStats, /* 0x61 */ 103 | FEnum_gu3dfGetInfo, /* 0x62 */ 104 | FEnum_gu3dfLoad, /* 0x63 */ 105 | FEnum_guAADrawTriangleWithClip, /* 0x64 */ 106 | FEnum_guAlphaSource, /* 0x65 */ 107 | FEnum_guColorCombineFunction, /* 0x66 */ 108 | FEnum_guDrawPolygonVertexListWithClip, /* 0x67 */ 109 | FEnum_guDrawTriangleWithClip, /* 0x68 */ 110 | FEnum_guEncodeRLE16, /* 0x69 */ 111 | FEnum_guEndianSwapBytes, /* 0x6a */ 112 | FEnum_guEndianSwapWords, /* 0x6b */ 113 | FEnum_guFogGenerateExp2, /* 0x6c */ 114 | FEnum_guFogGenerateExp, /* 0x6d */ 115 | FEnum_guFogGenerateLinear, /* 0x6e */ 116 | FEnum_guFogTableIndexToW, /* 0x6f */ 117 | FEnum_guMPDrawTriangle, /* 0x70 */ 118 | FEnum_guMPInit, /* 0x71 */ 119 | FEnum_guMPTexCombineFunction, /* 0x72 */ 120 | FEnum_guMPTexSource, /* 0x73 */ 121 | FEnum_guMovieSetName, /* 0x74 */ 122 | FEnum_guMovieStart, /* 0x75 */ 123 | FEnum_guMovieStop, /* 0x76 */ 124 | FEnum_guTexAllocateMemory, /* 0x77 */ 125 | FEnum_guTexChangeAttributes, /* 0x78 */ 126 | FEnum_guTexCombineFunction, /* 0x79 */ 127 | FEnum_guTexCreateColorMipMap, /* 0x7a */ 128 | FEnum_guTexDownloadMipMap, /* 0x7b */ 129 | FEnum_guTexDownloadMipMapLevel, /* 0x7c */ 130 | FEnum_guTexGetCurrentMipMap, /* 0x7d */ 131 | FEnum_guTexGetMipMapInfo, /* 0x7e */ 132 | FEnum_guTexMemQueryAvail, /* 0x7f */ 133 | FEnum_guTexMemReset, /* 0x80 */ 134 | FEnum_guTexSource, /* 0x81 */ 135 | FEnum_grLfbBegin, /* 0x82 */ 136 | FEnum_grLfbBypassMode, /* 0x83 */ 137 | FEnum_grLfbEnd, /* 0x84 */ 138 | FEnum_grLfbGetReadPtr, /* 0x85 */ 139 | FEnum_grLfbGetWritePtr, /* 0x86 */ 140 | FEnum_grLfbOrigin, /* 0x87 */ 141 | FEnum_grLfbWriteMode, /* 0x88 */ 142 | FEnum_grSstOpen, /* 0x89 */ 143 | FEnum_grSstPassthruMode, /* 0x8a */ 144 | FEnum_guFbReadRegion, /* 0x8b */ 145 | FEnum_guFbWriteRegion, /* 0x8c */ 146 | FEnum_grSplash0, /* 0x8d */ 147 | FEnum_grCoordinateSpace, /* 0x8e */ 148 | FEnum_grDepthRange, /* 0x8f */ 149 | FEnum_grDisable, /* 0x90 */ 150 | FEnum_grDrawVertexArray, /* 0x91 */ 151 | FEnum_grDrawVertexArrayContiguous, /* 0x92 */ 152 | FEnum_grEnable, /* 0x93 */ 153 | FEnum_grFinish, /* 0x94 */ 154 | FEnum_grFlush, /* 0x95 */ 155 | FEnum_grGet, /* 0x96 */ 156 | FEnum_grGetProcAddress, /* 0x97 */ 157 | FEnum_grGetString, /* 0x98 */ 158 | FEnum_grGlideGetVertexLayout, /* 0x99 */ 159 | FEnum_grGlideSetVertexLayout, /* 0x9a */ 160 | FEnum_grLfbWriteRegion3x, /* 0x9b */ 161 | FEnum_grLoadGammaTable, /* 0x9c */ 162 | FEnum_grQueryResolutions, /* 0x9d */ 163 | FEnum_grReset, /* 0x9e */ 164 | FEnum_grSelectContext, /* 0x9f */ 165 | FEnum_grSstWinClose3x, /* 0xa0 */ 166 | FEnum_grTexDownloadTable3x, /* 0xa1 */ 167 | FEnum_grTexDownloadTablePartial3x, /* 0xa2 */ 168 | FEnum_grTexNCCTable3x, /* 0xa3 */ 169 | FEnum_grVertexLayout, /* 0xa4 */ 170 | FEnum_grViewport, /* 0xa5 */ 171 | FEnum_guGammaCorrectionRGB, /* 0xa6 */ 172 | FEnum_grGetGammaTableExt, 173 | FEnum_grChromaRangeModeExt, 174 | FEnum_grChromaRangeExt, 175 | FEnum_grTexChromaModeExt, 176 | FEnum_grTexChromaRangeExt, 177 | FEnum_grColorCombineExt, 178 | FEnum_grAlphaCombineExt, 179 | FEnum_grTexColorCombineExt, 180 | FEnum_grTexAlphaCombineExt, 181 | FEnum_grAlphaBlendFunctionExt, 182 | FEnum_grConstantColorValueExt, 183 | FEnum_grColorMaskExt, 184 | FEnum_grTBufferWriteMaskExt, 185 | FEnum_grBufferClearExt, 186 | FEnum_grTextureBufferExt, 187 | FEnum_grTextureAuxBufferExt, 188 | FEnum_grAuxBufferExt, 189 | FEnum_grStencilFuncExt, 190 | FEnum_grStencilMaskExt, 191 | FEnum_grStencilOpExt, 192 | FEnum_grLfbConstantStencilExt, 193 | FEnum_grSstWinOpenExt, 194 | FEnum_zzG2xFuncEnum_max, 195 | } G2xFuncEnum; 196 | 197 | /* End - generated by mkgfuncs */ 198 | 199 | 200 | #define PAGE_SIZE 0x1000 201 | 202 | #define GLIDE_LFB_BASE 0xfb000000 203 | #define GLIDE_FIFO_BASE 0xfb500000 204 | #define MBUFO_BASE (0xE8U << 24) 205 | #define MBUFO_SIZE (0x02U << 24) 206 | 207 | #define ALIGNED(x) ((x%8)?(((x>>3)+1)<<3):x) 208 | #define ALIGNBO(x) ((x%16)?(((x>>4)+1)<<4):x) 209 | #define SHLFB_SIZE 0x300000 210 | #define GRSHM_SIZE 0x300000 211 | #define GRLFB_SIZE 0x200000 212 | #define FIRST_FIFO 24 213 | #define MAX_FIFO 0x10000 214 | #define MAX_DATA ((GRSHM_SIZE - (4*MAX_FIFO) - (64*1024)) >> 2) 215 | #define G3_LOD_TRANSLATE(lod) (0x8-lod) 216 | #define G3_ASPECT_TRANSLATE(aspect) (0x3-(aspect)) 217 | #define GR_MIPMAPLEVELMASK_BOTH (0x3) 218 | #define GR_PARAM_IDX(p) ((p&0xF0U)? ((p&0x01U)? ((p>>4) + 6):((p>>4) + GR_PARAM_Q)):(p-1)) 219 | #define GR_VERTEX_PARAMETER 0x29 220 | #define GR_FOG_TABLE_ENTRIES 0x04 221 | #define GR_GLIDE_STATE_SIZE 0x06 222 | #define GR_GLIDE_VERTEXLAYOUT_SIZE 0x07 223 | #define GR_NUM_BOARDS 0x0f 224 | #define GR_EXTENSION 0xa0 225 | #define GR_HARDWARE 0xa1 226 | #define GR_RENDERER 0xa2 227 | #define GR_VENDOR 0xa3 228 | #define GR_VERSION 0xa4 229 | 230 | /* Parameters for strips */ 231 | #define GR_PARAM_XY 0x01 232 | #define GR_PARAM_Z 0x02 233 | #define GR_PARAM_W 0x03 234 | #define GR_PARAM_Q 0x04 235 | #define GR_PARAM_FOG_EXT 0x05 236 | #define GR_PARAM_A 0x10 237 | #define GR_PARAM_RGB 0x20 238 | #define GR_PARAM_PARGB 0x30 239 | #define GR_PARAM_ST0 0x40 240 | #define GR_PARAM_ST1 GR_PARAM_ST0+1 241 | #define GR_PARAM_Q0 0x50 242 | #define GR_PARAM_Q1 GR_PARAM_Q0+1 243 | 244 | #define GR_PARAM_DISABLE 0x00 245 | #define GR_PARAM_ENABLE 0x01 246 | #define GLIDEPT_CRASH_RC 3000 247 | 248 | #ifdef QEMU_OSDEP_H 249 | #if (((QEMU_VERSION_MAJOR << 8) | \ 250 | (QEMU_VERSION_MINOR << 4) | \ 251 | QEMU_VERSION_MICRO) < 0x710) 252 | #define qemu_real_host_page_size() qemu_real_host_page_size 253 | #define qemu_real_host_page_mask() qemu_real_host_page_mask 254 | #endif 255 | #endif /* QEMU_OSDEP_H */ 256 | 257 | #define COMMIT_SIGN \ 258 | const char rev_[ALIGNED(1)] 259 | -------------------------------------------------------------------------------- /qemu-0/hw/3dfx/glidewnd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU 3Dfx Glide Pass-Through 3 | * 4 | * Copyright (c) 2018-2020 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #include "qemu/osdep.h" 22 | #include "qemu/timer.h" 23 | #include "ui/console.h" 24 | 25 | #include "glide2x_impl.h" 26 | 27 | #define DPRINTF(fmt, ...) \ 28 | do { fprintf(stderr, " " fmt "\n", ## __VA_ARGS__); } while(0) 29 | 30 | #define GLIDECFG "glide.cfg" 31 | 32 | struct tblGlideResolution { 33 | int w; 34 | int h; 35 | }; 36 | 37 | static struct tblGlideResolution tblRes[] = { 38 | { .w = 320, .h = 200 }, //0x0 39 | { .w = 320, .h = 240 }, //0x1 40 | { .w = 400, .h = 256 }, //0x2 41 | { .w = 512, .h = 384 }, //0x3 42 | { .w = 640, .h = 200 }, //0x4 43 | { .w = 640, .h = 350 }, //0x5 44 | { .w = 640, .h = 400 }, //0x6 45 | { .w = 640, .h = 480 }, //0x7 46 | { .w = 800, .h = 600 }, //0x8 47 | { .w = 960, .h = 720 }, //0x9 48 | { .w = 856, .h = 480 }, //0xa 49 | { .w = 512, .h = 256 }, //0xb 50 | { .w = 1024, .h = 768 }, //0xC 51 | { .w = 1280, .h = 1024 }, //0xD 52 | { .w = 1600, .h = 1200 }, //0xE 53 | { .w = 400, .h = 300 }, //0xF 54 | { .w = 0, .h = 0}, 55 | }; 56 | 57 | static int cfg_scaleGuiOff; 58 | static int cfg_scaleX; 59 | static int cfg_cntxMSAA; 60 | static int cfg_cntxSRGB; 61 | static int cfg_cntxVsyncOff; 62 | static int cfg_fpsLimit; 63 | static int cfg_lfbHandler; 64 | static int cfg_lfbNoAux; 65 | static int cfg_lfbLockDirty; 66 | static int cfg_lfbWriteMerge; 67 | static int cfg_lfbMapBufo; 68 | static int cfg_Annotate; 69 | static int cfg_MipMaps; 70 | static int cfg_traceFifo; 71 | static int cfg_traceFunc; 72 | static void *hwnd; 73 | 74 | #ifdef CONFIG_DARWIN 75 | int glide_mapbufo(mapbufo_t *bufo, int add) { return 0; } 76 | #endif 77 | #ifdef CONFIG_LINUX 78 | #include "system/kvm.h" 79 | 80 | int glide_mapbufo(mapbufo_t *bufo, int add) 81 | { 82 | int ret = (!cfg_lfbHandler && !cfg_lfbWriteMerge && cfg_lfbMapBufo)? kvm_enabled():0; 83 | 84 | if (ret && bufo && bufo->hva) { 85 | kvm_update_guest_pa_range(MBUFO_BASE | (bufo->hva & ((MBUFO_SIZE - 1) - (qemu_real_host_page_size() - 1))), 86 | bufo->mapsz + (bufo->hva & (qemu_real_host_page_size() - 1)), 87 | (void *)(bufo->hva & qemu_real_host_page_mask()), 88 | bufo->acc, add); 89 | bufo->hva = (add)? bufo->hva:0; 90 | } 91 | 92 | return ret; 93 | } 94 | #endif 95 | #ifdef CONFIG_WIN32 96 | #include "system/whpx.h" 97 | 98 | int glide_mapbufo(mapbufo_t *bufo, int add) 99 | { 100 | int ret = (!cfg_lfbHandler && !cfg_lfbWriteMerge && cfg_lfbMapBufo)? whpx_enabled():0; 101 | 102 | if (ret && bufo && bufo->hva) { 103 | whpx_update_guest_pa_range(MBUFO_BASE | (bufo->hva & ((MBUFO_SIZE - 1) - (qemu_real_host_page_size() - 1))), 104 | bufo->mapsz + (bufo->hva & (qemu_real_host_page_size() - 1)), 105 | (void *)(bufo->hva & qemu_real_host_page_mask()), 106 | bufo->acc, add); 107 | bufo->hva = (add)? bufo->hva:0; 108 | } 109 | 110 | return ret; 111 | } 112 | 113 | static int cfg_createWnd; 114 | static LONG WINAPI GlideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 115 | { 116 | switch(uMsg) { 117 | case WM_MOUSEACTIVATE: 118 | return MA_NOACTIVATEANDEAT; 119 | case WM_ACTIVATE: 120 | case WM_ACTIVATEAPP: 121 | case WM_NCLBUTTONDOWN: 122 | return 0; 123 | default: 124 | break; 125 | } 126 | return DefWindowProc(hWnd, uMsg, wParam, lParam); 127 | } 128 | 129 | static HWND CreateGlideWindow(const char *title, int w, int h) 130 | { 131 | HWND hWnd; 132 | WNDCLASS wc; 133 | static HINSTANCE hInstance = 0; 134 | 135 | if (!hInstance) { 136 | memset(&wc, 0, sizeof(WNDCLASS)); 137 | hInstance = GetModuleHandle(NULL); 138 | wc.style = CS_OWNDC; 139 | wc.lpfnWndProc = (WNDPROC)GlideWndProc; 140 | wc.lpszClassName = "GlideWnd"; 141 | 142 | if (!RegisterClass(&wc)) { 143 | DPRINTF("RegisterClass() faled, Error %08lx", GetLastError()); 144 | return NULL; 145 | } 146 | } 147 | 148 | RECT rect; 149 | rect.top = 0; rect.left = 0; 150 | rect.right = w; rect.bottom = h; 151 | AdjustWindowRectEx(&rect, WS_CAPTION, FALSE, 0); 152 | rect.right -= rect.left; 153 | rect.bottom -= rect.top; 154 | hWnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_NOACTIVATE, 155 | "GlideWnd", title, 156 | WS_CAPTION | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 157 | CW_USEDEFAULT, CW_USEDEFAULT, rect.right, rect.bottom, 158 | NULL, NULL, hInstance, NULL); 159 | GetClientRect(hWnd, &rect); 160 | DPRINTF(" window %lux%lu", rect.right, rect.bottom); 161 | ShowCursor(FALSE); 162 | ShowWindow(hWnd, SW_SHOW); 163 | 164 | return hWnd; 165 | } 166 | #endif // CONFIG_WIN32 167 | 168 | static int scaledRes(int w, float r) 169 | { 170 | int i; 171 | for (i = 0xE; i > 0x7; i--) 172 | if ((tblRes[i].w == w) && (((float)tblRes[i].h) / tblRes[i].w == r)) 173 | break; 174 | if (i == 0x7) { 175 | i = 0x10; 176 | tblRes[i].w = w; tblRes[i].h = (w * r); 177 | } 178 | return i; 179 | } 180 | 181 | int GRFifoTrace(void) { return cfg_traceFifo; } 182 | int GRFuncTrace(void) { return (cfg_traceFifo)? 0:cfg_traceFunc; } 183 | int glide_fpslimit(void) { return cfg_fpsLimit; } 184 | int glide_vsyncoff(void) { return cfg_cntxVsyncOff; } 185 | int glide_lfbmerge(void) { return (cfg_lfbMapBufo)? 0:cfg_lfbWriteMerge; } 186 | int glide_lfbdirty(void) { return (cfg_lfbMapBufo)? 0:cfg_lfbLockDirty; } 187 | int glide_lfbnoaux(void) { return cfg_lfbNoAux; } 188 | int glide_lfbmode(void) { return cfg_lfbHandler; } 189 | void glide_winres(const int res, int *w, int *h) 190 | { 191 | *w = tblRes[res].w; 192 | *h = tblRes[res].h; 193 | } 194 | 195 | int stat_window(const int res, void *opaque) 196 | { 197 | int stat, sel, glide_fullscreen; 198 | window_cb *disp_cb = opaque; 199 | sel = (cfg_scaleX)? scaledRes(cfg_scaleX, ((float)tblRes[res].h) / tblRes[res].w):res; 200 | stat = 1; 201 | glide_fullscreen = glide_gui_fullscreen(0, 0); 202 | 203 | if (stat) { 204 | int wndStat = glide_window_stat(disp_cb->activate); 205 | if (disp_cb->activate) { 206 | wndStat = (wndStat > 1)? (((tblRes[sel].h & 0x7FFFU) << 0x10) | tblRes[sel].w):wndStat; 207 | if (wndStat == (((tblRes[sel].h & 0x7FFFU) << 0x10) | tblRes[sel].w)) { 208 | DPRINTF(" %s %ux%u %s", (glide_fullscreen)? "fullscreen":"window", 209 | (wndStat & 0xFFFFU), (wndStat >> 0x10), (cfg_scaleX)? "(scaled)":""); 210 | stat = 0; 211 | } 212 | } 213 | else 214 | stat = wndStat; 215 | } 216 | return stat; 217 | } 218 | 219 | void fini_window(void *opaque) 220 | { 221 | window_cb *disp_cb = opaque; 222 | disp_cb->activate = 0; 223 | #ifdef CONFIG_WIN32 224 | if (cfg_createWnd) 225 | DestroyWindow(hwnd); 226 | if (hwnd) 227 | glide_release_window(disp_cb, &cwnd_glide2x); 228 | #endif 229 | #if defined(CONFIG_LINUX) || defined(CONFIG_DARWIN) 230 | if (hwnd) 231 | glide_release_window(disp_cb, &cwnd_glide2x); 232 | #endif 233 | hwnd = 0; 234 | cfg_traceFifo = 0; 235 | cfg_traceFunc = 0; 236 | } 237 | 238 | void init_window(const int res, const char *wndTitle, void *opaque) 239 | { 240 | window_cb *disp_cb = opaque; 241 | 242 | cfg_scaleGuiOff = 0; 243 | cfg_scaleX = 0; 244 | cfg_cntxMSAA = 0; 245 | cfg_cntxSRGB = 0; 246 | cfg_cntxVsyncOff = 0; 247 | cfg_fpsLimit = 0; 248 | cfg_lfbHandler = 0; 249 | cfg_lfbNoAux = 0; 250 | cfg_lfbLockDirty = 0; 251 | cfg_lfbWriteMerge = 0; 252 | cfg_lfbMapBufo = 0; 253 | cfg_Annotate = 0; 254 | cfg_MipMaps = 0; 255 | cfg_traceFifo = 0; 256 | cfg_traceFunc = 0; 257 | 258 | FILE *fp = fopen(GLIDECFG, "r"); 259 | if (fp != NULL) { 260 | char line[32]; 261 | int i, c; 262 | while (fgets(line, 32, fp)) { 263 | i = sscanf(line, "ScaleGuiOff,%d", &c); 264 | cfg_scaleGuiOff = ((i == 1) && c)? 1:cfg_scaleGuiOff; 265 | i = sscanf(line, "ScaleWidth,%d", &c); 266 | cfg_scaleX = ((i == 1) && c)? c:cfg_scaleX; 267 | i = sscanf(line, "ContextMSAA,%d", &c); 268 | cfg_cntxMSAA = (i == 1)? ((c & 0x03U) << 2):cfg_cntxMSAA; 269 | i = sscanf(line, "ContextSRGB,%d", &c); 270 | cfg_cntxSRGB = ((i == 1) && c)? 1:cfg_cntxSRGB; 271 | i = sscanf(line, "ContextVsyncOff,%d", &c); 272 | cfg_cntxVsyncOff = ((i == 1) && c)? 1:cfg_cntxVsyncOff; 273 | i = sscanf(line, "FpsLimit,%d", &c); 274 | cfg_fpsLimit = (i == 1)? (c & 0x7FU):cfg_fpsLimit; 275 | i = sscanf(line, "LfbHandler,%d", &c); 276 | cfg_lfbHandler = ((i == 1) && c)? 1:cfg_lfbHandler; 277 | i = sscanf(line, "LfbNoAux,%d", &c); 278 | cfg_lfbNoAux = ((i == 1) && c)? 1:cfg_lfbNoAux; 279 | i = sscanf(line, "LfbLockDirty,%d", &c); 280 | cfg_lfbLockDirty = ((i == 1) && c)? 1:cfg_lfbLockDirty; 281 | i = sscanf(line, "LfbWriteMerge,%d", &c); 282 | cfg_lfbWriteMerge = ((i == 1) && c)? 1:cfg_lfbWriteMerge; 283 | i = sscanf(line, "LfbMapBufo,%d", &c); 284 | cfg_lfbMapBufo = ((i == 1) && c)? 1:cfg_lfbMapBufo; 285 | i = sscanf(line, "Annotate,%d", &c); 286 | cfg_Annotate = ((i == 1) && c)? 1:cfg_Annotate; 287 | i = sscanf(line, "MipMaps,%d", &c); 288 | cfg_MipMaps = ((i == 1) && c)? 1:cfg_MipMaps; 289 | i = sscanf(line, "FifoTrace,%d", &c); 290 | cfg_traceFifo = ((i == 1) && c)? 1:cfg_traceFifo; 291 | i = sscanf(line, "FuncTrace,%d", &c); 292 | cfg_traceFunc = ((i == 1) && c)? (c % 3):cfg_traceFunc; 293 | } 294 | fclose(fp); 295 | } 296 | 297 | int gui_height, glide_fullscreen = glide_gui_fullscreen(0, &gui_height); 298 | cfg_scaleGuiOff = (glide_fullscreen || cfg_scaleX)? 1:cfg_scaleGuiOff; 299 | cfg_scaleX = (!cfg_scaleGuiOff && (gui_height > 480) && (gui_height > tblRes[res].h))? 300 | (int)((1.f * tblRes[res].w * gui_height) / tblRes[res].h):cfg_scaleX; 301 | 302 | #define WRAPPER_FLAG_WINDOWED 0x01 303 | #define WRAPPER_FLAG_MIPMAPS 0x02 304 | #define WRAPPER_FLAG_ANNOTATE 0x10 305 | #define WRAPPER_FLAG_FRAMEBUFFER_SRGB 0x20 306 | #define WRAPPER_FLAG_VSYNCOFF 0x40 307 | #define WRAPPER_FLAG_QEMU 0x80 308 | uint32_t flags = (glide_fullscreen)? WRAPPER_FLAG_QEMU: 309 | (WRAPPER_FLAG_QEMU | WRAPPER_FLAG_WINDOWED); 310 | flags |= (cfg_MipMaps)? WRAPPER_FLAG_MIPMAPS:0; 311 | flags |= (cfg_Annotate)? WRAPPER_FLAG_ANNOTATE:0; 312 | flags |= (cfg_cntxVsyncOff)? WRAPPER_FLAG_VSYNCOFF:0; 313 | flags |= (cfg_cntxSRGB)? WRAPPER_FLAG_FRAMEBUFFER_SRGB:0; 314 | flags |= cfg_cntxMSAA; 315 | 316 | int sel = res; 317 | if (cfg_scaleX) { 318 | sel = scaledRes(cfg_scaleX, ((float)tblRes[res].h) / tblRes[res].w); 319 | conf_glide2x(flags, tblRes[sel].w); 320 | } 321 | else 322 | conf_glide2x(flags, 0); 323 | 324 | disp_cb->activate = 1; 325 | hwnd = (void *)(uintptr_t)(((tblRes[sel].h & 0x7FFFU) << 0x10) | tblRes[sel].w); 326 | #ifdef CONFIG_WIN32 327 | if (cfg_createWnd) 328 | hwnd = CreateGlideWindow(wndTitle, tblRes[sel].w, tblRes[sel].h); 329 | glide_prepare_window(((tblRes[sel].h & 0x7FFFU) << 0x10) | tblRes[sel].w, 330 | (cfg_cntxMSAA > 8)? 16:cfg_cntxMSAA, disp_cb, &cwnd_glide2x); 331 | #endif 332 | #if defined(CONFIG_LINUX) || defined(CONFIG_DARWIN) 333 | glide_prepare_window(((tblRes[sel].h & 0x7FFFU) << 0x10) | tblRes[sel].w, 334 | (cfg_cntxMSAA > 8)? 16:cfg_cntxMSAA, disp_cb, &cwnd_glide2x); 335 | #endif 336 | } 337 | 338 | typedef struct { 339 | uint64_t last; 340 | uint32_t fcount; 341 | float ftime; 342 | } STATSFX, * PSTATSFX; 343 | 344 | static STATSFX fxstats = { .last = 0 }; 345 | 346 | static void profile_dump(void) 347 | { 348 | PSTATSFX p = &fxstats; 349 | if (p->last) { 350 | p->last = 0; 351 | fprintf(stderr, "%-4u frames in %-4.1f seconds, %-4.1f FPS%-8s\r", p->fcount, p->ftime, (p->fcount / p->ftime)," "); 352 | fflush(stderr); 353 | } 354 | } 355 | 356 | static void profile_last(void) 357 | { 358 | PSTATSFX p = &fxstats; 359 | if (p->last) { 360 | p->last = 0; 361 | fprintf(stderr, "%-64s\r", " "); 362 | } 363 | } 364 | 365 | #ifndef NANOSECONDS_PER_SECOND 366 | #define NANOSECONDS_PER_SECOND get_ticks_per_sec() 367 | #endif 368 | 369 | static void profile_stat(void) 370 | { 371 | uint64_t curr; 372 | int i; 373 | 374 | PSTATSFX p = &fxstats; 375 | 376 | if (p->last == 0) { 377 | p->fcount = 0; 378 | p->ftime = 0; 379 | p->last = (glide_gui_fullscreen(0, 0))? 0:get_clock(); 380 | return; 381 | } 382 | 383 | curr = get_clock(); 384 | p->fcount++; 385 | p->ftime += (curr - p->last) * (1.0f / NANOSECONDS_PER_SECOND); 386 | p->last = curr; 387 | 388 | i = (GRFifoTrace() || GRFuncTrace())? 0:((int) p->ftime); 389 | if (i && ((i % 5) == 0)) 390 | profile_dump(); 391 | } 392 | 393 | void glidestat(PPERFSTAT s) 394 | { 395 | cfg_traceFunc = 1; 396 | s->stat = &profile_stat; 397 | s->last = &profile_last; 398 | } 399 | 400 | -------------------------------------------------------------------------------- /qemu-1/hw/mesa/mesagl_blit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QEMU MESA GL Pass-Through 3 | * 4 | * Copyright (c) ... in a Galaxy far, far away ... 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU General Public License 8 | * as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public 17 | * License along with this library; 18 | * if not, see . 19 | */ 20 | 21 | #include "qemu/osdep.h" 22 | 23 | #include "mesagl_impl.h" 24 | 25 | int mesa_gui_fullscreen(const void *); 26 | 27 | void MesaContextAttest(const char *div, int *out) 28 | { 29 | const char *aiv[] = { ATTEST_IV }; 30 | *out = 1; 31 | for (int i = 0; aiv[i]; i++) { 32 | *out = memcmp(div, aiv[i], strlen(aiv[i]))? 0:1; 33 | if (*out) break; 34 | } 35 | } 36 | 37 | static struct { 38 | unsigned vao, vbo; 39 | int prog, vert, frag, black; 40 | int adj, flip, has_swap; 41 | } blit; 42 | static unsigned blit_program_setup(void) 43 | { 44 | MESA_PFN(PFNGLATTACHSHADERPROC, glAttachShader); 45 | MESA_PFN(PFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation); 46 | MESA_PFN(PFNGLCOMPILESHADERPROC, glCompileShader); 47 | MESA_PFN(PFNGLCREATEPROGRAMPROC, glCreateProgram); 48 | MESA_PFN(PFNGLCREATESHADERPROC, glCreateShader); 49 | MESA_PFN(PFNGLGETINTEGERVPROC, glGetIntegerv); 50 | MESA_PFN(PFNGLGETSTRINGPROC, glGetString); 51 | MESA_PFN(PFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation); 52 | MESA_PFN(PFNGLLINKPROGRAMPROC, glLinkProgram); 53 | MESA_PFN(PFNGLSHADERSOURCEPROC, glShaderSource); 54 | MESA_PFN(PFNGLUSEPROGRAMPROC, glUseProgram); 55 | const char *vert_src[] = { 56 | "#version 120\n" 57 | "attribute vec2 in_position;\n" 58 | "varying vec2 texcoord;\n" 59 | "void main() {\n" 60 | " texcoord = vec2(1 + in_position.x, 1 + in_position.y) * 0.5;\n" 61 | " gl_Position = vec4(in_position, 0, 1);\n" 62 | "}\n", 63 | "#version 140\n" 64 | "#extension GL_ARB_explicit_attrib_location : require\n" 65 | "layout (location = 0) in vec2 in_position;\n" 66 | "out vec2 texcoord;\n" 67 | "void main() {\n" 68 | " texcoord = vec2(1 + in_position.x, 1 + in_position.y) * 0.5;\n" 69 | " gl_Position = vec4(in_position, 0, 1);\n" 70 | "}\n" 71 | }; 72 | const char *frag_src[] = { 73 | "#version 120\n" 74 | "uniform sampler2D screen_texture;\n" 75 | "uniform bool frag_just_black;\n" 76 | "varying vec2 texcoord;\n" 77 | "void main() {\n" 78 | " if (frag_just_black)\n" 79 | " gl_FragColor = vec4(0,0,0,1);\n" 80 | " else\n" 81 | " gl_FragColor = texture2D(screen_texture, texcoord);\n" 82 | "}\n", 83 | "#version 140\n" 84 | "uniform sampler2D screen_texture;\n" 85 | "uniform bool frag_just_black;\n" 86 | "in vec2 texcoord;\n" 87 | "out vec4 fragColor;\n" 88 | "void main() {\n" 89 | " if (frag_just_black)\n" 90 | " fragColor = vec4(0,0,0,1);\n" 91 | " else\n" 92 | " fragColor = texture(screen_texture, texcoord);\n" 93 | "}\n" 94 | }; 95 | int prog; 96 | if (!blit.prog) { 97 | int i = memcmp(PFN_CALL(glGetString(GL_VERSION)), "2.1 Metal", 98 | sizeof("2.1 Metal") - 1)? 1:0, 99 | srclen = ALIGNED((strlen(vert_src[i])+1)); 100 | char *srcbuf = g_new0(char, srclen); 101 | const char *vert_buf[] = { srcbuf }; 102 | strncpy(srcbuf, vert_src[i], srclen); 103 | if (blit.flip) { 104 | char *flip = strstr(srcbuf, "+ in_position.y"); 105 | *flip = '-'; 106 | } 107 | blit.vert = PFN_CALL(glCreateShader(GL_VERTEX_SHADER)); 108 | PFN_CALL(glShaderSource(blit.vert, 1, vert_buf, 0)); 109 | PFN_CALL(glCompileShader(blit.vert)); 110 | g_free(srcbuf); 111 | blit.frag = PFN_CALL(glCreateShader(GL_FRAGMENT_SHADER)); 112 | PFN_CALL(glShaderSource(blit.frag, 1, &frag_src[i], 0)); 113 | PFN_CALL(glCompileShader(blit.frag)); 114 | prog = PFN_CALL(glCreateProgram()); 115 | PFN_CALL(glAttachShader(prog, blit.vert)); 116 | PFN_CALL(glAttachShader(prog, blit.frag)); 117 | if (!i) 118 | PFN_CALL(glBindAttribLocation(prog, 0, "in_position")); 119 | PFN_CALL(glLinkProgram(prog)); 120 | blit.prog = prog; 121 | } 122 | PFN_CALL(glGetIntegerv(GL_CURRENT_PROGRAM, &prog)); 123 | PFN_CALL(glUseProgram(blit.prog)); 124 | blit.black = PFN_CALL(glGetUniformLocation(blit.prog, "frag_just_black")); 125 | return prog; 126 | } 127 | void MesaBlitFree(void) 128 | { 129 | MESA_PFN(PFNGLDELETEBUFFERSPROC, glDeleteBuffers); 130 | MESA_PFN(PFNGLDELETEPROGRAMPROC, glDeleteProgram); 131 | MESA_PFN(PFNGLDELETESHADERPROC, glDeleteShader); 132 | MESA_PFN(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays); 133 | if (blit.prog) { 134 | PFN_CALL(glDeleteProgram(blit.prog)); 135 | PFN_CALL(glDeleteShader(blit.vert)); 136 | PFN_CALL(glDeleteShader(blit.frag)); 137 | } 138 | if (blit.vbo) 139 | PFN_CALL(glDeleteBuffers(1, &blit.vbo)); 140 | if (blit.vao) 141 | PFN_CALL(glDeleteVertexArrays(1, &blit.vao)); 142 | memset(&blit, 0, sizeof(blit)); 143 | } 144 | struct save_states { 145 | int view[4]; 146 | int draw_binding, read_binding, texture, texture_binding, 147 | vao_binding, vbo_binding, boolean_map; 148 | }; 149 | #define FRAMEBUFFER_SRGB_(s) \ 150 | (s.boolean_map & 2) 151 | struct states_mapping { 152 | int gl_enum, *iv; 153 | }; 154 | static const int boolean_states[] = { 155 | GL_FRAMEBUFFER_SRGB, 156 | GL_BLEND, 157 | GL_CULL_FACE, 158 | GL_DEPTH_TEST, 159 | GL_SCISSOR_TEST, 160 | GL_STENCIL_TEST, 161 | 0, 162 | }; 163 | static int blit_program_buffer(void *save_map, const int size, const void *data) 164 | { 165 | MESA_PFN(PFNGLBINDBUFFERPROC, glBindBuffer); 166 | MESA_PFN(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray); 167 | MESA_PFN(PFNGLBUFFERDATAPROC, glBufferData); 168 | MESA_PFN(PFNGLDISABLEPROC, glDisable); 169 | MESA_PFN(PFNGLGENBUFFERSPROC, glGenBuffers); 170 | MESA_PFN(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays); 171 | MESA_PFN(PFNGLGETINTEGERVPROC, glGetIntegerv); 172 | MESA_PFN(PFNGLISENABLEDPROC, glIsEnabled); 173 | 174 | struct save_states *last = (struct save_states *)save_map; 175 | 176 | struct states_mapping mapping[] = { 177 | { GL_VIEWPORT, last->view }, 178 | { GL_FRAMEBUFFER_BINDING, &last->draw_binding }, 179 | { GL_READ_FRAMEBUFFER_BINDING, &last->read_binding }, 180 | { GL_ACTIVE_TEXTURE, &last->texture }, 181 | { GL_TEXTURE_BINDING_2D, &last->texture_binding }, 182 | { GL_VERTEX_ARRAY_BINDING, &last->vao_binding }, 183 | { GL_ARRAY_BUFFER_BINDING, &last->vbo_binding }, 184 | { GL_CONTEXT_PROFILE_MASK, &last->boolean_map }, 185 | { 0, 0 }, 186 | }; 187 | for (int i = 0; mapping[i].gl_enum; i++) 188 | PFN_CALL(glGetIntegerv(mapping[i].gl_enum, mapping[i].iv)); 189 | last->boolean_map &= GL_CONTEXT_CORE_PROFILE_BIT; 190 | 191 | for (int i = 0; boolean_states[i]; i++) { 192 | last->boolean_map |= PFN_CALL(glIsEnabled(boolean_states[i]))? (2 << i):0; 193 | if (last->boolean_map & (2 << i)) 194 | PFN_CALL(glDisable(boolean_states[i])); 195 | } 196 | if (last->boolean_map & GL_CONTEXT_CORE_PROFILE_BIT) { 197 | if (!blit.vao) 198 | PFN_CALL(glGenVertexArrays(1, &blit.vao)); 199 | PFN_CALL(glBindVertexArray(blit.vao)); 200 | } 201 | if (!blit.vbo) 202 | PFN_CALL(glGenBuffers(1, &blit.vbo)); 203 | PFN_CALL(glBindBuffer(GL_ARRAY_BUFFER, blit.vbo)); 204 | PFN_CALL(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW)); 205 | return 0; 206 | } 207 | static void blit_restore_savemap(const void *save_map) 208 | { 209 | MESA_PFN(PFNGLBINDBUFFERPROC, glBindBuffer); 210 | MESA_PFN(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray); 211 | MESA_PFN(PFNGLENABLEPROC, glEnable); 212 | 213 | struct save_states *last = (struct save_states *)save_map; 214 | 215 | if (last->boolean_map & GL_CONTEXT_CORE_PROFILE_BIT) 216 | PFN_CALL(glBindVertexArray(last->vao_binding)); 217 | 218 | PFN_CALL(glBindBuffer(GL_ARRAY_BUFFER, last->vbo_binding)); 219 | 220 | for (int i = 0; boolean_states[i]; i++) { 221 | if ((boolean_states[i] == GL_FRAMEBUFFER_SRGB) 222 | && !(last->read_binding == last->draw_binding)) 223 | continue; 224 | if (last->boolean_map & (2 << i)) 225 | PFN_CALL(glEnable(boolean_states[i])); 226 | } 227 | } 228 | void MesaBlitScale(void) 229 | { 230 | MESA_PFN(PFNGLACTIVETEXTUREPROC, glActiveTexture); 231 | MESA_PFN(PFNGLBINDTEXTUREPROC, glBindTexture); 232 | MESA_PFN(PFNGLBLITFRAMEBUFFERPROC, glBlitFramebuffer); 233 | MESA_PFN(PFNGLCOPYTEXIMAGE2DPROC, glCopyTexImage2D); 234 | MESA_PFN(PFNGLDELETETEXTURESPROC, glDeleteTextures); 235 | MESA_PFN(PFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray); 236 | MESA_PFN(PFNGLDRAWARRAYSPROC, glDrawArrays); 237 | MESA_PFN(PFNGLENABLEPROC, glEnable); 238 | MESA_PFN(PFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray); 239 | MESA_PFN(PFNGLGENTEXTURESPROC, glGenTextures); 240 | MESA_PFN(PFNGLTEXPARAMETERIPROC, glTexParameteri); 241 | MESA_PFN(PFNGLUNIFORM1IPROC, glUniform1i); 242 | MESA_PFN(PFNGLUSEPROGRAMPROC, glUseProgram); 243 | MESA_PFN(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer); 244 | MESA_PFN(PFNGLVIEWPORTPROC, glViewport); 245 | 246 | int v[4], fullscreen = mesa_gui_fullscreen(v); 247 | blit.has_swap = 1; 248 | 249 | if (blit.adj) { 250 | blit.adj = !blit.adj; 251 | return; 252 | } 253 | blit.flip = ScalerBlitFlip(); 254 | 255 | if (DrawableContext() 256 | && (v[3] > (v[1] & 0x7FFFU)) 257 | && (!fullscreen || RenderScalerOff())) { 258 | unsigned screen_texture, w = v[0], h = v[1] & 0x7FFFU, 259 | last_prog = blit_program_setup(); 260 | int aspect = (v[1] & (1 << 15))? 0:1, 261 | offs_x = v[2] - ((v[0] * 1.f * v[3]) / (v[1] & 0x7FFFU)); 262 | offs_x >>= 1; 263 | v[0] *= (1.f * v[3]) / (v[1] & 0x7FFFU); 264 | v[1] = v[3]; 265 | const float coord[] = { 266 | 1-((1.f * v[2] - v[0]) / v[2]),-1, 1,-1, 267 | 1-((1.f * v[2] - v[0]) / v[2]), 1, 1, 1, 268 | -1,-1, ((1.f * v[2] - v[0]) / v[2])-1,-1, 269 | -1, 1, ((1.f * v[2] - v[0]) / v[2])-1, 1, 270 | -1,-1, 1,-1, -1,1, 1,1, 271 | }; 272 | 273 | struct save_states save_map; 274 | 275 | if (!blit_program_buffer(&save_map, sizeof(coord), coord)) { 276 | PFN_CALL(glUniform1i(blit.black, GL_TRUE)); 277 | PFN_CALL(glViewport(0,0, v[2], v[3])); 278 | PFN_CALL(glEnableVertexAttribArray(0)); 279 | PFN_CALL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0)); 280 | if (save_map.read_binding == save_map.draw_binding) { 281 | PFN_CALL(glActiveTexture(GL_TEXTURE0)); 282 | PFN_CALL(glGenTextures(1, &screen_texture)); 283 | PFN_CALL(glBindTexture(GL_TEXTURE_2D, screen_texture)); 284 | PFN_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); 285 | PFN_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); 286 | PFN_CALL(glCopyTexImage2D(GL_TEXTURE_2D, 0, (FRAMEBUFFER_SRGB_(save_map) && ScalerSRGBCorr())? 287 | GL_SRGB:GL_RGBA, 0,0, w,h, 0)); 288 | if (aspect) { 289 | PFN_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); /* clear */ 290 | PFN_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 4, 4)); /* clear */ 291 | PFN_CALL(glViewport(offs_x,0, v[0],v[1])); 292 | } 293 | PFN_CALL(glUniform1i(blit.black, GL_FALSE)); 294 | PFN_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 8, 4)); /* scale */ 295 | PFN_CALL(glDeleteTextures(1, &screen_texture)); 296 | PFN_CALL(glActiveTexture(save_map.texture)); 297 | PFN_CALL(glBindTexture(GL_TEXTURE_2D, save_map.texture_binding)); 298 | } 299 | else { 300 | if (FRAMEBUFFER_SRGB_(save_map)) 301 | PFN_CALL(glEnable(boolean_states[0])); 302 | if (aspect) { 303 | PFN_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); /* clear */ 304 | PFN_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 4, 4)); /* clear */ 305 | PFN_CALL(glBlitFramebuffer(0,0,w,h, offs_x,v[1],v[0]+offs_x,0, 306 | (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT), 307 | GL_NEAREST)); 308 | } 309 | else 310 | PFN_CALL(glBlitFramebuffer(0,0,w,h, 0,v[3],v[2],0, 311 | (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT), 312 | GL_NEAREST)); 313 | } 314 | PFN_CALL(glDisableVertexAttribArray(0)); 315 | PFN_CALL(glViewport(save_map.view[0], save_map.view[1], 316 | save_map.view[2], save_map.view[3])); 317 | blit_restore_savemap(&save_map); 318 | } 319 | PFN_CALL(glUseProgram(last_prog)); 320 | } 321 | } 322 | 323 | void MesaRenderScaler(const uint32_t FEnum, void *args) 324 | { 325 | MESA_PFN(PFNGLGETINTEGERVPROC, glGetIntegerv); 326 | int v[4], fullscreen = mesa_gui_fullscreen(v), framebuffer_binding, blit_adj = 0; 327 | uint32_t *box; 328 | 329 | PFN_CALL(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer_binding)); 330 | 331 | switch(FEnum) { 332 | case FEnum_glBlitFramebuffer: 333 | case FEnum_glBlitFramebufferEXT: 334 | box = &((uint32_t *)args)[4]; 335 | blit_adj = 1; 336 | break; 337 | case FEnum_glScissor: 338 | case FEnum_glViewport: 339 | box = args; 340 | break; 341 | case GL_VIEWPORT: 342 | box = args; 343 | if (!box[0] && !box[1] && (v[3] > (v[1] & 0x7FFFU))) { 344 | box[2] = v[0]; 345 | box[3] = v[1] & 0x7FFFU; 346 | } 347 | /* fall through */ 348 | default: 349 | return; 350 | } 351 | if (DrawableContext() && !framebuffer_binding 352 | && (v[3] > (v[1] & 0x7FFFU)) 353 | && (fullscreen || !blit.has_swap) 354 | && !RenderScalerOff()) { 355 | int aspect = (v[1] & (1 << 15))? 0:1, 356 | offs_x = v[2] - ((v[0] * 1.f * v[3]) / (v[1] & 0x7FFFU)); 357 | offs_x >>= 1; 358 | for (int i = 0; i < 4; i++) 359 | box[i] *= (1.f * v[3]) / (v[1] & 0x7FFFU); 360 | if (aspect) { 361 | box[0] += offs_x; 362 | box[2] += (blit_adj)? box[0]:0; 363 | } 364 | else { 365 | box[0] *= (1.f * v[2]) / box[2]; 366 | box[2] = v[2]; 367 | } 368 | blit.adj = blit_adj; 369 | } 370 | } 371 | 372 | --------------------------------------------------------------------------------