├── 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 | [](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 |
--------------------------------------------------------------------------------